オーバーフィットとアンダーフィット

2376 ワード

実際の応用では,モデルがトレーニングセットで良好に表現できるだけでなく,トレーニングで得られたモデルも未知の新しい入力データ(これらの新しい入力データはテストセット)で良好に表現できることを望んでいることが多い.未知の新しい入力データで良好に表現できるこの能力を汎化と呼ぶ.モデルが未知の新しい入力データで得た誤差を汎化誤差,または測定誤差と呼び,汎化誤差が低いことも望んでいる.訓練誤差とテスト誤差を低減する過程で,我々は機械学習における2つの大きな挑戦に直面している:オーバーフィットとアンダーフィット.不適合とは、モデルがトレーニングセット上で十分に低い誤差を得ることができないことを意味し、過適合とは、トレーニング誤差とテスト誤差の差が大きすぎることを意味する.
通常、機械学習アルゴリズムモデルの容量を調整することによって、モデルがオーバーフィットまたはアンダーフィットに偏っているかどうかを制御することができる.一般的に、モデルの容量とは、様々な関数にフィットする能力を指し、容量がタスクの複雑さと提供されるデータの規模に適している場合、アルゴリズムは良い効果を示す.容量不足のモデルはトレーニングセットにフィットしにくいためフィットしにくい現象が発生し,容量の高いモデルは複雑なタスクを解決できるが,その容量がタスクの必要以上であると,各トレーニングデータにおけるランダムノイズの分布をよく記憶しているため,トレーニングデータにおける汎用的な傾向の学習を省略し,フィット現象が発生した可能性がある.
では、フィッティングをどのように検出したのでしょうか.
まず、一般的な検証方法を見てみましょう.データセット全体を訓練セット、検証セット、テストセットの3つの部分に分けます.区分コードは以下の通りです.
x_train,x_val = tf.split(x,num_or_size_splits=[50000,10000])
y_train,y_val = tf.split(y,num_or_size_splits=[50000,10000])

しかし、このようにしてデータが十分に利用されない.すなわち、検証セットのデータが逆伝播に関与しない場合、どのようにしてフィッティングを検証し、検証セットを訓練過程に参加させることができるのだろうか.
ここではクロス検証という方法があります.一般的には、まず訓練セットと検証セットを統合し、それから総集合をN部に分け、毎回N-1部を取って訓練し、1部を検証すればいいということです.このようにクロスして行うことで、ネットワークが記憶を形成しないことを保証することができます.
コードは次のとおりです.
for epoch in range(500):
    idx = tf.range(60000)
    idx = tf.random.shuffle(idx)
    x_train,y_train = tf.gather(x,idx[:50000]),tf.gather(y,idx[:50000])
    x_val,y_val = tf.gather(x,idx[-10000:]),tf.gather(y,idx[-10000:])
    
    db_train = tf.data.Dataset.from_tensor_slices((x_train,y_train))
    db_train = db_train.map(preprocess).shuffle(50000).batch(batchsize)
    
    db_val = tf.data.Dataset.from_tensor_slices((x_val,y_val))
    db_val = db_val.map(preprocess).batch(batchsize)

   # training
   # evaluate

tf.kerasは、コードが次のように簡単な方法を提供します.
network.fit(db_total,epochs=6,validation_split=0.1,validation_freq=1)

validation_splitパラメータは、epochごとに10分の1のデータが検証セットとして使用されることを示す0.1のような、全データセットから検証セットを分離する割合を指定します.