検証エラーはトレーニングエラー未満ですか?


57

この問題に関してここここで 2つの質問を見つけましたが、まだ明確な答えや説明はありません。検証エラーが私のConvolution Neural Networkのトレーニングエラーよりも小さいという同じ問題を強制します。どういう意味ですか?


トレーニング(cv)とテストケースの絶対数、および相互検証とテストの両方でMSEで観察された分散がわからないと、この質問に答えることができないと思います。
cbeleitesは

データをシャッフル
-user0

これから何を推測できますか?はい、ドロップアウト層とバッチノルム層を備えた高密度ネットワークから生成されます。![ここに画像の説明を入力します(] i.stack.imgur.com/KX1Fz.pngを
Srinath

回答:


69

実際の方法論(クロスバリデーション法、パフォーマンスメトリック、データ分割法など)を知らずに特定することは困難です。

ただし、一般的に言えば、トレーニングエラーはほとんど常に検証エラーを過小評価します。ただし、検証エラーがトレーニングよりも小さくなる可能性があります。次の2つの方法が考えられます。

  1. トレーニングセットには多くの「難しい」ケースがありました
  2. 検証セットには、主に予測する「簡単な」ケースがありました

そのため、モデルトレーニング方法論を実際に評価することが重要です。適切にトレーニングするためにデータを分割しない場合、結果は、単純ではないにしても、混乱する結論につながります。

私は4つの異なるカテゴリーでのモデル評価を考えています:

  1. アンダーフィッティング-検証およびトレーニングエラー高

  2. オーバーフィット-検証エラーが高く、トレーニングエラーが低い

  3. 適合性–検証エラーが低く、トレーニングエラーよりわずかに高い

  4. 不明な適合-検証エラーが低く、トレーニングエラーが「高い」

結果は機械学習の仕組みに直観に反するため、「不明」と言います。MLの本質は、未知のものを予測することです。「学習」したものよりも未知のものを予測する方が上手い場合、トレーニングと検証の間のデータは何らかの方法で異なっている必要があります。これは、データ分割方法を再評価するか、データを追加するか、パフォーマンスメトリックを変更する必要があることを意味します(実際に必要なパフォーマンスを測定していますか?)。

編集

前のpython lasagne質問へのOPの参照に対処するには。

これは、相互検証を必要とせず、トレーニング、検証、およびテストデータのサブセットを取得するだけの十分なデータがあることを示しています。さて、ラザニアのチュートリアルを見ると、ページの上部に同じ動作が見られることがわかります。奇妙な場合、著者がそのような結果を投稿すると信じることは難しいと思いますが、単に正しいと仮定するのではなく、さらに見てみましょう。ここで最も関心のあるセクションは、トレーニングループセクションです。下部のすぐ上に、損失パラメーターの計算方法が表示されます。

トレーニング損失を渡って計算された全体のトレーニングデータセット。同様に、検証損失検証データセット全体で計算されます。トレーニングセットは通常、検証の少なくとも4倍(80〜20)です。エラーがすべてのサンプルで計算されるとすると、検証セットの損失測定値の最大約4倍を期待できます。ただし、トレーニングが継続されるにつれて、トレーニングの損失と検証の損失が互いに近づいていることがわかります。これは、トレーニングエラーが検証エラーより低くなり始めた場合、モデルをオーバーフィットし始めるため、意図的なものです!!!

これでこれらのエラーが明らかになることを願っています。


2
素敵な答え。また、コードにバグがあり、トレーニングがトレーニングセットの最適なソリューションに収束していない可能性もあります。または、トレーニングの目的が非凸面であり、トレーニングアルゴリズムが検証セットに適しているローカルミニマムに収束する場合。
ソビ

@cdeterman thanks。私はRMSEをパフォーマンスメトリックとして使用しています。データをテスト用に20%、トレーニングと検証用に80%に分割しました(検証エラーを計算するためにトレーニングデータの20%が相互検証されています)。実際、検証エラーは低く、トレーニングエラーよりもわずかに低くなっています。テストエラーは、トレーニングおよび検証エラーよりも大きくなります。私たちは、手書き文字認識のためのMNISTdatasetで同様のケースを見つけることができますstats.stackexchange.com/questions/178371/...
Bido

@Bidoはあなたが最近編集した住所について質問しますか?
cdeterman

@cdetermanありがとう。あなたが答えを編集したことに気づきました。それは明確で有用です。
ビド

グレートの説明、あなたはいくつかのグラフを追加することができれば-それは可能な限り最高のものであろう
タラスMatsyk

109

1つの可能性:ネットワークでドロップアウト正規化レイヤーを使用している場合、検証エラーはトレーニングエラーよりも小さいことが合理的です。通常、ドロップアウトはトレーニング時にはアクティブになりますが、検証セットで評価するときには非アクティブになるためです。後者の場合、より滑らかな(通常はより良いことを意味します)関数を取得します。


12
なんてシンプルで賢明な答えでしょう!
rajb245

4
はい、これは確かに正解としてマークする必要があります。
シマナス

2
ドロップアウトレイヤーを削除しましたが、検証の損失は最初はトレーニングの損失よりも低くなっています (レイヤーの正則化も指定していません!)
ジョサイアヨーダー

私の場合に合います。多くのドロップアウトを使用します。
アンドレクリストファーアンデルセン

@JosiahYoder-これについて共有できることはありますか?1650の入力機能があります。ネットワークを小さい(1650、50、1)ドロップアウトまたはドロップアウトなしに保つと、初期エポックのトレーニングエラーは検証エラーよりも大きくなります。大規模なネットワーク(1650、1200、800、100 .....セルアクティベーションを使用した100の約10層)を使用すると、検証の精度が高くなるという奇妙なパターンが多少緩和されます。
MiloMinderbinder

19

@DKの答えにコメントするのに十分なポイントはありませんが、これはKerasのドキュメントに関するFAQとして回答されています:

「トレーニングの損失がテストの損失よりもはるかに高いのはなぜですか?

Kerasモデルには、トレーニングとテストの2つのモードがあります。ドロップアウトやL1 / L2重みの正規化などの正規化メカニズムは、テスト時にオフになります。

また、トレーニング損失は、トレーニングデータの各バッチでの損失の平均です。モデルは時間とともに変化するため、エポックの最初のバッチでの損失は一般に最後のバッチでの損失よりも大きくなります。一方、エポックのテスト損失は、エポックの最後にあるモデルを使用して計算されるため、損失が低くなります。」


1
これも質問に完全に答えているわけではありません。ドロップアウトを無効にしても、いくつかのエポックのトレーニング損失の約半分の検証損失が連続して表示されます!
ジョサイアヨーダー

トレーニングデータは開発データを代表していますか?
18

データセットをトレーニングとテストにランダムに分割しました。視覚的には良いサンプルであるように見えました。私は、常に平均値を予測するよりも最良の分類器がわずかに優れている回帰問題に取り組んでいました。
ジョサイアヨーダー

あなたの答えは、尋ねられた質問である検証の損失よりも大きいトレーニングの損失について語っていません。トレーニングの損失とテストの損失にもっと集中します
enjal

6

私の2セント:ドロップアウト層がなくても同じ問題がありました。私の場合、バッチ標準レイヤーが原因でした。それらを削除したとき-トレーニングの損失は検証の損失と同様になりました。たぶん、トレーニング中にバッチノルムが与えられた入力バッチの平均と分散を使用するために起こりました。これはバッチごとに異なる場合があります。ただし、バッチノルムは評価中に実行中の平均と分散を使用します。どちらもトレーニング中の単一バッチの平均と分散よりもトレーニングセット全体の特性をはるかに反映しています。少なくとも、それはpytorchでバッチノルムが実装される方法です


1
@ Mans007に感謝します。これは私に起こり、私はKerasを使用していました。バッチ標準レイヤーが原因でした。
Roei Bahumi

4

何らかの方法で@cdeterman@DKの両方の答えを組み合わせる別の可能性は、何らかのデータ拡張メカニズムを使用している場合です。インファクトデータの増強は通常、トレーニングセットでのみ行われ、検証セットでは行われません(ドロップアウト正則化に関して)。これにより、トレーニングセット内のケースよりも予測が容易なケースを含む検証セットが作成される場合があります。


2

同様の結果が得られました(テストの損失はトレーニングの損失よりも有意に低かった)。ドロップアウトの正規化を削除すると、両方の損失がほぼ等しくなりました。


0

@cdetermanと@DKには良い説明があります。もう1つ理由がありdata leakageます。トレインデータの一部は、テストデータと「密接に関連」しています。

潜在的な例:1000匹の犬と1000匹の猫がペットごとに500枚の似た写真を持っていると想像してください(一部の飼い主はペットを非常によく似た位置で撮るのが大好きです)。したがって、ランダムな70/30分割を行うと、列車データがテストデータに漏洩することになります。


0

簡単に言えば、トレーニング損失と検証損失が正しく計算された場合、トレーニング損失が検証損失よりも大きくなることは不可能です。これは、逆伝播により、トレーニングセットで計算されるエラーが直接減少し、検証セットで計算されるエラーが間接的に(保証さえされない!)だけ減少するためです。

トレーニング中と検証中に異なるいくつかの追加要素が必要です。ドロップアウトは良いものですが、他にもあります。使用しているライブラリのドキュメントを必ず確認してください。通常、モデルとレイヤーにはデフォルトの設定がありますが、通常は注意を払っていません。


0

トレーニングエラーよりも低い検証は、ドロップアウトなどに関連する変動が原因で発生する可能性がありますが、長期的に続く場合、これはトレーニングと検証のデータセットが同じ統計集団から実際に引き出されていないことを示している可能性があります。これは、サンプルがシリーズからのものであり、トレーニングデータセットと検証データセットを適切にランダム化していない場合に発生する可能性があります。


0

現時点では、確率的勾配ベースの方法は、ほとんどの場合、ディープラーニングに最適なアルゴリズムです。つまり、データはバッチとして取り込まれ、勾配が計算され、パラメーターが更新されます。つまり、各バッチが選択されるたびに、データの損失を計算することもできます。この枠組みの下では、2つの方法がありますどのように損失が、私は訓練誤差が検証エラーよりも大きい場合、この現象につながることができたと考えることができることを計算されますが。以下に、Kerasが実際にこれらの方法でサンプル内エラーを計算するように見えることを示します。

1.)トレーニングエラーはエポック全体で平均化されますが、エポックの最後で一度にすべてが行われますが、検証エラーはエポックの最後でのみです。検証エラーには完全に更新されるという利点がありますが、トレーニングエラーには更新が少ないエラー計算が含まれます。もちろん、漸近的にこの効果は一般的に消えるべきです。

