【问题标题】:Create 5-dimension input shape to 3d-CNN in python [duplicate]在python中为3d-CNN创建5维输入形状[重复]
【发布时间】:2019-02-26 12:15:59
【问题描述】:

我有一个包含 460 张图像的 15 类数据集。我想将每 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))

这是我的模型摘要:

但我收到以下错误:

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-dim,但我做不到。

【问题讨论】:

  • 根据tensorflow站点,conv3d层的输入应该是[batch, in_depth, in_height, in_width, in_channels]的格式。批处理是batch_sizein_depth 应该是no_of_images_at_a_time,在你的情况下是8in_heightin_width6060in_channels3。我可以看到这个in_depth 尺寸不存在,batch_size 相当大。这可能会导致问题吗?如果您不使用inputShape 提供图像,那么使用batch_input_shape=inputShape 是没有意义的。
  • @avin 谢谢你的回复。是的,我照你说的做。 h、w、ch 分别为 60、60、3。深度是8。但我不知道什么是批处理?因为我知道批次无法填充,keras已经知道了,所以我必须输入4D张量,而keras将其视为5D。但是它给了我一个错误,它期望有 5D 张量,当我将所有数据集图像的编号作为附加代码放置时,它也会给我关于 conv3d 的预期维度的错误。它指的是 (model.fit) 行,我想火车和测试数据的问题,它们必须是 5d 数组。你能帮我做点什么吗?

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


【解决方案1】:

如果我理解正确,您希望使用 8 张图像来拟合您的模型,这实际上称为 batch。所以当你调用model.fit()方法时设置batch_size = 8。我认为您感到困惑的另一点是输入形状。如果您想让图像适合网络,您的输入形状是图像的height x width 和通道数,在您的情况下为 RGB。所以,集合input_shape = (3, 60, 60)。请注意,网络结构不包括其中的图像总数。因为NN结构不需要知道训练数是多少。当您将训练图像拟合到网络时,它只需要 batch 并完成训练工作。最后,您需要使用 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'))

【讨论】:

  • 感谢您的回答。我按照您建议的 2DCNN 结构进行了 8 批大小,但我不确定它是否符合我的要求。我希望输入同时是 8 个图像(多输入 CNN),我认为这个结构会一张一张地处理图像,而 batch_size 是批的大小而不是输入的数量(多输入),所以我转向了 3DCNN。我的想法是真的还是我错了??即我可以使用 batch_size =8 作为多输入吗??
  • 是的,我做了与 2DCNN 相同的结构,但我不知道它是否真的做到了我想要的。我将图像裁剪为 8 段,我想同时将同一图像的所有(* 段)输入到相同的结构(多输入 CNN)中。如果我使用 2DCNN 结构并初始化 batch_size 8 对我来说有好处吗? batch_size 和 multi_input 是同一个概念吗?你能帮我么?我希望我的想法清晰易懂。
  • 我现在明白你的问题了。在我看来,你是对的,你应该使用 3D 卷积和池化层。但是,同样,输入形状将不包括训练图像的数量。如果我是你,我设置输入形状 (8, 60, 60, 3) 并添加 3d conv 和 pooling 层。然后,您可以使用任意数量的训练图像作为批处理调用 method.fit(),例如 16、32 或 64。
  • 我会试试的,谢谢。
猜你喜欢
  • 1970-01-01
  • 2020-10-20
  • 2021-05-19
  • 1970-01-01
  • 1970-01-01
  • 2018-08-23
  • 1970-01-01
  • 1970-01-01
  • 2019-09-04
相关资源
最近更新 更多