質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

5844閲覧

validation loss が上昇している原因を知りたい。

Muchpomp

総合スコア1

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/11/25 06:37

編集2021/11/26 07:54

前提・実現したいこと

現在、以下のコードを参考にしてデータセットを置き換えて学習を行っています。

trainingはうまく進んでいるように見えますが、validationはうまくいっていません。元コードとの変更点はデータセットの変更を通すために少し変更した程度です。

いろいろ調べましたが、似たような例は見つからず困っている次第です。

よろしくお願いします。

使用しているデータセットは2048*4096,training:10400枚,validation:373枚です。(training dataは水増ししています。)

追記:とりあえず学習を進めてみているので何かあったら報告します。
・ReduceLP0nPlateauを追加して学習した結果、Epoch3以降val lossが上昇
・学習率を下げて学習した結果、地道にlossが下がるもののlossが4ほどで停滞する

参考にしているコード

以下の画像はデータを水増しする前の結果です。

水増し方法(わかりずらかったら申し訳ありません。)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coffeebar

2021/11/25 07:27

学習率が高すぎるのでは? learning rateを小さくして、再トライしてみてはどうでしょう。
jbpb0

2021/11/25 07:45

数値では、過学習してるっぽく見えます その確認のために、今回の学習が終わったら、次は > training dataは水増ししています。 を止めてみたら、いかがでしょうか もしそれで、trainingとvalidationの数値が近づくなら、水増ししたものがvalidation dataとかけ離れたものになっていて、それを頑張って学習した結果過学習してしまって、validation dataでは精度出ない、的なことになってるのかも
meg_

2021/11/25 08:14

> validation loss が上昇している原因を知りたい。 > trainingはうまく進んでいるように見えますが、validationはうまくいっていません。 一般的には過学習の傾向を示していると思いますが、 > いろいろ調べましたが、似たような例は見つからず困っている次第です。 ということは何か特別な処理をされているのでしょうか?
Muchpomp

2021/11/25 13:49

coffeebarさん ご回答ありがとうございます。 書くのを忘れていましたが、lrを0.001から0.0001にして行っています。どちらにせよ学習はうまくいっていないので、もうひと段階下げることを検討してみます。 ありがとうございます。
Muchpomp

2021/11/25 13:51

jbpb0さん ご回答ありがとうございます。 水増しする前は1000枚くらいでval accが20%位までは上がっていたので、ご回答通りのことが起こっているかもしれません。 貴重なご意見ありがとうございます。
Muchpomp

2021/11/25 13:56

meg_さん ご回答ありがとうございます。 やはり過学習と考えるのが一般的のようですね。ほぼ初めての機械学習なので過学習について詳しく調べようと思います。 特別な処理をしているわけではないですが、調べたところtrainingも上がっていなかったり、学習の途中からvalidation lossが上昇している例が多かったので、自身に起こっていることはそれとは違うものであると考えておりました。 貴重なご意見ありがとうございます。
jbpb0

2021/11/26 01:12 編集

> training:10400枚 > 水増しする前は1000枚くらい trainingデータの9割くらいが水増しデータですよね もし水増しがうまくいってない(validationデータと全然違うものが多数生成されてる)のなら、validationデータでは最初から精度出ないことは有り得ます ただ、trainingデータの1割くらいはvalidationデータと似てるはずだから、もう少しなんとかなりそうという気もします (気がするだけ) とりあえず、HRCo4さんも回答に書いてるように、水増しデータがどんなのか(適切な水増しになってるのか)を確認したらいいと思います
Muchpomp

2021/11/26 01:51

jbpb0さん ご回答ありがとうございます。 水増しデータを見てみましたが、特に問題はなさそうに見えます。 水増し方法はランダムに画像の左側を切り取り、右側にくっつけるという方法です。 なんだか水増し方法自体があまり良くない気もしてきました。
jbpb0

2021/11/26 02:48

