しんさんのブログ

科学や技術のこと読書のことなど

「人工知能と経済の未来」 井上 智洋著 を読みました

人工知能が経済にどのような影響を与えるのかをテーマにした本です。
現在のAIは囲碁や将棋で、人間に勝つまでに進歩しましたがそれはあくまで一つの或いはよく似た複数の仕事をこなす専用AIです。
2030年から40年にかけて、それが汎用AIに進化する、いやむしろ汎用AIという新しいAIが発明されるだろうと予想されています。
本当に今から10~20年で汎用AIと呼ばれるものが出現するのかどうかはわかりませんが、もし汎用AIが出現すれば、いったい何が起きるのかが考察されています。
本書は、人の生活の仕組みが劇的に変化することを革命と呼び経済の切り口でこの革命について、その本質を説明しています。
例えば、人類が始めに体験した大きな革命として、定住革命があります。
これは、狩猟採集から農業を行うようになった変化です。
食料を自ら生産しストックするようになったこのころから経済活動といったものが始まったと考えられます。
しかし、この時代には農作物の生産には土地+労働が必要とされ、より多くの生産を得るためにはより多くの耕作地を必要としました。
しかし、生産可能な土地の面積には限りがあるので成長が持続することはできず、また生産量が伸びてもそれに応じて人口が増えて、一人当たりの収穫は変化しないというマルサスの罠という現象に直面し人が豊かになることはなかったそうです。
その後、第1次産業革命により、機械化経済が始まります。
現代に生きる我々も基本的にはこのとき始まった機械化経済の枠組みの中にいます。
では機械化経済では何が起こったか? 人は豊かになったのか?
機械化経済では、生産の手段は機械+労働になり、土地が有限だったために成長が持続できなかった時とは異なり、資本を投入し生産設備(機械)を増やすことで生産量を増やすことができるようになりました。
しかし機械化経済の時代では生産力を倍にしてもOutputはせいぜい線形にしか伸びることはなく、設備を増強した分、労働力も増やさないといけないので、人はそれ程豊かになることはないそうです。(これは日々我々が実感していますよね)
General Purpose Technology(GPT)と呼ばれる新しい技術が発明されるたびに、第2次、第3次の産業革命が起きて、それは内燃機関だったりコンピュータやインターネットだったりするわけですが、そういう新しい汎用技術により数十年にわたって成長率が伸びることがあり、そのたびに人は豊かにはなりましたが、それもあくまで機械化経済の枠組みから外れることはなく、成長率はいずれ1パーセントほどの低い水準に収束することになります。
ここで著者は、汎用人工知能というGPTにより今後数十年以内に第4次の産業革命が起き、機械化経済から"純粋機械化経済"の時代に移行すると主張しています。
純粋ってどういうことだろう?と思いますが、それは生産活動に人が関与することがない、”純粋に”機械だけで生産活動ができるという意味です。
これはつまりAIによって人は仕事を奪われてしまう、別の言い方をすれば働かなくてもいい時代がくるということです。
純粋機械化経済の時代では、生産活動に人というボトルネックがありませんので、経済成長率を大きく持続的に伸ばすことができ、人類がこれまで経験したことがない豊かな時代に入ることができるとしています。
しかし、そのままでは仕事を機械に奪われてしまう労働者はこの富を得ることができなくて、資本や生産設備を持つ人のみが富を独占することになります。
どうすればこの豊かな時代に皆が幸せになれるのか、その仕組みを作るのが経済の役割ですので、著者は専門家としてどういう経済体制に移行すれば人類が体験したことのないこの大きな革命からユートピアを作ることができるかを非常に楽観的な視点から論じています。
そして、その働かなくても欲しいものが何でも手に入る豊かな時代に人はなにをすればいいのか?それは本書の最後の最後「おわりに」と題された章に凝縮されています。
著者が「おわりに」で述べているような世界が本当に来るのかどうか?それはきっとまだ誰もわからないと思いますが、その革命の基になる汎用AIをいち早く手にできるように世界中で研究開発が行われているのは確かです。
汎用AIの研究・開発に少しでも貢献したいなと考えながら本書を閉じました。

