web-dev-qa-db-ja.com

Kerasの相互検証

Kerasで多層パーセプトロンを実装し、scikit-learnを使用して相互検証を実行しています。このため、私は問題で見つかったコードに触発されました ケラスのクロス検証

from sklearn.cross_validation import StratifiedKFold

def load_data():
    # load your data using this function

def create model():
    # create your model using this function

def train_and_evaluate__model(model, data[train], labels[train], data[test], labels[test)):
    # fit and evaluate here.

if __name__ == "__main__":
    X, Y = load_model()
    kFold = StratifiedKFold(n_splits=10)
    for train, test in kFold.split(X, Y):
        model = None
        model = create_model()
        train_evaluate(model, X[train], Y[train], X[test], Y[test])

ニューラルネットワークに関する私の研究では、ニューラルネットワークの知識表現はシナプスの重みにあり、ネットワークトレースプロセス中に更新される重みにより、ネットワークエラー率が低下し、パフォーマンスが向上することがわかりました。 (私の場合、教師あり学習を使用しています)

ニューラルネットワークのパフォーマンスのトレーニングと評価を改善するために使用される一般的な方法は、モデルのトレーニングと評価のためにデータセットのパーティションを返す相互検証です。

私の疑問は...

このコードスニペットでは:

for train, test in kFold.split(X, Y):
    model = None
    model = create_model()
    train_evaluate(model, X[train], Y[train], X[test], Y[test])

生成されたパーティションごとに新しいニューラルネットを定義、トレーニング、評価しますか?

私の目標がデータセット全体のネットワークを微調整することである場合、単一のニューラルネットワークを定義し、生成されたパーティションでトレーニングすることが正しくないのはなぜですか?

つまり、なぜこのコードはこのようになっているのでしょうか?

for train, test in kFold.split(X, Y):
    model = None
    model = create_model()
    train_evaluate(model, X[train], Y[train], X[test], Y[test])

そうではない?

model = None
model = create_model()
for train, test in kFold.split(X, Y):
    train_evaluate(model, X[train], Y[train], X[test], Y[test])

コードがどのように機能するかについての私の理解はありますか?それとも私の理論?

ありがとう!

10
Alisson Hayasi

データセット全体のネットワークを微調整することが私の目標である場合

「微調整」が何を意味するのか、あるいは相互検証(CV)を実行する目的が正確に何なのかさえ明確ではありません。一般に、CVは次のいずれかの目的に使用されます。

  • モデルの選択(ハイパーパラメーターの値を選択)
  • モデル評価

コードでハイパーパラメーター選択用の検索グリッドを定義しないため、モデルの期待されるパフォーマンス(エラー、精度など)を得るためにCVを使用しているように見えます。

とにかく、何らかの理由でCVを使用している場合、最初のスニペットは正しいものです。あなたの2番目のスニペット

model = None
model = create_model()
for train, test in kFold.split(X, Y):
    train_evaluate(model, X[train], Y[train], X[test], Y[test])

