LoginSignup
2
5

More than 5 years have passed since last update.

初等深層学習・手書き文字認識編

Last updated at Posted at 2018-07-30

環境

Microsoftが提供するAzureNotebook下のJupyterNotebookを使います。
ですので、ブラウザさえあれば実践できます。

実装

早速やっていきましょう!
AzureのJupyterの使い方は省略します。おそらく直感でほぼいけるので…

ざっくりとした説明をその都度していきますが、私個人の理解であり、もしかしたら間違っているかもしれません。(そんなこと無いよう気をつけますが・・・)

まず、セルにこれを入れてRun(実行)しましょう。

!pip install keras
!pip install numpy
!pip install matplotlib

pipコマンドの先頭はJupyterでは「!」を使用します。

次に、必要なモジュールのインポートです。

import keras
from keras.models import Sequential
from keras.layers import Conv2D,MaxPooling2D,Activation,Flatten,Dense
from keras.optimizers import Adadelta
from keras.datasets import mnist

import numpy as np
import matplotlib.pyplot as plt

各種モジュールがインポートされました!
この子達を使って、Sequentialモデルという単入力・単出力のモデルを構築します。

model = Sequential()

model.add(Conv2D(3,(2,2),input_shape = (28,28,1)))
model.add(Activation("relu"))

model.add(Conv2D(6,(2,2)))
model.add(Activation("relu"))

model.add(MaxPooling2D(pool_size = (2,2)))

model.add(Conv2D(9,(2,2)))
model.add(Activation("relu"))

model.add(Conv2D(12,(2,2)))
model.add(Activation("relu"))

model.add(MaxPooling2D(pool_size = (2,2)))

model.add(Flatten())

model.add(Dense(1024))
model.add(Activation("relu"))

model.add(Dense(512))
model.add(Activation("relu"))

model.add(Dense(256))
model.add(Activation("relu"))

model.add(Dense(10))
model.add(Activation("softmax"))

model.compile(loss = keras.losses.categorical_crossentropy,
              optimizer = Adadelta(),
              metrics = ["accuracy"])

さて、解説といきましょう!

最初にmodel変数にSequentialクラスのインスタンスを生成しました。。
このインスタンスにはまだ何も加えられていません。これに層を加えていくことで、モデルが構築されていきます。

まず、Conv2D()についてです。これはConvolution層と言われ、畳み込み層と訳されます。画像データを空間情報を維持したまま計算し、その特徴量を検出します。今回は手書き文字なので、線の形などに留まりますが、例えば犬の特徴量を検出する際は、体表の模様に始まり、次第に輪郭→目・鼻・口→顔→犬といった風に、だんだんと情報の幅を広くしていきます。

こうすることで、より容易に物を識別することが可能となり、精度が飛躍的に向上しました。

各層の下には、Activationという活性化関数をつけています。これなしに、人工知能は成り立たないといっても過言ではありません。ReLUという関数を今回は使用していますが、理由としては「便利だから」とだけ言っておきます。今はその認識でOKです。

特徴量を抽出したら、次はそれを1次元にします。つまり、空間情報を扱うのをやめ、次のDense層に渡せるようにします。Flatten()の役割がこれです。

あとはDense(ノード数)で、ニューラルネットワークを作り、最後に10クラス分類のためにDense(10)として、クラス分類のためのSoftmax()を重ねて終わりです。

Softmax()は、クラスごとの確率を求めたいときに使われます。計算式は割愛しますが、総和分のあるクラスに相当する値を返します。
これを確率とみなせるのです。

因みに、MaxPooling2D()は、計算量を削減する層です。(2,2)のフィルタの中の最大値を抜き出すことで、表す情報はほとんど変化しないままに、情報量を4分の1に減らしてくれます。

データセット

モデルの学習に使われるデータ群をデータセットと言います。以下のコードを実行して、データを取得し、可視化までしてみましょう。

(xTrain,yTrain),(xTest,yTest) = mnist.load_data()

xTrain = xTrain.reshape(-1,28,28,1) / 255
xTest = xTrain.reshape(-1,28,28,1) / 255

yTrain = keras.utils.to_categorical(yTrain,10)
yTest = keras.utils.to_categorical(yTest,10)

plt.imshow(xTrain[0].reshape(28,28))
print(yTrain[0])

これを実行すると、手書きの数字と、0と1が出力されるはずです。
1が左から何番目にあるか、「0、1、2、・・・」と数えてみましょう。
n番目と、表示されている数字(n)が一致していますね?

これが学習用データと解答データです。

また、255で割っているのは0〜255の値で表されている色情報を0〜1の間に押し込むためです。

学習

さらりとデータの整形を済ませてしまいましたが、いよいよ学習させてみます。
コードは以下の通りです。

log = model.fit(xTrain,yTrain,
                batch_size = 256,
                epochs = 16,
                validation_data = (xTest,yTest))

xTrain,yTrainというのは、先程の学習データとその解答データです。

batch_sizeというのは、一度に数万のデータとにらめっこするのは大変ですので、ちっちゃい塊にして、与える時の塊の大きさです。計算時間や、精度にまで影響する値です。

epochsというのは、学習を繰り返す回数です。本来はだんだん大きな値を指定するものですが、今回は16でいいでしょう。

validation_dataというのは、モデルの汎化度を検証するためのデータです。モデルがきちんと色々な問題に対応できるかをこれで測ります。これは、学習には全く影響しません。

可視化

ここまで苦労してきたのに、その成果がわからないのはつまらないものです。
というわけで、その軌跡をグラフで示しましょう!

plt.plot(log.history["acc"],label = "Train Accuracy")
plt.plot(log.history["val_acc"],label = "Test Accuracy")
plt.legend()

Train Accuracyが上がるにつれて、Testの方も上がっていっていますね!(たぶん)
この2線がよっぽど離れていない限り、モデルは正常に学習しています。
この2線が離れてしまうと、モデルは過学習という状態に陥っています。
これは、偏学習とも言われ、今までいい結果を出していたモデルが、いきなりアホの子になってしまうこともあります。これをいかに回避するかが重要となってきます。

最後に

ここまで読んでいただき、本当にありがとうございます!
ただ、この記事は過不足なく情報を網羅しているわけではありません…
演算式や、詳細な原理などは省いています。
ですので、もしこの記事で興味をそそられたということがございましたら、ぜひ色々なサイトを見てみてください!
世界は広いです、色々な人が色々な方法で色々な問題にアプローチしています!

この記事が貴方のAIライフへの糸口となることを祈っています!

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5