この記事はtraP Advent Calender 2018 16日目の記事です。
自己紹介
初めまして、drunと言います。
高校までプログラミングに触ってこなかったので、1から四苦八苦して勉強しています。
趣味は漫画、ラノベ、ゲーム(fgo一筋)、将棋等々です。
ということで、他の皆さんに比べて専門的な知識が全くないので、先日校内でやっていた画像認識に関する機械学習セミナーの話でもしようと思います。
まずはPythonと機械学習の基礎
セミナーの前半ではPythonの基本的な使い方を学びました。
そもそも、インスタやYouTube、PepperなどもPythonで書かれているそうですね。
そしてデータサイエンスや人工知能のメジャーなツールやライブラリがPythonから利用できるらしいので、この分野を扱うならPythonは必須らしいです。(僕も勉強始めました)
ここではPythonの基本的な構文などは省略させてもらいます。
後半でやっと機械学習を実際に行います。その流れは次の通りです。
- データの準備
- 学習方法を決める
- 学習させる
- 未知のデータに対して予測・評価
ライブラリはTensorflow、Keras、Matplotlibを使いました。
Anaconda3.5.1.0をインストールしたあと、ターミナルからアナコンダ環境に切り替え、
pip install tensorflow==1.8.0
pip install keras==2.1.6
pip install cognitive_face
を実行して、tensorflow, keras, cognitive_faceをinstallします。
1.データの準備
ここではMNISTと呼ばれる、画像認識のチュートリアルとして使われる手書き文字のデータセットを使います。
まずはMNISTのデータを読み込みます。
(X_train,y_train),(X_test,y_test) = mnist.load_data()
画像データは各々縦Xpx、横YpxというX×Yの情報になっていますが、これをZ×1という横長の1次元の配列に変えます。ここでは60000枚の画像を784×1の形にするので、
x_train = x_train.reshape(60000,784)
とします。
次に0~255の画素値を、0~1の間に調整、要するに255分の1にします。この方がコンピューターが処理しやすいらしいです。
x_train = x_train('float32')
x_train /= 255
今回は数字の認識処理なので、画像データに対して数字の正解のデータが存在します。数字は1桁なので正解のデータは0~9の10通りのどれかが割り当てられています。これを二進数で表すため、要素数10のリストにして、0と1で表現させます(カテゴリカル変数化)。
y_train_label = np_utils.to_categorical(y_train)
y_test_label = np_utils.to_categorical(y_test)
2.学習方法を決める
今回はニューラルネットワークを用いて学習させます。他にも学習モデルはあり、やりたいことに合わせてアルゴリズムを選択するといいそうです。(ニューラルネットワークの説明も省きます)
model = Sequential()
model.add(Dense(512, input_shape=(784,))) #1×784次元だったものを1×512次元にしている
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Dense(10)) #更に計算して1×10次元にしている
model.add(Activation('softmax'))
return model
model = build_multilayer_perceptron()
でモデルを構築します。
更に
model.summary()
でモデルの構造を確認できます。
最後にコンパイルをします。
model.compile(loss='categorical_crossentropy',
optimizer=SGD(),
metrics=['accuracy'])
3.学習させる
やっと学習をさせます。
history = model.fit(x_train, y_train_label,
batch_size=128,
epochs=10, #何回の学習をさせるか。1epoch毎に重みづけを更新し、正答率を上げようとする
verbose=1,
validation_data=(x_test, y_test_label))
表示された実行結果で例えばacc:~は正答率を、loss:~は誤答率を表します。回数を重ねるごとにaccが上昇し、lossが減少するのが分かると思います。
4.未知のデータに対して予測・評価
最後に今度は未知のデータを提示し、コンピューターに予想させます。
score = model.evaluate(x_test, y_test_label, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
を実行して、test用のデータを予測し、正答率を計算します。
間違えたものを表示させたかったら次を実行します。
predicts = model.predict_classes(x_test)
wrongs = []
for i, (x,y) in enumerate(zip(y_test,predicts)):
if x != y:
wrongs.append((i,(x,y)))
f = plt.figure(figsize=(15,15))
for i ,(index, (label, predict)) in enumerate(wrongs[:20]):
i += 1
axes = f.add_subplot(4,5,i)
axes.set_title("label:{0}, predict:{1}".format(label, predict))
axes.imshow(X_test[index])
何と予想したが実際は何だった、と出てくると思います。
あとがき
ほとんどセミナーの受け売りです。
僕自身、プログラムの内容を全て理解できている訳ではありませんので、間違ってたらすいません。
もし、興味を持っていただけたら、ぜひご自分で調べてみることを強く強く強くおススメします。。。
ちなみにセミナーではこの後、学習の層を1つ増やして正答率を上げたり、Microsoft AzureのfaceAPIを使って笑顔判定器をつくりました。
講師のAcroquest社の方々、ありがとうございました。
明日の担当はJohnさんと、maboさんです。どんな記事になるのか楽しみですね!