[英]Keras fit_generator : Error when checking target: expected activation_32 to have 4 dimensions, but got array with shape (4, 4)
[英]Keras(FIT_GENERATOR)- Error, when checking target: expected activation_1 to have 3 dimensions, but got array with shape (32, 416, 608, 3)
我已经研究分割问题很多天了,在终于找到了如何正确读取数据集之后,我遇到了这个问题:
ValueError: Error when checking target: expected activation_1(Softmax) to have 3 dimensions, but got array with shape
(32, 416, 608, 3)
I used the functional API, since I took the FCNN architecture from [here](https://github.com/divamgupta/image-segmentation-keras/blob/master/Models/FCN32.py).
它根据我的任务(IMAGE_ORDERING =“channels_last”(TensorFlow后端))稍微修改和改编。 任何人都可以帮助我吗? 提前致谢。 下面的架构适用于 FCNN,我尝试实现它以实现分割。 这是架构(在调用 model.summary() 之后):
1.
2.
具体错误是:
“导入数据集”功能:
“Fit_Generator 方法调用”:
img_input = Input(shape=(input_height,input_width,3)) #Block 1 x = Convolution2D(64, (3, 3), activation='relu', padding='same', name='block1_conv1', data_format=IMAGE_ORDERING)(img_input) x = BatchNormalization()(x) x = Convolution2D(64, (3, 3), activation='relu', padding='same', name='block1_conv2', data_format=IMAGE_ORDERING)(x) x = BatchNormalization()(x) x = MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool', data_format=IMAGE_ORDERING)(x) f1 = x # Block 2 x = Convolution2D(128, (3, 3), activation='relu', padding='same', name='block2_conv1', data_format=IMAGE_ORDERING)(x) x = BatchNormalization()(x) x = Convolution2D(128, (3, 3), activation='relu', padding='same', name='block2_conv2', data_format=IMAGE_ORDERING)(x) x = BatchNormalization()(x) x = MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool', data_format=IMAGE_ORDERING )(x) f2 = x # Block 3 x = Convolution2D(256, (3, 3), activation='relu', padding='same', name='block3_conv1', data_format=IMAGE_ORDERING)(x) x = BatchNormalization()(x) x = Convolution2D(256, (3, 3), activation='relu', padding='same', name='block3_conv2', data_format=IMAGE_ORDERING)(x) x = BatchNormalization()(x) x = Convolution2D(256, (3, 3), activation='relu', padding='same', name='block3_conv3', data_format=IMAGE_ORDERING)(x) x = BatchNormalization()(x) x = MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool', data_format=IMAGE_ORDERING )(x) f3 = x # Block 4 x = Convolution2D(512, (3, 3), activation='relu', padding='same', name='block4_conv1', data_format=IMAGE_ORDERING)(x) x = BatchNormalization()(x) x = Convolution2D(512, (3, 3), activation='relu', padding='same', name='block4_conv2',data_format=IMAGE_ORDERING)(x) x = BatchNormalization()(x) x = Convolution2D(512, (3, 3), activation='relu', padding='same', name='block4_conv3',data_format=IMAGE_ORDERING)(x) x = BatchNormalization()(x) x = MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool', data_format=IMAGE_ORDERING)(x) f4 = x # Block 5 x = Convolution2D(512, (3, 3), activation='relu', padding='same', name='block5_conv1', data_format=IMAGE_ORDERING)(x) x = BatchNormalization()(x) x = Convolution2D(512, (3, 3), activation='relu', padding='same', name='block5_conv2',data_format=IMAGE_ORDERING)(x) x = BatchNormalization()(x) x = Convolution2D(512, (3, 3), activation='relu', padding='same', name='block5_conv3', data_format=IMAGE_ORDERING)(x) x = BatchNormalization()(x) x = MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool', data_format=IMAGE_ORDERING)(x) f5 = x x = (Convolution2D(4096,(7,7) , activation='relu' , padding='same', data_format=IMAGE_ORDERING))(x) x = Dropout(0.5)(x) x = (Convolution2D(4096,(1,1) , activation='relu' , padding='same',data_format=IMAGE_ORDERING))(x) x = Dropout(0.5)(x) #First parameter = number of classes+1 (de la background) x = (Convolution2D(20,(1,1) ,kernel_initializer='he_normal' ,data_format=IMAGE_ORDERING))(x) x = Convolution2DTranspose(20,kernel_size=(64,64), strides=(32,32),use_bias=False,data_format=IMAGE_ORDERING)(x) o_shape = Model(img_input,x).output_shape outputHeight = o_shape[1] print('Output Height is:', outputHeight) outputWidth = o_shape[2] print('Output Width is:', outputWidth) #https://keras.io/layers/core/#reshape x = (Reshape((20,outputHeight*outputWidth)))(x) #https://keras.io/layers/core/#permute x = (Permute((2, 1)))(x) print("Output shape before softmax is", o_shape) x = (Activation('softmax'))(x) print("Output shape after softmax is", o_shape) model = Model(inputs = img_input,outputs = x) model.outputWidth = outputWidth model.outputHeight = outputHeight model.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics =['accuracy'])
FCNN 架构示例中的原始代码适用于(416, 608)
的输入维度。 而在您的代码中,输入维度是(192, 192)
(忽略通道维度)。 现在如果你仔细观察,这个特殊的层
x = MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool', data_format=IMAGE_ORDERING)(x)
生成维度(6, 6)
的输出(您可以在model.summary()
进行验证)。
下一个卷积层
o = (Convolution2D(4096,(7,7) , activation='relu' , padding='same', data_format=IMAGE_ORDERING))(o)
使用大小为(7, 7)
卷积滤波器,但您的输入已经减小到小于该大小(即(6, 6)
)。 尝试先修复它。
此外,如果您查看model.summary()
输出,您会注意到它不包含在block5_pool层之后定义的层。 其中有一个transposed convolution
层(它基本上对您的输入进行了上采样)。 您可能想看看并尝试解决这个问题。
注意:在我所有的维度中,我都忽略了通道维度。
编辑下面的详细答案
首先,这是我的keras.json
文件。 它使用Tensorflow后端,在channel_last设置image_ordering
。
{
"floatx": "float32",
"epsilon": 1e-07,
"backend": "tensorflow",
"image_data_format": "channels_last"
}
接下来,我复制粘贴我的确切型号代码。 请特别注意下面代码中的内联注释。
from keras.models import *
from keras.layers import *
IMAGE_ORDERING = 'channels_last' # In consistency with the json file
def getFCN32(nb_classes = 20, input_height = 416, input_width = 608):
img_input = Input(shape=(input_height,input_width, 3)) # Expected input will have channel in the last dimension
#Block 1
x = Convolution2D(64, (3, 3), activation='relu', padding='same', name='block1_conv1', data_format=IMAGE_ORDERING)(img_input)
x = BatchNormalization()(x)
x = Convolution2D(64, (3, 3), activation='relu', padding='same', name='block1_conv2', data_format=IMAGE_ORDERING)(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool', data_format=IMAGE_ORDERING)(x)
f1 = x
# Block 2
x = Convolution2D(128, (3, 3), activation='relu', padding='same', name='block2_conv1', data_format=IMAGE_ORDERING)(x)
x = BatchNormalization()(x)
x = Convolution2D(128, (3, 3), activation='relu', padding='same', name='block2_conv2', data_format=IMAGE_ORDERING)(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool', data_format=IMAGE_ORDERING )(x)
f2 = x
# Block 3
x = Convolution2D(256, (3, 3), activation='relu', padding='same', name='block3_conv1', data_format=IMAGE_ORDERING)(x)
x = BatchNormalization()(x)
x = Convolution2D(256, (3, 3), activation='relu', padding='same', name='block3_conv2', data_format=IMAGE_ORDERING)(x)
x = BatchNormalization()(x)
x = Convolution2D(256, (3, 3), activation='relu', padding='same', name='block3_conv3', data_format=IMAGE_ORDERING)(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool', data_format=IMAGE_ORDERING )(x)
f3 = x
# Block 4
x = Convolution2D(512, (3, 3), activation='relu', padding='same', name='block4_conv1', data_format=IMAGE_ORDERING)(x)
x = BatchNormalization()(x)
x = Convolution2D(512, (3, 3), activation='relu', padding='same', name='block4_conv2',data_format=IMAGE_ORDERING)(x)
x = BatchNormalization()(x)
x = Convolution2D(512, (3, 3), activation='relu', padding='same', name='block4_conv3',data_format=IMAGE_ORDERING)(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool', data_format=IMAGE_ORDERING)(x)
f4 = x
# Block 5
x = Convolution2D(512, (3, 3), activation='relu', padding='same', name='block5_conv1', data_format=IMAGE_ORDERING)(x)
x = BatchNormalization()(x)
x = Convolution2D(512, (3, 3), activation='relu', padding='same', name='block5_conv2',data_format=IMAGE_ORDERING)(x)
x = BatchNormalization()(x)
x = Convolution2D(512, (3, 3), activation='relu', padding='same', name='block5_conv3', data_format=IMAGE_ORDERING)(x)
x = BatchNormalization()(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool', data_format=IMAGE_ORDERING)(x)
f5 = x
x = (Convolution2D(4096,(7,7) , activation='relu' , padding='same', data_format=IMAGE_ORDERING))(x)
x = Dropout(0.5)(x)
x = (Convolution2D(4096,(1,1) , activation='relu' , padding='same',data_format=IMAGE_ORDERING))(x)
x = Dropout(0.5)(x)
x = (Convolution2D(20,(1,1) ,kernel_initializer='he_normal' ,data_format=IMAGE_ORDERING))(x)
x = Convolution2DTranspose(20,kernel_size=(64,64), strides=(32,32),use_bias=False,data_format=IMAGE_ORDERING)(x)
o_shape = Model(img_input, x).output_shape
# NOTE: Since this is channel last dimension ordering, the height and width dimensions are along [1] and [2], not [2] and [3]
outputHeight = o_shape[1]
outputWidth = o_shape[2]
x = (Reshape((outputHeight*outputWidth, 20)))(x) # Channel should be along the last dimenion of reshape
# No need of permute layer anymore
print("Output shape before softmax is", o_shape)
x = (Activation('softmax'))(x)
print("Output shape after softmax is", o_shape)
model = Model(inputs = img_input,outputs = x)
model.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics =['accuracy'])
return model
model = getFCN32(20)
print(model.summary())
接下来,我将提供我的model.summary()
外观的片段。 如果你看一下最后几层,它是这样的:
因此,这意味着,该conv2d_transpose
层产生尺寸的输出(448, 640, 20)
并在其上施加前SOFTMAX变平出来。 所以输出的维度是(286720, 20)
。 同样,您的target_generator
(在您的情况下为mask_generator
)也应该生成类似维度的目标。 同样,您的input_generator
也应该生成大小为[batch size, input_height,input_width, 3]
输入批次,如函数的img_input
中所述。
希望这将帮助您找到问题的根源并找出合适的解决方案。 请查看代码中的细微变化(以及内嵌注释)以及如何创建输入和目标批次。
我再次尝试使用 SegNet 架构,但我得到了完全相同的错误。 看来这不是架构问题,而是来自 fit_generator && 来自使用掩码的问题。
更新:通过向神经网络提供正确形式的输入掩码解决了该问题。
您可能在flow_from_directory()
调用中缺少color_mode='grayscale'
掩码。 RGB 是color_mode
的默认值。
flow_args = dict(
batch_size=batch_size,
target_size=target_size,
class_mode=None,
seed=seed)
image_generator = image_datagen.flow_from_directory(
image_dir, subset='training', **flow_args)
mask_generator = mask_datagen.flow_from_directory(
mask_dir, subset='training', color_mode='grayscale', **flow_args)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.