翻訳:4.4。モデルの選択、過適合、および過剰適合pytorch

機械学習の科学者としての私たちの目標は、パターンを発見することです。しかし、単にデータを記憶するのではなく、どうすれば実際に共通のパターンを発見したことを確認できますか?たとえば、患者を認知症の状態に関連付ける遺伝子マーカーのパターンを探したいとします。ここでは、ラベルはセットから抽出され{dementia, mild cognitive impairment, healthy}ます。各人の遺伝子はそれらを一意に識別します(同一の兄弟を無視します)ので、覚えておくことができます。データセット全体。

モデルに「それはボブです!私は彼を覚えています!彼はアルツハイマー病です!」と言わせたくありません。理由は単純です。将来モデルを展開するとき、モデルがこれまでに見たことのない患者に遭遇するでしょう。私たちの予測は、モデルが実際に一般的なパターンを見つけた場合にのみ役立ちます。

より正式に要約すると、私たちの目標は、トレーニングセットの基礎となる母集団の規則性を捉えるパターンを発見することです。これに成功すれば、これまで会ったことのない個人に対してもリスクを評価することができます。この問題、つまり一般化のパターンをどのように発見するかは、機械学習の基本的な問題です。

危険なのは、モデルをトレーニングするときに、データのごく一部にしかアクセスできないことです。最大の公開画像データセットには、約100万枚の画像が含まれています。多くの場合、数千または数万のデータ例から学ぶ必要があります。大規模な病院システムでは、数十万の医療記録にアクセスできる場合があります。限られたサンプルを扱う場合、より多くのデータを収集するにつれて、最終的には保持できない明確な関連を見つけるリスクがあります。

基礎となる分布を適合させるよりも厳密にトレーニングデータを適合させる現象は過剰適合と呼ばれ、過剰適合と戦うために使用される手法は正則化と呼ばれます。前のセクションでは、Fashion-MNISTデータセットを実験しているときにこの効果を観察した可能性があります。実験中にモデル構造またはハイパーパラメーターを変更した場合、十分なニューロン、レイヤー、およびトレーニングエポックがあれば、テストデータの精度が低下しても、モデルは最終的にトレーニングセットで完全な精度を達成できることに気付くかもしれません。

4.4.1トレーニングエラーと汎化エラー

この現象をより正式に議論するには、トレーニングエラーと汎化エラーを区別する必要があります。トレーニングエラーは、トレーニングデータセットでモデルによって計算されたエラーですが、汎化エラーは、元のサンプルと同じ基になるデータ分布から抽出された追加のデータ例の無限ストリームに適用した場合のモデルのエラーの期待値です。

問題は、汎化誤差を正確に計算できないことです。これは、データの無限のストリームが架空のオブジェクトであるためです。実際には、トレーニングセットから保持されたランダムに選択されたデータ例で構成される独立したテストセットにモデルを適用することにより、汎化誤差を推定する必要があります。

次の3つの思考実験は、この状況をよりよく説明するのに役立ちます。大学生が最終試験の準備をしようとしていると考えてください。勤勉な学生は一生懸命練習し、彼の能力をテストするために前の年の試験を使用します。それでも、過去の試験でうまくやっているからといって、それが重要なときに彼がうまくいくとは限りません。たとえば、学生は試験問題への回答を暗記して準備しようとする場合があります。これには、生徒が多くのことを覚えておく必要があります。彼女は過去の試験の答えを完全に覚えることさえできます。別の生徒は、特定の答えが与えられる理由を理解することによって準備しようとするかもしれません。ほとんどの場合、後者の学生の方がうまくいくでしょう。

同様に、ルックアップテーブルを使用して質問に答えるだけのモデルを考えてみましょう。許可された入力のセットが離散的でかなり小さい場合、このアプローチは多くのトレーニング例を見た後でうまく機能する可能性があります。これまでに見たことのない例に直面した場合、モデルは依然としてランダムな推測に勝るものはありません。実際、入力スペースが大きすぎて、考えられるすべての入力に対応する答えを記憶できません。たとえば、白黒28x28写真について考えてみます。各ピクセルが256グレースケール値を取ることができる場合、
257^784可能な画像があります。つまり、低解像度のグレースケールのサムネイルサイズの画像には、宇宙にあるよりもはるかに多くの原子が含まれています。そのようなデータに遭遇したとしても、ルックアップテーブルを保存することはできません。

