这是我第一次使用LSTM网络。我有一个帧速率为30 fps的视频。我有一个CNN网络(基于AlexNet),我想将CNN网络的最后一层送入循环网络(我正在使用tensorflow)。假设我的batch_size=30
,等于fps,我希望时间步长为1 second
(所以,每30帧)。我网络的最后一层的输出将是[bast_size, 1000]
,所以在我的情况[30, 1000]
中,现在我必须将输出的大小重新整理为[batch_size, time_steps, features]
(在我的情况下:{ {1}})?那是对的吗?或者我错了吗?
答案 0 :(得分:1)
考虑使用Conv2D和MaxPool2D层构建CNN模型,直到到达Flatten层为止,因为Flatten层的矢量化输出将是您将数据输入到结构的LSTM部分。
因此,像这样构建您的CNN模型:
model_cnn = Sequential()
model_cnn.add(Conv2D...)
model_cnn.add(MaxPooling2D...)
...
model_cnn.add(Flatten())
现在,这很有趣,Keras的当前版本与某些TensorFlow结构不兼容,这些结构不允许您将整个层堆叠在一个顺序对象中。
因此,现在该使用Keras 模型对象来完成一个技巧的神经网络了:
input_lay = Input(shape=(None, ?, ?, ?)) #dimensions of your data
time_distribute = TimeDistributed(Lambda(lambda x: model_cnn(x)))(input_lay) # keras.layers.Lambda is essential to make our trick work :)
lstm_lay = LSTM(?)(time_distribute)
output_lay = Dense(?, activation='?')(lstm_lay)
最后,现在是时候将我们两个分离的模型放在一起了:
model = Model(inputs=[input_lay], outputs=[output_lay])
model.compile(...)
现在,在我们的OpenCV部分中,使用如下所示的算法直接对视频进行预处理,以便为您的网络构建大张量的帧:
video_folder = '/path.../'
X_data = []
y_data = []
list_of_videos = os.listdir(vide_folder)
for i in list_of_videos:
#Video Path
vid = str(video_folder + i) #path to each video from list1 = os.listdir(path)
#Reading the Video
cap = cv2.VideoCapture(vid)
#Reading Frames
#fps = vcap.get(5)
#To Store Frames
frames = []
for j in range(40): #here we get 40 frames, for example
ret, frame = cap.read()
if ret == True:
print('Class 1 - Success!')
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #converting to gray
frame = cv2.resize(frame,(30,30),interpolation=cv2.INTER_AREA)
frames.append(frame)
else:
print('Error!')
X_data.append(frames) #appending each tensor of 40 frames resized for 30x30
y_data.append(1) #appending a class label to the set of 40 frames
X_data = np.array(X_data)
y_data = np.array(y_data) #ready to split! :)
只需训练一下! :)
答案 1 :(得分:0)
如果合并来自不同视频的几个小序列以形成批处理,则模型的最后一层(RNN)的输出应该已经是[batch_size,window_size,num_classes]。基本上,您希望使用重塑层包装您的CNN,这将重叠每个批次的帧:
但是这会占用大量内存,因此您可以将批量大小设置为1,如果我理解正确,这就是您正在做的事情。在这种情况下,您可以省去第一次重塑。
我不确定上面的轴的顺序,但一般逻辑保持不变。
作为旁注:如果您打算在某些时候使用批量标准化,则可能需要提高批量大小,因为来自单个段的连续帧可能不会包含很多种类。同时仔细检查批量标准化轴,它应涵盖时间轴和批次轴。