Translate

2018年1月4日木曜日

TensorFlow 1.5.0 rc0がリリースされた

1月4日仕事始めの日に出社して、
同僚に新年の挨拶を済ませふと席に戻ると、


というツィートがタイムラインに入ってきた..


..新年早々マイナーバージョンアップかよ..1.4.1でたばっかじゃん...

Docker Hubにも 1.5.0-rc のイメージが既に投稿されているし..

..ということでリリース記事を翻訳してみた。
#参照される方はat your own riskでお願いします。
------

TensorFlow 1.5.0-rc0



アセット




リリース1.5.0


Breaking Changes

  • 予めビルドされたバイナリは、CUDA 9 とcuDNN 7 に対して構築されています。
  • 私たちのLinuxバイナリは、ubuntu 16コンテナを使用してビルドされており、ubuntu 14ではglibcの非互換性の問題が発生する可能性があります。
  • 1.6リリースからは、あらかじめビルドされたバイナリはAVX命令を使用します。
  • 古いCPUでTFが破損する可能性があります。

主な機能と改善点

  プレビュー版が利用可能になりました。
  • TensorFlow Lite
  デベロッパープレビューが利用可能になりました。
  • CUDA 9 および cuDNN 7 のサポート


バグフィックス、その他の変更

  • auto_correlationtf.contrib.distributions に追加。
  • DenseFlipout 確率的層を追加。
  • DenseVariational 他の確率的層のためのより単純なテンプレートとして再標準化。
  • tf.contrib.distributions QuadratureCompoundクラスはバッチをサポート。
  • Stream::BlockHostUntilDone boolではなくStatusを返却。
  • GCSファイルシステムの要求タイムアウトをカスタマイズ。


貢献への謝辞


このリリースには、Google社の多くの人々からの貢献によるものです:
4d55397500, Abdullah Alrasheed, abenmao, Adam Salvail, Aditya Dhulipala, Ag Ramesh,
Akimasa Kimura, Alan Du, Alan Yee, Alexander, Amit Kushwaha, Amy, Andrei Costinescu,
Andrei Nigmatulin, Andrew Erlichson, Andrew Myers, Andrew Stepanov, Androbin, AngryPowman,
Anish Shah, Anton Daitche, Artsiom Chapialiou, asdf2014, Aseem Raj Baranwal, Ash Hall,
Bart Kiers, Batchu Venkat Vishal, ben, Ben Barsdell, Bill Piel, Carl Thomé, Catalin Voss,
Changming Sun, Chengzhi Chen, Chi Zeng, Chris Antaki, Chris Donahue, Chris Oelmueller,
Chris Tava, Clayne Robison, Codrut, Courtial Florian, Dalmo Cirne, Dan J, Darren Garvey,
David Kristoffersson, David Norman, David RöThlisberger, DavidNorman, Dhruv, DimanNe,
Dorokhov, Duncan Mac-Vicar P, EdwardDixon, EMCP, error.d, FAIJUL, Fan Xia,
Francois Xavier, Fred Reiss, Freedom" Koan-Sin Tan, Fritz Obermeyer, Gao, Xiang,
Guenther Schmuelling, Guo Yejun (郭叶军), Hans Gaiser, HectorSVC, Hyungsuk Yoon,
James Pruegsanusak, Jay Young, Jean Wanka, Jeff Carpenter, Jeremy Rutman, Jeroen BéDorf,
Jett Jones, Jimmy Jia, jinghuangintel, jinze1994, JKurland, Joel Hestness, joetoth,
John B Nelson, John Impallomeni, John Lawson, Jonas, Jonathan Dekhtiar, joshkyh, Jun Luan,
Jun Mei, Kai Sasaki, Karl Lessard, karl@kubx.ca, Kb Sriram, Kenichi Ueno, Kevin Slagle,
Kongsea, Lakshay Garg, lhlmgr, Lin Min, liu.guangcong, Loki Der Quaeler, Louie Helm,
lucasmoura, Luke Iwanski, Lyndon White, Mahmoud Abuzaina, Marcel Puyat, Mark Aaron Shirley,
Michele Colombo, MtDersvan, Namrata-Ibm, Nathan Luehr, Naurril, Nayana Thorat, Nicolas Lopez,
Niranjan Hasabnis, Nolan Liu, Nouce, Oliver Hennigh, osdamv, Patrik Erdes,
Patryk Chrabaszcz, Pavel Christof, Penghao Cen, postBG, Qingqing Cao, Qingying Chen, qjivy,
Raphael, Rasmi, raymondxyang, Renze Yu, resec, Roffel, Ruben Vereecken, Ryohei Kuroki,
sandipmgiri, Santiago Castro, Scott Kirkland, Sean Vig, Sebastian Raschka, Sebastian Weiss,
Sergey Kolesnikov, Sergii Khomenko, Shahid, Shivam Kotwalia, Stuart Berg, Sumit Gouthaman,
superzerg, Sven Mayer, tetris, Ti Zhou, Tiago Freitas Pereira, Tian Jin, Tomoaki Oiki,
Vaibhav Sood, vfdev, Vivek Rane, Vladimir Moskva, wangqr, Weber Xie, Will Frey,
Yan Facai (颜发才), yanivbl6, Yaroslav Bulatov, Yixing Lao, Yong Tang, youkaichao,
Yuan (Terry) Tang, Yue Zhang, Yuxin Wu, Ziming Dong, ZxYuan, 黄璞

問題を提起した方、解決するのを助け、質問し、質問に答えてくれたすべての方にも感謝しています。

-----

TensorFlow Liteは聞いたことあるけど、
Eager Execution?

..初めて聞いた
..ということでリンク先のREADME.mdも翻訳してみた。

-----

Eager Execution


警告:これはプレビュ版/プレα版です。APIとパフォーマンスの特性は変更される可能性があります。

Eager Executionは、命令型プログラミングスタイル(NumPy)を提供するTensorFlowへの実験的なインターフェイスです。Eager Execution を有効にすると、TensorFlow操作はすぐに実行されます(あなたは事前に構築されたグラフを Session.run()で実行しません)。

たとえば、次のようなTensorFlowでの単純な計算を考えてみましょう。


x = tf.placeholder(tf.float32, shape=[1, 1])
m = tf.matmul(x, x)

with tf.Session() as sess:
  print(sess.run(m, feed_dict={x: [[2.]]}))

#  [[4.]] とprintされる

Eager execution はこの術をよりシンプルにします:


x = [[2.]]
m = tf.matmul(x, x)

print(m)

警告


この機能は初期段階にあり、分散GPUトレーニングとマルチGPUトレーニングとCPUパフォーマンスのスムーズなサポートという点ではまだまだ課題が残っています。
 




インストール


Eager Execution はまだ TensorFlow リリースの一部ではないため、ソースを使用して ビルドするか、最新の夜間ビルドを必要とします。夜間ビルドは次のように利用できます。



最新の夜間ビルドDockerイメージを起動するには次のコマンドを実行します:


# GPUを使う場合は、https://github.com/NVIDIA/nvidia-docker を使ってください
nvidia-docker pull tensorflow/tensorflow:nightly-gpu
nvidia-docker run -it -p 8888:8888 tensorflow/tensorflow:nightly-gpu

# GPUがない場合、CPUのみ版を使ってください。
docker pull tensorflow/tensorflow:nightly
docker run -it -p 8888:8888 tensorflow/tensorflow:nightly

Jupiterのノートブック環境では、ブラウザの http://localhost:8888 にアクセスしてください。

ドキュメンテーション

TensorFlowにおける Eager Execution の概要ついては、以下を参照してください。



変更履歴


-----

ああ、TensorFlowを知らない人がいきなりソースコードを読もうとするとき
一番のヤマが"計算グラフ"だけど、
それをなくそうってことか..
そうすると手数の多いTensorFlowがほかのライブラリとの優位性をうしなうんじゃないのかな..

それよりKerasを使えば良いってことにならない?

..生暖かく想像するとEoDと称してJava2からJava5,6,7ときたような変更をちょこちょこ入れてくる気か、Googleよ..


2017年12月26日火曜日

Proxy管理下の Ubuntu Server 16.04.3 LTS導入済みマシン2台をつかってKubernetes環境を構築する

GeForce1050Ti搭載のGPU物理マシンが3台あるので、
これにDocker環境をあげて機械学習用に使うつもりなのだけど、
せっかく3台あるので前から気になっていた Kubernetes 環境で
立ち上げてみようかと、試してみた。

でも、あまりインストールに関する記事がない..
これからは Kubernetes だ!
とかいう記事はいくつかあるのだけど、
マイナーなTensorFlowとくらべても少ないなあ..

..ということで試行錯誤しながら、
インストール手順を作成してみた。

-----

1. 前提


マスター、ノード2台のマシンが用意されている状態とする。
Proxy Server proxy.server.com:8080 、
NTP Server ntp.server とする。

  • ホスト名 master
    •  OS: Ubuntu Server 16.04.3 LTS
    •  インストール時に Open SSH Server パッケージをチェック追加した最小構成
    •  IPアドレス:10.1.1.1/24
    •  sudo 可能なユーザでログイン可能

  • ホスト名 node01
    •  OS: Ubuntu Server 16.04.3 LTS
    •  インストール時に Open SSH Server パッケージをチェック追加した最小構成
    •  IPアドレス:10.1.1.2/24
    •  sudo 可能なユーザでログイン可能

※動作確認のため、上記マシンとLAN接続されたブラウザが動作するPCが別途必要


2. マスターの準備


  • master へログイン
  • sudo su -
  • echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf
  • sysctl -p
  • vi /etc/apt/apt.conf
# 以下の2行を追加
Acquire::https::Proxy "http://proxy.server:8080/";
Acquire::http::Proxy "http://proxy.server:8080/";
  • apt update && apt -y upgrade && apt install -y ntpdate
  • ntpdate ntp.server
  • vi /etc/hosts
# 最終行に以下の2行を追加
10.1.1.1  master
10.1.1.2  node01
  • vi ~/.curlrc
# 新規追加
proxy=http://proxy.server:8080/
  • curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
  • vi /etc/apt/sources.list.d/kubernetes.list
# 新規追加
deb http://apt.kubernetes.io/ kubernetes-xenial main
  • apt update && apt install -y docker-engine
  • mkdir /etc/systemd/system/docker.service.d
  • vi /etc/systemd/system/docker.service.d/http-proxy.conf
# 新規追加、環境変数 NO_PROXY のエントリはネットワーク構成に合わせて変更
[Service]
Environment="HTTP_PROXY=http://solidproxy.exa-corp.co.jp:8080" "HTTPS_PROXY=http://solidproxy.exa-corp.co.jp:8080" "NO_PROXY=localhost,127.0.0.1,10.1.1.0/24,master,node01"
  • systemctl daemon-reload
  • systemctl restart docker
  • docker run hello-world
  • aptitude install -y kubelet kubeadm kubectl kubernetes-cni
  • vi ~/.bashrc
# 最終行へ追加、環境変数 NO_PROXY のエントリはネットワーク構成に合わせて変更
export http_proxy=http://solidproxy.exa-corp.co.jp:8080
export https_proxy=http://solidproxy.exa-corp.co.jp:8080
export no_proxy=localhost,127.0.0.1,10.1.1.0/24,master,node01
  • exit → 一旦rootから抜ける
  • sudo su -
  • swapoff -a
  • free -m
  • kubeadm init
# 実行最後にでてくるkubeadmコマンドをコピー(後でnode01上で実行する)
You can now join any number of machines by running the following on each node
as root:

  kubeadm join --token xxxxxxxxxxxxxxxxxx10 10.1.1.109:6443 --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • exit
  • sudo cp /etc/kubernetes/admin.conf $HOME/
  • sudo chown $(id -u):$(id -g) $HOME/admin.conf
  • export KUBECONFIG=$HOME/admin.conf
  • kubectl get nodes → kubernetes バージョンを確認、ここでは 1.9.0 とする
  • kubectl apply -f https://cloud.weave.works/k8s/v1.9/net

3. ノードの準備


  • node01 へログイン
  • sudo su -
  • echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf
  • sysctl -p
  • vi /etc/apt/apt.conf
# 以下の2行を追加
Acquire::https::Proxy "http://proxy.server:8080/";
Acquire::http::Proxy "http://proxy.server:8080/";
  • apt update && apt -y upgrade && apt install -y ntpdate
  • ntpdate ntp.server
  • vi /etc/hosts
# 最終行に以下の2行を追加
10.1.1.1  master
10.1.1.2  node01
  • vi ~/.curlrc
# 新規追加
proxy=http://proxy.server:8080/
  • curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
  • vi /etc/apt/sources.list.d/kubernetes.list
# 新規追加
deb http://apt.kubernetes.io/ kubernetes-xenial main
  • apt update && apt install -y docker-engine
  • mkdir /etc/systemd/system/docker.service.d
  • vi /etc/systemd/system/docker.service.d/http-proxy.conf
# 新規追加、環境変数 NO_PROXY のエントリはネットワーク構成に合わせて変更
[Service]
Environment="HTTP_PROXY=http://solidproxy.exa-corp.co.jp:8080" "HTTPS_PROXY=http://solidproxy.exa-corp.co.jp:8080" "NO_PROXY=localhost,127.0.0.1,10.1.1.0/24,master,node01"
  • systemctl daemon-reload
  • systemctl restart docker
  • docker run hello-world
  • aptitude install -y kubelet kubeadm kubectl kubernetes-cni
  • vi ~/.bashrc
# 最終行へ追加、環境変数 NO_PROXY のエントリはネットワーク構成に合わせて変更
export http_proxy=http://solidproxy.exa-corp.co.jp:8080
export https_proxy=http://solidproxy.exa-corp.co.jp:8080
export no_proxy=localhost,127.0.0.1,10.1.1.0/24,master,node01
  • exit → 一旦rootから抜ける
  • sudo su -
  • swapoff -a
  • free -m
  • kubeadm join --token xxxxxxxxxxxxxxxxxx10 10.1.1.109:6443 --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

