在LSTM

时间:2018-04-05 08:57:38

标签: python tensorflow deep-learning lstm

这是我第一次使用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}})?那是对的吗?或者我错了吗?

2 个答案:

答案 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,这将重叠每个批次的帧:

  • 输入 - > [batch_size,window_size,nchannels,height,width]
  • 重塑 - > [batch_size * window_size,nchannels,height,width]
  • CNN - > [batch_size * window_size,feat_size]
  • 重塑 - > [batch_size,window_size,feats_size]
  • RNN - > [batch_size,window_size,num_outputs](假设按帧预测)

但是这会占用大量内存,因此您可以将批量大小设置为1,如果我理解正确,这就是您正在做的事情。在这种情况下,您可以省去第一次重塑。

我不确定上面的轴的顺序,但一般逻辑保持不变。

作为旁注:如果您打算在某些时候使用批量标准化,则可能需要提高批量大小,因为来自单个段的连续帧可能不会包含很多种类。同时仔细检查批量标准化轴,它应涵盖时间轴和批次轴。