前回の続きです。
検証損失と検証精度の推移をグラフ化しました。
学習損失は学習データの難易度により上がったり下がったりですが、検証損失と検証精度は回を追うごとに確実に良くなっています。
Pythonで2軸グラフを初めて描きました。取りあえず描くだけならExcelより断然楽ですね。
import chainer
import chainer.links as L
import chainer.functions as F
from chainer import iterators
from chainer import optimizers
import numpy as np
import matplotlib.pyplot as plt
from chainer.dataset import concat_examples
from chainer import serializers
print(f'chainerバージョン {chainer.__version__}')
class MLP(chainer.Chain):
def __init__(self, number_hidden_units=1000, number_out_units=10):
super(MLP, self).__init__()
with self.init_scope():
self.layer1=L.Linear(None, number_hidden_units)
self.layer2=L.Linear(number_hidden_units, number_hidden_units)
self.layer3=L.Linear(number_hidden_units, number_out_units)
def __call__(self, input_data):
result1 = F.relu(self.layer1(input_data))
result2 = F.relu(self.layer2(result1))
return self.layer3(result2)
def testEpoch(train_iterator,loss,c):
print(f'学習回数:{train_iterator.epoch:02d} --> 学習損失:{float(loss.data):.02f}')
# 検証損失と精度
test_losses = list()
test_accuracies = list()
i = 1
while True:
test_dataset = test_iterator.next()
test_data, test_teacher_labels = concat_examples(test_dataset)
# 検証データをモデルに渡す
prediction_test = model(test_data)
# 検証データに対して得られた予測値と正解を比較し損失を算出する
loss_test = F.softmax_cross_entropy(prediction_test, test_teacher_labels)
test_losses.append(loss_test.data)
# 精度を計算する
accuracy = F.accuracy(prediction_test, test_teacher_labels)
test_accuracies.append(accuracy.data)
print(f'{i}回目 検証損失:{np.mean(test_losses):.4f} 検証精度:{np.mean(test_accuracies):.2f}')
if test_iterator.is_new_epoch:
loss_and_acciracy = [c,np.mean(test_losses),np.mean(test_accuracies)]
test_iterator.reset()
print(loss_and_acciracy)
print('\n', end='')
break
i = i + 1
return loss_and_acciracy
train_data, test_data = chainer.datasets.get_mnist(withlabel=True, ndim=1)
model = MLP()
# print('入力層のバイアスパラメータ配列の形\n', model.layer1.b.shape)
# print('初期化後の値\n', model.layer1.b.data)
BATCH_SIZE = 100
train_iterator = iterators.SerialIterator(train_data, BATCH_SIZE)
test_iterator = iterators.SerialIterator(test_data, BATCH_SIZE,
repeat=False, shuffle=False)
optimizer = optimizers.SGD(lr=0.01)
optimizer.setup(model)
MAX_EPOCH = 5
c = 1
loss_list = list()
loss_and_acciracy = list()
while train_iterator.epoch < MAX_EPOCH:
# 学習データセットをイテレータから取り出す
train_dataset = train_iterator.next()
# 学習データセットを学習データと正解データに分離する
train_data, teacher_labels = concat_examples(train_dataset)
# 予測値の計算をする
prediction_train = model(train_data)
# 得られた予測値と正解データと比較し学習損失を計算する
loss = F.softmax_cross_entropy(prediction_train, teacher_labels)
# ニューラルネットワークの中の勾配を初期化する
model.cleargrads()
# 勾配を計算する
loss.backward()
# 損失を反映してパラメータを更新する
optimizer.update()
# 一回学習(epoch)する度に検証データに対する予測精度を計る
if train_iterator.is_new_epoch:
loss_list.append(loss)
print(loss_list)
test_result = testEpoch(train_iterator,loss,c)
loss_and_acciracy.append(test_result)
c = c + 1
print(f'学習損失 loss_list {loss_list}')
print(f'検証損失&検証精度 loss_and_acciracy {loss_and_acciracy}')
# 2軸グラフの各データリスト作成
x_data = [data[0] for data in loss_and_acciracy]
bar_height_data = [data[1] for data in loss_and_acciracy]
line_height_data = [data[2] for data in loss_and_acciracy]
x = np.array(x_data)
bar_height = np.array(bar_height_data)
line_height = np.array(line_height_data)
# 棒グラフ(検証損失)を出力
fig, ax1 = plt.subplots()
ax1.bar(x, bar_height, align="center", color="#1e90ff", linewidth=0)
ax1.set_ylabel('loss')
# 折れ線グラフ(検証精度)を出力
ax2 = ax1.twinx()
ax2.plot(x, line_height, linewidth=4, color="#da70d6")
ax2.set_ylabel('acciracy')
plt.show()
# 学習済モデルを保存する
serializers.save_npz('chainer-mnist.model', model)
--------------------------------------------------
出力(最後の2行)
--------------------------------------------------
学習損失 loss_list [variable(0.6423535), variable(0.27920458), variable(0.25227988), variable(0.34563792), variable(0.2176703)]
検証損失&検証精度 loss_and_acciracy [[1, 0.48583707, 0.88409996], [2, 0.34386325, 0.9078999], [3, 0.29848826, 0.9186], [4, 0.27616385, 0.9211], [5, 0.25501966, 0.9291]]