4. 動作確認


  • masterへログイン
  • kubectl create namespace sock-shop
  • kubectl create -f "https://github.com/microservices-demo/microservices-demo/blob/master/deploy/kubernetes/complete-demo.yaml?raw=true"
  • kubectl describe svc front-end -n sock-shop
# NodePortを確認
Name:                     front-end
Namespace:                sock-shop
Labels:                   name=front-end
Annotations:             
Selector:                 name=front-end
Type:                     NodePort
IP:                       10.98.214.109
Port:                       80/TCP
TargetPort:               8079/TCP
NodePort:                   30001/TCP
Endpoints:               
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                  

  • 動作確認用PCのブラウザから http://10.1.1.1:30001/ を開く
→weave socksサイトが開いたら成功

A. 参考





以上
-----

docker ps すると、もうワケワカラン状態に..

Kubernetes環境だと複雑になりすぎてコッチが困るので、
機械学習の実行環境レベルだと Docker Compose までにしといたほうがいいかもなあ..



2017年12月19日火曜日

MS Bot Framework を使っていたら、突然Bot Framework State serviceを廃止する旨のメールが英語で飛んできた



Slackのボットを作ったりするのに MS Bot Framework を使っているのだけど、
突然表題ののような英語のメールが飛び込んできた。




ので、Google先生のちからを借りて勝手に翻訳してみた。
以下、翻訳文である。
#参照される方は at your own risk でお願いします。


Subject: Action required: The Bot Framework State service will retire in March 2018; update your bots to use your own state storage

件名:アクション必須:Bot Framework Stateサービスは2018年3月に廃止されます。 独自の状態記憶域を使用するようにボットを更新してください。


When you store your own state data, you have better control and more privacy over your bot’s state data. We strongly recommend that you store this data in your own storage accounts and subscriptions. Because of this, we’ll retire the Bot Framework State service on March 31, 2018.

独自の状態データを保存すると、ボットの状態データに対してより優れた制御とプライバシーが得られます。 このデータは、独自のストレージアカウントとサブスクリプションに保存することを強くお勧めします。 このため、2018年3月31日にBot Framework Stateサービスを廃止します。

You’re receiving this email because you’re currently using the Microsoft Bot Framework State service.

現在あなたは、Microsoft Bot Framework Stateサービスを使用しているので、このメールを送信させていただいました。

What is the Bot Framework State service?

By default, bots built on the BotBuilder SDK and Azure Bot Service Preview have stored their conversation state in a service called the Bot Framework State service. Within the Bot Framework, the Bot State service lets your bot store and retrieve state data that is related to the conversations that your bot conducts using the Bot Connector service. The Bot State service will be retired on March 31, 2018.


Bot Framework State service とは何?

BotBuilder SDKとAzure Bot Service Previewで構築されたボットは、デフォルトでは Bot Framework State service と呼ばれるサービスに対話状態を保存しています。ボットフレームワーク内で、 Bot Framework State service を使用すると、ボットコネクタサービスを使用してボットが行う会話に関連する状態データをボットストアして取り出すことができます。 Bot Stateサービスは2018年3月31日に廃止されます。


What does this change mean for you?
  • You need to store your bot state information in your own storage accounts and subscriptions, providing you more control and privacy over your bot’s state data
  • Your bots will need to be updated to use their own state storage to continue operating after March 31, 2018.
  • Starting on December 13, 2017, you’ll receive build warnings as well as warnings in the Bot Framework emulator.

この変更はあなたにとって何を意味するのか?

  • ボットの状態情報を独自のストレージアカウントとサブスクリプションに保存する必要があります。これにより、ボットの状態データに対してより多くの制御とプライバシーを提供します。
  • 2018年3月31日以降も動作を継続するために、ボットを独自のステートストレージを使用して更新する必要があります。
  • 2017年12月13日より、Bot Frameworkエミュレータでビルド警告と警告が表示されます。



Recommended action
  • Update your bots to use their own state storage. We recommend the following:
  • Saving state data in SQL with .NET
  • Saving state data with BotBuilder-Azure in Node.js
  • Saving state data with BotBuilder-Azure in .NET

推奨される行動

  • 独自の状態記憶域を使用するようにボットを更新する。以下を推奨します:
  • .NETでSQLを使用した状態データの保存を行う
  • BotBuilder-Azure in Node.js で状態データを保存する
  • BotBuilder-Azure in .NET で状態データを保存する



For more information, please visit the Manage state data documentation webpage.

詳細については、状態データの管理ドキュメンテーションWebページをご覧ください。

For questions or feedback, please visit Stack Overflow or contact Azure support.
 
ご質問やご意見は、Stack OverflowまたはAzureサポートにお問い合わせください。

Thank you,

ありがとうございます。

Your Azure Team

あなたのAzureチームよ

たしかにBot Frameworkって常に相手が同じ場合の前提で実装できるようになっていて
便利だったんだよね..
ただ、なんでかリバースProxy型のサイトが間に入っている構成になっていて
ここが有料になったら怖いなあ..とは思ってたんだよね..

いやらしいトコ突いてきたねえ..これまでの実装を維持したいならAzure上のコンテナを使えってか..
そうじゃなきゃ自分でセッション管理してみれば?ときた..


..Azure、ズッチーなあ!(山本高広風に)

NVIDIA Docker のバージョンが上がり Docker Composeでも対応できるようになった件

たまたまAWSの x2.large 上にTensorFlow実行環境を作成しようと、
ひさしぶりにNVIDIA Dockerのサイトへ行ったら..



バージョン、上がっとるがな..


ということで、慌ててREADME.mdを勝手に翻訳してみた。
#参照の際は at your own risk でお願いします。

-----(2017/12/17時点の NVIDIA Docker README.md)-----
警告:このプロジェクトはアルファ版(libnvidia-container)をベースにしています。すでに1.0よりも安定していますが、テスト支援を必要としています。

ライセンス:New BSD
ドキュメント:wiki
パッケージ:リポジトリ



ドキュメント

完全なドキュメントおよびFAQは、(GitHubの)リポジトリWikiを参照してください。


クイックスタート

既に使用されているディストリビューション上にNVIDIAドライバサポートされているバージョンDockerがインストールされていることを確認してください(前提条件を参照)。

※翻訳時点の前提条件
  • カーネルバージョンが3.10より大きい GNU/Linux x86_64
  • 1.12以降のバージョンのDocker
  • Fermi(2.1)より後のアーキテクチャを実装したNVIDIA GPU
  • NVIDIA ドライバ 361.93 (古いドライバはテストしていません)

/etc/docker/daemon.json をカスタムしている場合は、 nvidia-docker2 パッケージがこのファイルを上書きする可能性があります。

Xenial x86_64

