2017年07月22日

ディープラーニング本のサンプルプログラム(1)・・・3章のneuralnet_mnist.py

storage.mantan-web.jp_images_2017_05_21_20170521dog00m200017000c_001_size8.jpg

deeplearning1.jpg

この本を学習しています。この本の構成は以下の通りです。

1章 Python入門
2章 パーセプトロン
3章 ニューラルネットワーク
4章 ニューラルネットワークの学習
5章 誤差逆伝播法
6章 学習に関するテクニック
7章 畳み込みニューラルネットワーク
8章 ディープラーニング
付録A Softmax-with-Loss レイヤの計算グラフ
参考文献

各章のサンプルプログラムを実行して結果とソースコードを紹介しています。

この回では3章で紹介されているサンプルプログラムです。

ファイル名:neuralnet_mnist.pr
------------------------------------------------
# coding: utf-8
import sys, os
sys.path.append(os.pardir) # 親ディレクトリのファイルをインポートするための設定
import numpy as np
import pickle
from dataset.mnist import load_mnist
from common.functions import sigmoid, softmax


def get_data():
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
return x_test, t_test


def init_network():
with open("sample_weight.pkl", 'rb') as f:
network = pickle.load(f)
return network


def predict(network, x):
W1, W2, W3 = network['W1'], network['W2'], network['W3']
b1, b2, b3 = network['b1'], network['b2'], network['b3']

a1 = np.dot(x, W1) + b1
z1 = sigmoid(a1)
a2 = np.dot(z1, W2) + b2
z2 = sigmoid(a2)
a3 = np.dot(z2, W3) + b3
y = softmax(a3)

return y


x, t = get_data()
network = init_network()
accuracy_cnt = 0
for i in range(len(x)):
y = predict(network, x[i])
p= np.argmax(y) # 最も確率の高い要素のインデックスを取得
if p == t[i]:
accuracy_cnt += 1

print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
------------------------------------------------

このプログラムはとても参考になるプログラムで、いろいろなことに応用できます。

まず初めて実行するすると、次のような表示が出てきます。

初めて実行すると
(親ディレクトリ)\ch03>python neuralnet_mnist.py
Downloading train-images-idx3-ubyte.gz ...
Done
Downloading train-labels-idx1-ubyte.gz ...
Done
Downloading t10k-images-idx3-ubyte.gz ...
Done
Downloading t10k-labels-idx1-ubyte.gz ...
Done
Converting train-images-idx3-ubyte.gz to NumPy Array ...
Done
Converting train-labels-idx1-ubyte.gz to NumPy Array ...
Done
Converting t10k-images-idx3-ubyte.gz to NumPy Array ...
Done
Converting t10k-labels-idx1-ubyte.gz to NumPy Array ...
Done
Creating pickle file ...
Done!
Accuracy:0.9352

2回目以降は次のように出ます。
(親ディレクトリ)\ch03>python neuralnet_mnist.py
Accuracy:0.9352

要するにMNISTの画像データがない場合はWEBサイトからPCに自動ダウンロードしてから、プログラムを実行してテスト画像1万枚の識別の正解率を表示します。

PCにMNISTの画像データがある場合は正解率を表示します。

正解率は93.62%もあります。このプログラムはすでに学習したパラメータを利用していますが、1万回テストして9362回も正解しています。手書きの数字の判別です。すごいですね。

このプログラムの核心はpredict(network, x)の定義の中の次の部分です(あくまで私の理解です)。

a1 = np.dot(x, W1) + b1
z1 = sigmoid(a1)
a2 = np.dot(z1, W2) + b2
z2 = sigmoid(a2)
a3 = np.dot(z2, W3) + b3
y = softmax(a3)

文字なので単純な数を扱っているように見えますが、すべて多次元配列です。

keijyo1.jpg

この処理を100枚ずつのバッチ処理で行ったのが、次のプラグラムです。

ファイル名:neuralnet_mnist_batch.pr
------------------------------------------------
# coding: utf-8
import sys, os
sys.path.append(os.pardir) # 親ディレクトリのファイルをインポートするための設定
import numpy as np
import pickle
from dataset.mnist import load_mnist
from common.functions import sigmoid, softmax


def get_data():
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
return x_test, t_test


def init_network():
with open("sample_weight.pkl", 'rb') as f:
network = pickle.load(f)
return network


def predict(network, x):
w1, w2, w3 = network['W1'], network['W2'], network['W3']
b1, b2, b3 = network['b1'], network['b2'], network['b3']

