在python中为3d-CNN创建5维输入形状

时间:2019-02-26 12:15:59

标签: python keras deep-learning conv-neural-network

我有一个15类的数据集,全部包含460张图像。我想同时将每8个图像序列输入相同的CNN结构。我使用conv3d来做到这一点,但是我对输入形状感到困惑,它返回错误。 这是我的模型:

IMAGE_DIMS = (8, 460, 60, 60, 3)
data = []
labels = []

# loading images...
imagePaths = "dataset\\path"
listing = os.listdir(imagePaths)

for imagePath in listing:

    image_fold = os.listdir(imagePaths + "\\" + imagePath)
    for file in image_fold:
        im = (imagePaths + "\\" + imagePath + "\\" + file)
        image = cv2.imread(im)
        image = cv2.resize(image, (IMAGE_DIMS[2], IMAGE_DIMS[3]))
        image = img_to_array(image)
        data.append(image)

        label= imagePath.split(os.path.sep)[-1]
        labels.append(label)
# scale the raw pixel intensities to the range [0, 1]
data = np.array(data, dtype="float") / 255.0
labels = np.array(labels)

# binarize the labels
lb = LabelBinarizer()
labels = lb.fit_transform(labels)
(trainX, testX, trainY, testY) =     train_test_split(data, labels, test_size=0.2, random_state=42)


model = Sequential()
sample= IMAGE_DIMS[0]
frame=IMAGE_DIMS[1]
height = IMAGE_DIMS[2]
width=IMAGE_DIMS[3]
channels=IMAGE_DIMS[4]
classes=len(lb.classes_)

inputShape = (sample, frame, height, width, channels)
chanDim = -1

if K.image_data_format() == "channels_first":
    inputShape = (sample, frame, channels, height, width)
    chanDim = 1

model.add(Conv3D(32, (3, 3, 3),    padding="same", batch_input_shape=inputShape))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling3D(pool_size=(2, 2, 2),    padding="same", data_format="channels_last"))
model.add(Dropout(0.25))

model.add(Conv3D(64, (3, 3, 3), padding="same"))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling3D(pool_size=(2, 2, 2),    padding="same", data_format="channels_last"))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(128))
model.add(Activation("relu"))
model.add(BatchNormalization())
model.add(Dropout(0.5))

# softmax classifier
model.add(Dense(classes))
model.add(Activation("softmax"))
model.summary()

opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)
  model.compile(loss="categorical_crossentropy",   optimizer= opt, metrics=["accuracy"])

H = model.fit(trainX, trainY, batch_size=BS, epochs=EPOCHS, verbose=1,validation_data (testX,testY))

这是我的模型摘要: enter image description here

但是出现以下错误:

ValueError: Error when checking input: expected conv3d_1_input to have 5 dimensions, but got array with shape (368, 60, 60, 3)

我该如何解决错误,有人可以帮助我,我将非常感谢您的帮助。我知道输入形状的问题,编译器参考了model.fit步骤。我认为trainX,testX,trainY和testY必须在5维中,但我无法做到这一点。

1 个答案:

答案 0 :(得分:0)

如果我的理解正确,您希望使用8张图像来拟合模型,这实际上称为批处理。因此,当您调用方法model.fit()时,请设置batch_size = 8。我想您还感到困惑的另一点是输入形状。如果您要使图像适合网络,则输入形状为图像的height x width和通道数(在您的情况下为RGB)。因此,集合input_shape = (3, 60, 60)。请注意,网络结构中未包含图片总数。因为NN结构不需要知道什么是训练编号。当您将训练图像适合网络时,只需将其批处理并执行训练工作即可。最后,您需要使用2D来代替3D卷积层。可以将其视为在训练图像上移动的2D框架,并针对每个通道进行移动。因此,帧大小需要具有2D形状,将其设置为(x, x)。该帧在documents中称为内核。

以下代码仅是示例,未经测试。我希望它有助于理解结构:

model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(3, 60, 60)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(number_of_classes))
model.add(Activation('softmax'))