web-dev-qa-db-ja.com

Keras-fit_generator()でバッチとエポックはどのように使用されますか?

8000フレームのビデオがあり、それぞれ200フレームのバッチでKerasモデルをトレーニングしたいと思います。ビデオをフレームごとにループし、(3 x 480 x 640)フレームをシェイプのnumpyマトリックスXに蓄積するフレームジェネレーター_(200, 3, 480, 640)_ バッチサイズ、rgb 、フレームの高さ、フレームの幅)-および200番目のフレームごとにXおよびYを生成します。

_import cv2
...
def _frameGenerator(videoPath, dataPath, batchSize):
    """
    Yield X and Y data when the batch is filled.
    """
    camera = cv2.VideoCapture(videoPath)
    width = camera.get(3)
    height = camera.get(4)
    frameCount = int(camera.get(7))  # Number of frames in the video file.

    truthData = _prepData(dataPath, frameCount)

    X = np.zeros((batchSize, 3, height, width))
    Y = np.zeros((batchSize, 1))

    batch = 0
    for frameIdx, truth in enumerate(truthData):
        ret, frame = camera.read()
        if ret is False: continue

        batchIndex = frameIdx%batchSize

        X[batchIndex] = frame
        Y[batchIndex] = truth

        if batchIndex == 0 and frameIdx != 0:
            batch += 1
            print "now yielding batch", batch
            yield X, Y
_

---(fit_generator() の実行方法は次のとおりです。

_        batchSize = 200
        print "Starting training..."
        model.fit_generator(
            _frameGenerator(videoPath, dataPath, batchSize),
            samples_per_Epoch=8000,
            nb_Epoch=10,
            verbose=args.verbosity
        )
_

私の理解は、_samples_per_Epoch_サンプルがモデルで見られ、_samples_per_Epoch_ =バッチサイズ*バッチ数= 200 * 40になったときにエポックが終了するということです。次のエポックはフレーム0から再びトレーニングを開始します。これは正しいですか?

このセットアップではエポックごとにジェネレーターから_fit_generator_に40バッチ(各200フレーム)が渡されると予想しています。これは、エポックごとに合計8000フレームになります-すなわち、_samples_per_Epoch=8000_。その後、後続のエポックでは、_fit_generator_はジェネレーターを再初期化して、ビデオの最初から再びトレーニングを開始します。しかし、これは事実ではありません。 最初のエポックが完了すると(モデルがバッチ0から24を記録した後)、ジェネレーターは中断したところから再開します。新しいエポックは、トレーニングデータセットの最初から再開するべきではありませんか?

_fit_generator_の理解に誤りがある場合は、説明してください。私はドキュメンテーション、この 、およびこれらの 関連問題 を調べました。 TensorFlowバックエンドでKeras v1.0.7を使用しています。この問題は Keras repo にも投稿されています。

17
BoltzmannBrain

最初のエポックが完了した後(モデルがバッチ0から24を記録した後)、ジェネレーターは中断したところから再開します

これは何が起こるかを正確に説明しています。ジェネレータをリセットまたは巻き戻したい場合は、内部でこれを行う必要があります。 kerasの動作は多くの状況で非常に役立つことに注意してください。たとえば、データの1/2を確認してエポックを終了し、残りの半分でエポックを実行できます。これは、ジェネレーターのステータスがリセットされた場合は不可能です(検証をより厳密に監視するのに役立ちます)。

9
yhenon

while 1:ループを追加することで、ジェネレーターを強制的にリセットすることができます。それが私が進めている方法です。したがって、ジェネレーターはエポックごとにバッチデータを生成できます。

6
Adrien G.

Generatorは完全に分離された関数であるため、再度呼び出されるたびに無限ループを続けます。

私が正当化できないのは、fit_generator()が十分なサンプルを持つまでジェネレーターを呼び出すということです。変数batch_sizeが見つかりませんが、サイズを定義する内部変数を設定する基準が必要です。

各ループシーケンス内の状態を印刷するときにこれをチェックしました。

def generator():

while 1:
    for i in range(0,len(x_v)-1):
        if (i != predict_batch_nr):
            print("\n -> usting Datasett ", i+1 ," of ", len(x_v))
            x = x_v[i] #x_v has Batches of different length
            y = y_v[i] #y_v has Batches of different length

            yield x, y


model.fit_generator(generator(),steps_per_Epoch=5000,epochs=20, verbose=1)

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

4914/5000 [============================>.] - ETA: 13s - loss: 2442.8587
usting Datasett  77  of  92
4915/5000 [============================>.] - ETA: 12s - loss: 2442.3785
-> usting Datasett  78  of  92
-> usting Datasett  79  of  92
-> usting Datasett  80  of  92
4918/5000 [============================>.] - ETA: 12s - loss: 2442.2111
-> usting Datasett  81  of  92
-> usting Datasett  82  of  92
0