Kerasのコーディングではまったこと集

Kerasのsessionはきちんとclearさせてないとエラーがでます

Tensoflow + Keras のコードの実行で、

TypeError: 'NoneType' object is not callable

というエラーがでて原因がわからず少しはまりました。
どうやら、kerasのバックエンドのTensorFlowのsessionをclearしていないのが原因だったようです。
以下の記事を参考にしましたら、エラーが消えました。
keras+tensorflowで終了処理でエラーが発生する | CodeLab技術ブログ

ネットワークの可視化に関して

ネットワークを可視化したかったので、以下のドキュメントを参考にしました。
可視化 - Keras Documentation

from keras.utils import plot_model
plot_model(model, to_file='model.png')

たったこれだけなら簡単だと思ったのですが、必要なパッケージがインストールされていなくてそのままでは動かなかったです。

私の環境では、以下のようにすれば動作しました。

conda install graphviz
conda install pydot

さらに、以下のサイトから"Stable 2.38 Windows install packages"をダウンロードしインストールしました。
http://www.graphviz.org/download/
そして、Windows環境変数のPathに C:\Program Files (x86)\Graphviz2.38\bin を追加しました。
以上で無事、ネットワークのグラフが表示されました。

Google のTPU v3について

Google I/O 2018で発表された、機械学習を効率よく演算できる専用ASICチップのTPUについてです。
第3世代の発表が今回行われていたので、メモってみます。

彼らのアナウンスをまとめると:

TPUには4つのTPU演算ユニットが載っている。
TPU v2: 180Tera ops per second per one TPU chip which include 4 TPU units.
TPU v3は8倍?とアナウンスされているので、
TPU v3: 180 * 8 = 1.44Peta ops per second per one TPU chip which include 4 TPU units.
さらに TPU v3を束ねたサーバーは256 TPUs なので、
1.44Peta * 256TPU = 369Peta ops per second

という計算で、100Peta以上というアナウンスになっているのでしょうか。
8bit int の演算だと思っていましたが、100Peta flops と書いてあるし、floatの計算なのでしょうか。

よく読むと、Podが8倍の性能になって100kTeraFloposと書いてあり、チップの演算速度8倍になったとは言ってないですね。
逆算すると、
100Peta / 256 = 390 TeraFlops なので、チップそのものはv2 の2倍程度の速度向上のようです。

TensorflowのTutorial "Deep MNIST for Experts"を試した時のメモ

wshinya.hatenablog.com

前回は"MNIST For ML Beginners"の解説を読みプログラムを実行してみました。
今回は、以下のリンクから"Deep MNIST for Experts"の解説を読みプログラムを実行してみます。
Deep MNIST for Experts  |  TensorFlow

前回のBeginners編と今回のExperts編の一番大きな違いは、Beginners編では画像のローカル構造を無視してしまい、1次元のベクトルに展開してしまいましたが、Exprets編では2次元の画像の2次元のまま扱う手法としてCNNを用いているところです。
CNNを用いることで数字の形の特徴をとらえることができ、認識率が大きく向上することが期待されます。

  • 今回のネットワーク構成

畳み込み層
プーリング層
畳み込み層
プーリング層
全結合層
Softmax層

となっています。

2回の畳み込み層により画像のローカルな構造とよりグローバルな構造をとらえることができます。
そのあとは、多値分類問題として、全結合層+Softmax regressionという前回と同じような構造になっています。

まずはmnist_deep.py を実行してみました。
するとWARNINGがずらずらと表示されいますが、
"xxx is deprecated and will be removed in a future version."
という将来のバージョンでこのコマンドは使えなくなりますよという警告ですので、当面は無視しておいても問題なさそうです。
そして実際に学習が進み最終的には、
step 19900, training accuracy 1
test accuracy 0.9913
今度は、testデータで99%の精度を超えてきます。簡単なCNNですがかなりの精度がでますね。

