Google Cloud Shellについて
Google Cloudには、Google Cloud Shellという、Shell環境がデフォルトで用意されています。
Google Cloudアカウントを開設すると、メニューバーからアクセスできるシェル環境で、Google Cloud SDK/gcloudがビルトインされていて便利です。
画像はgoogleより引用
以下、2016年07月26日の情報です。
基本的な特徴
* ブラウザベースでアクセスできるCLI環境
* 5GBの永続的ストレージが用意されている。
* Java,Go,Pythonなどの言語をサポートしている。
* Webプレビュー機能
* gcloudを利用する際の認証が済んでいる
* tmuxサポート
一時的に利用できる仮想マシンのインスタンス
読んで字のごとくですが、一時的に利用できる仮想マシンです。コマンドラインボタンを押すと、プロビジョニングされ、新たなインスタンスを立ち上げています。自分のディレクトリ(/home/username/)の情報は、5GBの永続的ストレージから読み込まれているようで情報が保持されますが、cronは引き継がないようですので、別の仕組みを用意する必要がありそうです。
ブラウザベースでアクセスできるCLI環境
Compute Engineと同様にブラウザからアクセスできます。macのシェルからアクセスする必要がなくなりました。
5GBの永続的ストレージ
Google Cloud Shell用に5GBのストレージが用意されています。 APIを叩く等の小さな管理作業をするためのスペースとしては十分だと思います。それ以上の作業をする場合は、別のストレージに展開することになります。
Java,Go,Pythonなどの言語をサポート
対応している言語はこちらにあります
https://cloud.google.com/shell/docs/features#language_support
Java,Go,Python(2系のみ),Node.js,Ruby,PHPです。同じページにサポートしているシェルやエディタの情報があり、シェルはsh, bash、エディタは、emacs,vim,nanoに対応しています。他、make, pip , git , docker , mysql clientに対応しています。管理系で必要なものはだいたい入っているという印象です。
https://cloud.google.com/shell/docs/features
Webプレビュー
Webアプリケーションのプレビューができるようです。Ruby on Railsなどではテストサーバーを立ち上げてローカルで動作を確認しますが、そういった機能だと思います。
gcloudを利用する際の認証が済んでいる
gcloudの認証ができているので、立ち上げたCompute Engineに直接アクセスできるようです。まだ試していません。
tmuxサポート
tmuxをサポートしています。tmuxは作業中のセッションを保存したり、画面を複数端末で見れて便利なシェルのユーティリティですが、インスタンス自体が一時的なので、セッション保存がどこまで活用できるかはやや不明です。まだ試していません。
Google Cloud Plathome上にTensorflowを展開する
Tensorflowを使いはじめて、はや4ヶ月。そろそろ手元のMacbookではマシンパワーがおぼつかないケースが出てきました。
既存のAWSのDebianに入れようかとも考えましたが、せっかくなので、Google Cloud Plathomeを使うことにしました。
申し込みからコードの実行まで1.5時間ぐらいでした。以下、その記録です。
1. 申し込む
cloud.google.comから申し込みます。
既存のGoogleアカウントでログインしましたが、再度住所等の情報を入力しました。60日、$300分の無料クレジットがついてきます。クレジットカードの入力が必要です。
2. 利用する
チュートリアルが表示されます。ゲーミフィケーションのような流れです。pythonによるHello, Worldチュートリアルがあったので、それに従ってみたところ、Webアプリケーションができてしまいました。App Engineというアプリケーション用のクラウドプラットホームを使っていたようです。Herokuに似ています。Webアプリケーションを構築するのであれば魅力的ですが、今回は違うようです。
少し調べるとGoogle Prediction APIというものがありましたが、Tensorflowではないようです。また、Cloud Machine LearningというJupyter Notebookが利用できるものもありましたが、Limited Previewでした。GoogleのサイトでJupyter Notebookを用いたデモを見たことがあり、こちらも興味深いのですが、今回は対話形式は特に必要としておらず、cronなどによるスケジュールなどをしたかったので、こちらの利用も見送りました。
結局、AWSのEC2のような、VMを作るタイプのCompute Engineというものを使うことにしました。 割とスタンダードなクラウド環境です。CPUとメモリのサイズをカスタマイズできるので、CPU=8コア , メモリ=7.2GBを選択しました。メモリはこんなに必要ないのですが、どうやらこれが最小サイズのようです。時代ですね。
3. ログイン
Compute Engine上で作成したインスタンスへのアクセスはブラウザベースで行えます。SSHのアイコンをクリックすると、ブラウザ上にエミュレートされたターミナルが立ち上がります。AWSのkey pairと比べると簡単にアクセスできる一方で、益々googleアカウントの重要性が増すなと思いました。
Chromeを使っている場合(私がそうだったのですが)、ターミナル・プラグインのインストールを勧められます。これを利用することで、ほぼターミナルと遜色のない環境になります。
4.Tensorflowをインストールする
ここから先は、おなじみの作業です。私はanacondaを使っているので、
Anacondaをダウンロードし、インストールします。
user$ wget http://repo.continuum.io/archive/Anaconda3-4.1.1-Linux-x86_64.sh user$ chmod u+x Anaconda3-4.1.1-Linux-x86_64.sh user$ ./Anaconda3-4.1.1-Linux-x86_64.sh
Cloud Plathomeで用意されたdebianはコンパクトなものでしたので、インストール途中でbzip2がないと警告を受けました。apt-get update、apt-get install bzip2したのち、再度anacondaを入れました。
root# apt-get update root# apt-get install bzip2
その後、tensorflowを以下を参考に入れます。
といっても今回は環境切り分けを特にしないので、pip install --upgrade でおしまいです。
user$ touch~/anaconda3/lib/python3.5/site-packages/easy-install.pth
user$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.9.0-cp35-cp35m-linux_x86_64.whl
user$ pip install --upgrade $TF_BINARY_URL
5. 実行
まずは単純にpythonのコードを実行するだけをしました。実行中にCPUの使用率を見ると、該当するプロセスの利用率がおおよそ230%と3コアしか利用できていませんでした。この辺りの指定の仕方は、もう少し調べようと思います。今回は、学習パラメータを複数持たせた結果を知りたかったので、4つのプロセスを同時に走らせました。
6. その他
ずうっとマシンリソースを使い続けるわけではないので、動的に仮想マシンを制御することになります。少し調べたところ、gcloudというツールで制御できるようです。
更に、プリエンプティブル VMという仮想マシンを利用することで、よりリーズナブルに利用できそうです。
データ分析の為にPandasを利用する その2
前回の記事では、Pandasの簡単な操作をしました。面白いのでもう少し続けてみます。
今度はcsvを2つ用意しました。
$ cat tmp01.csv ,a,b,c 1,1,10,100 2,2,,200 3,4,30,300 $ cat tmp02.csv ,d 1,3 3,9
まずは普通に読みます。
$ python >>> import pandas as pd >>> tmp_data01 = pd.read_csv("tmp01.csv") >>> tmp_data01 Unnamed: 0 a b c 0 1 1 10.0 100 1 2 2 NaN 200 2 3 4 30.0 300
先頭をインデックスとして読みます。
>>> tmp_data01 = pd.read_csv("tmp01.csv",index_col=0) >>> tmp_data01 a b c 1 1 10.0 100 2 2 NaN 200 3 4 30.0 300
欠損データを前のデータでパディングします。
>>> tmp_data01 = pd.read_csv("tmp01.csv",index_col=0).fillna(method="pad") >>> tmp_data01 a b c 1 1 10.0 100 2 2 10.0 200 3 4 30.0 300
tmp02を読みます。
>>> tmp_data02 = pd.read_csv("tmp02.csv",index_col=0) >>> tmp_data02 d 1 3 3 9
tmp01とtmp02をつなげます。http://pandas.pydata.org/pandas-docs/stable/merging.html を参考にしました。
>>> data = pd.concat([tmp_data01,tmp_data02],axis=1) >>> data a b c d 1 1 10.0 100 3.0 2 2 10.0 200 NaN 3 4 30.0 300 9.0
パディングではなく、線形補完してみます。
>>> data = pd.concat([tmp_data01,tmp_data02],axis=1).interpolate(method='linear') >>> data a b c d 1 1 10.0 100 3.0 2 2 10.0 200 6.0 3 4 30.0 300 9.0
1つだけくりぬいてみます
>>> a_data = data["a"] >>> a_data 1 1 2 2 3 4 Name: a, dtype: int64
前項との和を計算します。
>>> a_plus_data = a_data + a_data.shift() >>> a_plus_data 1 NaN 2 3.0 3 6.0 Name: a, dtype: float64
Logもとってみましょう。
>>> import numpy as np >>> d_data = data["d"] >>> d_data 1 3.0 2 6.0 3 9.0 Name: d, dtype: float64 >>> d_log_data = np.log(d_data/d_data.shift()) >>> d_log_data 1 NaN 2 0.693147 3 0.405465 Name: d, dtype: float64
便利ですね。
データ分析の為にPandasを利用する
Jupyter Notebookを使いたくて、Anacondaをインストールしたところ、データ分析の為のツールであるPandasもインストールされていたので使ってみました。存外便利でしたので、メモをとります。
以下のようなcsvファイルを用意しました。
$cat tmp.csv a,b,c 1,1,1 2,,2 3,3,3
pandaをimportして、csvファイルを読みます。
$ python >>> import pandas as pd >>> tmp_data = pd.read_csv("tmp.csv") >>> tmp_data a b c 0 1 1.0 1 1 2 NaN 2 2 3 3.0 3
欠損データを前のデータでパディングしてみます。
>>> tmp_data = pd.read_csv("tmp.csv").fillna(method="pad") >>> tmp_data a b c 0 1 1.0 1 1 2 1.0 2 2 3 3.0 3
fillna(0)でゼロパディングもできます。
describeでデータの数、平均値などの情報を取得します。
>>> tmp_data.describe() a b c count 3.0 3.000000 3.0 mean 2.0 2.333333 2.0 std 1.0 1.154701 1.0 min 1.0 1.000000 1.0 25% 1.5 2.000000 1.5 50% 2.0 3.000000 2.0 75% 2.5 3.000000 2.5 max 3.0 3.000000 3.0 >>>
その2では、もう少し複雑なことをやってみたいと思います。
企業が人工知能(またはディープラーニング)を始めるのに必要なヒト、モノ、コト
企業が、自社のビジネスに人工知能を取り込むには、どんなリソースがあればよいかまとめてみました。
1) ニューラルネットワーク開発部隊 (ヒト)
2) 分散システムのインフラストラクチャ (モノ)
3) ビジネスモデリング (コト)
1) ニューラルネットワーク開発部隊 (ヒト)
ビジネス要件から適切なネットワークを選択できる人材
動体検知や文字認識などの画像処理であれば畳み込みネットワーク、文字認識や時系列データであればリカレントニューラルネットワーク等、ニューラルネットワークは応用したい分野毎に異なります。目的に応じて最適なネットワークを選択できる人材がまずはなにより必要です。
IT開発でいう「SE」の領域にあたりますし、後述の通りニューラルネットワークで求められる人材は、従来のIT開発のメンバーと親和性が高いので、従来までの「SE」と同じスキルセットと見なされやすいですが、少し違うと思います。
IT革命により、近年のIT開発の技術選択は体系化がなされた知識を学ぶ事で進行可能でしたが、人工知能の場合は、まだ発展途上な面もあり、数理的な知識が求められます。加えて、適切なITシステムを選択するセンスも従来通り求められてくるでしょう。プロセスマネジメントは別のメンバーに任せて、ビジネス要件に最適なテクノロジーを追い求めることに特化した方が、当面の間は効率的だと思います。
- 数学的な理解/知識
既に確立されている仕組みを使うのであれば、理系大学程度の基礎的な知識でいけると思います。これは高校時代に数学が好きだった理系出身ならある程度は標準搭載している知識です。
ただし(少し前の私を含め)多くの社会人は学生時代の学びの記憶を忘却の彼方においやってしまっているので、高校数学あたりからノートを片手に数週間復習するような機会を取る必要はあると思います。
分野としては、行列計算や偏微分などの知識になると思います。代数や複素解析はあまり出てこないです。
新しいロジックを考えたり、ロジックを組み合わせる必要がある領域に手を出す必要があれば、より詳しい数学的な知識を持つ人材がやはり重要になってきます。競合する企業も人工知能を採用しているような分野なら、体系的な学問を更に深く習得している人材までが求められるでしょう。
この章はヒトをテーマにまとめましたが、人工知能のフレームワークはソフトウェアの重要な概念なのでここで紹介させてください。
実際にデータを扱い、開発を効率的に進めていく為には、人工知能に向けた開発フレームワークを利用することになります。ニューラルネットワークでよく使う関数などがビルトインされているツールがあれば、毎回作らずに済むので便利だからです。TensorFlow、Chainerなどの実装があります。
フレームワークは少なからず実装に影響を及ぼします。例えば、文字認識などで利用されるリカレントニューラルネットワークの1つであるLSTMををとっても、幾つかの種類があり、ツールにより実装されているものが異なるようです。私は当面、TensorFlowを使おうと思います。
言語はフレームワークがサポートしているプログラミング言語を使えばよいです。昔はC言語や業界に特化した言語が使われており、言語自体の知識が求められましたが、最近はWeb開発などで積極的に使われてきたライトウェト系の言語(Pythonなど)でも扱えるのでとっつきやすくなっています。Web開発の経験があるレベルでも手をつけることができると思います。数学的な知識と合わせて、「高校時代に数学が好きだった理系出身のWebプログラマ」であれば戦える分野になりました。
ただし、プロダクトレベルに耐え得るようにするには、開発を効率に進める為にも、また開発したプロダクトに問題が発生しない為にも、テストや開発の方法論(MVCのようないわゆる開発フレームワーク)といったプログラミング開発における実装上の課題に取り組めることが重要になっていきす。
2) 分散システムのインフラストラクチャ (モノ)
- ハードウェア
マシンリソース、CPU&GPUです。処理すべきデータと処理するネットワークの構造により変わってきます。チュートリアルであつかうMNIST程度のものを扱うにはラップトップでも可能ですが、膨大なデータを複雑なロジックで計算する際は、クラウドを利用することになります。
自社でインフラを構築するのは、少なくとも組織を構築する直後にはあまり得策ではないと思います。Webのように常にリソースを使い続けるものと比較しても、資産化しておく意味があまりないからです。
- 分散フレームワーク
Map&Reduce / Hardoopのようなものを指しています。複数のハードウェアを同時に
扱う為には必要です。既存のフレームワークを採用しても、自社で構築するとするとそれなりに労を要します。
- データベース
データを格納する為に、DBを使います。初期においては、ポータブルに使えるという意味でcsvやsqliteのようなものを使ってもいいかもしれません。また、従来からLAMPなどで開発をしていたWebエンジニアであれば、MySQLのような馴染みのあるDBを使ってもいいと思いますが、あらかじめ膨大なデータを扱うことを前提として、NoSQL系がよく利用されているようです。
総じて言えば、ローカル環境で試験的なアプローチをするのであれば、ラップトップでも問題ありません。それを超えるタイミングで、スケールアウト可能なクラウドのシステムを採用するのが、分散システムの賢い採用方式だと思います。
3) ビジネスモデリング (コト)
従来から数理的なアプローチ存在する分野、例えば金融や画像処理といった分野では、方法論が揃いつつあります。また、ビジネス上の適応目的も明らかになっていますので、応用も比較的容易です。
Google Cloud Plathomeには、金融に対して適応するデモがありますが、これは従来まで市場間分析などで利用されていた自己相関分析に対してニューラルネットワークを応用した例です。
Machine Learning with Financial Time Series Data - Solutions — Google Cloud Platform
余談ですが、この例ではフィードフォワードネットワークと呼ばれるディープラーニングの中でも比較的シンプルなものを採用しています。それでもそれなりのパフォーマンスが出ているあたり、人工知能の未来を感じさせてくれます。
今まであまり適応されていない分野に向けた適応となると、ビジネスモデルを発見するようなセンスも必要になります。IT技術とビジネスの両方を経験されたスペシャリストを見つけることが近道かもしれません。
いままでは人間の経験と勘(あるいはその道の天才)に頼っていた部分を機械化することで、新たなビジネスチャンスを生み出せることが人工知能の本質です。自社への適応を検討する企業としては、この本質に向けて目的意識を持ち続けておくことが、ビジネスへの応用向けた近道だと思います。
ニューラルネットワークを使っているかは不明ですが、Dentsu Media LabとPanasonicによる東京オリンピックに向けたアプローチはこういった意味で興味深いと思います。
MNIST for ML Beginnersの数学的な意味合い
Tensor flowの初めの一歩のチュートリアルであるMNIST For ML Beginners
について、数学的な意味合いを書いてみようと思います。
(ブログに不慣れなもので、修正/継ぎ足しながら公開していくことをお許しください)
まず、このチュートリアルで実行していることは、
入力がn次元の配列 (は実数)が複数個あった時 、個々の出力 ()を得る写像を用意して、出力が 個々のに対する解 (あるz=1以外はz=0) に近い結果を得れるように、Fを最適化することです。
ここで、の各要素 は実数と書きましたが、これは概念上の話であり、プログラムの実装上ではfloatになります。以後、集合(つまり配列)の要素は数学上は実数ですが、プログラム上はfloatであると考えて下さい。は、となるm個の(実数の)集合です。また任意の要素は0以上であり、したがって、は0から1までの値をとることになります。0%から100%の確率的な値だと考えると分かりやすいと思います(確率分布と言います)。解は (1, 0, .. , 0) , (0, 1, .. , 0) , (0,0, .. , 1) のような1つだけが1で残りが全て0のm個の集合(=配列)です。これも、1つが100%で、残りが0%ということを示していると考えてください(この1つだけが1の集合はone hotな集合と呼ばれています。)。結果が近いかどうかの評価は、複数の入力 が与えられた時の各々のxに対する出力 が解 に対するしてどれだけ正解したか(=正解率)で判断します(はのI番目の要素という意味ではなく、入力集合の1つの要素であるという意味です)。
各集合() に対して、正解()、つまり教師が与えてられている状態で、写像 の最適化を行うプロセスであることから、このチュートリアルは「教師付き」学習と呼ばれるものになります。
ML Beginnersでは、入力 に28x28ピクセルの画像(つまり、n=784次元のベクトル(=配列))を用いており、正解と出力に0から9までの数字(つまり、yおよびzはm=10次元の0から1までの実数をとるベクトル)を用いています。正解率はおよそ91%程度で、これは機械学習界隈ではあまり優秀な結果ではないようです。なお、Expert向けのチュートリアルでは、正解率は99.2%程度になります。
両者の何が違うかというと、写像を作りこむロジックです。写像の方法としてはBeginners/Expertsのいずれも、行列 (重み) とベクトル (バイアス)を用いて、m=784次元のベクトルxからn=10次元のベクトルeを得る為の、 という変換をおこないますが、最適なの組み合わせを選ぶまでのロジックが違います。Beginnersでは、この(W,b)の組み合わせを得る為に、 活性化関数(activation function)としてsoftmax関数を、解と比較するための定量的な尺度として交差エントロピー (cross entropy)を、尺度の最適解の探索に勾配降下法を用いています。
このような数式から、Wは(784x10)の行列であり、bは10次元のベクトルになります。
各xごとにFを更新していく(=最適化していく、つまり学習していく)プロセスは以下のステップで進めます。(BeginnersとExpertsの違いは、このステップ自体の違いにあり、選択する関数の違いなどではありません)
1) 学習前の(W,b)の組み合わせが存在する。 (Wはnxm=784x10の行列(=2次元配列)、bはm=10のベクトル(=要素10の配列))
2) xを入力として、 e = Wx + b の解を得る。(eはm=10のベクトルです)
3) 得た解 eを活性化関数を用いて、yに変換する。(ここでは、活性化関数にsoftmax関数を用いています)
4) 正しい解 z と y に対して「差」を定量化する。(ここでは交差エントロピーを用いています)
5) 一定のアルゴリズムを用いて「差」が最小化させる。(ここでは勾配降下法を用いています)
6) 差が最小化された(W,b)の組み合わせを「学習結果」として次のxに対する初期値として与える。
最終的に得た、(W,b)の組み合わせにより、他のデータ x からの出力 y = F(x) = softmax(Wx+b) がZと適合しているか を確認することで得た正解率が、このプロセスに対する評価となります。
以降、各関数の意味合いについて書きたいと思います。
入力に対する最初の変換 e= Wx + b
e=Wx+bが行おうとしていることは、あらかじめ持っている入力の次元を求める出力の次元に合わせることです。チュートリアルの例では、ピクセルの要素である28x28=784個の数値から、0から9までの数値に対する判断をする必要があるので、784個の配列(=実数集合)を10個の配列に変換します。Wは(m,n)行列であり、Wxという行列変換により、m(=784)次元の実数集合からn(=10)次元の実数集合へ変換します。その後、n次元の配列bによりバイアスをかけて、n次の実数集合である出力eを得ます。式が一次方程式の形をなすところからわかるように、これはいわゆる線形変換であり、m次元の入力からn次元の出力を得る手段は他にもありえますが、この形式を用いるのが一般的です。ニューラルネットワークでは、このような線形変換を複数回繰り返すことで、様々な変換の表現を得ることになります。
活性化関数 softmax
次にsoftmax関数についてです。まず、softmax関数の定義は あるm次元の実数のベクトル を入力とし、同じ次元の出力を得る関数で、要素 に対応する出力が となるものです。分母から見て明らかなように、となります。つまり、総和が常に1 (=100%)になるように設計された関数と言えます。
softmaxはシグモイド関数の多変量版です。シグモイド関数は、実数に対して という形の関数で、グラフにすると以下のようなものになります(このグラフはa=1の時のものです)。
この関数は、、sigmoid(0)=0.5となっています。これは日本語にすると、「全ての実数を0%から100%の間に写し込む。マイナスであればあるほど0%になり、プラスであればあるほど100%になる。真ん中の0は50%」という表現になり、与えられた値を確率に変換する為の関数であると考えることができます。
つぎに、なぜsoftmaxがsigmoidの多変量版なのかということを考えたいと思います。
aは空間を横に狭める作用をもたらす程度のものなので、以後a=1として考えます。
まず、をと表現し、シグモイド関数の分母分子にをかけることで、となります。この関数は、xの値が0の場合、となり、50%の確率に落ち着くことになります。
この確率空間の変量が実は2、つまりベクトル だったらと考えます。はの時に1ですから、sigmoidは実は、の状態と考えるとと考えることができます。を0に固定せず、実数に拡張すると、と解釈することができます。
この関数は、例えばとが同じ値だと、0.5=50%となります。2つの変量がある際、どちらに対する定量的な尺度が同じだとすると、片側に対する可能性が50%であるという風に解釈することができます。一方で、片方が片方よりも大きい値だとすると、に対する可能性が高くなると解釈できます。
では、次にこれを変量がn個ある状態と解釈するにはどうすればいいでしょうか。に対しては、であるという解釈を入れるとわかりやすいと思います。3以上のiに対して、 が成り立ちますから、
とみなし、これを実数値を持つ変数と考えることで、
を得ることができます。
これは、n個の変量、例えばn=10として、0から9までの整数をとる正解があった際に、0と1をとる確率までは考えたが、それ以外のことはまるで考えていない(つまり、定量的には、2から9まではである)と考えていた状態から、それ以外(2から9までの数字のことです)を考慮に入れて拡張させたと考えると、わかりやすいと思います。
参考までに、2変量(x,y)のxに関するsoftmax関数の3次元画像はこのような形になります。
交差エントロピーは以下の記事に書き足しました。
勾配降下法はまた別の記事に書きたいと思います。