TLDR
Извлечение функций с использованием CNN, подача в отдельную модель LSTM «многие ко многим».Бинарная классификация, но отношение класса 1 к классу 2 составляет 1: 4, что приводит к переобучению во время тренировки.
Из того, что я понимаю, если я удаляю данные класса 2, такие что теперь соотношение составляет 1: 1, перетасуйте данные с помощьюметки, так что модель не угадывает класс 1 для первой половины выборок, я буду разрушать временную последовательность данных.Модель не сможет делать хорошие прогнозы на основе соседних кадров.
Как мне решить эту проблему?
------------------------------------------------------------------------------------------------------------------------------------
Идея состоит в том, чтобы создать бота Flappy Bird, который берет последовательность из 5 изображений и предсказывает, прыгать или нет.Чтобы добиться этого, я взял в качестве входных данных 20 000 изображений игрового процесса со скоростью около 10 кадров в секунду и извлек функции из слоя Flatten () следующей архитектуры.
Ввод: (samples, height, width, channels)
другими словами (20 000, 250, 150, 3)
Особенности: (20 000, 14336)
model = Sequential()
model.add(Conv2D(64, 3, 3, border_mode='same', input_shape=(250,150,3), activation='relu'))
model.add(Conv2D(64, 3, 3, border_mode='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(128, 3, 3, border_mode='same', activation='relu'))
model.add(Conv2D(128, 3, 3, border_mode='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(256, 3, 3, border_mode='same', activation='relu'))
model.add(Conv2D(256, 3, 3, border_mode='same', activation='relu'))
model.add(Conv2D(256, 3, 3, border_mode='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(512, 3, 3, border_mode='same', activation='relu'))
model.add(Conv2D(512, 3, 3, border_mode='same', activation='relu'))
model.add(Conv2D(512, 3, 3, border_mode='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(512, 3, 3, border_mode='same', activation='relu'))
model.add(Conv2D(512, 3, 3, border_mode='same', activation='relu'))
model.add(Conv2D(512, 3, 3, border_mode='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.summary()
RMSprop = optimizers.RMSprop(lr=0.0001)
model.compile(loss='binary_crossentropy', optimizer=RMSprop, metrics=['accuracy'])
callbacks = [EarlyStopping(monitor='val_acc', min_delta=0.0001, mode='max', patience=10)]
Затем я изменил функции до (4 000, 5, 14336)
, где 5 - это мойшаг времени.Я также изменил свои метки до (4 000, 5, 2)
, где прыжок, а не прыжок закодирован одним щелчком.Затем я взял эти функции в качестве входных данных для многих LSTM.
model = Sequential()
model.add(LSTM(256, return_sequences=True, input_shape=(5, 14336), dropout=0.5))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2, activation='softmax'))
model.summary()
RMSprop = optimizers.RMSprop(lr=0.0001)
model.compile(loss='binary_crossentropy', optimizer=RMSprop, metrics=['accuracy'])
callbacks = [EarlyStopping(monitor='val_acc', min_delta=0.0001, mode='max', patience=10)]
Как и ожидалось, модель переоснастилась, и я прекратил обучение:
Epoch 6/50
3232/3232 [==============================] - 138s 43ms/step - loss: 0.5020 - acc: 0.8058 - val_loss: 0.5541 - val_acc: 0.7735
Как уже упоминалось, я подумалбалансируя классы и перетасовывая данные (оба из которых я не сделал), насколько я понимаю, это испортит последовательность изображений, которая отнимет весь смысл использования LSTM.
Я пытался использовать только CNN, обученный на отдельных кадрах с тасовкой и сбалансированными классами, и это достигло 0,9 val_acc и 0,95 акк, что довольно прилично.Однако, при тестировании бота, он не смог длиться более 6 секунд;его рекорд был всего 3.
Любая помощь приветствуется.