Я пытаюсь обучить CNN-LSTM читать последовательность из 6 кадров за раз в CNN (VGG16 без верхнего уровня) и передавать извлеченные функции LSTM в Keras.
Проблема в том, что, поскольку мне нужно отправлять 6 кадров за раз, мне нужно изменять форму каждые 6 кадров и добавлять измерение. Кроме того, поскольку метки предназначены для каждого кадра, мне нужно создать еще одну переменную, чтобы получить метку первого кадра для каждой последовательности и поместить ее в новый массив, а затем скормить обе для загрузки модели (код ниже).
Проблема в том, что данные становятся слишком большими для использования model.fit (), и даже при попытке использовать его с небольшой частью данных я получаю странные ужасные результаты, поэтому я пытаюсь использовать model.fit_generator для итерации ввода в модель. Но поскольку я не могу напрямую загружать данные, которые загружаю из набора данных (потому что мне нужно изменить форму и сделать то, что я объяснил в первом абзаце), я пытаюсь создать свой собственный генератор. Однако дела идут не очень хорошо, и я продолжаю получать ошибки о том, что кортеж не является итератором. Кто-нибудь знает, как я могу исправить код, чтобы он работал?
train_batches = ImageDataGenerator().flow_from_directory(train_path, target_size=(224, 224),
classes=['Bark', 'Bitting', 'Engage', 'Hidden', 'Jump',
'Stand', 'Walk'], batch_size=18156, shuffle=False)
valid_batches = ImageDataGenerator().flow_from_directory(valid_path, target_size=(224, 224),
classes=['Bark', 'Bitting', 'Engage', 'Hidden', 'Jump',
'Stand', 'Walk'], batch_size=6, shuffle=False)
test_batches = ImageDataGenerator().flow_from_directory(test_path, target_size=(224, 224),
classes=['Bark', 'Bitting', 'Engage', 'Hidden', 'Jump',
'Stand','Walk'], batch_size=6, shuffle=False)
def train_gen():
n_frames=6
n_samples=6 #to decide
H=W=224
C = 3
imgs, labels = next(train_batches)
y = np.empty((n_samples, 7))
j = 0
for i in range(n_samples):
y[i] = labels[j]
j +=6
frame_sequence = imgs.reshape(n_samples,n_frames, H,W,C)
return frame_sequence,y
def valid_gen():
v_frames=6
v_samples=1
H=W=224
C = 3
vimgs,vlabels = next(valid_batches)
y2 = np.empty((v_samples, 7))
k = 0
for l in range(v_samples):
y2[l] = vlabels[k]
k +=6
valid_sequence = vimgs.reshape(v_samples,v_frames, H,W,C)
return valid_sequence,y2
def main():
cnn = VGG16(weights='imagenet',
include_top='False', pooling='avg')
cnn.layers.pop()
print(cnn.summary())
cnn.trainable = False
video_input= Input(shape=(None,224,224,3), name='video_input')
print(video_input.shape)
encoded_frame_sequence = TimeDistributed(cnn)(video_input) # the output will be a sequence of vectors
encoded_video = LSTM(256)(encoded_frame_sequence) # the output will be a vector
output = Dense(7, activation='relu')(encoded_video)
video_model = Model(inputs=[video_input], outputs=output)
tr_data = train_gen()
vd_data= valid_gen()
print(video_model.summary())
imgs, labels = next(train_batches)
vimgs,vlabels = next(valid_batches)
print("Training ...")
video_model.compile(Adam(lr=.001), loss='categorical_crossentropy', metrics=['accuracy'])
video_model.fit_generator(tr_data,
steps_per_epoch=1513,
validation_data=vd_data,
validation_steps=431,
epochs=1,
verbose=2)
Есть ли ошибка в том, как я определяю генератор?






Похоже, я неправильно определил генераторы. Как объяснил мне администратор Keras, у этого определения есть две проблемы.
Обратите внимание, что в остальной части кода, с которым я имел дело, есть несколько ошибок, но поскольку этот вопрос касается генератора, я отправляю ответ только по этой части (есть два генератора, но они похожи, за исключением ввода):
def train_gen():
n_frames=6
n_samples=5 #to decide
H=W=224
C = 3
while True:
imgs, labels = next(train_batches)
#frame_sequence = imgs.reshape(n_samples,n_frames, H,W,C)
y = np.empty((n_samples, 7))
j = 0
#print("labels")
#print(labels)
#print("y")
#print(y.shape)
if len(labels) == n_frames*n_samples:
frame_sequence = imgs.reshape(n_samples,n_frames, H,W,C)
for i in range(n_samples):
y[i] = labels[j]
# print("inside: ")
#print(y[i])
# print(labels[j])
j +=6
yield frame_sequence,y
n_samples относится к количеству последовательностей. n_frames - количество кадров в 1 последовательности. Допустим, мы рассматриваем 1 последовательность из 8 кадров. Это означает, что если я прочитал 16 кадров за одну итерацию, мне нужно было бы установить n_samples равным 2 и n_frames = 8. Итак, если вы установите длину последовательности на 25 и вы прочитаете 100 кадров за итерацию, у вас действительно будет n_samples = 4. Это может быть слишком сложно для вашего процессора / графического процессора, хотя
Я думаю, вам стоит реализовать класс для генератора данных, я нашел эту ссылку, это может вам помочь. Подробный пример использования генераторов данных с Keras
Спасибо за ссылку. Я поискал его, когда пытался решить проблему, но метод слишком сложен для моей цели. Я думаю, что опубликованное мной решение отлично справляется со своей задачей.
не могли бы вы объяснить мне, в чем разница между n_samples ia и n_frame. Это n_samples = number_videos, n_frames = #frames_in_a_video. Следовательно, это может означать папку со 100 кадрами, которую я делаю на 4 партии по 25 кадров?