# nvidia-docker 1.0 がインストール済みの場合:
# nvidia-docker および既存のGPUコンテナをすべて削除する必要があります
docker volume ls -q -f driver=nvidia-docker | xargs -r -I{} -n1 docker ps -q -a -f volume={} | xargs -r docker rm -f
sudo apt-get purge -y nvidia-docker

# パッケージ利己地鶏の追加
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \
  sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/ubuntu16.04/amd64/nvidia-docker.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update

# nvidia-docker2 のインストールと Dokcer デーモン設定のリロード
sudo apt-get install -y nvidia-docker2
sudo pkill -SIGHUP dockerd

# 最新の公式CUDAイメージ上で nvidia-smi を実行し正常動作を確認
docker run --runtime=nvidia --rm nvidia/cuda nvidia-smi


CentOS/RHEL 7 x86_64

# nvidia-docker 1.0 がインストール済みの場合:
# nvidia-docker および既存のGPUコンテナをすべて削除する必要があります
docker volume ls -q -f driver=nvidia-docker | xargs -r -I{} -n1 docker ps -q -a -f volume={} | xargs -r docker rm -f
sudo yum remove nvidia-docker

# パッケージ利己地鶏の追加
curl -s -L https://nvidia.github.io/nvidia-docker/centos7/x86_64/nvidia-docker.repo | \
  sudo tee /etc/yum.repos.d/nvidia-docker.repo

# nvidia-docker2 のインストールと Dokcer デーモン設定のリロード
sudo yum install -y nvidia-docker2
sudo pkill -SIGHUP dockerd

# 最新の公式CUDAイメージ上で nvidia-smi を実行し正常動作を確認
docker run --runtime=nvidia --rm nvidia/cuda nvidia-smi

その他のディストリビューション/アーキテクチャ

Wikiのインストール章を参照してください。

問題(Issue)および貢献

どんな変更を行う場合でも、事前に Contributor License Agreement の署名付きコピーを digits@nvidia.com へ提出する必要があります。
  • 新しい問題を提出してお知らせください
  • あなたは pull request を開くことによって貢献することができます
-----(2017/12/17時点の NVIDIA Docker README.md)-----


..ん?

docker run --runtime=nvidia って指定すれば
nvidia-docker コマンドでなくてもいいんだ..

ちょっと検索すると、次のブログ記事を見つけた

[WonderPlanet Tech Blog] nvidia-dockerをdocker-composeから使う
http://tech.wonderpla.net/entry/2017/11/14/110000

..いつのまに devices なんてセクションが
docker-compose.yml にかけるようになったんだ..

まあ、おかげでDocker Compose できるようになったし..

あと、公式ではないけど nvidia-docker-compose なるコマンドを
GitHub で公開しているヒトもいた。

nvidia-docker-compose
https://github.com/eywalker/nvidia-docker-compose




公式でもなさそうなのだけど、
興味があったのでREADME.mdを翻訳してみた。
#こちらもat your own risk でお願いします。

-----(2017/12/18時点の nvidia-docker-compose README.md)-----
nvidia-docker-compose とは、nvidia-docker で動作するGPU 対応の Docker コンテナが docker-compose で動作するようにラップする単純なPythonスクリプトです。

依存関係

nvidia-docker-compose は以下のパッケージを必要とします。
  • Docker Engine
  • nvidia-docker
以下で説明するインストール手順のなかで自動的にインストールされる、docker-composePyYAMLJinja2 python パッケージにも依存関係があります。

nvidia-docker-compose および nvidia-docker2

既にご存じの方もおられるとおもいますが、nvidia-docker2 リリースが動作するNVIDIAでは、Dockerインフラにより緊密に統合されています(詳細は、プロジェクトリポジトリ https://github.com/NVIDIA/nvidia-dockermaster ブランチを参照してください)。この新しい統合の大きな利点の一つは、GPU で docker-compose を起動するために nvidia-docker-compose を必要としないことです。nvidia-docker2docker-compose で動作させる方法は、Issue#23 を参照してください。
/etc/docker/daemon.json に以下のような記述をおこないます
{
    "default-runtime": "nvidia",
    "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": [ ]
        }
    }
}

インストールする前に

nvidia-docker-composenvidia-docker が適切に機能するかどうかに依存しますが、とりわけ、nvidia-docker を実行すると自動的に作成される追加の Docker ボリュームに依存します。 nvidia-docker-compose をインストールして実行する前に、 nvidia-docker を少なくとも1回はテストして、すべてのボリュームが正しくセットアップされ、正しく機能していることを確認してください。特に、次のコマンドを実行することをお勧めします。
$ nvidia-docker run --rm nvidia/cuda nvidia-smi
使用可能なすべてのGPUがマシン上に正しく表示されている場合は、作業を進めます。 そうでない場合は、nvidia-docker-compose を使用する前にnvidia-docker のドキュメントを参照し、正しく機能することを確認してください。

インストール

スクリプトをインストールするには、次のコマンドを実行して下さい:
$ pip install nvidia-docker-compose
もし、システムが提供するPythonを使用しているのであれば、先頭に sudo を付けて実行する必要があります。

nvidia-docker-compose の利用

nvidia-docker-compose は、docker-compose のドロップイン代替コマンドです。 docker-compose と同じオプションで簡単に実行できます:
$ nvidia-docker-compose ...
システム構成に依存してsudoを付けて実行する必要があるかもしれません(i.e. dockerを実行する際にsudoを先頭につけている場合等)。
nvidia-docker-compose を実行すると、YAML型式設定ファイル nvidia-docker-compose.yml をローカルに作成します。nvidia-docker-comose 実行中にこのファイルを削除してもかまいません。Git リポジトリ内で .gitignore を使用している場合は、nvidia-docker-compose.yml をこのファイルに追加することをお勧めします。nvidia-docker-compose.yml が生成されたら、このファイルを使ってGPU対応のコンテナを標準の docker-compose コマンドでで起動することもできます。次のようにファイルを指定して実行してください:

$ docker-compose -f nvidia-docker-compose.yml ...

マルチGPUセットアップによる柔軟な実行

最初のGPUである /dev/nvidia0 などを選択して記述することによって、各コンテナに対するGPUの可視性を制御できます。ただし、手動でこれを行うことは、あなたが nvidia-docernvidia-docker-compose の機能を妨害する可能性があることを意味しており、 docker-compose.yml のどのサービスがどのGPUで実行すべきかを事前に指定する方法はありませんでした。これは、異なるマシンは異なる数のGPUを搭載している事実がさらに複雑にさせています、そしてこのため 2 GPU 搭載マシン上で devices セクションの下に /dev/nvidia4 と記述されたサービスを実行するとエラーが発生します。

GPUターゲットの指定

nvidia-docker-compose バージョン0.4.0から新たに devices ヘッダの下に /dev/nvidia* を含めることでGPUをサービスへ指定できるようになりました。次のように指定します
version: "2"
services
  process1:
    image: nvidia/cuda
    devices:
      - /dev/nvidia0
  process2:
    image: nvidia/cuda
    devices:
      - /dev/nvidia1
      - /dev/nvidia2