2.)バッチ更新が行われる前にトレーニングエラーが計算されます。確率的勾配ベースの方法では、勾配にノイズがあります。丘を登っている間、すべてのトレーニングサンプルで計算されたグローバル損失が減少する可能性が高くなります。ただし、モードに非常に近づくと、バッチのサンプルに対して更新の方向が負になります。我々はモードの周りにバウンスされているのでしかし、これは意味し、平均して、我々は、サンプルに対して正の方向を選択する必要がありますアウトバッチの。ここで、特定のバッチ内のサンプルに関して更新しようとしている場合、更新前に損失を計算することで、含まれていない潜在的に多くのバッチ更新によってプッシュされていることを意味します。メソッドは、データセット内の他のサンプルを最も優先してパラメーターをプッシュしているため、予想される損失にわずかに上方バイアスがかかっています。

漸近的には、(1)の効果はなくなり、(2)は消えないことに注意してください!以下に、Kerasが(1)と(2)の両方を行うように見えることを示します。

(1)メトリックが最後に一度にすべてではなく、エポックの各バッチで平均化されることを示す。サンプル内の精度とval_accuracyの大きな違いが、最初のエポックでval_accuracyを優先していることに注目してください。これは、サンプル内のエラーの一部が非常に少ないバッチ更新で計算されたためです。