> 水増し方法はランダムに画像の左側を切り取り、右側にくっつけるという方法 以下の二点が気になります A. 元々の画像の右端か左端に見切れてる人が写ってる場合、水増しで両端がくっついて、結果半分だけの人みたいなのができてしまう B. 元々の画像の、水増しで切ったところに人が写ってると、水増し後画像ではその人は両端に見切れて配置される 上記の内のB.は、画像の見切れてる人もセグメンテーションしたいのなら、問題無いように思います 水増し前の元々の画像にも、もしかしたら見切れてる人のセグメンテーション教師データが含まれてるかもしれないし 一方A.は、現実には有り得ない画像を生成してることになりますよね そういうのがtrainingデータの水増し分9割のどれくらいを占めてるのかは分かりませんが、結構多いなら、そのような現実に有り得ない画像を頑張って学習して、結果過学習してしまうと、validationデータにはそんなの無いので精度出ないかも
Muchpomp

2021/11/26 03:23

jbpb0さん ご回答ありがとうございます。 画像に関してですが、現在パノラマ画像をデータセットとして使っており、0度から360度までが移っている画像です。 例えば左端が0度で右端が360度であるとしたら切り取った左端と右端をくっつけても、もともとつながっている位置関係にあるため見切れるというようなことは起こっていません。 念のため水増しデータをいくつか見てみましたが、どこで切り取ったかわからないくらい違和感はありませんでした。
jbpb0

2021/11/26 04:18

なるほど、360°つながってる(円筒を内側から見てるような)画像を、どこか一ヶ所で切って展開した画像になっていて、元々は同じ画像から切る場所がいろいろ違う画像を作ってるのですか それなら、画像としては問題無いでしょうね ただ、それだと実質同じ(切るところだけ違う)画像が10枚くらいあることになるような気がしますので、水増ししてもあまりバリエーションは増えてないような
Muchpomp

2021/11/26 06:45

jbpb0さん ご回答ありがとうございます。 たしかにバリエーションは増えませんね。 バリエーションを増やすには画像の都合上、回転や拡大はvalidationのデータと離れてしまいそうなのでHRCo4さんがおっしゃられている明度や彩度の変換をやってみようと考えています。
guest

回答1

0

ベストアンサー

傾向は過学習っぽいですが、2エポック目からその傾向がみられるのは少し変ですね。
極端にデータ数が少ない場合は2エポック目から過学習が起こる可能性もありますが、今回のようなある程度データ数を揃えた場合、ある程度学習が進んで train, val 共に一旦下がってから乖離していくはずです。

ぱっと思いつく原因は3点あります。
0. 水増し方法が悪影響しており、普通では起こりえない画像になっている可能性。
水増しでどのくらい増やしているのかわかりませんが、例えば水増しに回転処理を入れており、範囲を0~360度としてしまっているとします。入力画像が風景などの場合、回転により空が下、地面が上といった普通では起こりえない画像が生成して、さらに10400枚の内、大半がそういった画像となっており、validation とかけ離れたものになってしまっている。

  1. trainとvalidationの画像がそもそも類似したものでない可能性。

例えば、trainは街並み(建物や道路、人など)の画像で学習しているが、validationでは風景(山や海、川など)の画像としてしまっている。

  1. 入力サイズがそのネットワーク(DeepLabV3+)に適していない。

参考元を見てみましたが、入力サイズが 512x512 を使用しているのに対して、試されているのが 2048x4096 と大分大きい画像となっています。そのため、受容野(receptive field)の画像に対する比率が変わり参考元と違う傾向となってしまっている。ただし、この推測はデータ自体によるものなので、trainとvalidationが乖離している直接的な原因の可能性は低いです。

一度、水増し後の画像を出力して確認するところから始めるといいかもしれません。

投稿2021/11/26 00:40

HRCo4

総合スコア140

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Muchpomp

2021/11/26 01:43

HRCoさん 長文でのご回答ありがとうございます。 1.水増し方法はランダムに画像の左側を切り取り、右側にくっつけるという方法で水増ししています。一応図も貼っておきます。 2.trainとvalidationは同じ屋内画像のデータセットから分けて使用しているため、移っているオブジェクトなどは類似しています。 3.入力サイズに関してはtraining画像は512*1024に変換しているのですがvalidationの画像サイズは大きいままで行っています。validationのリサイズも検討してみます。 水増し画像を確認しましたが、水増し後のシャッフルもできていて問題なさそうに見えます。
HRCo4