a1 = np.dot(x, w1) + b1
z1 = sigmoid(a1)
a2 = np.dot(z1, w2) + b2
z2 = sigmoid(a2)
a3 = np.dot(z2, w3) + b3
y = softmax(a3)

return y


x, t = get_data()
network = init_network()

batch_size = 100 # バッチの数
accuracy_cnt = 0

for i in range(0, len(x), batch_size):
x_batch = x[i:i+batch_size]
y_batch = predict(network, x_batch)
p = np.argmax(y_batch, axis=1)
accuracy_cnt += np.sum(p == t[i:i+batch_size])

print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
------------------------------------------------

当然ながら実行結果はneuralnet_mnist.prの実行結果と同じになります。

(親ディレクトリ)\ch03>python neuralnet_mnist_batch.py
Accuracy:0.9352

そして形状は次のようになります。

a1 = np.dot(x, w1) + b1
z1 = sigmoid(a1)
a2 = np.dot(z1, w2) + b2
z2 = sigmoid(a2)
a3 = np.dot(z2, w3) + b3
y = softmax(a3)

keijyo2.jpg

この辺は数学の行列に慣れている人にはすんなり理解できると思います。

こんなところからもPythonは数学や物理などでも有用な機械学習言語だと分かりますねえ。

今回はこれで終了です。




posted by tsurutsuru at 14:29| Comment(0) | 日常茶飯事

2017年07月21日

しばらくは学習本のサンプルプログラムを実行しその結果とソースコードを紹介していきます

storage.mantan-web.jp_images_2017_05_21_20170521dog00m200017000c_001_size8.jpg

deeplearning1.jpg

この本を学習しています。

しばらくの間、この本の中で紹介されているプログラムを実際に実行してその結果とソースコードを紹介していきます。

順番は章に従って、1章からやっていきます。

次回から始めます。

では。
posted by tsurutsuru at 08:27| Comment(0) | 日常茶飯事

回帰直線の傾きは重み、切片はバイアスに相当します・・・ディープラーニングの理解に回帰直線の理解はとても役に立ちます

storage.mantan-web.jp_images_2017_05_21_20170521dog00m200017000c_001_size8.jpg

deeplearning1.jpg

この本を学習しています。

私がしばしば回帰直線の求め方に言及しているのは、ニューラルネットワークの理解に役に立つからです。

回帰直線のの傾きは重み、切片はバイアスなんですね。

傾きや切片は損失関数(残差の2乗の総和)を偏微分して求めます。

ですから同じなんです。だから、ニューラルネットワークの理解に役に立つのです。

posted by tsurutsuru at 07:55| Comment(0) | 日常茶飯事

2017年07月20日

簡単なニューラルネットワークの学習を回帰直線でやってみました

storage.mantan-web.jp_images_2017_05_21_20170521dog00m200017000c_001_size8.jpg

deeplearning1.jpg

この本を学習しています。

ディープラーニングは深い層を持ったニューラルネットワークです。

ですから、ニューラルネットワークの学習が分かればディープラーニングも分かるわけです。

そこで簡単な回帰分析による回帰直線を求めるのにニューラルネットワークの学習を使ってやってみます。

まず分析するデータです。

表1.jpg

平成22年度に文科省が調査した女子の平均身長です。

明らかに年齢と身長の間に相関関係があることが分かります。

それではExcelを使ってグラフを描いてみます。

図1.jpg
求めたいか回帰直線のグラフも描いてあります。

Excelの分析ツール(回帰分析)によるこのデータの結果は次の通りです。

表2.jpg

さて、Excel VBAでプログラムを書いて1万回ほどニューラルネットワークの学習をやらせて、求める回帰直線の傾きと切片を求めてみました。

初期値はどういう決め方がいいのかまだよく分かっていないのでとりあえず1番目の点と最後の点を結んだ直線の傾きと切片としました。

本当は(各点のx座標の平均、各点のy座標の平均)は求める回帰直線上にあるということを知っているのですが、その知識は使わないことにします。

損失関数は残差の2乗の総和としました。

ハイパーパラメータ(偏微分の学習率)ですが、傾きは0.001(0.01だと発散してしまったのでこの値に)、切片は0.01にしました。

以下が1万回コンピュータに学習させた結果のグラフです。

図2.jpg

図3.jpg

2つのグラフを見てもらうと分かるように確かに学習していますねえ。

