【问题标题】:Correcting input dimensions for CNN, LSTM based classifier using Keras, Python使用 Keras、Python 校正 CNN、基于 LSTM 的分类器的输入尺寸
【发布时间】:2020-01-11 23:42:18
【问题描述】:

我正在为网络流量分类目的实现 2D(可能是 1D)CNN+ LSTM 分类器。 CNN 本质上将用作特征提取器,LSTM 将用于分类。

我使用了 TimeDistributed 层来帮助将 CNN 和 LSTM 层组合在一起(附代码。) 由于输入大小动态变化,因此数据点的数量已用无表示。 no_rows=20(每个流考虑分类的数据包数) no_cols=7(每个数据包考虑的特征数)

尽管使用了 TimeDistributed 层包装,但我仍面临一些输入维度问题。不太清楚如何解决这个问题。

使用 Reshape 作为图层来解决此问题是我遇到的众多修复之一,但没有奏效。请告诉我如何构建这个结构以及如何修复我的代码。

谢谢!

(使用基于 Linux 的 AWS 实例、Ubuntu 16.04 和 Tensorflow 后端来实现代码)

  1. 使用来自 Keras 核心层的 Reshape 层来修复 CNN 的输出,但没有解决问题。
  2. 由于存在动态变化的输入大小,不得不移除 Flatten 层并将其替换为 GlobalMaxPooling2D 层。
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size = 0.30, random_state = 36)

model = Sequential()

# Adding CNN Model layers

model.add(TimeDistributed(Conv2D(32, kernel_size = (4 , 2), strides = 1, padding='valid', activation = 'relu', input_shape = (None,20,7,1))))
model.add(TimeDistributed(BatchNormalization()))
model.add(TimeDistributed(Conv2D(64, kernel_size = (4 , 2), strides = 1, padding='valid', activation = 'relu')))
model.add(TimeDistributed(BatchNormalization()))
#model.add(TimeDistributed(Reshape((-1,1))))
model.add(TimeDistributed(GlobalMaxPooling2D()))
#model.add(Reshape((1,1)))

# Adding LSTM layers

model.add(LSTM(128, recurrent_dropout=0.2))
model.add(Dropout(rate = 0.2))
model.add(Dense(100))
model.add(Dropout(rate = 0.4))
model.add(Dense(108))

model.add(Dense(num_classes,activation='softmax'))


# Compiling this model

model.compile(loss = 'categorical_crossentropy', optimizer='adam',metrics = ['accuracy'])
#print(model.summary())

#Training the Network

history = model.fit(X_train, Y_train, batch_size=32, epochs = 1, validation_data=(X_test, Y_test))

运行上面提到的代码 sn-p 我遇到以下错误消息:

"Input tensor must be of rank 3, 4 or 5 but was {}.".format(n + 2))
ValueError: Input tensor must be of rank 3, 4 or 5 but was 2.

【问题讨论】:

  • 请检查 xtrain 的输入形状,它应该是 input_shape = (None,20,7,1) 的矩阵

标签: python tensorflow keras deep-learning


【解决方案1】:

您可以做的一件事是从您的视频源制作一批固定输入(帧数)并进行处理。这样做的代码是:

def get_data(video_source, batch_size):
    x_data = []
    #Reading the Video from file path
    cap = cv2.VideoCapture(video_source)    
    for i in range(batch_size):
        #To Store Frames
        frames = []
        for j in range(frame_to_process): #here we get frame_to_process
            ret, frame = cap.read()
            if not ret:
                # print('No frames found!')
                break
            # converting to frmae gray
            # frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 
            # resizing frame to a particular input shape
            # frame = cv2.resize(frame,(30,30),interpolation=cv2.INTER_AREA)
            frames.append(frame)
        # appending each batch
        x_data.append(frames)
    return x_data

# number of frames in each batch
frame_to_process = 30
# size of each batch
batch_size = 32
# make batch of video inputs
X_data = np.array(get_data(video_source, batch_size, frame_to_process))

提示:另外,您可以使用ConvLSTM,而不是使用Conv2DConvLSTM,这可以稍微提高性能。

无论如何,如果您想动态处理帧,您可以将代码转换为具有Dynamic Graphs 的 Pytorch,您可以在其中提供可变批量大小的输入。

【讨论】:

    猜你喜欢
    • 2018-09-18
    • 2019-02-04
    • 2018-08-19
    • 2022-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    相关资源
    最近更新 更多