「ラベル画像のトリミング(4)」では、学習率の調整が重要であることが判明しましたので、今回も引き続き学習率に着目して検証を進めたいと思います。
なお、前回のまとめで「固定の学習率を使用するのではなく、状況に応じて学習率を変動させる方法」へのチャレンジを匂わせておきましたが、結論から言えば、この方法はあまり有効ではありませんでした。
その辺も含めて、今回の検証内容を記載します。
方針
前回の検証で一点不思議に思っていたのは、lossの遷移が多少のスパイクを含みながらも全体的には順調に減衰していくのに対し、val_lossの遷移は100epoch辺りまでは一旦増加し、その後減衰に向かう(かなり増減が激しいですが)と言うことです。
これは学習率を変えて実施した3つのパターン全てに共通して言えることでした。
学習の目的がval_lossの最小化であることを考えると、最初の100epoch辺りまでは(その後の成果のためには必要なのでしょうが)かなり無駄な(良い成果が出ないと分かっている)期間と言えなくもないです。
改めて考えてみると、今回実装した学習方法では既に学習済みのモデルに追加学習ができるようになっているので、毎回ゼロスタートで学習を行う必要はありません。
学習済みモデルをベースにすれば前述の無駄な学習期間を毎回耐え忍ぶ必要もなくなるかもしれません。
と言うことで、今回の学習では前回の学習結果のうち最もval_lossの値が小さかった0.0001(2000)で生成されたモデルをベースに学習を行うことにします。
また、今回のメインテーマである学習率の設定に関しては、とりあえずベースとなったモデルの学習率である0.0001
に対して、より小さい値として、0.000064, 0.000032, 0.000016の3パターンを試してみることにします。
なお、数値の記載において0の数が増えてきましたので、見やすいように指数表記にしたいと思います。
よって、0.0001は1.0E-04との表記になりますし、同様に先の3パターンは6.40E-05, 3.20E-05, 1.60E-05と表記します。
ちなみに、今回の学習率の数値の決め方に関しては、今後さらに細かい学習率を試したくなった場合を考慮して、最小値1.0E-06に対して2のn乗となる値(逆に言えば、値を半分にし続けていくと1.0E-06になる値)と言うことで選定しました。
なお、学習率の下限として想定している1.0E-06と言う値はGemini先生のアドバイスにより決定しています。
以上の想定に基づいて各1000epochの学習を行います。
検証結果
loss, val_lossの遷移
以下に、前述の3パターンに関するloss, val_lossの遷移を示します。
左から6.40E-05, 3.20E-05, 1.60E-05の順で、青線がloss, 赤線がval_lossの遷移を示しています。
なお、スパイク部分までを含めて描画すると全体の遷移が見難くなるので、縦軸の上限値は0.1としました。



loss, val_lossのいずれに関しても大きな違いはないように感じます。
やはり、6.40E-05が若干高めですが、それでも全体的に0.025から0.04辺りの間で増減を繰り返している印象です。
loss, val_lossのそれぞれに関して、3パターンの遷移を比較してみます。
まずは、各遷移の全体像から。
左からloss, val_lossの遷移になります。


loss, val_lossともに、スパイクのタイミングに違いはありますが、全体の遷移に関しては、やはり大差はないように見えます。
縮尺を変えて見てみましょう。