1層目の畳み込み層の
W_conv1 = weight_variable([5, 5, 1, 32])
は、5x5x1(channel数、いまはgray scaleなので1)の畳み込みフィルターが32種類あるということを示しています。
2層目では、
W_conv2 = weight_variable([5, 5, 32, 64])
となっており、5x5x32のフィルターが64種類あることを意味しています。
ここでの32や64はネットワークの途中で学習して特徴量の数に対応しています。
また各層ごとに2x2でMax poolingしていますので,画像サイズは
28 x 28 -> 14 x 14 -> 7x7 と順次スケールされていきます。

2層目のmax poolingが終わった時点では7x7の画像が64枚出力されています。
これをreshapeして1次元ベクトルに変換しているのが
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
です。fully connected layerを構成するためのweight, W_fc1とバイアスb_fc1
をこれに作用させることで、全結合層計算ができます。
最後に活性化関数としてreluを適用してのが以下の行です.
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

このネットワークでは過学習を防止するためにdropout、つまり適当にネットワークの重みWをゼロにするという操作を行います。
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
初めの行はdropoutの際に接続が保持される確率を格納するためのplaceholderで学習時には0.5で推論時にはdropoutしないように1.0にセットしています。
最後に10種類の数値に対応するように単層のsoftmax回帰に相当する層を追加しています。

最適化は
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
とAdamを使用しています。

GradientDescentとAdamで結果がどれくらいちがうのかちょっと実験してみました。
学習率はどちらも0.0001
ADAM:
step 100, training accuracy 0.88
test accuracy 0.9195
SGD:
step 100, training accuracy 0.26
test accuracy 0.2062
まあ、予想通りですが、SGDに比べるとADAMの方がかなり収束が早いです。

TensorflowのTutorial "MNIST For ML Beginners"を試した時のメモ

Tensorflowを勉強するにはTensorflowのTutorialを自分で入力して実行しながら理解するのが一番手っ取り早いです。
特に初めてTensorflowを動かすときには、以下のリンク先のMNIST for ML BeginnersというTutorialがおすすめです。
MNIST For ML Beginners  |  TensorFlow

このチュートリアルは、単純な1層のネットワークで手書き文字を認識するというものです。
1層ですので、重みとバイアスも一つしかありませんが、それでもニューラルネットワークに必要な最小限の要素をすべて含んでいます。

TensorflowのtutorialにはMNISTの手書きデータを使うものはこのbiginner用とCNNを使ったものの2種類があります。
以下に、実際にコードを理解して実行したときの自分用のメモを残しておきます。

                  • -

mnist.train.images は [画像の数, 28x28=784] の shapeで値は0-1の画素の輝度
ラベルは 0~9 の数字でone-hot表現されています。
one-hot表現は例えば、
3 なら [0,0,0,1,0,0,0,0,0,0]
というふうに表現されます。
従ってラベルは
mnist.train.labels [画像の数, 10]というshapeで、値はfloatです。

> x = tf.placeholder(tf.float32, [None, 784])

xは学習データ(手書き数字の画像データを1次元にしたもの), Noneは画像の数は任意の長さを取りうることを意味する。
placeholderはこのように、学習データなどを入れる入れ物。

重みやバイアスは、実行時に随時更新されますので、tfのvariable変数として以下のように定義しています。
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))

wは入力が784次元で出力が10次元なので[784, 10]となります。 
784列10行の行列と思えばいい。

ニューラルネットワークの計算のcoreの部分です。
> y = tf.nn.softmax(tf.matmul(x, W) + b)

tf.matmul(x, W)の部分ですが、データ数をNとすると
xは N x 784 の行列で, Wは 784 x 10の行列なので、結果のyはN行10列の行列です。
つまり各行にxの各行にたいする画像データを0から9のどの数値と予測したかの確率がyの各行に入ります。