最後に、いくつかの潜在的に利用可能なコンテキスト機能に基づいて、コイントスの結果(クラス0:ヘッド、クラス1:テール)を分類しようとする問題を検討します。コインが公正であると仮定します。どのアルゴリズムを考えても、汎化誤差は常に1/2です。ただし、ほとんどのアルゴリズムでは、抽選の運によっては、トレーニング誤差がはるかに小さいと予想されます。任意の機能!データセットを検討してください{0, 1, 1, 1, 0, 1}機能のないアルゴリズムは、限られたサンプルから1であるように見える多数派クラスを常に予測することに依存する必要があります。この場合、常にクラス1を予測するモデルは、汎化誤差よりもはるかに優れた1/3を生成します。データの量が増えると、ヘッドの割合が大幅に逸脱し、トレーニングエラーが汎化エラーと一致する確率が1/2になります。

4.4.1.1。統計学習理論

一般化は機械学習の基本的な問題であるため、多くの数学者や理論家がこの現象を説明するための正式な理論の開発に人生を捧げてきたことに驚くことはないかもしれません。同じ名前の定理で、GlivenkoとCantelliは、トレーニングエラーが汎化エラーに収束する速度を導き出しました一連の独創的な論文で、VapnikとChervonenkisは、この理論をより一般的なクラスの関数に拡張しました。この作品は、統計学習理論の基礎を築きました。

これまでに解決し、この本の大部分で使用する標準の教師あり学習設定では、トレーニングデータとテストデータの両方が同じ分布から独立して描画されると想定しています。これはしばしばiid仮定と呼ばれ、データをサンプリングするプロセスにメモリがないことを意味します。言い換えると、2番目に抽出されたサンプルと3番目に描画されたサンプルは、2番目に描画されたサンプルと2ppmのサンプルよりも相関関係がありません。

優れた機械学習科学者になるには批判的思考が必要です。仮説が失敗する一般的なケースを提示して、この仮説にすでに穴を開けているはずです。UCSF医療センターの患者から収集したデータで死亡リスク予測子をトレーニングし、それをマサチューセッツ総合病院の患者に適用した場合はどうなりますか?これらの分布はまったく同一ではありません。また、ネクタイは時間的に関連している可能性があります。ツイートのトピックを分類するとどうなりますか?ニュースサイクルは、議論されたトピックに時間依存性を生み出し、独立性の仮定に違反します。

場合によっては、iidの仮定にわずかに違反することで逃げることができ、モデルは引き続き非常にうまく機能します。結局のところ、ほとんどすべての実際のアプリケーションには、少なくともiidの仮定に対する軽微な違反が含まれていますが、顔認識、音声認識、言語翻訳など、さまざまなアプリケーションに役立つツールが多数あります。

その他の違反は必ずトラブルの原因となります。たとえば、大学生向けに特別にトレーニングして顔認識システムをトレーニングしようとし、それをナーシングホームの老年医学を監視するためのツールとして展開したいとします。大学生は年配の大人とは非常に異なって見える傾向があるため、これが機能する可能性は低いです。

以降の章では、iidの仮定に違反することから生じる問題について説明します。今のところ、一般化を理解することは、iidの仮定を当然のこととして考えても、難しい問題です。さらに、深いニューラルネットワークが一般化する理由を説明する可能性のある正確な理論的基盤を解明することは、学習理論の最も偉大な思想家を悩ませ続けます。

モデルをトレーニングするときは、トレーニングデータにできるだけ一致する関数を見つけようとします。関数が非常に柔軟で、真の関連付けと同じくらい簡単にスプリアスパターンをキャッチできる場合、パフォーマンスが高すぎて、見えないデータに一般化するモデルが生成されない可能性があります。これはまさに私たちが避けたい、または少なくとも制御したいことです。深層学習の多くの手法は、過剰適合を防ぐために設計されたヒューリスティックとトリックです。

