メルマガ登録
※TensorFlowとは2015年11月9日にオープンソース化されたGoogleの機械学習ライブラリです。
本ブログでは、実際のTensorFlowの使い方を連載方式でご紹介しています。
皆様こんにちは。
テクノロジー&ソフトウェア開発本部の佐藤貴海です。
本日は「Deep MNIST For Experts」の使い方についてご紹介します。
前回の「MNIST For ML Beginners」に続き、今回からいよいよ”Deep”です。前回は単なるロジスティック回帰でしたが、今回からは学習する層を重ねて、MNIST判別99%超えを目指します。
前回は、28×28ピクセルの画像(784次元)を、そのままSoftmax Regressionに与えて学習しました。
今回は、Softmax Regressionを使う点は同じですが、与える入力を多層の(Deepな)ニューラルネットワークで生成します。
いわゆる「ディープラーニング」と呼ばれる手法は、Softmax Regressionといった一般的な教師あり学習の手法に適用させる説明変数を、多層のニューラルネットワークで作ってしまおう、という手法です。
もともとは人手で試行錯誤して変数を作っていた部分を自動化できる、という点が「ディープラーニング」の謳い文句です。「表現学習」と呼ばれることもあります。
学習する方法としては、以下の2つがあります。
今回は後者のひとつである、Softmax Regressionとニューラルネットワークを同時に学習する手法をとります。
今回のモデルは、以下の計6層で構成します。
いわゆる畳み込みニューラルネットワーク(Convolutional neural network: CNN)です。
さすがに、このブログ上でCNNを解説するのは無理があるので、CNNについて雰囲気を記載するとこんな感じです。
TensorFlowでの実装方法への解説は、コードに直接コメント形式で記載しましたので、以下をご参照ください。
さらに、CNNについての詳細なTensorFlowでの実装は「4-1. Convolutional Neural Networks」で紹介する予定です。お楽しみに。
チュートリアルに従い、以下のコードを実際に動かしてみます。
# -*- coding: utf-8 -*-
# Author: takami.sato
import tensorflow as tf
import input_data
def weight_variable(shape):
"""適度にノイズを含んだ(対称性の除去と勾配ゼロ防止のため)重み行列作成関数
"""
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
def bias_variable(shape):
"""バイアス行列作成関数
"""
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)
def conv2d(x, W):
"""2次元畳み込み関数
"""
return tf.nn.conv2d(x,
W,
strides=[1, 1, 1, 1], # 真ん中2つが縦横のストライド
padding='SAME')
def max_pool_2x2(x):
"""2x2マックスプーリング関数
"""
return tf.nn.max_pool(x,
ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1], # 真ん中2つが縦横のストライド
padding='SAME')
def main():
# mnistのダウンロード
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
sess = tf.InteractiveSession()
with tf.device("/gpu:1"):
# データ用可変2階テンソルを用意
x = tf.placeholder("float", shape=[None, 784])
# 正解用可変2階テンソルを用意
y_ = tf.placeholder("float", shape=[None, 10])
# 画像をリシェイプ 第2引数は画像数(-1は元サイズを保存するように自動計算)、縦x横、チャネル
x_image = tf.reshape(x, [-1, 28, 28, 1])
### 1層目 畳み込み層
# 畳み込み層のフィルタ重み、引数はパッチサイズ縦、パッチサイズ横、入力チャネル数、出力チャネル数
# 5x5フィルタで32チャネルを出力(入力は白黒画像なので1チャンネル)
W_conv1 = weight_variable([5, 5, 1, 32])
# 畳み込み層のバイアス
b_conv1 = bias_variable([32])
# 活性化関数ReLUでの畳み込み層を構築
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
### 2層目 プーリング層
# 2x2のマックスプーリング層を構築
h_pool1 = max_pool_2x2(h_conv1)
### 3層目 畳み込み層
# パッチサイズ縦、パッチサイズ横、入力チャネル、出力チャネル
# 5x5フィルタで64チャネルを出力
W_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
### 4層目 プーリング層
h_pool2 = max_pool_2x2(h_conv2)
### 5層目 全結合層
# オリジナル画像が28x28で、今回畳み込みでpadding='SAME'を指定しているため
# プーリングでのみ画像サイズが変わる。2x2プーリングで2x2でストライドも2x2なので
# 縦横ともに各層で半減する。そのため、28 / 2 / 2 = 7が現在の画像サイズ
# 全結合層にするために、1階テンソルに変形。画像サイズ縦と画像サイズ横とチャネル数の積の次元
# 出力は1024(この辺は決めです) あとはSoftmax Regressionと同じ
W_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
# ドロップアウトを指定
keep_prob = tf.placeholder("float")
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
### 6層目 Softmax Regression層
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
# 評価系の関数を用意
cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
sess.run(tf.initialize_all_variables())
for i in range(20000):
batch = mnist.train.next_batch(50)
if i%100 == 0:
train_accuracy = accuracy.eval(feed_dict={x:batch[0],
y_: batch[1],
keep_prob: 1.0})
print("step %d, training accuracy %g"%(i, train_accuracy))
train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})
print("test accuracy %g"%accuracy.eval(feed_dict={
x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))
if __name__ == "__main__":
main()
このような形で、層が複数のニューラルネットワークを構築することができます。
基本的に、積み重ねるだけの素直な実装方法となっています。
これを実行すると、以下の様な出力となります。
Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
I tensorflow/core/common_runtime/local_device.cc:25] Local device intra op parallelism threads: 12
I tensorflow/core/common_runtime/gpu/gpu_init.cc:88] Found device 0 with properties:
name: GeForce GTX 960
major: 5 minor: 2 memoryClockRate (GHz) 1.1775
pciBusID 0000:03:00.0
Total memory: 2.00GiB
Free memory: 1.95GiB
I tensorflow/core/common_runtime/gpu/gpu_init.cc:88] Found device 1 with properties:
name: Tesla K40c
major: 3 minor: 5 memoryClockRate (GHz) 0.745
pciBusID 0000:01:00.0
Total memory: 11.25GiB
Free memory: 10.79GiB
I tensorflow/core/common_runtime/gpu/gpu_init.cc:45] cannot enable peer access from device ordinal 0 to device ordinal 1I tensorflow/core/common_runtime/gpu/gpu_init.cc:45] cannot enable peer access from device ordinal 1 to device ordinal 0
I tensorflow/core/common_runtime/gpu/gpu_init.cc:112] DMA: 0 1
I tensorflow/core/common_runtime/gpu/gpu_init.cc:122] 0: Y N
I tensorflow/core/common_runtime/gpu/gpu_init.cc:122] 1: N Y
I tensorflow/core/common_runtime/gpu/gpu_device.cc:643] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX 960, pci bus id: 0000:03:00.0)
I tensorflow/core/common_runtime/gpu/gpu_device.cc:643] Creating TensorFlow device (/gpu:1) -> (device: 1, name: Tesla K40c, pci bus id: 0000:01:00.0)
I tensorflow/core/common_runtime/gpu/gpu_region_allocator.cc:47] Setting region size to 1881214976
I tensorflow/core/common_runtime/gpu/gpu_region_allocator.cc:47] Setting region size to 11002706535
I tensorflow/core/common_runtime/local_session.cc:45] Local session inter op parallelism threads: 12
step 0, training accuracy 0.14
step 100, training accuracy 0.78
step 200, training accuracy 0.94
step 300, training accuracy 0.88
(中略)
step 19800, training accuracy 1
step 19900, training accuracy 1
test accuracy 0.9926
無事、99%を超える精度を得ることができました。
TensorFlowでは、非常に少ないコード量で、畳み込み層やプーリング層といった様々な層を重ねて、”Deep”な学習をすることができます。(データの前処理を既存コードに頼っていますが。。。)
次回は、「2-2. Variables: Creation, Initializing, Saving, and Restoring」を公開予定です。
あなたにオススメの記事
2023.12.01
生成AI(ジェネレーティブAI)とは?ChatGPTとの違いや仕組み・種類・活用事例
2023.09.21
DX(デジタルトランスフォーメーション)とは?今さら聞けない意味・定義を分かりやすく解説【2024年最新】
2023.11.24
【現役社員が解説】データサイエンティストとは?仕事内容やAI・DX時代に必要なスキル
2023.09.08
DX事例26選:6つの業界別に紹介~有名企業はどんなDXをやっている?~【2024年最新版】
2023.08.23
LLM(大規模言語モデル)とは?生成AIとの違いや活用事例・課題
2024.03.22
生成AIの評価指標・ベンチマークとそれらに関連する問題点や限界を解説