>>> model.fit(Xtrn, Xtrn, epochs = 3, batch_size = 100, 
...                 validation_data = (Xtst, Xtst))
Train on 46580 samples, validate on 1000 samples
Epoch 1/3
46580/46580 [==============================] - 8s 176us/sample 
- loss: 0.2320 - accuracy: 0.9216 
- val_loss: 0.1581 - val_accuracy: 0.9636
Epoch 2/3
46580/46580 [==============================] - 8s 165us/sample 
- loss: 0.1487 - accuracy: 0.9662 
- val_loss: 0.1545 - val_accuracy: 0.9677
Epoch 3/3
46580/46580 [==============================] - 8s 165us/sample 
- loss: 0.1471 - accuracy: 0.9687 
- val_loss: 0.1424 - val_accuracy: 0.9699
<tensorflow.python.keras.callbacks.History object at 0x17070d080>

(2)表示エラーは、各バッチの更新前に計算されます。エポック1の場合batch_size = nRows(つまり、1つのバッチ内のすべてのデータ)、エポック1のサンプル内エラーは約0.5(ランダム推測)ですが、検証エラーは0.82です。したがって、バッチ更新の前にサンプル内エラーが計算さ、バッチ更新後に検証エラーが計算されました。

>>> model.fit(Xtrn, Xtrn, epochs = 3, batch_size = nRows, 
...                 validation_data = (Xtst, Xtst))
Train on 46580 samples, validate on 1000 samples
Epoch 1/3
46580/46580 [==============================] - 9s 201us/sample 
- loss: 0.7126 - accuracy: 0.5088 
- val_loss: 0.5779 - val_accuracy: 0.8191
Epoch 2/3
46580/46580 [==============================] - 6s 136us/sample 
- loss: 0.5770 - accuracy: 0.8211 
- val_loss: 0.4940 - val_accuracy: 0.8249
Epoch 3/3
46580/46580 [==============================] - 6s 120us/sample 
- loss: 0.4921 - accuracy: 0.8268 
- val_loss: 0.4502 - val_accuracy: 0.8249
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.