メルマガ登録
※TensorFlowとは2015年11月9日にオープンソース化されたGoogleの機械学習ライブラリです。
本ブログでは、実際のTensorFlowの使い方を連載方式でご紹介しています。
皆様こんにちは。
テクノロジー&ソフトウェア開発本部の佐藤貴海です。
今日から本題のTensorFlow入門編に突入します。今回は、「MNIST For ML Beginners」の使い方をご紹介しようと思います。
http://www.tensorflow.org/tutorials/mnist/beginners/index.md
MNISTとは、「Mixed National Institute of Standards and Technology database」の略で、手書きの数字「0~9」に正解ラベルが与えられているデータセットです。
http://yann.lecun.com/exdb/mnist/:title
手軽に入手でき、データサイズも大きくないので深層学習周りではよく使用されます。
手書き文字は28ピクセル×28ピクセルの画像で与えられており、この784次元のデータを使って0~9を予測します。
このチュートリアルでは”For ML Beginners”と題しているだけあり、Softmax Regressionという多クラス分類(画像を0~9の10クラスに分類)するのに最もシンプルな手法を採用しています。
Softmax Regressionの日本語訳は、色々あるみたいですが、PRML(PATTERN RECOGNITION AND MACHINE LEARNING)では多クラスロジスティック回帰と呼ばれています。私も日本語訳がパッと出てこなかったのですが、ロジスティック回帰と一緒に習ってしまうからかもしれません。
お馴染みの線形回帰の場合は、
説明変数ベクトル\( {x \in \mathbb{R}^{m}} \)と
回帰係数ベクトル\( {a \in \mathbb{R}^{m}} \)の内積に
バイアス\( {b\in \mathbb{R}} \)を加えたモノが
目的変数\( {y\in \mathbb{R}} \)となるように学習します。
$$ { \displaystyle y = a^{T}x+b } $$
これだと、出力(目的変数)が1個しか出てこないので、多クラスの判別には使えません。
これを多クラス(今回は10クラス)にするため、回帰係数を行列\( {W \in \mathbb{R}^{10 \times m}}\)にして出力を無理矢理10個にしてみます。
$$ :{ \displaystyle y = Wx+b } $$
(同じ記号使ってすみません。ここでは\( {y\in \mathbb{R}^{10}, b\in \mathbb{R}^{10}}\)です。)
ただし、このままだと\( {y}\)は訳が分からない数字です。
いまは10個の数字を当てたいので、\( {y}\)が以下のような性質を持っていると嬉しいわけです。
そこで、訳が分からない数字\( {y}\)が上記の性質を持たせるために、Softmax関数という(活性化)関数を噛ませます。
$${ \displaystyle
y = softmax(Wx+b)
}$$
これでそれっぽい\( {y\in \mathbb{R}^{10}}\)になったので、あとは、\( {y}\)がしっかり予測になるように、\( {W, b}\)を学習してしまえば良いわけです。
学習とはつまり、\( {y}\)の正解が0の場合[1, 0, 0, 0, 0, 0, 0, 0, 0, 0[/latex]に“近く”なる様な、\( {W, b}\)を見つけてしまえば、それがゴールです。
この“近い”というのを定義しているのが、誤差関数という関数で、線形回帰の場合はお馴染みの二乗誤差を使っています。
今回も二乗誤差で学習することも可能ですが、せっかく\(y\)を確率として解釈できるようにしたので、より適した交差エントロピー誤差関数を使用します。
このように、活性化関数にSoftmax関数を使用し、誤差関数に交差エントロピー誤差関数を使用したものが多クラスロジスティック回帰です。
機械学習に始めて触れる方は、この活性化関数と誤差関数をかなり適当に決めてしまっているのに驚かれるかもしれません。実際、工学的には、上手くいけばどんな組合せであっても良いのです。結果が全てです。
ただし、「Softmax関数と交差エントロピー誤差関数」、「普通の線形回帰の二乗誤差(恒等関数と二乗誤差)」といった組み合わせは、正準連結(canonical link)という性質を持っており、よく使用されます。さらに知りたい方は一般化線形モデル(GLM)で調べて見て下さい。
前振りが長くなりましたが、実際に動かして見ます。
チュートリアルに載っている、断片的なコードを集めたものが以下となります。
# -*- coding: utf-8 -*-
# Author: takami.sato
import tensorflow as tf
import input_data
def main():
# mnistのダウンロード
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
# 複数GPUがあるので指定
with tf.device("/gpu:1"):
# n * 784 の可変2階テンソル
x = tf.placeholder("float", [None, 784])
# 重み行列とバイアスの宣言
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
# ソフトマックス層を定義
y = tf.nn.softmax(tf.matmul(x, W) + b)
# 正解用2階テンソルを用意
y_ = tf.placeholder("float", [None, 10])
# 誤差関数の交差エントロピー誤差関数を用意
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
# 学習方法を定義 0.01は学習率
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
# 変数の初期化 ここでGPUにメモリ確保か
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
# 1に一番近いインデックス(予測)が正解とあっているか検証し、その平均
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
# 学習開始
for i in range(1000):
batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
#print sess.run(accuracy, feed_dict={x: batch_xs, y_: batch_ys})
print sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels})
if __name__ == "__main__":
main()
ほとんど書き写しですが、今回は複数GPUがあるので”with tf.device(“/gpu:1”):”陽に指定しています。
input_dataについては、こちらから各自DLをお願いします。
https://tensorflow.googlesource.com/tensorflow/+/master/tensorflow/examples/tutorials/mnist/input_data.py
基本的に、TensorFlowの簡単な使い方は以下の流れだと思われます。
PFN(株式会社Preferred Networks)社が公開しているChainerも似たようなインターフェースだったので、GPUを使う以上、似てくると思われます。
これを実行すると・・・
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 1
I 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
0.9167
現在使ってるマシンには、GeForce GTX 960とTesla K40cの2枚が刺さっています。Teslaが/gpu:1に指定されてしまったので、先ほど陽に指定しました。
最終行に出てるのが、printされた精度です。大体92%出ており、チュートリアルの結果と一致しています。
簡単なSoftmax Regressionでも9割ぐらいの精度は出ています。
ちなみに以下の公式HPによると、現在は誤差率0.23%つまり99.77%の精度で判別できています。
MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges
次回は、「2-1.Deep MNIST for Experts」を公開予定です。
あなたにオススメの記事
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の評価指標・ベンチマークとそれらに関連する問題点や限界を解説