E資格向けの自習アウトプット
自分用メモ
TensorFlow は、Googleさんが公開している機械学習で便利なライブラリ
現在のところPython では、PyTorch と2大巨頭って感じ?今まで PyTorch 使いなれてきましたが、KPS 的に TensorFlow 使いこなせるようになったほうがよさげなので、この度初挑戦
余談ですが、「テンサー」か「テンソル」かは、Googleの中の人もどっちも使うって言ってた(ようするにどっちでもおk)
なんとなく、ちゃんと学問として線形代数とかやってた人はテンソル派な気がする(なんか頭よさそー)
TensorFlow でモデルを作る下準備
まずは開発環境のバージョンを確認
import sys import tensorflow as tf sys.version, tf.__version__ ('3.8.7 (tags/v3.8.7:6503f05, Dec 21 2020, 17:59:51) [MSC v.1928 64 bit (AMD64)]', '2.4.0')
Python:3.8.7
TensorFlow:2.4.0
今回使うライブラリ群をまとめてインポート
CNN でよく使う関数があらかじめ用意されています
(Kerasを別に呼び出さなくよくなってるの便利)
from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Conv2D from tensorflow.keras.layers import MaxPool2D from tensorflow.keras.optimizers import Adam from tensorflow.keras.layers import Dense, Activation, Dropout, Flatten from tensorflow.keras.utils import plot_model, to_categorical from tensorflow.keras.datasets import cifar10
Conv2D:畳み込み処理
MaxPool2D:プーリング
Adam、Dropoutなどなど見覚えのあるのたくさんあります
このあたり関数の設置をモデルごとにイチイチ時間をかけなくてもよいのが、TensorFlow を使うメリットですね
学習用データセットの準備
CIFAR-10 という機械学習でよく使われる画像データセットを使います
6万枚の画像(32x32)と10種類クラスラベルがセットになったデータセット
(X_train, t_train),(X_test, t_test) = cifar10.load_data()
データセットは(バッチサイズ, H, W, チャネル数)になっている
X_train.shape === (50000, 32, 32, 3)
データの前処理
ピクセル情報は 0 - 255 で表現されているので、0-1に正規化し
10クラス分の one-hot-vector 表現に変換する
# floatに型変換 X_train = X_train.astype('float32') X_test = X_test.astype('float32') # 各画素値を 0-1 に正規化 X_train /= 255.0 X_test /= 255.0 # クラス分けの数に one-hot-vector 表現に classes = 10 t_train = to_categorical(t_train, classes) t_test = to_categorical(t_test, classes) t_train === array([[0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 1.], [0., 0., 0., ..., 0., 0., 1.], ..., [0., 0., 0., ..., 0., 0., 1.], [0., 1., 0., ..., 0., 0., 0.], [0., 1., 0., ..., 0., 0., 0.]], dtype=float32)
TensorFlow でモデル定義
こんな感じで、まずはモデルを定義します
# モデルの定義 model = Sequential() # 第一層(入力層) model.add(Conv2D(32,3,input_shape=(32,32,3))) model.add(Activation('relu')) # 第二層(中間層) model.add(Conv2D(32,3)) model.add(Activation('relu')) model.add(MaxPool2D(pool_size=(2,2))) # 第三層(中間層) model.add(Conv2D(64,3)) model.add(Activation('relu')) model.add(MaxPool2D(pool_size=(2,2))) # 第四層(出力層) model.add(Flatten()) model.add(Dense(1024)) model.add(Activation('relu')) model.add(Dense(classes, activation='softmax')) adam = Adam(lr=1e-4) model.compile(optimizer=adam, loss='categorical_crossentropy', metrics=["accuracy"])
まだ学習はスタートしません
定義した内容の確認、この一覧を見れるのは便利かも
model.summary() Model: "sequential_4" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d_12 (Conv2D) (None, 30, 30, 32) 896 _________________________________________________________________ activation_16 (Activation) (None, 30, 30, 32) 0 _________________________________________________________________ conv2d_13 (Conv2D) (None, 28, 28, 32) 9248 _________________________________________________________________ activation_17 (Activation) (None, 28, 28, 32) 0 _________________________________________________________________ max_pooling2d_8 (MaxPooling2 (None, 14, 14, 32) 0 _________________________________________________________________ conv2d_14 (Conv2D) (None, 12, 12, 64) 18496 _________________________________________________________________ activation_18 (Activation) (None, 12, 12, 64) 0 _________________________________________________________________ max_pooling2d_9 (MaxPooling2 (None, 6, 6, 64) 0 _________________________________________________________________ flatten_4 (Flatten) (None, 2304) 0 _________________________________________________________________ dense_8 (Dense) (None, 1024) 2360320 _________________________________________________________________ activation_19 (Activation) (None, 1024) 0 _________________________________________________________________ dense_9 (Dense) (None, 10) 10250 ================================================================= Total params: 2,399,210 Trainable params: 2,399,210 Non-trainable params: 0 _________________________________________________________________
TensorFlow の学習
fit メソッドに(学習用データセット、正解ラベル、バッチサイズ、エポック数を設定)を設定して一行
エポック数分クリック返され、エポックごとに loss と accuracy が表示されます
history = model.fit(X_train, t_train, batch_size=128, epochs=10, verbose=1, validation_split=0.1) === Epoch 1/10 352/352 [==============================] - 32s 91ms/step - loss: 1.9641 - accuracy: 0.2943 - val_loss: 1.5312 - val_accuracy: 0.4526 Epoch 2/10 352/352 [==============================] - 35s 98ms/step - loss: 1.4862 - accuracy: 0.4707 - val_loss: 1.3845 - val_accuracy: 0.5032 Epoch 3/10 352/352 [==============================] - 33s 94ms/step - loss: 1.3642 - accuracy: 0.5128 - val_loss: 1.3020 - val_accuracy: 0.5354 Epoch 4/10 352/352 [==============================] - 33s 94ms/step - loss: 1.2694 - accuracy: 0.5538 - val_loss: 1.2081 - val_accuracy: 0.5786 Epoch 5/10 352/352 [==============================] - 33s 94ms/step - loss: 1.1937 - accuracy: 0.5835 - val_loss: 1.1789 - val_accuracy: 0.5906 Epoch 6/10 352/352 [==============================] - 33s 95ms/step - loss: 1.1302 - accuracy: 0.6034 - val_loss: 1.1261 - val_accuracy: 0.6124 Epoch 7/10 352/352 [==============================] - 33s 95ms/step - loss: 1.0869 - accuracy: 0.6204 - val_loss: 1.0827 - val_accuracy: 0.6248 Epoch 8/10 352/352 [==============================] - 33s 95ms/step - loss: 1.0425 - accuracy: 0.6370 - val_loss: 1.0628 - val_accuracy: 0.6266 Epoch 9/10 352/352 [==============================] - 33s 94ms/step - loss: 1.0115 - accuracy: 0.6507 - val_loss: 1.0293 - val_accuracy: 0.6436 Epoch 10/10 352/352 [==============================] - 33s 95ms/step - loss: 0.9706 - accuracy: 0.6656 - val_loss: 1.0025 - val_accuracy: 0.6592
val_accuracyは、0.65xxxなのでまだまだ正解率は荒いですが、
とりあえずこれで推論実施してみる
結果確認、モデルの保存
学習したモデルで、画像一枚分予測(推論)をおこなってみる
1枚分の画像は (1, 32, 32, 3) の shape で渡してやります
X_test[:1].shape === (1, 32, 32, 3)
predict メソッドで推論を実行
res = model.predict(X_test[:1]) res, tf.mathargmax( === (array([[0.0033276 , 0.00095791, 0.07522933, 0.54298466, 0.03727062, 0.2813044 , 0.03228953, 0.01226154, 0.01322491, 0.00114957]], dtype=float32), <tf.Tensor: shape=(), dtype=int64, numpy=3>)
正解ラベルと見比べてみると、「numpy=3」で一致しているので、とりあえずは推論成功の模様
tf.math.argmax(t_test[0]) === <tf.Tensor: shape=(), dtype=int64, numpy=3>
モデルをパラメータごと保存
model.save('save-path')
さいごに
CNN の基本を実装してみました
E資格的には、CNNの応用モデルも抑えるべきなので、歴史を振り返りつつ
基本中の基本の CNN どう進化していったのかを覚えよう