上記は、サービス process1 は最初のGPU( /dev/nvidia0 )のみを、サービス process2 は2番めと3番めのGPU ( /dev/nvidia1/dev/nvidia2 )をそれぞれ参照するように定義しています。devices セクションに /dev/nvidia* を指定しない場合は、これまでのバージョンの場合と同様にすべての有効なGPUが自動的に割り当てられます。

docker-compose.yml ファイルでJinja2 を使う

バージョン0.4.0からの新機能
ターゲットマシン上で利用可能なGPUの数と同じ数のコンテナコンテナを(同じ構成で)起動したいという比較的一般的な使用例をサポートするために、今度は nvidia-docker-compose にてJinja2の利用をサポートします。GPUターゲティングを指定する機能と組み合わせることで、GPUの可用性に柔軟性を持たせた docker-compose 設定を作成できるようになりました。次のテンプレートを準備し、docker-compose.yml.jinja として保存します:
version: "2"
services:
  {% for i in range(N_GPU) %}
  notebook{{i}}:
    image: eywalker/tensorflow:cuda
    ports:
      - "300{{i}}:8888"
    devices:
      - /dev/nvidia{{i}}
    volumes:
      - ./notebooks:/notebooks
  {% endfor %}
そして、このjinja2 テンプレートを -t / --template フラグをつけて指定し実行します:
$ nvidia-docker-compose --template docker-compose.yml.jinja ...
Jinja テンプレートを処理して、次のような docker-compose.yml へ展開します:
version: "2"
services:
  notebook0:
    image: eywalker/tensorflow:cuda
    ports:
      - "3000:8888"
    devices:
      - /dev/nvidia0
    volumes:
      - ./notebooks:/notebooks
  notebook1:
    image: eywalker/tensorflow:cuda
    ports:
      - "3001:8888"
    devices:
      - /dev/nvidia1
    volumes:
      - ./notebooks:/notebooks
  notebook2:
    image: eywalker/tensorflow:cuda
    ports:
      - "3002:8888"
    devices:
      - /dev/nvidia2
    volumes:
      - ./notebooks:/notebooks
上記は、3GPUマシンで実行、展開した例です。Jinja変数 N_GPU には自動的にシステム上の有効なGPU数が反映されます。この docker-compose.yml は次に nvidia-docker-compose によりほかの設定ファイルと同じように処理されGPUが使用可能なコンテナを起動します。

Composeファイルのみ生成する

GPU対応の Compose ファイルの作成だけおこない後でコンテナ起動したい場合は、-G / --generate フラグをつけて nvidia-docker-compose を実行すると、docker-compose を実行せずに作成ファイルを生成しただけで終了します。
$ nvidia-docker-compose -G ...

その他のコマンドラインオプション

代替の nvidia-docker-plugin ホストアドレスの指定や(デフォルトのnvidia-docker-compose.yml の代替として)代わりのターゲットの Docker Compose ファイルを指定などのようなその他の設定については、コマンドラインヘルプを参照してください:
$ nvidia-docker-compose -h

使い方

nvidia-docker-compose は、2つのアクションを実行するシンプルなPythonスクリプトです:
  • docker-compose 設定ファイル(デフォルトは docker-compose.yml)の構文を解釈して、GPUが有効なコンテナを実行するのに必要な設定がなされている新たなYAML型式の nvidia-docker-compose.yml を作成します。設定パラメータは nvidia-docker-plugins から読み込まれます。
  • 新たに生成された設定ファイル nvidia-docker-compose.yml docker-compose を実行します。
-----(2017/12/18時点の nvidia-docker-compose README.md)-----

ここまでやるとやり過ぎに見えるけど、
Jinjaテンプレートを使って
有効なGPU数を自動で展開して個別のDockerコンテナを作ってくれる
機能は便利だ..




..でもなあ..そろそろコンテナを
Docker Composeでなくて
Kubernetes で管理しようかなと
思ってたところなんだよなあ..

コンテナ貸しパブリックIaaSはこぞってKuberenetes使ってるし...

Docker Compose はそろそろオワコンかな..と思ってたところなんだよなあ..



p.s.

ちなみに..TensorFlowも1.4.1マイナーバージョンアップしてました..

2017年11月21日火曜日

TensorFlowにおけるフィーチャ列はこうしてね的なブログ記事を翻訳してみた


TensorFlow 1.4.0 になってイロイロガチャガチャしている。

一番ビックリしたのがTutorialのSequence-to-Sequence。
イキナリブログ記事のリンクだけになっていた..

Sequence-to-Sequence Models
https://www.tensorflow.org/tutorials/seq2seq

以下翻訳した文章。
-----

Sequence-to-Seqyuence モデル


最新の Tensorflow API を使用してシーケンス間モデルを構築するための TensorFlow ニューラルマシン翻訳チュートリアルをご覧ください。

-----

相当互換性無視して変えちゃったものだから、
TensorFlowの研修とかやっている人たちも大変だ..


それもこれも
TensorFlow 1.4.0 が悪いんや...
 


..と嘆いていても始まらないので
今日もチクチク勉強をした。

今日読んだのがコレ。

Google Developers
Introducing TensorFlow Feature Columns
https://developers.googleblog.com/2017/11/introducing-tensorflow-feature-columns.html

タイトルを訳すと、
TensorFlow フィーチャ列の紹介

ようは、Estimatorになりinput_fnで入力データを投入するようになったのだけど
その入力データの要素をフィーチャ(特徴)とよんでおり
事前処理でこうしておけよ、今あるEstimatorはこれこれこの型式でしか受け入れねえからよ
という意味合いがあるようだ。

前置きはさておいて、翻訳した本文を載せておく。

当然このブログ上の翻訳はすべてat your own risk で参照のこと。
-----
2017年11月20日(月)
TensorFlowチームによる投稿

TensorFlow Datasets および Estimators を紹介するブログシリーズの第2部へようこそ。この記事では、フィーチャ列(feature columns)として、Estimator の訓練や推論に必要な特徴をあらわすデータ構造を取り上げています。フィーチャ列は非常に豊富で、さまざまなデータを表現できます。
ではパート1にはいりましょう。我々は、既製の Estimator である DNNClassifier を使用し、4つの入力フィーチャ列からアイリスの花の種類を予測するモデルを訓練することとします。このサンプルでは、数値フィーチャ列のみを作成します(tf.feature_column.numeric_column)。フィーチャ列は花弁と萼片の長さをモデル化するのに十分でしたが、実世界のデータセットには当然花以外のすべての種類・類別に対する数値以外のフィーチャ列も含まれています:
数値以外のフィーチャタイプをどのように表現できますか?それはまさにこのブログ記事で取り上げようとしていることなのです。

ディープニューラルネットワークへの入力

