ロゴ ロゴ

Tensorflowで遊ぶ

はじめに

最近はバイト以外で基本的には家から出ず、布団で寝て過ごしてます。そんな中そろそろパソコンを買おうと思っているのですが、せっかくいいGPU(明らかにゲームで使うにはオーバースペックの物を買おうと思っている)を買うのであれば、しっかり”酷使”してあげたいなと思ったので、軽ーく勉強しておこうかなと思います。

VMwareの仮想環境

今回は前にVMwareで作成したUbuntuの仮想環境上でTensorflowを動かしていこうと思います。行うのはMINISTデータセット(手書き数字のデータセット)の数字判定です。VMwareにUubntuを入れてTensorflowをインストールするまでの流れはここここから確認してください。

ソースコード解説

DeepLearningに関してはうまく説明できる程の頭はないので省略します。知りたい人はSonyの小林さんの解説がわかりやすかったのでNeuralNetworkConsoleのYoutubeチャンネルからDeepLearning入門という再生リストを見てみてください。

ソースコードの参考は基本的にはTensorflow公式チュートリアルを参考にしてます。

ライブラリの読み込み

まずはimportするものからです。

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np

上から、Tensorflow(上から3つ)、グラフ作成用のmatplotlib、画像読み込み用のPILにデータの前処理用にnumpyです。

モデルの構築

モデルをどのようなものにするか決めます。ここを変えると精度であったり学習にかかる時間などが変化します。基本的にはここを試行錯誤するのかな??

def create_model():
    model = models.Sequential()
    model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
    model.add(layers.MaxPooling2D((2, 2)))
    model.add(layers.Conv2D(64, (3, 3), activation='relu'))
    model.add(layers.MaxPooling2D((2, 2)))
    model.add(layers.Conv2D(64, (3, 3), activation='relu'))
    model.add(layers.Flatten())
    model.add(layers.Dense(512, activation='relu'))
    model.add(layers.Dense(512, activation='relu'))
    model.add(layers.Dense(512, activation='relu'))
    model.add(layers.Dense(256, activation='relu'))
    model.add(layers.Dense(256, activation='relu'))
    model.add(layers.Dense(256, activation='relu'))
    model.add(layers.Dense(128, activation='relu'))
    model.add(layers.Dense(64, activation='relu'))
    model.add(layers.Dense(32, activation='relu'))
    model.add(layers.Dense(10, activation='softmax'))
    model.summary()
    model.compile(optimizer='adam',
                  loss='sparse_categorical_crossentropy',
                  metrics=['accuracy'])
    return model

中身は結構適当に定義しています。今回は畳み込みニューラルネットワーク(CNN : Convolutional Neural Network)を作成しました。これもチュートリアルをちょっと改造しただけです。画像をあいまいにして枚数を増やすことで精度を上げるみたいなものです。これに関しても先ほど紹介したSonyの小林さんのチャンネルで説明があったので(以下略)

画像読み込み

MINISTの読み込みは初心者向けクイックスタートの物を丸パクリです。

(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data()

train_images = train_images.reshape((60000, 28, 28, 1))
test_images = test_images.reshape((10000, 28, 28, 1))

train_images, test_images = train_images / 255.0, test_images / 255.0

モデルの学習

読み込んだ学習データを用いて学習を行っていきます。

model = create_model()

history = model.fit(train_images, train_labels, epochs=20, validation_data=(test_images,  test_labels))

fitの引数に関して軽く説明するとtrain_imagesは学習用の画像データ、train_labelsは学習用の画像に書かれている数字、epochsはエポック数、validation_dataはバリデーション用のデータです。そのままです。エポック、バリデーションがわからない人はググってください。ちなみにエポック数もとりあえずの値なので何も調整してません。過学習してる可能性もあります。

自分でペイントで書いた数字で確認

6をWindowsのペイントで書いてpngで保存しました。画像の大きさは28×28に設定したのでそのまま読み込むだけです。2行目のconvert(‘L’)に関してはRGBからモノクロに変えるものです。

img = Image.open('/home/kotetsu/program/test.png')
img = img.convert('L')
img = np.expand_dims(img, 2)
img = np.array(img) / 255
img_expand = img[np.newaxis]

predictions_single = model.predict(img_expand)
print(predictions_single)
print(type(predictions_single))
print(predictions_single[0].argmax())
print(predictions_single[0,predictions_single[0].argmax()])

10行目はモデルの予測した数字、11行目はその数字である確率(小数)です。

グラフの出力

これは過学習をしていないか、最適エポック数はいくつなのかなどを確認するためのグラフ出力です。EarlyStoppingなどで過学習を防止することもできますが、再度精度が上昇することもあるらしいのでやめました。

metrics = ['loss', 'accuracy'] 

plt.figure(figsize=(10, 5))

for i in range(len(metrics)):

    metric = metrics[i]

    plt.subplot(1, 2, i+1)
    plt.title(metric)

    plt_train = history.history[metric] 
    plt_test = history.history['val_' + metric]

    plt.plot(plt_train, label='training') 
    plt.plot(plt_test, label='test') 
    plt.legend()

plt.show()

実行結果

実行結果は以下のようになりました。6の画像は97.5%の確率で6であると判定され、グラフは過学習してるのかしてないのかよくわからない感じでした。

終わりに

これを応用すればデータ分析や将棋AIなども作れるということで、どうにかして作ってみたいのですが、その前にGANなども作ってみたいです。SonyのNNCというツールを使うと自動でチューニングしてくれるシステムもあるようなので、パソコンを購入し次第それも本格的に触ってみようと思います。

コメント入力

関連サイト