MNISTのニューラルネットワークでの学習の教師データ数と精度の関係
MNISTには全部で6万個の訓練用データがありますが、単純なニューラルネットワークで学習させたときの訓練用データの数と学習結果の精度の関係を見てみました。
size | process_time | train_loss | train_accuracy | test_loss | test_accuracy |
---|---|---|---|---|---|
60000 | 76.70 | 0.0051 | 0.9988 | 0.1270 | 0.9752 |
15000 | 23.22 | 0.0038 | 0.9999 | 0.1766 | 0.9609 |
3750 | 10.67 | 0.0143 | 0.9997 | 0.2706 | 0.9268 |
950 | 7.61 | 0.0296 | 1.0000 | 0.4152 | 0.8790 |
250 | 7.28 | 0.0661 | 0.9960 | 0.7151 | 0.7821 |
左から、訓練用データサイズ、処理時間(秒)、訓練データでの損失関数値、訓練データでの精度、テストデータでの損失関数値、テストデータでの精度です。
学習推移のグラフ
size=60000
size=15000
size=3750
size=950
size=250
Pythonコード
Google Colaboratoryで実行しました。
import time import numpy as np from matplotlib import pyplot as plt import tensorflow as tf from tensorflow.keras.datasets import mnist plt.rcParams['figure.figsize'] = (16.0, 7.0) (x_train, y_train), (x_test, y_test) = mnist.load_data() # 入力と出力サイズ in_size = 28 * 28 out_size = 10 # モデル構造を定義 def createModel(): hidden_size = 64 model = tf.keras.models.Sequential() model.add(tf.keras.layers.Dense(hidden_size, activation='relu', input_shape=(in_size,))) model.add(tf.keras.layers.Dense(out_size, activation='softmax')) return model # 学習の様子をグラフへ描画 def plotLearning(result): fig = plt.figure() xs = range(1, len(result.history['loss']) + 1) # ロスの推移をプロット ax1 = fig.add_subplot(1, 1, 1) ax1.set_ylim(0, 2.5) ax1.set_ylabel('Loss') ax1.plot(xs, result.history['loss']) ax1.plot(xs, result.history['val_loss']) # 正解率の推移をプロット ax2 = ax1.twinx() ax2.set_ylim(0.75, 1.0) ax2.set_ylabel('Accuracy') ax2.plot(xs, result.history['accuracy']) ax2.plot(xs, result.history['val_accuracy']) plt.title('Loss & Accuracy') plt.legend(['train', 'test'], loc='upper left') plt.show() def calc(train_size, epochs): model = createModel() # モデルを構築 model.compile( loss = "categorical_crossentropy", optimizer = "adam", metrics=["accuracy"]) start = time.time() print("train_size: %d, epochs: %d" % (train_size, epochs)) x_train_reshape = x_train.reshape(-1, in_size).astype('float32') / 255 x_test_reshape = x_test.reshape(-1, in_size).astype('float32') / 255 y_train_onehot = tf.keras.backend.one_hot(y_train, out_size) y_test_onehot = tf.keras.backend.one_hot(y_test, out_size) x_train_reshape = x_train_reshape[:train_size] y_train_onehot = y_train_onehot[:train_size] # 学習を実行 result = model.fit(x_train_reshape, y_train_onehot, batch_size=50, epochs=epochs, verbose=1, validation_data=(x_test_reshape, y_test_onehot)) processTime = time.time() - start print("train_size: %d, epochs: %d, processTime: %f" % (train_size, epochs, processTime)) plotLearning(result) return "| %d | %5.2f | %6.4f | %6.4f | %6.4f | %6.4f |" % (train_size, processTime, result.history['loss'][-1], result.history['accuracy'][-1], result.history['val_loss'][-1], result.history['val_accuracy'][-1]) table = [] table.append(calc(60000, 30)) table.append(calc(15000, 30)) table.append(calc(3750, 30)) table.append(calc(950, 30)) table.append(calc(250, 30)) for s in table: print(s)
2020/10/12 追記
ニューロン数と精度の関係も見てみました。