2021/11/26 02:21 編集

画像処理後の結合部分(処理前の左端と右端)はあまり違和感なく結合される画像でしょうか? 境界がはっきりとわかる場合はあまりお勧めはしません。(左端のピクセルの推定に右端のピクセルを用いることになるので) 個人的によく用いる水増し方法として、入力画像を HSV 変換して明度と彩度を0.8~1.2倍にしたりしてます。(1倍以上にしているため、もちろん255を超えたときの処理も必要です。) あとは、学習率に関してですが、学習済みのweight用いての学習(fine tuning)の場合は1e-4でもいいかと思いますが、初期weight(乱数生成)の場合は1e-2, 1e-3あたりでもいいかと思います。ReduceLROnPlateauなどを用いて val loss あるいは val acc を監視して都度学習率を下げるのが良いかと思います。 trainとvalでサイズ比が異なるのも原因の可能性は十分にありますね。(trainでは2ピクセル横にあったものがvalでは8ピクセル横になるので3x3のconvolutionが2つで見えていたものが8つ必要になってくるのでフィルターの学習がおかしくなります) まずはtrainとvalで条件を揃えて期待した値がでるかの確認から行うことをお勧めします。 【追記】 train を(おそらくメモリの関係上)512x1024、validation を 2048x4096 で行う場合、train をリサイズで 512x1024 にするのではなく、512x1024のクロップにすれば validation とのサイズ比は維持できます。ついでにランダムクロップにすることでtrainデータの水増しにもなります。(1537x3073=約470万パターン) ただ、リサイズした画像(2048x4096→リサイズ1024x2048→クロップ512x1024、2048x4096→リサイズ512x1024など)も少量入れることで全体の精度向上にもつながるのでいろいろ試してみるのがいいです。
Muchpomp

2021/11/26 03:28

HRCo4さん ご回答ありがとうございます。 画像に関してですが、現在パノラマ画像をデータセットとして使っており、0度から360度までが移っている画像です。 例えば左端が0度で右端が360度であるとしたら切り取った左端と右端をくっつけても、もともとつながっている位置関係にあるため見切れるというようなことは起こっていないと考えています。 実際、いくつか水増しデータを見ましたが見切れるような画像は確認できませんでした。 いただいた解決策を試してみようと思います。 ご丁寧に説明してくださり本当にありがとうございます。
Muchpomp

2021/11/26 08:36

HRCo4さん 現在、教えていただいた水増し方法を試しているのですが、2点気になることがあります。 ・色相の回転はする必要があるか ・255を超えてしまうときの処理として計算前にuint16に型変更を行い、計算後にuint8に戻すという風に処理をしているのですがこのような処理で正しいでしょうか。 答えていただけると幸いです。
HRCo4

2021/11/26 08:51 編集

>・色相の回転はする必要があるか 色相は色合いが変わってしまうため非推奨です。(例えばリンゴ[赤]の色相が数度変わって[黄]になってしまうとか) 彩度や明度も極端に変えてしまうと悪くなる原因ですので 0.8~1.2 の数値は調整してください。 >・255を超えてしまうときの処理として計算前にuint16に型変更を行い、計算後にuint8に戻すという風に処理をしているのですがこのような処理で正しいでしょうか。 uint16 であればまずオーバーフローすることがないためそれでも問題ありません。 自分は以下のような処理をしています。(もっと効率的・高速なやり方があるかもしれませんが、、、) s = random.uniform(0.80, 1.20) # 彩度 v = random.uniform(0.80, 1.20) # 明度 img_hsv[:,:,1] = np.where(img_hsv[:,:,1] * s < 255, img_hsv[:,:,1] * s, 255) img_hsv[:,:,2] = np.where(img_hsv[:,:,2] * v < 255, img_hsv[:,:,2] * v, 255) ※ img_hsv が uint8 なので255未満は *s(v) しても uint8 に変換されます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問