モデルをトレーニングします順次異なるパーティションで(つまり、パーティション#1でトレーニングし、パーティション#2でトレーニングを続けます)、これは基本的にデータセット全体でトレーニングしているだけで、確かにそうではありません交差検証...

つまり、最終ステップafter CVは、CVプロシージャで指定された選択したハイパーパラメーターやモデルのパフォーマンスに満足した後、しばしば暗示されるだけでなく(初心者が頻繁に見逃します) 、戻ってモデルを再度トレーニングします。今回は全体の利用可能なデータを使用します。

9
desertnaut

ネストされた相互検証について読むと、あなたの質問の多くが答えられると思います。これは、モデルのハイパーパラメーターを「微調整」するための良い方法です。ここにスレッドがあります:

https://stats.stackexchange.com/questions/65128/nested-cross-validation-for-model-selection

認識すべき最大の問題は、「ピーク」または循環ロジックです。基本的に-モデルの精度を評価するために使用されるデータのnoneがトレーニング中に確認されるようにします。

これが問題となる可能性がある1つの例は、特徴抽出のためにPCAやICAなどを実行している場合です。このようなことを行う場合は、トレーニングセットでPCAを実行してから、トレーニングセットからテストセットに変換マトリックスを適用する必要があります。

2
PK Douglas

モデルのパフォーマンスをテストする主な目的は、次の手順を実行することです。

  1. トレーニングセットでモデルをトレーニングします。
  2. 新しいデータの到着をシミュレートするために、トレーニングプロセス中に使用されていないデータでモデルを評価します。

基本的に-最終的にモデルをテストする必要があるデータは、モデルを適用するためにクライアント/アプリケーションから取得する最初のデータ部分を模倣する必要があります。

そのため、交差検証が非常に強力です。データセット全体のすべてのデータポイントを新しいデータのシミュレーションとして使用できます。

そして今-あなたの質問に答えるために-すべての相互検証は次のパターンに従うべきです:

for train, test in kFold.split(X, Y
     model = training_procedure(train, ...)
     score = evaluation_procedure(model, test, ...)

結局のところ、最初にモデルをトレーニングしてから、それを新しいデータで使用するからです。 2番目のアプローチでは、トレーニングプロセスの模倣として扱うことはできません。 2番目の折り畳みでは、モデルは最初の折り畳みからの情報を保持します。これはトレーニング手順とは異なります。

もちろん、ネットワークを微調整するために、10回の連続トレーニングを使用するトレーニング手順を適用できます。ただし、これは相互検証ではありません。上記のスキーマを使用してこの手順を評価する必要があります。

1
Marcin Możejko

コメントアウトされた関数により、これは少しわかりにくくなりますが、アイデアは、フォールドを反復するときにモデルのパフォーマンスを追跡し、最後にこれらの低レベルのパフォーマンスメトリックまたは平均化されたグローバルパフォーマンスを提供することです。例えば:

train_evaluate関数は、理想的には各分割の精度スコアを出力し、最後に組み合わせることができます。

def train_evaluate(model, x_train, y_train, x_test, y_test):
    model.fit(x_train, y_train)
    return model.score(x_test, y_test)

X, Y = load_model()
kFold = StratifiedKFold(n_splits=10)
scores = np.zeros(10)
idx = 0
for train, test in kFold.split(X, Y):
    model = create_model()
    scores[idx] = train_evaluate(model, X[train], Y[train], X[test], Y[test])
    idx += 1
print(scores)
print(scores.mean())

したがって、この演習の目的は、モデルを許可する可能性のある特定のセグメントだけでなく、設計されたモデルがデータのすべてのセグメントでどのように機能するかを決定することであるため、各フォールドに新しいモデルを作成する必要がありますうまく機能します。

このタイプのアプローチは、ハイパーパラメーターを介したグリッド検索とともに適用すると特に強力になります。このアプローチでは、クロス検証スプリットを使用して、さまざまなハイパーパラメーターでモデルをトレーニングし、スプリットおよび全体のパフォーマンスを追跡します。最終的に、どのハイパーパラメータがモデルのパフォーマンスを最大限に高めるかについて、より良いアイデアを得ることができます。より詳細な説明については、 sklearn Model Selection を参照し、相互検証とグリッド検索のセクションに特に注意を払ってください。

1
Grr

KerasモデルでScikit-Learn APIのラッパーを使用できます。

入力xおよびyが与えられた場合、5倍交差検証の繰り返しの例を次に示します。

from sklearn.model_selection import RepeatedKFold, cross_val_score
from tensorflow.keras.models import * 
from tensorflow.keras.layers import * 
from tensorflow.keras.wrappers.scikit_learn import KerasRegressor

def buildmodel():
    model= Sequential([
        Dense(10, activation="relu"),
        Dense(5, activation="relu"),
        Dense(1)
    ])
    model.compile(optimizer='adam', loss='mse', metrics=['mse'])
    return(model)

estimator= KerasRegressor(build_fn=buildmodel, epochs=100, batch_size=10, verbose=0)
kfold= RepeatedKFold(n_splits=5, n_repeats=100)
results= cross_val_score(estimator, x, y, cv=kfold, n_jobs=2)  # 2 cpus
results.mean()  # Mean MSE
0
Megatron