lossに関しては緩やかに減衰を続けているように見えますが、val_lossに関しては後半は0.025〜0.04くらいの間で激しく増減しているものの、減衰傾向があるかに関しては、かなり怪しいです。
前回と同様に各ケースにおいてval_lossが最小となった状況をまとめてみます。
比較対象としてベースモデル(1.0E-04)の学習結果も併記しておきます。
1.0E-04 | 6.40E-05 | 3.20E-05 | 1.60E-05 | |
epoch | 1864 | 157 | 575 | 518 |
loss | 0.0083 | 0.0083 | 0.0054 | 0.0067 |
val_loss | 0.0326 | 0.0264 | 0.0263 | 0.0249 |
val_lossは1.0E-04と比較していずれも良くなっていますが、3パターンで大差がありません。
また、最小値が記録されたタイミングがいずれも学習の最終段階とは言い難く、特に6.40E-05などはかなり早い段階で記録された後に更新されていません。
この状況を見ると、現在の学習方法(学習用データやハイパーパラメータの設定)ではval_lossの下限は0.025辺りで、学習率の操作ではこれ以上の改善は見込めないのではないかとの印象を持ちます。
セグメンテーション結果
上記3パターンで生成されたモデルに関するセグメンテーション結果に関しても確認してみます。
なお、前回は学習用や評価用のデータに関するセグメンテーション結果を示していました。
しかし、学習用データに関しては、それが適切に処理されるように学習を行なっているので、良い結果が出るのは当然です。
評価用データに関しても、val_loss(評価用データのアノテーション結果とセグメンテーション結果の差)が最小だったモデルを採用しているので、やはり良い結果が出るように操作してようなものです。
つまり、val_lossが最小だったモデルは、学習用・評価用両方のデータに最適化されてしまっていて、それらデータのセグメンテーション結果を見てもモデルの汎用性は確認できないように思います。
と言うことで、今回から学習用・評価用データとは別に、セグメンテーション結果確認専用のデータを使用することにします。
加えて、学習用・評価用データは比較的お行儀が良い(配置や背景が一定している)画像であるため、セグメンテーション用データに関しては少々捻ったものを用意してみました。
具体的には以下の5種類になります。
- 左寄りに写っている
- 右寄りに写っている
- 小さく写っている
- 大きく写っている
- 背景に余計な物が写り込んでいる
上記特徴を持つ画像を4セット、計20点を用意しました(例によってI君作)。
特に背景に関しては、個人的には予想もしなかったパターンが採用され、それが思わぬ結果をもたらしています。
では、実際のセグメンテーション結果を見てみましょう。
こちらも、比較用にベースモデル(1.0E-04)の結果を載せておきました。
元画像 | 1.0E-04 | 6.40E-05 | 3.20E-05 | 1.60E-05 | |
1-1 | ![]() | ![]() | ![]() | ![]() | ![]() |
1-2 | ![]() | ![]() | ![]() | ![]() | ![]() |
1-3 | ![]() | ![]() | ![]() | ![]() | ![]() |
1-4 | ![]() | ![]() | ![]() | ![]() | ![]() |
1-5 | ![]() | ![]() | ![]() | ![]() | ![]() |
2-1 | ![]() | ![]() | ![]() | ![]() | ![]() |
2-2 | ![]() | ![]() | ![]() | ![]() | ![]() |
2-3 | ![]() | ![]() | ![]() | ![]() | ![]() |
2-4 | ![]() | ![]() | ![]() | ![]() | ![]() |
2-5 | ![]() | ![]() | ![]() | ![]() | ![]() |
3-1 | ![]() | ![]() | ![]() | ![]() | ![]() |
3-2 | ![]() | ![]() | ![]() | ![]() | ![]() |
3-3 | ![]() | ![]() | ![]() | ![]() | ![]() |
3-4 | ![]() | ![]() | ![]() | ![]() | ![]() |
3-5 | ![]() | ![]() | ![]() | ![]() | ![]() |
4-1 | ![]() | ![]() | ![]() | ![]() | ![]() |
4-2 | ![]() | ![]() | ![]() | ![]() | ![]() |
4-3 | ![]() | ![]() | ![]() | ![]() | ![]() |
4-4 | ![]() | ![]() | ![]() | ![]() | ![]() |
4-5 | ![]() | ![]() | ![]() | ![]() | ![]() |
まず、全般的に予測していたよりは良い感じでラベル部分を抽出できているとの印象を持ちます。
先に書いたように、今までの確認では最適化された範囲のデータでの確認を行なっていただけとの懸念がありましたので、もっと悪い結果を想定していた分、実際の結果に関してはある程度満足しています。
val_lossの値が示すように、ベースモデルと比較して今回生成した3モデルの結果はいずれも精度が向上しており、かつ3モデル間の差はあまりないように見えます。
ただし、精度的課題はまだまだあるようです。
まず目を引くのが、背景にダンボールが置かれた画像において、ダンボールに貼られた宛先やバーコードなどのシールをラベルとして認識してしまっている点です。
前回の投稿でも、ワインボトルに貼られたシールをラベルの一部として認識している例を挙げましたが、今回のケースはボトル以外の部分でもそれっぽく見える部分はラベルと見做されてしまうと言うことを意味しています(と言うか、ワインボトルと言う対象物を認識できている訳ではないようです)。
これは、I君の思惑通りなのか…?
また、ラベルの絵柄に関する得意・不得意もあるようで、2セット目のラベルは右上の部分が除外されがちですし、3セット目のラベルも、単純な白背景の一部が除外されており、特に大写しにしたケースでその傾向が顕著である点は不思議です。
いずれも、それほど特殊なデザインではないのですが。
その他、ワインボトルの口の部分に付いている薄い金属製のカバー(「キャップシール」とか言うらしいですが)もラベルと認識されているようですし、背景となっている壁の左上に描かれている何らかの図形に対しても反応してしまっています。
まとめ
途中でも触れましたが、現在の画像データおよびハイパーパラメータで学習率のみを操作して精度を上げるのは、val_loss=0.025辺りが限界のように思えます。
実はval_lossの更新状況を見ながら学習率を変更する(小さくしていく)方式も試しているのですが、やはりval_loss=0.025辺りから下がらなくなりました。
と言うことで、学習率操作による精度向上は今回までとし、次回は別の視点で精度向上を目指したいと思います。