4.4.1.2。モデルの複雑さ

単純なモデルと豊富なデータがある場合、汎化誤差はトレーニング誤差と同様であると予想されます。より複雑なモデルと少数の例を使用すると、トレーニングエラーは減少すると予想されますが、一般化のギャップは拡大します。モデルの複雑さを正確に構成するものは、複雑な問題です。モデルがうまく一般化するかどうかは、多くの要因によって決まります。たとえば、より多くのパラメータを持つモデルは、より複雑であると見なされる場合があります。パラメータがより広い範囲の値を取ることができるモデルは、より複雑になる可能性があります。通常、ニューラルネットワークの場合、より多くのトレーニング反復を必要とするモデルはより複雑であり、早期停止(より少ないトレーニング反復)を必要とするモデルはより複雑でないと見なします。

異なるモデルクラス(決定木とニューラルネットワークなど)のメンバー間の複雑さを比較するのは難しい場合があります。今のところ、簡単な経験則が非常に役立ちます。統計学者が複雑と見なすのは、任意の事実を簡単に説明できるモデルですが、表現力は限られていますが、データを十分に説明できるモデルは、おそらく真実に近いでしょう。ポッパーの科学理論の偽造可能性の基準と密接に関連しています。理論がデータに適合し、それを反証するために使用できる特定のテストがある場合、理論は優れています。すべての統計的推定は事後的であるため、これは重要です。つまり、事実を観察した後に推定するため、相関の誤謬の影響を受けやすくなります。今のところ、アイデアは脇に置いて、より具体的な問題に固執します。

このセクションでは、直感的に理解できるように、モデルクラスの一般化に影響を与える傾向のあるいくつかの要因に焦点を当てます。

  1. 調整可能なパラメーターの数。調整可能なパラメーター(自由度と呼ばれることもあります)の数が多い場合、モデルは過剰適合しやすくなる傾向があります。

  2. パラメータが取る値。重みがより広い範囲の値をとることができる場合、モデルは過剰適合の影響を受けやすくなります。

  3. トレーニング例の数。モデルが単純な場合でも、1つまたは2つの例だけでデータセットを過剰適合させるのは簡単です。ただし、データセットに数百万の例を過剰適合させるには、非常に柔軟なモデルが必要です。

4.4.2。モデルの選択

機械学習では、通常、いくつかの候補モデルを評価した後、最終モデルを選択します。このプロセスはモデル選択と呼ばれます。比較するモデルが根本的に異なる場合があります(たとえば、決定木と線形モデル)。また、異なるハイパーパラメータ設定でトレーニングされた同じクラスのモデルのメンバーを比較する場合もあります。

たとえば、MLPの場合、さまざまな数の非表示レイヤー、さまざまな数の非表示ユニット、および各非表示レイヤーに適用されるさまざまな活性化関数の選択肢を持つモデルを比較したい場合があります。最適な候補モデルを決定するために、通常、検証データセットを使用します。

4.4.2.1検証データセット

原則として、すべてのハイパーパラメータを選択するまで、テストセットに触れないでください。モデル選択プロセス中にテストデータを使用すると、テストデータが過剰適合する可能性があります。そうすると深刻な問題になります。トレーニングデータを過剰適合させた場合、正直に保つために常にテストデータの評価が行われます。しかし、テストデータを過剰適合させているかどうかをどうやって知ることができますか?

したがって、モデルの選択にテストデータを使用しないでください。ただし、モデルのトレーニングに使用されるデータの汎化誤差を推定できないため、モデル選択のトレーニングデータだけに依存することもできません。

実際のアプリケーションでは、画像がよりぼやけます。理想的には、テストデータに一度だけ触れて、最良のモデルを評価したり、少数のモデルを相互に比較したりしますが、実際のテストデータが1回の使用で破棄されることはめったにありません。実験の各ラウンドに新しいテストセットを提供することはめったにありません。

