前回の記事の続き。
epochを重ねても訓練/テスト誤差が改善しないのはどうしてだろうか? この疑問に対して、色々と試した結果を以下にまとめている。
銀河イメージ
今回使用した、Galaxy10 DECals Datasetがどのようなデータかここで見てみたい。
# DataLoaderに格納されているイメージデータとラベルを表示
# 格納されているイメージデータは、正規化されている
import matplotlib.pyplot as plt
# 銀河形状名称(分類するクラス)
gala_classes = np.array(['Disturbed', 'Merging', 'Round Smooth', 'In-between RS', 'Cigar',
'Barred Spiral', 'Tight Spiral', 'Loose Spiral', 'Edge-on w/o Bulge', 'Edg-on w/t Bulge'])
n_img = 25 # 表示する画像数
gala_loader = DataLoader(train_dataset, batch_size=n_img, shuffle=True)
dataiter = iter(gala_loader) # イタレータ
images, labels = next(dataiter) # dataiter.next() はエラー
col = 5
row = (n_img + col -1)//col
plt.figure(figsize=(12,3*row))
for i in range(n_img):
ax = plt.subplot(row, col, i+1)
plt.imshow(np.transpose(images[i], (1, 2, 0))) # チャネルを一番最後に変更
ax.set_title(gala_classes[labels[i]])
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.show()
前回、train_datasetとtest_datasetを得たCellの次において実行すると、次のようなイメージが得られる。
上記の形状のタイトルのデータセットの名称の通り、但し、表示のスペースの関係で一部略したが、各々の意味は次の通り。RS=Round Smooth、w/o=without、w/t=with。
人間でも中々識別出来ない。Galaxy Zooの活動に頭が下がる。
データに回転、左右反転を施す
銀河の傾きのバリエーションを増やすために、transformsでコメントアウトしていた2行を有効にした結果は、次の通り。
まだ、訓練/テスト誤差はepochを重ねても横ばいのままで、改善は見られない。
学習率を変更
データに対し、更にランダムな切り抜き、ノイズ付加、情報損失等のデータ拡張を施すことも考えたが、その前に学習率を変更してみる。
次の通り、前回のコードの「訓練と評価関数群」の最初のセルを次の通り変更し、学習率を小さく設定。 そう言えば、情報源で上げたこの記事にも学習率は色々と試し、最終的に0.00001に決めたとの記載を思い出した。
# 損失関数の設定
criterion = nn.CrossEntropyLoss()
# 最適化手法を設定
optimizer = optim.Adam(model.parameters(), lr=0.00001)
今度は、epochを重ねると訓練/テスト誤差共に改善されていることが分かる。30回のエポックでは過学習の傾向も見られない。
30回のエポックに掛かった時間は2,786秒(46分26秒)であった。もうハーフやってみようか!
60回のエポックに掛かった時間は5,574秒(92分54秒)であった。
epochが50数回を過ぎたあたりから、過学習の傾向が出始めているようにも見える。
VGG16のまとめ
VGG16の場合、学習率$lr$を$0.00001$とすることが、一番のポイントで、50回程度のエポックで損失値$0.02$程度であった。
次回は、モデルとしてResNetを使って試してみる。