この予想された出力yと正解とを使って表されたロス関数を最小化することで、適切なW,bを決めます。
従って正解も上記yと同じshapeである必要があるので、
> y_ = tf.placeholder(tf.float32, [None, 10])
というように、N行10列の行列としてplaceholderを用意しておきます。

多値分類問題なのでロス関数としてcross entropyを使用します。
> cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
tf.reduce_meanは指定されたshapeの成分についての和をとる関数で、今の場合は、reduction_indices=[1]となっているので
1番目の要素についての和をとります。
つまり、0から9の予想された数値の方向に和をとり、N個の要素をもつ1次元配列にします。
この1次元配列は、N個の学習データそれぞれに対するロス関数の値を格納しています。
最後に、tf.reduce_meanで、N個の学習データ(バッチ処理1回分)のそれぞれのロス関数すべての平均をとってこれを最適化関数として使用しています。

ここが少し混乱しやすいのですが、実際のtutorialのコードでは上記の部分が以下のようにsoftmax_cross_entropy_with_logitsという関数で書かれています。
>cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y))
解説を読むと、前者の書き方のほうが数値的に不安定するそうです。

実施のコードで試してみると、前者の場合の精度は私の実行環境では、約0.92、後者では、0.91でほぼ同じ結果になりました。
実行時間は前者では約0.77sec, 後者では0.90secでlogits関数の計算の分だけ速度が落ちているようです。
(実際のコードを一番最後に添付しておきます)

logits関数とは、L = log(p/(1-p)) のことで変形するとp= 1/(1+exp(-L))で、p=0.5の時0,P>0.5のときL>0, p<0.5のときL<0となる関数。
確率p [0, 1.0] -> [-inf, inf]にマップする。
softmaxで確率[0, 1.0]の出力を得て、それをlogitsに通すことで正解の確率が大きければ値はより大きくなる。マイナスが掛かっているのでloss関数としては値が小さくなるということです。
確率が0や1に近い時に勾配が数値的に消失したり不安定にあったりするのを防ぐ効果があります。
stackoverflow.com


最適化はGradientDescentで学習率は0.5に設定しています。
>train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

学習結果の評価
>correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
tf.argmaxは引数の配列の中で一番値の高いもののindexを返す。yは[教師データの数, 正解の確率]という配列になっているので、
1番目の要素(数値の0から9のそれぞれの予測確率)から一番高いもの一つが選ばれます。
tf.equalで教師データと一致しているときにTrue, 異なっているときにFalseをセットします。

# 精度の計算
>accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
tf.castはTrue, Falseを以下のように数値に変換
[True, False, True, True] -> [1,0,1,1]
tf.reduce_meanでこの1,0,1,1,・・・の平均をとり結果を全体の精度とする。

今回試してみた実際のコードは以下のようになります。

import tensorflow as tf
import time

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data", one_hot=True)

start_time = time.time()

x = tf.placeholder(tf.float32, [None, 784])

W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))

y = tf.nn.softmax(tf.matmul(x, W) + b)

y_ = tf.placeholder(tf.float32, [None, 10])
#cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y))

train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
# interactiveSessionでtfのsessionを作成
sess = tf.InteractiveSession()
# global変数の初期化
tf.global_variables_initializer().run()

print ("--- start training ---")
for _ in range(1000): # 1000ステップの学習を行う
    # 1 batch = 100個のデータでbatch学習を行う
    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
print ("--- finish training ---")

# 予測yと正解ラベルy_が同じ値であればTrue、ことなればFalseがセットされる
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
# 精度の計算
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print("精度:")
print( sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))

end_time = time.time()
print ("time: " + str(end_time - start_time) + "sec")

深層学習でよく使われる学習用データセットまとめ

3D系のデータセットは別の記事にまとめました
wshinya.hatenablog.com