この問題を解決するための一般的な方法は、トレーニングとテストのデータセットに加えて、検証データセット(または検証セット)を含む3つの方法にデータを分割することです。その結果、検証データとテストデータの間の境界線が心配そうに曖昧になるというぼやけた慣習になります。特に明記されていない限り、この本の実験では、実際にはトレーニングデータと検証データと呼ばれるものを使用しており、実際のテストセットは使用していません。したがって、この本の各実験で報告されている精度は、実際には検証の精度であり、実際のテストセットの精度ではありません。

4.4.2.2.K分割交差検定

トレーニングデータが不足している場合、適切な検証セットを構成するのに十分なデータを提供できない場合もあります。この問題に対する一般的なアプローチは、K分割交差検定を使用することです。ここで、元のトレーニングデータはK個の重複しないサブセットに分割されます。次に、モデルのトレーニングと検証をK回実行します。そのたびK-1に、サブセットでトレーニングを行い、別のサブセット(そのラウンドのトレーニングに使用されていないサブセット)で検証します。最後に、K実験からペアを渡します。

4.4.3.過適合または過剰適合?過適合または過剰適合?

トレーニングエラーと検証エラーを比較するときは、2つの一般的なケースに注意する必要があります。まず、トレーニングエラーと検証エラーの両方が大きいが、それらの間に小さなギャップがある場合に注意を払いたいと思います。モデルがトレーニングエラーを減らすことができない場合は、モデルが単純すぎて(つまり、十分に表現力がない)、モデル化しようとしているパターンをキャプチャできない可能性があります。さらに、トレーニングエラーと検証エラーの間の一般化のギャップが小さいため、より複雑なモデルを回避できると信じる理由があります。この現象はアンダーフィッティングと呼ばれます。

一方、前述のように、トレーニングエラーが検証エラーよりも大幅に低い場合(深刻な過剰適合を示す)に注意する必要があります。過剰適合は必ずしも悪いことではないことに注意してください。特に深層学習では、最良の予測モデルは、ホールドアウトデータよりもトレーニングデータの方がはるかに優れていることがよく知られています。最終的に、私たちは通常、トレーニングエラーと検証エラーの間のギャップよりも検証エラーに関心があります。

過剰適合か過適合かは、モデルの複雑さと利用可能なトレーニングデータセットのサイズによって異なります。どちらのトピックについても、以下で説明します。

4.4.3.1モデルの複雑さ

過剰適合とモデルの複雑さに関するいくつかの古典的な直感を説明するために、多項式を使用した例を示します。単一の特徴と対応する実数値ラベルyを含むトレーニングデータxが与えられると、次数dの多項式dを見つけようとします。
ここに画像の説明を挿入
高次多項式はより多くのパラメーターを持ち、モデル関数の選択範囲が広がります。トレーニングデータセットを修正しました。高次多項式関数は、低次多項式に比べて常に低い(最悪の場合は等しい)トレーニングエラーを達成する必要があります。実際、データ例ごとにxの値が異なる限り、データサンプルの数に等しい次数の多項式関数をトレーニングセットに完全に適合させることができます。図4.4.1に、多項式の次数と、過適合と過剰適合の関係を視覚化します。
ここに画像の説明を挿入

4.4.3.2データセットサイズ

覚えておくべきもう1つの重要な考慮事項は、データセットのサイズです。モデルを修正すると、トレーニングデータセットに含まれるサンプルが少なくなるほど、過剰適合が発生する可能性が高くなります(さらに悪くなります)。トレーニングデータの量を増やすと、一般化誤差は一般に減少します。また、一般的に、より多くのデータが問題になることはありません。固定タスクとデータ分散の場合、モデルの複雑さとデータセットサイズの間に関係があることがよくあります。より多くのデータがあれば、より複雑なモデルに適合させようとするかもしれません。単純なモデルは、十分なデータがないと打ち負かすのが難しい場合があります。多くのタスクで、ディープラーニングは、数千のトレーニング例が利用可能な場合にのみ線形モデルよりも優れたパフォーマンスを発揮します。ディープラーニングの現在の成功の一部は、インターネット企業、安価なストレージによるものです。

4.4.4。多項式回帰

これで、多項式をデータに適合させることにより、これらの概念をインタラクティブに調べることができます。

