Task 4モデルのトレーニングと検証

11996 ワード

機械学習モデル(特に深さ学習モデル)の訓練過程において,モデルは非常にフィッティングしやすい.深さ学習モデルは絶えず訓練する過程で訓練誤差は次第に低下するが,テスト誤差の動きは必ずしもそうではない.
モデルの訓練中、モデルは訓練データのみを利用して訓練を行うことができ、モデルはテストセットのサンプルに接触することができない.したがって,モデルが訓練セット学をうまくやりすぎると,モデルは訓練サンプルの詳細を記憶し,モデルの試験セットでの汎化効果が劣り,この現象をオーバーフィット(Overfitting)と呼ぶ.オーバーフィットに対応するアンダーフィット(Underfitting)は、モデルのトレーニングセットでのフィット効果が劣ることである.上記の問題を解決するための最良の解決方法:テストセットと可能な限り分布が一致するサンプルセット(検証セットと呼ぶことができる)を構築し、訓練中にモデルの検証セットでの精度を絶えず検証し、モデルの訓練を制御する.
試合問題が与えられた後、試合問題側は訓練セットとテストセットの2つの部分のデータを与えます.参加者は訓練セットの上にモデルを構築し、テストセットの上でモデルの汎化能力を検証する必要がある.したがって,参加者はモデル対テストセットの予測結果を提出することによって,自分のモデルの汎化能力を検証することができる.同時に、参加者も提出回数の制限を制限し、参加選手の「点数」を避ける.
一般的には、参加選手も自分でローカルに検証セットを分けてローカル検証を行うことができます.トレーニングセット、検証セット、およびテストセットはそれぞれ異なる役割を果たします.
  • トレーニングセット(Train Set):モデルは、モデルパラメータのトレーニングおよび調整に使用されます。

  • 検証セット(Validation Set):モデルの精度を検証し、モデルのスーパーパラメータを調整します。

  • テストセット(Test Set):モデルの汎化能力を検証します。


  • 訓練セットと検証セットは別々であるため,モデルの検証セット上の精度はモデルの汎化能力をある程度反映できる.検証セットを分割する際には、検証セットの分布がテストセットとできるだけ一致しなければならないことに注意する必要があります.そうしないと、モデルの検証セットでの精度は指導的な意味を失います.
    検証セットがこんなに重要である以上、ローカル検証セットをどのように区分するか.いくつかの試合では、試合の問題側は検証セットを与えます.試合問題者が検証セットを与えていない場合、参加選手は訓練セットから一部を分割して検証セットを得る必要がある.検証セットの区分には、次のような方法があります.
  • 予約方法(Hold-Out)

    は、トレーニングセットを直接2つの部分に分け、新しいトレーニングセットと検証セットに分けます.このような区分方式の利点は最も直接的で簡単である.欠点は、検証セットが1つしか得られず、モデルが検証セットにフィットする可能性があることです.シーンを残して適用するのはデータ量が大きい場合です.
  • クロス検証法(Cross Validation,CV)

    は訓練セットをK部に分割し、そのうちK-1部を訓練セットとし、残りの1部を検証セットとし、K訓練を循環する.この分割方式は,すべての訓練セットが検証セットであり,最終モデル検証精度はK部平均で得られた.この方式の利点は,検証セットの精度が比較的信頼性が高く,訓練K回でK個の多様性の違いのあるモデルを得ることができることである.CV検証の欠点は,K回の訓練が必要であり,データ量が大きい場合には不適切であることである.
  • セルフサンプリング法(BootStrap)

    は、戻されたサンプリングによって新しいトレーニングセットと検証セットが得られ、毎回のトレーニングセットと検証セットに違いがある.この分割方式は、データ量が小さい場合に一般的に適用される.-pytorch実装コード
  •   ```python
    train_loader = torch.utils.data.DataLoader(
        train_dataset,
        batch_size=10, 
        shuffle=True, 
        num_workers=10, 
    )
        
    val_loader = torch.utils.data.DataLoader(
        val_dataset,
        batch_size=10, 
        shuffle=False, 
        num_workers=10, 
    )
    
    model = SVHN_Model1()
    criterion = nn.CrossEntropyLoss (size_average=False)
    optimizer = torch.optim.Adam(model.parameters(), 0.001)
    best_loss = 1000.0
    for epoch in range(20):
        print('Epoch: ', epoch)
    
        train(train_loader, model, criterion, optimizer, epoch)
        val_loss = validate(val_loader, model, criterion)
        
        #  
        if val_loss < best_loss:
            best_loss = val_loss
            torch.save(model.state_dict(), './model.pt')
    

    各Epochのトレーニングコードは以下の通りです.
    def train(train_loader, model, criterion, optimizer, epoch):
        #  
        model.train()
    
        for i, (input, target) in enumerate(train_loader):
            c0, c1, c2, c3, c4, c5 = model(data[0])
            loss = criterion(c0, data[1][:, 0]) + \
                    criterion(c1, data[1][:, 1]) + \
                    criterion(c2, data[1][:, 2]) + \
                    criterion(c3, data[1][:, 3]) + \
                    criterion(c4, data[1][:, 4]) + \
                    criterion(c5, data[1][:, 5])
            loss /= 6
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
    
    
     Epoch :
    ```python     
    def validate(val_loader, model, criterion):
        #  
        model.eval()
        val_loss = []
    
        #  
        with torch.no_grad():
            for i, (input, target) in enumerate(val_loader):
                c0, c1, c2, c3, c4, c5 = model(data[0])
                loss = criterion(c0, data[1][:, 0]) + \
                        criterion(c1, data[1][:, 1]) + \
                        criterion(c2, data[1][:, 2]) + \
                        criterion(c3, data[1][:, 3]) + \
                        criterion(c4, data[1][:, 4]) + \
                        criterion(c5, data[1][:, 5])
                loss /= 6
                val_loss.append(loss.item())
        return np.mean(val_loss)
    

    モデルの保存とロード


    Pytorchではモデルの保存とロードが非常に簡単で、モデルパラメータの保存とロードが一般的です:torch.save(model_object.state_dict(), 'model.pt') model.load_state_dict(torch.load(' model.pt'))

    チューニングテクニック:http://karpathy.github.io/2019/04/25/recipe/