arXivTimesに素晴らしいまとめがあります。
github.com

商用利用可能な6種類の最大4Kサイズの人物の肌テクスチャが無料配布されています

商用利用可能な6種類の最大4Kサイズの人物の肌テクスチャが無料配布されています • 3DCG最新情報サイト MODELING HAPPY

MNIST:

手書き文字認識学習用データ
28pixel x 28pixel x 1channel
60000枚:training用
10000枚:test用
クラス: 10個の数字

機械学習におけるHello World的なデータ
ちなみに、MNISTとはMixed National Institute of Standard Technologyの省略形で、日本語に訳せば"国立標準技術研究所"でしょうか。
日本では旧通産省工業技術院、今の産業技術研究所に相当するアメリカの研究機関です。

CIFAR-10:

一般物体認識のベンチマークとしてよく使われている写真データ
32pixel x 32pixel x 3channel
50000枚:training用
10000枚:test用

画像は10種類にラベル付けされている
クラス:airplane, automobile, bird, cat, deer, dog, frog, horse, ship, truck

AlexNet(SuperVision)のAlex Krizhevskyさんが整備
(AlexさんはILSVRC2012で優勝)
以下のサイトに詳しく解説されています
aidiary.hatenablog.com

CIFAR-100:
CIFAR-10の100種類のクラス分け版
qiita.com

Microsoft COCO ( MS COCO ):

画像と、画像の認識、セグメンテーション、画像を説明する短いキャプションがセットになったデータ
以下の解説を参照のこと
qiita.com

Imagenet:

ダウンロードできるのは学術関係者に限定される
ImageNetとはスタンフォード大学がインターネット上から画像を集め分類したデータセット。一般画像認識用に用いられる。ImageNetを利用して画像検出・識別精度を競うThe ImageNet Large Scale Visual Recognition Challenge(ILSVRC)などコンテストも開かれる
現在、1400万枚以上のデータが集まり、2万クラス以上あるらしい
ネット上の画像を集めてきているので結構リンク切れがあったりするらしい。

GoogleのOpen Image Dataset v4

Googleが用意した1,540万のバウンディングボックス含む190万画像600カテゴリのデータセット
Open Images V7
ai.googleblog.com
ダウンロードは以下のサイトから
github.com

Caltech101

101個にカテゴリー分類されたデータ.
画像の品質がいい。
http://www.vision.caltech.edu/Image_Datasets/Caltech101/

The PASCAL Visual Object Classes Homepage

Yoloの学習済みモデルが公開されている.
http://host.robots.ox.ac.uk/pascal/VOC/

YFCC100M

flickerから収集した画像、動画データ.
http://yfcc100m.appspot.com/?

OpenImageDataset v4

物体検出用のデータ。オブジェクトの位置・サイズ、名前がつけられている。
ライセンス:The annotations are licensed by Google Inc. under CC BY 4.0 license. The images are listed as having a CC BY 2.0 license.
https://storage.googleapis.com/openimages/web/index.html

顔画像のデータセット

約13000枚の顔画像で、人の名前がフルネームでつけられている。
人は5000人以上、1680人は2枚以上の画像あり。
人種、表情、顔の向き、撮影の状態はランダムで、多様性あり。
http://vis-www.cs.umass.edu/lfw/

Celebの顔写真のデータセット

20万枚の画像
http://mmlab.ie.cuhk.edu.hk/projects/CelebA.html

102種類の花の画像データセット

データサイズは8189枚
Visual Geometry Group - University of Oxford

              • -

他のデータセットもKerasのドキュメントで解説されています
https://keras.io/ja/datasets/

Kerasを使っていてPILが必要になったときの対処法

conda install PILとやったらpythonのversionが3.5だと怒られてしまいます。
PILの代わりに、

conda install Pillow

とすればいいようです。

以下のサイトを参考にしました。
qiita.com

Pillowについては以下を参照
qiita.com