import math
import numpy as np
import torch
from torch import nn
from d2l import torch as d2l

4.4.4.1。データセットを生成する

まず、データが必要です。xが与えられると、次の3次多項式を使用してトレーニングデータとテストデータにラベルを生成します。
ここに画像の説明を挿入

max_degree = 20  # Maximum degree of the polynomial
n_train, n_test = 100, 100  # Training and test dataset sizes
true_w = np.zeros(max_degree)  # Allocate lots of empty space
true_w[0:4] = np.array([5, 1.2, -3.4, 5.6])

features = np.random.normal(size=(n_train + n_test, 1))
np.random.shuffle(features)
poly_features = np.power(features, np.arange(max_degree).reshape(1, -1))
for i in range(max_degree):
    poly_features[:, i] /= math.gamma(i + 1)  # `gamma(n)` = (n-1)!
# Shape of `labels`: (`n_train` + `n_test`,)
labels = np.dot(poly_features, true_w)
labels += np.random.normal(scale=0.1, size=labels.shape)

ここに画像の説明を挿入

# Convert from NumPy ndarrays to tensors
true_w, features, poly_features, labels = [torch.tensor(x, dtype=
    torch.float32) for x in [true_w, features, poly_features, labels]]

features[:2], poly_features[:2, :], labels[:2]
(tensor([[ 0.4015],
         [-0.2346]]),
 tensor([[ 1.0000e+00,  4.0154e-01,  8.0618e-02,  1.0791e-02,  1.0832e-03,
           8.6992e-05,  5.8218e-06,  3.3396e-07,  1.6762e-08,  7.4787e-10,
           3.0030e-11,  1.0962e-12,  3.6681e-14,  1.1330e-15,  3.2497e-17,
           8.6992e-19,  2.1832e-20,  5.1567e-22,  1.1504e-23,  2.4312e-25],
         [ 1.0000e+00, -2.3458e-01,  2.7513e-02, -2.1513e-03,  1.2616e-04,
          -5.9190e-06,  2.3141e-07, -7.7548e-09,  2.2739e-10, -5.9266e-12,
           1.3903e-13, -2.9647e-15,  5.7955e-17, -1.0458e-18,  1.7522e-20,
          -2.7402e-22,  4.0174e-24, -5.5435e-26,  7.2244e-28, -8.9193e-30]]),
 tensor([5.2693, 4.6050]))

4.4.4.2モデルのトレーニングとテスト

まず、特定のデータセットの損失を評価する関数を実装しましょう。

def evaluate_loss(net, data_iter, loss):  #@save
    """Evaluate the loss of a model on the given dataset."""
    metric = d2l.Accumulator(2)  # Sum of losses, no. of examples
    for X, y in data_iter:
        out = net(X)
        y = y.reshape(out.shape)
        l = loss(out, y)
        metric.add(l.sum(), l.numel())
    return metric[0] / metric[1]

次に、トレーニング関数を定義します。

def train(train_features, test_features, train_labels, test_labels,
          num_epochs=400):
    loss = nn.MSELoss(reduction='none')
    input_shape = train_features.shape[-1]
    # Switch off the bias since we already catered for it in the polynomial
    # features
    net = nn.Sequential(nn.Linear(input_shape, 1, bias=False))
    batch_size = min(10, train_labels.shape[0])
    train_iter = d2l.load_array((train_features, train_labels.reshape(-1,1)),
                                batch_size)
    test_iter = d2l.load_array((test_features, test_labels.reshape(-1,1)),
                               batch_size, is_train=False)
    trainer = torch.optim.SGD(net.parameters(), lr=0.01)
    animator = d2l.Animator(xlabel='epoch', ylabel='loss', yscale='log',
                            xlim=[1, num_epochs], ylim=[1e-3, 1e2],
                            legend=['train', 'test'])
    for epoch in range(num_epochs):
        d2l.train_epoch_ch3(net, train_iter, loss, trainer)
        if epoch == 0 or (epoch + 1) % 20 == 0:
            animator.add(epoch + 1, (evaluate_loss(net, train_iter, loss),
                                     evaluate_loss(net, test_iter, loss)))
    print('weight:', net[0].weight.data.numpy())

