この問題に関してこことここで 2つの質問を見つけましたが、まだ明確な答えや説明はありません。検証エラーが私のConvolution Neural Networkのトレーニングエラーよりも小さいという同じ問題を強制します。どういう意味ですか?
この問題に関してこことここで 2つの質問を見つけましたが、まだ明確な答えや説明はありません。検証エラーが私のConvolution Neural Networkのトレーニングエラーよりも小さいという同じ問題を強制します。どういう意味ですか?
回答:
実際の方法論(クロスバリデーション法、パフォーマンスメトリック、データ分割法など)を知らずに特定することは困難です。
ただし、一般的に言えば、トレーニングエラーはほとんど常に検証エラーを過小評価します。ただし、検証エラーがトレーニングよりも小さくなる可能性があります。次の2つの方法が考えられます。
そのため、モデルトレーニング方法論を実際に評価することが重要です。適切にトレーニングするためにデータを分割しない場合、結果は、単純ではないにしても、混乱する結論につながります。
私は4つの異なるカテゴリーでのモデル評価を考えています:
アンダーフィッティング-検証およびトレーニングエラー高
オーバーフィット-検証エラーが高く、トレーニングエラーが低い
適合性–検証エラーが低く、トレーニングエラーよりわずかに高い
不明な適合-検証エラーが低く、トレーニングエラーが「高い」
結果は機械学習の仕組みに直観に反するため、「不明」と言います。MLの本質は、未知のものを予測することです。「学習」したものよりも未知のものを予測する方が上手い場合、トレーニングと検証の間のデータは何らかの方法で異なっている必要があります。これは、データ分割方法を再評価するか、データを追加するか、パフォーマンスメトリックを変更する必要があることを意味します(実際に必要なパフォーマンスを測定していますか?)。
編集
前のpython lasagne質問へのOPの参照に対処するには。
これは、相互検証を必要とせず、トレーニング、検証、およびテストデータのサブセットを取得するだけの十分なデータがあることを示しています。さて、ラザニアのチュートリアルを見ると、ページの上部に同じ動作が見られることがわかります。奇妙な場合、著者がそのような結果を投稿すると信じることは難しいと思いますが、単に正しいと仮定するのではなく、さらに見てみましょう。ここで最も関心のあるセクションは、トレーニングループセクションです。下部のすぐ上に、損失パラメーターの計算方法が表示されます。
トレーニング損失を渡って計算された全体のトレーニングデータセット。同様に、検証損失は検証データセット全体で計算されます。トレーニングセットは通常、検証の少なくとも4倍(80〜20)です。エラーがすべてのサンプルで計算されるとすると、検証セットの損失測定値の最大約4倍を期待できます。ただし、トレーニングが継続されるにつれて、トレーニングの損失と検証の損失が互いに近づいていることがわかります。これは、トレーニングエラーが検証エラーより低くなり始めた場合、モデルをオーバーフィットし始めるため、意図的なものです!!!
これでこれらのエラーが明らかになることを願っています。
1つの可能性:ネットワークでドロップアウト正規化レイヤーを使用している場合、検証エラーはトレーニングエラーよりも小さいことが合理的です。通常、ドロップアウトはトレーニング時にはアクティブになりますが、検証セットで評価するときには非アクティブになるためです。後者の場合、より滑らかな(通常はより良いことを意味します)関数を取得します。
@DKの答えにコメントするのに十分なポイントはありませんが、これはKerasのドキュメントに関するFAQとして回答されています:
「トレーニングの損失がテストの損失よりもはるかに高いのはなぜですか?
Kerasモデルには、トレーニングとテストの2つのモードがあります。ドロップアウトやL1 / L2重みの正規化などの正規化メカニズムは、テスト時にオフになります。
また、トレーニング損失は、トレーニングデータの各バッチでの損失の平均です。モデルは時間とともに変化するため、エポックの最初のバッチでの損失は一般に最後のバッチでの損失よりも大きくなります。一方、エポックのテスト損失は、エポックの最後にあるモデルを使用して計算されるため、損失が低くなります。」
私の2セント:ドロップアウト層がなくても同じ問題がありました。私の場合、バッチ標準レイヤーが原因でした。それらを削除したとき-トレーニングの損失は検証の損失と同様になりました。たぶん、トレーニング中にバッチノルムが与えられた入力バッチの平均と分散を使用するために起こりました。これはバッチごとに異なる場合があります。ただし、バッチノルムは評価中に実行中の平均と分散を使用します。どちらもトレーニング中の単一バッチの平均と分散よりもトレーニングセット全体の特性をはるかに反映しています。少なくとも、それはpytorchでバッチノルムが実装される方法です
何らかの方法で@cdetermanと@DKの両方の答えを組み合わせる別の可能性は、何らかのデータ拡張メカニズムを使用している場合です。インファクトデータの増強は通常、トレーニングセットでのみ行われ、検証セットでは行われません(ドロップアウト正則化に関して)。これにより、トレーニングセット内のケースよりも予測が容易なケースを含む検証セットが作成される場合があります。
@cdetermanと@DKには良い説明があります。もう1つ理由がありdata leakage
ます。トレインデータの一部は、テストデータと「密接に関連」しています。
潜在的な例:1000匹の犬と1000匹の猫がペットごとに500枚の似た写真を持っていると想像してください(一部の飼い主はペットを非常によく似た位置で撮るのが大好きです)。したがって、ランダムな70/30分割を行うと、列車データがテストデータに漏洩することになります。
現時点では、確率的勾配ベースの方法は、ほとんどの場合、ディープラーニングに最適なアルゴリズムです。つまり、データはバッチとして取り込まれ、勾配が計算され、パラメーターが更新されます。つまり、各バッチが選択されるたびに、データの損失を計算することもできます。この枠組みの下では、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