最終的に1万回(時間を測れば良かったのですが数分で終了したと思います)で次のようになりました。

傾き 0.7767 ⇒ 0.72077
切片 145.268 ⇒ 146.048

とてもいい結果が出ていると思うのですが、どうでしょうか。

傾きも切片も正解と比べて99.9%一致しています。

ほんと面白いですねえ。

(お断り)
今回だけではありませんが、数学の知識がないとここまで出来ないと思います。
難しいことはやっていませんが、かと言って誰でも出来るかというと難しいと思います。


posted by tsurutsuru at 23:40| Comment(0) | 日常茶飯事

ディープラーニング本の拾い読み記(4)

storage.mantan-web.jp_images_2017_05_21_20170521dog00m200017000c_001_size8.jpg

アマゾンでベストセラーになっている下記の本の拾い読み記を書いています。ほとんどが自分の備忘録のために書いていますので、読まれる方には分かりづらいかと思います。

deeplearning1.jpg

さて、ここまで拾い読みして理解できたのは、画像認識のディープラーニングでは、CNN(convolutional neural network)がとても重要な役割をはたしているようだということです。

CNNは日本語では、畳み込みニューナルネットワークと訳しているようです。

画像認識のコンペティションでは、ディープラーニングによる手法のほとんどすべてがCNNをベースとしているそうです。

物体認識や物体検出などもCNNをベースにした手法が多いそうです。物体検出は自動車の自動運転に求められる技術です。

CNNの基本は、畳み込み層とプーリング層です。

畳み込み層のイメージは次の通りです。

tatamikomi1.jpg

フィルターが重みです。

さて、ここでニューラルネットワークの学習の手順を思い出してください。

---------------------------------------------------------------
さて、ここでニューラルネットワークの学習の手順を確認しておきます。

(前提)ニューラルネットワークは、適応可能な重みとバイアスがあり、その重みとバイアスを訓練データに適応するように調整することを学習と呼ぶ。ニューラルネットワークの学習は次の4つの手順で行う。

〔ステップ1(ミニバッチ)〕
訓練データの中からランダムに一部のデータを選び出す。その選ばれたデータをミニバッチと言い、ここでは、そのミニバッチの損失関数の値を減らすことを目的とする。

〔ステップ2(勾配の算出)〕
ミニバッチの損失関数を減らすために、各重みパラメータの勾配を求める。勾配は、損失関数の値を最も減らす方向を示す。

〔ステップ3(パラメータの更新)〕
重みパラメータを勾配方向に最小量だけ更新する。

〔ステップ4(繰り返す)〕
ステップ1、ステップ2、ステップ3を繰り返す。
---------------------------------------------------------------

ですから、CNNの畳み込み層に出てくるフィルターとバイアスの最適値を求めることになります。

さて、ステップ2の勾配は微分を利用するのでした。

微分は数値微分よりも誤差逆伝播法を使う方が比較的簡単に計算できると学習本にあります。

誤差逆伝播法のイメージは次の通りです。

gyakydenpa1.jpg

細かいことに引っかかっていると内容が分からなくなります。

こういう時は高いところから全体を俯瞰するのが一番です。

本質なものを忘れないようにして細かい部分を学習していきましょう。

今回はここまでです。




posted by tsurutsuru at 14:48| Comment(0) | 日常茶飯事

ディープラーニングを学ぼうとしている若い方々へ・・・皆さんはいい時代に生まれましたねえ!

storage.mantan-web.jp_images_2017_05_21_20170521dog00m200017000c_001_size8.jpg

ディープラーニングを学ぼうとしている若い方々へ一言。

皆さんはいい時代に生まれましたねえ。

ディープラーニングが脚光を浴び始めたのは2012年です。それからまだ5年しか経過していません。

要するにディープラーニングはまだ黎明期なのです。

こういう時期にディープラーニングを徹底的に学習して自分のものにすれば、これはもう一生もんの宝物です。

現在日本の企業はディープラーニング技術者をこぞって大量に採用しようとしています。

明らからにこの方面の人材は不足しています。

いまディープラーニングを徹底的に学習して自分のものにしておけば就職の時に有利に働くでしょう。

皆さんはいい時代に生まれましたねえ。羨ましいですよ。ほんと。

deeplearning1.jpg

こういう本を繰り返し読んでぜひディープラーニングを自分のものとして下さい。

では。
posted by tsurutsuru at 11:57| Comment(0) | 日常茶飯事