どのような種類のデータをディープニューラルネットワークに実際に送り込むことができるかを尋ねることから始めましょう。答えは、もちろん数字です(たとえば、 tf.float32)。実際には、ニューラルネットワークのすべてのニューロンは、重みおよび入力データに対して乗算および加算演算を実行しています。しかし、現実の入力データには、たとえば product_class(製品クラス)といった非数値(カテゴリ)のデータが含まれることがよくあります。次の3つの非数値値を含むことができる機能を考えてみましょう:
  • キッチン用品
  • エレクトロニクス
  • スポーツ
一般的な機械学習モデルでは、1 が値の存在を表し、0が値の不存在を表す単純なベクトルとして分類値を表します。たとえば、製品クラス(product_class) を スポーツ に設定すると、機械学習モデルは通常 product_class [0, 0, 1]のようになります。
  • 0:キッチン用品、存在しません
  • 0:エレクトロニクス、存在しません
  • 1::スポーツ、存在します
従って、row データは数値またはカテゴリにすることができるので、機械学習モデルはすべてのフィーチャを数値またはベクトルのいずれかとして表しています。


フィーチャ列の紹介

図2 が示すような feature_columns に、Estimator(DNNClassifierIrisの場合)の引数を使用して、モデルへの入力を指定します。フィーチャ列は、入力したデータを input_fnモデルで橋渡しします。
フィーチャをフィーチャ列として表すには、tf.feature_column パッケージの関数を呼び出します。この記事は、このパッケージの9つの機能について説明しています。図3に示すように、9つの関数 bucketized_column は両方とも、Categorical-Column オブジェクトまたは Dense-Column オブジェクトを返します。ただし、両方のクラスから継承します。
 これらの機能を詳しく見てみましょう。

数値列

アイリス分類器はすべての入力フィーチャ(SepalLength(花弁長)、 SepalWidth(花弁幅)、 PetalLength(萼片長)、 PetalWidth(萼片幅))のために tf.numeric_column()を呼び出しました。 tf.numeric_column()はオプションの引数を提供しますが、引数を指定せずに関数を呼び出すことは、デフォルトのデータ型(tf.float32)で数値をモデルに入力するための完全な簡単な方法です。たとえば:
# デフォルトは tf.float32 スカラーになる
numeric_feature_column = tf.feature_column.numeric_column(key="SepalLength")

引数 dtype を使ってデフォルト以外の数値データ型を指定します。たとえば:
# tf.float64 スカラーへ再表現
numeric_feature_column = tf.feature_column.numeric_column(key="SepalLength",
                                                          dtype=tf.float64)

デフォルトでは、数値列は単一の値(スカラー)を作成します。引数shapeを使って,別の型を指定します。たとえば:
# Represent a 各セルが tf.float32 を含む10-要素ベクトルへ再表現
vector_feature_column = tf.feature_column.numeric_column(key="Bowling",
                                                         shape=10)

# 各セルに tf.float32 スカラを含む 10x5 行列へ再表現
matrix_feature_column = tf.feature_column.numeric_column(key="MyMatrix",
                                                         shape=[10,5]) 



バケット化カラム

多くの場合、モデルに直接数値を入力するのではなく、その数値を数値範囲に基づいて異なるカテゴリに分割します。これを行うには、バケット化された列を作成します。たとえば、家が建てられた年を表す生データを考えてみましょう。その年をスカラー数値列として表す代わりに、次の4つのバケットに年を分けることができます。 
 モデルは、バケットを次のようにあらわします。

数値を完全に有効な入力としてモデルに分割すると、なぜこのようなカテゴリの値になりますか?カテゴリ化は1つの入力番号を4要素ベクトルに分割することに注意してください。したがって、モデルは単なる1つではなく4つの個別の重みを学習できるようになりました。4つの重みは、1つより豊かなモデルを作成します。さらに重要なことは、バケット化は、要素のうちの1つだけが設定され(1)、他の3つの要素がクリア(0)されるため、モデルが異なる年のカテゴリを明確に区別できるようにします。単一の数字(1年)を入力として使用すると、モデルはカテゴリを区別できません。そのため、バケットはモデルに学習に使用できる重要な情報を追加します。

次のコードは、バケット化されたフィーチャを作成する方法を示しています。
# raw 入力データの数値カラム
numeric_feature_column = tf.feature_column.numeric_column("Year")

# 1960年、1980年、2000年を表す数値カラムのバケット化
bucketized_feature_column = tf.feature_column.bucketized_column(
    source_column = numeric_feature_column,
    boundaries = [1960, 1980, 2000])

次の点に注意してください。
  • バケット化された列を作成する前に、最初に生の年を表す数値列を作成しました。
  • 数値列を最初の引数として tf.feature_column.bucketized_column() へ渡しました。
  • 3要素 boundaries ベクトルを指定すると、4要素バケット化ベクトルが作成されます 。


カテゴリID列

カテゴリID列は、バケット化された列の特殊なケースです。伝統的なバケット化された列では、各バケットは値の範囲を表し ます(たとえば、1960年から1979年まで)。カテゴリ識別列では、各バケットは単一の一意の整数を表します。たとえば、整数範囲 [0, 4] を表すとします。(つまり、整数 0, 1, 2, または 3 を表すとします)この場合、カテゴリIDマッピングは次のようになります。

なぜカテゴリID列として値を表現したいのでしょう?バケット化された列の場合と同様に、モデルはカテゴリ型ID列の各クラスの個別の重みを学習できます。たとえば、文字列を表現するために文字列を使用する代わりに、product_class の各クラスを固有の整数値で表現してみましょう:
  • 0="kitchenware"
  • 1="electronics"
  • 2="sport"

カテゴリID列を実装するために tf.feature_column.categorical_column_with_identity() を呼び出します。たとえば:
#入力 "feature_name_from_input_fn" のカテゴリ化された出力を作成。
# これは値は 0 以上 num_backets 未満となる整数でなければならない。
identity_feature_column = tf.feature_column.categorical_column_with_identity(
    key='feature_name_from_input_fn', 
    num_buckets=4) # Values [0, 4)

# 上記の 'feature_name_from_input_fn' は、input_fn(以下を参照)から
# 返される整数キーと一致する必要があります。
# この場合 'Integer_1' または 'Integer_2' は 'feature_name_from_input_fn'
# の代わりに有効な文字列になります。
# 詳細は、このブログシリーズの第1部を参照してください。
def input_fn():
    ......
    return ({ 'Integer_1':[values], ...., 'Integer_2':[values] },
            [Label_values])


カテゴリ語彙カラム

文字列をモデルに直接入力することはできません。代わりに、文字列を数値またはカテゴリの値にマップする必要があります。カテゴリ化された語彙列は、文字列をone-hotベクトルとして表現する良い方法です。たとえば:

ご覧のように、カテゴリ語彙カラムは、カテゴリIDカラムの列挙型です。TensorFlowには、カテゴリ別の語彙列を作成するための2つの異なる機能があります。

この tf.feature_column.categorical_column_with_vocabulary_list() 関数は、明示的な語彙リストに基づいて各文字列を整数にマップします。たとえば:
# 文字列である入力 "feature_name_from_input_fn" 与えられた場合、
# 入力を語彙リストの要素の1つにマッピングすることによって、
# モデルにカテゴリ的なフィーチャを作成する
vocabulary_feature_column =
    tf.feature_column.categorical_column_with_vocabulary_list(
        key="feature_name_from_input_fn",
        vocabulary_list=["kitchenware", "electronics", "sports"]) 

