CNN在keras中有多个conv3d

时间:2018-04-09 16:04:39

标签: tensorflow deep-learning keras conv-neural-network convolution

我正在尝试使用多个conv3d在Keras中创建一个CNN模型来处理cifar10数据集。但面临以下问题:

  

ValueError:('指定的大小包含值为< =的维度   0',( - 8000,256))

以下是我正在尝试执行的代码。

from __future__ import print_function
import keras
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv3D, MaxPooling3D
from keras.optimizers import SGD
import os
from keras import backend as K

batch_size = 128
num_classes = 10
epochs = 20
learning_rate = 0.01

(x_train, y_train), (x_test, y_test) = cifar10.load_data()
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
img_rows = x_train.shape[1]
img_cols = x_train.shape[2]
colors = x_train.shape[3]


if K.image_data_format() == 'channels_first':
    x_train = x_train.reshape(x_train.shape[0], 1,colors, img_rows, img_cols)
    x_test = x_test.reshape(x_test.shape[0], 1,colors, img_rows, img_cols)
    input_shape = (1, colors, img_rows, img_cols)
else:
    x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, colors, 1)
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, colors, 1)
    input_shape = (img_rows, img_cols, colors, 1)


# Convert class vectors to binary class matrices.
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

model = Sequential()
model.add(Conv3D(32, kernel_size=(3, 3, 3),activation='relu',input_shape=input_shape))
model.add(Conv3D(32, kernel_size=(3, 3, 3),activation='relu'))
model.add(MaxPooling3D(pool_size=(2, 2, 1)))
model.add(Dropout(0.25))
model.add(Conv3D(64, kernel_size=(3, 3, 3),activation='relu'))
model.add(Conv3D(64, kernel_size=(3, 3, 3),activation='relu'))
model.add(MaxPooling3D(pool_size=(2, 2, 1)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))

sgd=SGD(lr=learning_rate)


model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=sgd,
              metrics=['accuracy'])

history = model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(x_test, y_test))

score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

我尝试使用 conv3d并且工作,但准确性非常低。代码段如下:

model = Sequential()
model.add(Conv3D(32, kernel_size=(3, 3, 3),activation='relu',input_shape=input_shape))
model.add(MaxPooling3D(pool_size=(2, 2, 1)))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))

2 个答案:

答案 0 :(得分:0)

问题

问题在于颜色通道:它最初等于3,并且您正在应用大小为3padding='valid'的卷积。在第一个Conv3D之后,输出张量为:

(None, 30, 30, 1, 32)

......并且不能再对该维度应用卷积。您提供的简单示例仅仅是因为只有一个卷积层。

解决方案

一个选项是设置padding='same',以便保留张量形状:

(None, 32, 32, 3, 32)

然而,对我来说,颜色的卷积并没有增加很多价值,所以我选择这个模型:

model = Sequential()
model.add(Conv3D(32, kernel_size=(3, 3, 1), activation='relu', input_shape=input_shape))
model.add(Conv3D(32, kernel_size=(3, 3, 1), activation='relu'))
model.add(MaxPooling3D(pool_size=(2, 2, 1)))

model.add(Dropout(0.25))
model.add(Conv3D(64, kernel_size=(3, 3, 1), activation='relu'))
model.add(Conv3D(64, kernel_size=(3, 3, 1), activation='relu'))
model.add(MaxPooling3D(pool_size=(2, 2, 1)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dense(10, activation='softmax'))

答案 1 :(得分:0)

实际上,在卷积层中,维度会被保留,而在池化层中,您可以进行下采样。 问题是你在这里失去了维度。因此,您可以设置填充相同或使用 3X3过滤器和一个频道,而不是使用3个频道。