4.4.4.3 3次多項式関数フィッティング(通常)

まず、データ生成関数と同じ次数の3次多項式関数から始めます。結果は、モデルのトレーニングとテストの損失を効果的に減らすことができることを示しています。学習したモデルパラメータも真の値に近いですw = [5, 1.2, -3.4, 5.6]

# Pick the first four dimensions, i.e., 1, x, x^2/2!, x^3/3! from the
# polynomial features
train(poly_features[:n_train, :4], poly_features[n_train:, :4],
      labels[:n_train], labels[n_train:])
weight: [[ 4.999099   1.2192062 -3.377857   5.5528784]]

ここに画像の説明を挿入

4.4.4.4線形関数フィッティング(アンダーフィッティング)

線形関数フィッティングをもう一度見てみましょう。初期のエポックが低下した後、このモデルのトレーニング損失をさらに減らすことは困難になります。最後のエポック反復の後、トレーニング損失はまだ高いです。線形モデルは、非線形モデル(ここでは3次多項式関数など)を適合させるために使用すると、適合しにくい傾向があります。

# Pick the first two dimensions, i.e., 1, x, from the polynomial features
train(poly_features[:n_train, :2], poly_features[n_train:, :2],
      labels[:n_train], labels[n_train:])
weight: [[3.7911081 2.5833387]]

ここに画像の説明を挿入

4.4.4.5高階多項式関数のフィッティング(過剰適合)

次に、次数が高すぎる多項式を使用してモデルをトレーニングしてみましょう。ここでは、高次の係数がゼロに近い値を持つ必要があることを知るのに十分なデータがありません。したがって、過度に複雑なモデルは、トレーニングデータのノイズの影響を非常に受けやすくなります。トレーニング損失は効果的に減らすことができますが、テスト損失は依然としてはるかに高くなります。これは、複雑なモデルがデータに過剰適合していることを示しています。

# Pick all the dimensions from the polynomial features
train(poly_features[:n_train, :], poly_features[n_train:, :],
      labels[:n_train], labels[n_train:], num_epochs=1500)
weight: [[ 5.0019913   1.2659464  -3.3324203   5.2160134  -0.31978676  1.2983036
   0.01977059  0.20886001 -0.02627637 -0.17851575 -0.16669305 -0.2156814
  -0.09898872 -0.18689805  0.05609591 -0.10168056 -0.1683235   0.22086866
  -0.16249742 -0.05473528]]

ここに画像の説明を挿入
以降の章では、過剰適合の問題と、重量の減少やドロップアウトなど、それらに対処する方法について引き続き説明します。

4.4.5一般

  • 汎化誤差はトレーニング誤差から推定できないため、トレーニング誤差を最小化するだけでは、必ずしも汎化誤差が減少するわけではありません。機械学習モデルは、汎化誤差を最小限に抑えるために過剰適合を防ぐように注意する必要があります。

  • 検証セットは、その使用があまりにもカジュアルでない限り、モデルの選択に使用できます。

  • 適合不足とは、モデルがトレーニングエラーを減らすことができないことを意味します。過剰適合は、トレーニングエラーが検証エラーよりもはるかに低い場合に発生します。

  • 適切に複雑なモデルを選択し、不十分なトレーニングサンプルの使用を避ける必要があります。

4.4.6。エクササイズ

1.多項式回帰問題を正確に解くことができますか?ヒント:線形代数を使用してください。

2.多項式モデルの選択を検討します。

2.1トレーニング損失とモデルの複雑さ(多項式の次数)をプロットします。何を観察していますか?トレーニング損失を0に減らすには、いくつの次数多項式が必要ですか?

2.2この場合のテスト損失をプロットします。

2.3データ量に基づいて同じグラフを生成します。

3.(1 / i!)x ^ iの正規化された多項式標数を削除するとどうなりますか?この問題を他の方法で解決できますか?

4.汎化誤差がゼロになると期待できますか?

参考

https://d2l.ai/chapter_multilayer-perceptrons/underfit-overfit.html

おすすめ

転載: blog.csdn.net/zgpeace/article/details/124397764