前述の関数には重大な欠点があります。つまり語彙リストが長い場合はタイピングが多すぎます。このような場合は、代わりに tf.feature_column.categorical_column_with_vocabulary_file() を呼び出すことで、語彙を別のファイルに配置できます。たとえば:
# 文字列である入力 "feature_name_from_input_fn"が与えられた場合、
# 入力を語彙ファイル内の要素の1つにマッピングすることによって、
# モデルに対するカテゴリ化されたフィーチャを作成する
vocabulary_feature_column =
    tf.feature_column.categorical_column_with_vocabulary_file(
        key="feature_name_from_input_fn",
        vocabulary_file="product_class.txt",
        vocabulary_size=3)

# product_class.txtには、次のような場合には1行の語彙要素が必要
kitchenware
electronics
sports


ハッシュバケットを使ったカテゴリ制限

これまでのところ、私たちは素朴な数のカテゴリで作業してきました。たとえば、この product_class の例では 3 つのカテゴリしかありません。しかし、しばしばカテゴリの数が膨大になり、それぞれの語彙や整数に個別のカテゴリを持たせることができないため、あまりにも多くのメモリを消費することになります。これらのケースでは、代わりに質問を回して「どのくらいの数のカテゴリを入力してもらえますか」と尋ねることができます。実際、この tf.feature_column.categorical_column_with_hash_buckets() 関数を使用するとカテゴリの数を指定できます。たとえば、次のコードは、この関数が入力のハッシュ値を計算し、モジュロ演算子を使用して hash_bucket_size 個のカテゴリの1つに配置する方法を示しています。
# 入力 "feature_name_from_input_fn" のカテゴリ出力を作成
# カテゴリは次のように:hash_value("feature_name_from_input_fn") % hash_bucket_size
hashed_feature_column =
    tf.feature_column.categorical_column_with_hash_bucket(
        key = "feature_name_from_input_fn",
        hash_buckets_size = 100) # The number of categories

この時点で、あなたは正しいことを考えるかもしれません: "これは狂っています!" 結局のところ、異なる入力値をより小さなカテゴリのセットにフォーカスしています。これは、恐らく完全に無関係な2つの入力が同じカテゴリにマッピングされることを意味し、結果的にニューラルネットワークにおいても同様の意味となります。図 7 は、このジレンマを示しており、 kitchenware および sports の両方がカテゴリ(ハッシュバケット)12 に割り当てれています:
 機械学習の多くの直感的な現象と同様に、実際にはハッシュがよく機能することがよくあります。これは、ハッシュカテゴリがモデルにある程度の分離を提供するためです。このモデルは、さらに kitchenware から sports を分離するための追加機能を使用することができます。


フィーチャクロス

ここで最後に取り上げるのは、複数の入力機能を1つにまとめることができるカテゴリの列です。それは フィーチャクロス(feature crosses)という名で知られており、フィーチャを組み合わせることにより、そのフィーチャコンビネーションが何を意味するものであっても、モデルは個別のウェイトを具体的に学習できます。

より具体的な例としてここでは、ジョージア州アトランタの不動産価格をモデルで計算したいとします。この都市の不動産価格は場所によって大きく異なります。緯度と経度を別々のフィーチャとして表現することは、不動産の場所の依存関係を特定する上であまり役に立ちません。ただし、緯度と経度を1つのフィーチャに渡すと、位置を特定できます。アトランタを100×100の長方形セクションのグリッドとして表現し、10,000個のセクションのそれぞれをその緯度と経度の交差点で識別するとします。このクロスはモデルが個々のセクションに関連する価格設定条件を拾うことを可能にします。これは緯度と経度だけよりもはるかに強いシグナルです。

図8は、都市のコーナーの緯度と経度の値を示す私たちの計画を示しています。
この解決法については、これまでに見てきたいくつかのフィーチャ列と tf.feature_columns.crossed_column() 関数を組み合わせて使用しました 。
# input_fn関数で入力緯度・経度をそれぞれ範囲 [0, 100) の整数値に変換
def input_fn():
    # データセットを使用して、経度と緯度の入力値を読み取る
    latitude = ...   # tf.float32 型の値
    longitude = ...  # tf.float32 型の値

    # この例では、lat_int, long_int のフィーチャ列を返却
    # 完全なプログラムの辞書はおそらくより多くのキーを持つ
    return { "latitude": latitude, "longitude": longitude, ...}, labels

# マップからわかるように、緯度範囲 [33.641336, 33.887157] を100個の
# バケットに分割したいと考えている。これを行うには、np.linspace を使用して、
# この範囲の min と max の間の 99 個の数値のリストを取得する。
# このリストを使用して、緯度を 100個のバケット化が可能となる。
latitude_buckets = list(np.linspace(33.641336, 33.887157, 99))
latitude_fc = tf.feature_column.bucketized_column(
    tf.feature_column.numeric_column('latitude'),
    latitude_buckets)

# 緯度同様、経度のバケット化を実行
longitude_buckets = list(np.linspace(-84.558798, -84.287259, 99))
longitude_fc = tf.feature_column.bucketized_column(
    tf.feature_column.numeric_column('longitude'), longitude_buckets)

# fc_longitude x fc_latitude のクロスフィーチャを作成
fc_san_francisco_boxed = tf.feature_column.crossed_column(
    keys=[latitude_fc, longitude_fc],
    hash_bucket_size=1000) # 正確なルールはない、1,000バケットという数は良いのだろうか?
以下のいずれかからクロスを作成することができます:
  • フィーチャ名; つまり、input_fnから返却されたdictからの名前。
  • categorical_column_with_hash_bucketを覗いたカテゴリ化カラム(図3を参照のこと) 。

フィーチャ列 latitude_fc longitude_fc をクロスさせると、TensorFlow は以下のように構成された (latitude_fc, longitude_fc) の 10,000 個の組み合わせを作成します:
(0,0),(0,1)...  (0,99)
(1,0),(1,1)...  (1,99)
…, …,          ...
(99,0),(99,1)...(99, 99)
この関数 tf.feature_column.crossed_column は、これらの組み合わせに対してハッシュ計算を実行し、hash_bucket_size でモジュロ演算を実行して結果をカテゴリに入れます。前に説明したように、ハッシュ関数とモジュロ関数を実行すると、おそらくカテゴリの衝突が発生します。つまり、複数(緯度、経度)のフィーチャクロスが同じハッシュバケットになります。実際には、フィーチャクロスを実行することは、依然としてモデルの学習能力に大きな価値をもたらします。

やや直感的には、フィーチャクロスを作成するときは、元の(クロスしていない)フィーチャをモデルに含める必要があります。例えば、 (latitude, longitude) フィーチャクロスだけでなく、 latitude および longitude を別個のフィーチャ列として提供します。別個に提供したフィーチャ列 latitude 及びlongitude は、モデルが異なるフィーチャクロスを含むハッシュバケットの内容物を分離するのに役立ちます。

