Resnet与自定义数据

时间:2018-03-09 15:34:16

标签: python-3.x keras classification resnet

我正在尝试使用我的自定义数据修改Resnet50,如下所示:

X = [[1.85, 0.460,... -0.606] ... [0.229, 0.543,... 1.342]] 
y = [2, 4, 0, ... 4, 2, 2]

X是784幅图像的长度为2000的特征向量。 y是一个大小为784的数组,包含标签的二进制表示。

以下是代码:

def __classifyRenet(self, X, y):
    image_input = Input(shape=(2000,1))
    num_classes = 5
    model = ResNet50(weights='imagenet',include_top=False)
    model.summary()
    last_layer = model.output
    # add a global spatial average pooling layer
    x = GlobalAveragePooling2D()(last_layer)
    # add fully-connected & dropout layers
    x = Dense(512, activation='relu',name='fc-1')(x)
    x = Dropout(0.5)(x)
    x = Dense(256, activation='relu',name='fc-2')(x)
    x = Dropout(0.5)(x)
    # a softmax layer for 5 classes
    out = Dense(num_classes, activation='softmax',name='output_layer')(x)

    # this is the model we will train
    custom_resnet_model2 = Model(inputs=model.input, outputs=out)

    custom_resnet_model2.summary()

    for layer in custom_resnet_model2.layers[:-6]:
        layer.trainable = False

    custom_resnet_model2.layers[-1].trainable

    custom_resnet_model2.compile(loss='categorical_crossentropy',
                                 optimizer='adam',metrics=['accuracy'])
    clf = custom_resnet_model2.fit(X, y,
                                    batch_size=32, epochs=32, verbose=1,
                                    validation_data=(X, y))
    return clf

我打电话给:

clf = self.__classifyRenet(X_train, y_train)

发出错误:

ValueError: Error when checking input: expected input_24 to have 4 dimensions, but got array with shape (785, 2000)

请帮忙。谢谢!

1 个答案:

答案 0 :(得分:3)

1. First, understand the error.

Your input does not match the input of ResNet, for ResNet, the input should be (n_sample, 224, 224, 3) but you are having (785, 2000). From your question, you have 784 images with array of size 2000, which doesn't really align with the original ResNet50 input shape of (224 x 224) no matter how you reshape it. That means you cannot use the ResNet50 directly with your data. The only thing you did in your code is to take the last layer of ResNet50 and added you output layer to align with your output class size.

2. Then, what you can do.

If you insist to use the ResNet architecture, you will need to change the input layer rather than output layer. Also, you will need to reshape your image data to utilize the convolution layers. That means, you cannot have it in a (2000,) array, but need to be something like (height, width, channel), just like what ResNet and other architectures are doing. Of course you will also need to change the output layer as well just like you did so that you are predicting for your classes. Try something like:

model = ResNet50(input_tensor=image_input_shape, include_top=True,weights='imagenet')

This way, you can specify customized input image shape. You can check the github code for more information (https://github.com/keras-team/keras/blob/master/keras/applications/resnet50.py). Here's part of the docstring:

input_shape: optional shape tuple, only to be specified
    if `include_top` is False (otherwise the input shape
    has to be `(224, 224, 3)` (with `channels_last` data format)
    or `(3, 224, 224)` (with `channels_first` data format).
    It should have exactly 3 inputs channels,
    and width and height should be no smaller than 197.
    E.g. `(200, 200, 3)` would be one valid value.