web-dev-qa-db-ja.com

ニューラルネットワークが最初のエポック後に高い損失値で動かなくなるのはなぜですか

ニューラルネットワークを使用して回帰を行っています。 NNが実行するのは簡単なタスクです。予測したい10の機能と1つの出力があります。プロジェクトにpytorchを使用していますが、モデルがうまく学習していません。損失は​​非常に高い値(40000)で始まり、最初の5〜10エポックの後、損失は急速に6000〜7000に減少します。相互検証機能を使用できるように、pytorchではなくskorchに変更することも試みましたが、それも役に立ちませんでした。さまざまなオプティマイザを試し、レイヤーとニューロンをネットワークに追加しましたが、それは役に立たず、非常に高い損失値である6000で止まりました。ここでは回帰を行っています。10個の機能があり、1つの連続値を予測しようとしています。それは簡単にできるはずです。それが私をより混乱させる理由です。

これが私のネットワークです:レイヤーとユニットの追加からバッチの正規化、アクティベーションの変更など、より複雑なアーキテクチャの作成からすべての可能性を試しました。

class BearingNetwork(nn.Module):
    def __init__(self, n_features=X.shape[1], n_out=1):
        super().__init__()
        self.model = nn.Sequential(

            nn.Linear(n_features, 512), 
            nn.BatchNorm1d(512),
            nn.LeakyReLU(),
            nn.Linear(512, 64),
            nn.BatchNorm1d(64),
            nn.LeakyReLU(),
            nn.Linear(64, n_out),
#             nn.LeakyReLU(),
#             nn.Linear(256, 128),
#             nn.LeakyReLU(),
#             nn.Linear(128, 64),
#             nn.LeakyReLU(),
#             nn.Linear(64, n_out)
        )

    def forward(self, x):
        out = self.model(x)
        return out

そしてこれが私の設定です:skorchの使用はpytorchよりも簡単です。ここでは、R2メトリックも監視しています。RMSEをカスタムメトリックとして作成し、モデルのパフォーマンスも監視しています。私はAdamのamsgradも試しましたが、それは役に立ちませんでした。

R2 = EpochScoring(r2_score, lower_is_better=False, name='R2')
explained_var_score = EpochScoring(EVS, lower_is_better=False, name='EVS Metric')
custom_score = make_scorer(RMSE)
rmse = EpochScoring(custom_score, lower_is_better=True, name='rmse')

bearing_nn = NeuralNetRegressor(

    BearingNetwork,
    criterion=nn.MSELoss,
    optimizer=optim.Adam,
    optimizer__amsgrad=True,
    max_epochs=5000,
    batch_size=128,
    lr=0.001,
    train_split=skorch.dataset.CVSplit(10),
    callbacks=[R2, explained_var_score, rmse, Checkpoint(), EarlyStopping(patience=100)],
    device=device

)

入力値も標準化しています。

私の入力は次のような形をしています:

torch.Size([39006, 10])

出力の形は次のとおりです。

torch.Size([39006, 1])

私はBatch_sizeとして128を使用していますが、32、64、512、さらには1024などの他の値も試しました。出力の正規化は必要ありませんが、それも試しましたが、値を予測すると機能しませんでしたが、損失が大きくなっています。これについて誰かが私を助けてください、私はすべての役立つアドバイスをいただければ幸いです。また、最初の5つのエポックで損失がどのように減少しているかを視覚化するために、エポック上のトレーニングおよびバリューの損失とメトリックのスクリーンショットを追加します。

loss and metrics over epochs

5
basilisk

注目すべき指標はR ^ 2であり、損失関数の大きさではありません。損失関数の目的は、それが正しい方向に進んでいるかどうかをオプティマイザに知らせることだけです。これは、データセットと学習設定全体で比較できる適合度の尺度ではありません。それがR ^ 2の目的です。

R ^ 2スコアは、出力の分散全体の約3分の1を説明していることを示しています。これは、多くの場合、機能が10個しかないデータセットに対して非常に良い結果です。実際、データの形状を考えると、非表示のレイヤーが必要以上に大きく、フィッティングのリスクが高い可能性が高くなります。

このモデルを実際に評価するには、(1)R ^ 2スコアがOLSのようなより単純な回帰アプローチとどのように比較されるか、(2)出力分散の30%以上をキャプチャする必要があるという確信を持つ必要がある理由を知る必要があります。入力変数による。

#1の場合、少なくともR ^ 2は悪いであってはなりません。 #2については、標準的な数字の分類の例を検討してください。人間がそれを行うことができるため、非常に高い精度(つまり、R ^ 2が1に近づく)で数字を認識するために必要なすべての情報がわかっています。ソースデータでキャプチャされない重要な分散のソースがあるため、他のデータセットの場合は必ずしもそうではありません。

1
kkoning

損失が40000から6000に減少すると、NNモデルは一般的な関係を学習しましたが、すべてを学習したわけではありません。予測変数を変換し、それらを派生変数としてモデルに供給して、それが役立つかどうかを確認することで、この学習を支援できます。最も影響力のある予測子を最初に追加することにより、NNモデルに機能を段階的に追加してみることができます。すべての反復で、モデルのパフォーマンス(つまり、トレーニング損失)を評価します。

最初のステップが役に立たず、他のアプローチを受け入れる場合は、データのダイナミクスの推定、ガウスプロセス回帰または分位回帰が役立つはずです。これらのメソッドは、線形回帰手法などの仮定から解放されているためです。また、独立変数と従属変数の関係のさまざまな側面を調査するのにも役立ちます。

0
Samiie