これに関する完全なコードサンプルについては、このリンクを参照してください。また、この記事の末尾にある参照セクションでは、フィーチャクロスのサンプルがさらにたくさんあります。


インジケータ列と埋め込み列

インジケータ列と埋め込み列は、フィーチャに直接作用することはありませんが、代わりにカテゴリ型列を入力として使用します。

インジケータ列を使用しているときは、TensorFlowに、product_class サンプルで見たことを正確に行うように指示しています。つまり、 インジケータ列は、各カテゴリをone-hotベクトルの要素として扱います。一致するカテゴリは値 1 とし、残りは 0 となります。


インジケータ列 を作成する方法は次のとおりです。
categorical_column = ... # 任意のカテゴリ化列を作成、 図3を参照のこと

# カテゴリ列をインジケータ列として表す
# これはカテゴリ毎に1つの要素を持つone-hotベクトルを作成することを意味している
indicator_column = tf.feature_column.indicator_column(categorical_column)

さて、クラスが3つしかないのではなく、100万..もしくは10億あるとします。こうなると、カテゴリの数が増えるにつれてインジケータ列を使いニューラルネットワークを訓練することは不可能になります。

この制限を克服するために埋め込み列を使用できます。 埋め込み列は、データを多くの次元の one-hot ベクトルとして表現する代わりに、そのデータを、各セルが 0 または 1 だけでなく、任意の数を含むことができる低次元の通常のベクトルとして表します。埋め込み列には、インジケータ列よりもはるかに少ないセルが含まれています。

インジケータ列と埋め込み列を比較する例を見てみましょう。私たちの入力サンプルが、わずか 81 語の限られたパレットとは異なる言葉で構成されているとします。さらに、データセットが提供するものが、4つの別々のサンプルで以下の入力語を提供すると仮定します:
  • "dog"
  • "spoon"
  • "scissors"
  • "guitar"
ここで 図10は、列またはインジケータ列を埋め込むための処理経路を示しています。

例が処理されると、categorical_column_with... 関数の1つが例の文字列を数値のカテゴリ値にマップします。たとえば、関数は"spoon"を [32] にマップします(32という数値は私たちの想像です。実際の値は、マッピング機能によって異なります)。あなたは、次の2つの方法のいずれかでこれらの数値カテゴリ値を表すことができます。
  • インジケータ列として。関数は、カテゴリ値(0, 32, 79, 80)のインデックスに 1 を、他のすべての位置に 0 を設定して、各数値カテゴリ値を 81 要素ベクトルに変換します(パレットは81語で構成されているため)。
  • 埋め込み列として。関数は、数値カテゴリ値 (0, 32, 79, 80) をルックアップテーブルのインデックスとして使用します。そのルックアップテーブルの各スロットは、3要素ベクトルを含みます。
埋め込みベクトルの値はどのようにして魔法のように割り当てられますか?実際には、課題はトレーニング中に発生します。つまり、モデルは問題を解決するために入力数値のカテゴリ値を埋め込みベクトル値にマップする最良の方法を学習します。組み込みベクトルはトレーニングデータからカテゴリ間の新しい関係を学習するため、列を埋め込むことでモデルの機能が向上します。

この例で埋め込みベクトルのサイズが 3 である理由は何ですか?さて、次の「数式」は、埋め込みディメンションの数に関する一般的な経験則を提供します。
embedding_dimensions =   number_of_categories ** 0.25
すなわち、埋め込みベクトル次元は、カテゴリ数の4乗根でなければなりません。この例の語彙サイズは81であるため、推奨されるディメンションの数は3です。
3 = 81 ** 0.25
これは単なる一般的なガイドラインであることに注意してください。必要に応じて埋め込み寸法の数を設定することができます。

embedding_column を作成するために tf.feature_column.embedding_column を呼び出します。埋め込みベクトルの次元は、上で説明した手元の問題に依存しますが、一般的な値は、3まで、300まで、あるいはそれ以上にまで低くなります:
categorical_column = ... # 図3 にあるようなカテゴリ化カラムを作成

# Represent the categorical column as an embedding column.
# This means creating a one-hot vector with one element for each category.
# カテゴリ型列を埋め込み列として表す
# これはカテゴリ毎に1つの要素を持つ one-hot ベクトルを作成することを意味する
embedding_column = tf.feature_column.embedding_column(
    categorical_column=categorical_column,
    dimension=dimension_of_embedding_vector)
埋め込みは機械学習の大きなテーマです。この情報は、フィーチャ列として使用するためのもので、簡単に説明していますので、詳細について知りたい方は、この記事の最後を参照してください。


フィーチャ列をEstimatorへ渡す

まだあるのですか?と思っている方も多いと思いますが、フィーチャ列の基礎を卒業する前にあと少しだけ残っています。

図1を見直してもらえばわかりますが、フィーチャ列は入力データ(input_fnから返されたフィーチャ辞書によって提供)をモデルに入力された値にマッピングします。フィーチャ列を feature_columns 推定値の引数リストとして指定します。feature_columns 引数は、Estimatorによって異なることに注意してください:
・フィーチャ列のすべてのタイプを受け入れる。
dense columnのみ受け入れる(図3を参照のこと)。他の列タイプは、前述のように indicator_column または embedding_column にラップする必要がある。
LinearClassifier および LinearRegressorのように、引数 linear_feature_columns はどんな列タイプも受け入れ可能。
・引数 dnn_feature_columns、しかしながら(DNNClassifier DNNRegressor のように) dense columnに制限。

上記のルールの理由は、この入門記事の範囲を超えているため解説しませんが、今後のブログ記事では必ずカバーしていきたいと思います。


サマリ

フィーチャ列を使って入力データをモデルにフィードする表現にマップします。このシリーズの第1回では numeric_column のみ使用しましたが、この記事で説明している他の機能を使用すると、他の機能の列を簡単に作成できます。

フィーチャ列の詳細については、次の記事をご覧ください:

もしあなたが埋め込みに関してより詳しく知りたい場合は、次の記事を御覧ください:
-----
今用意されているEstimatorの具現クラス..とPythonでもいうのかはわからないけど
へのフィーチャ列にはある程度決まりがあるみたいで
Denseでないとだめな列もあったりするのね..

..埋め込み列迄書かれてあるのを見て、
すかさずチュートリアルのWord Embeddingsのページに行ったが
ここはまだTensorFlow本家からは動いてないみたいでホッとした...
語彙リストがなんで単語のリストなのかもなんとなくわかったけど
やっぱり Sequence-to-Sequence が気になるなあ..










TensorFlow 1.5.0 rc0がリリースされた

1月4日仕事始めの日に出社して、 同僚に新年の挨拶を済ませふと席に戻ると、 Release TensorFlow 1.5.0-rc0 · tensorflow/tensorflow https://t.co/PCptAzrb9u — Buck Borasky - F...