raghakot / keras-resnet

Residual networks implementation using Keras-1.0 functional API
Other
1.39k stars 616 forks source link

Stride cannot be greater than or equal to filter size #3

Closed MdAsifKhan closed 7 years ago

MdAsifKhan commented 8 years ago

I think there is a bug, filter size should be greater then subsample length. After block1 init_subsample is 2X2 line no. 48: conv_1_1 = _bn_relu_conv(nb_filters, 1, 1, subsample=init_subsample)(input) filter size = (1,1) stride = (2,2) for block2, 3 and 4 block2 = _residual_block(block_fn, nb_filters=128, repetations=4)(block1) block3 = _residual_block(block_fn, nb_filters=256, repetations=6)(block2) block4 = _residual_block(block_fn, nb_filters=512, repetations=3)(block3)

def f(input): for i in range(repetations): init_subsample = (1, 1) if i == 0 and not is_first_layer: ---> init_subsample = (2, 2) input = block_function(nb_filters=nb_filters, init_subsample=init_subsample)(input) return input

MdAsifKhan commented 8 years ago

I think issue seems to be at line no. 79 if stride_width > 1 or stride_height > 1 or not equal_channels: shortcut = Convolution2D(nb_filter=residual._keras_shape[1], nb_row=1, nb_col=1, subsample=(stride_width, stride_height), init="he_normal", border_mode="valid")(input) Subsampling size in shortcut should be (1,1).

raghakot commented 8 years ago

Can you post a gist of what you are trying? Are you having issues running the current code? If you are using python3, try from future import division

MdAsifKhan commented 8 years ago

Hi @raghakot , I am just using the given example with cifar10 dataset. While running I get the following error: Stride should be less than or equal to filter size.

I tried debugging the code: in your bottleneck function you apply convolution of 1x1. conv_1_1 = _bn_relu_conv(nb_filters, 1, 1, subsample=init_subsample)(input) This works fine for the first layer but after that for other layers
init_subsample = (2, 2) (line number 93) Here you are applying convolution of 1x1 with stride of 2. This seems to create an error.

raghakot commented 8 years ago

cifar 10 has input shape of 2, 32, 32. The example works on 3, 224, 224. You would need to change that. Also, you cannot has as many layers because conv and pooling layers reduce size.

Do you have a gist i can look at? Here is the modified example for cifar 10:

def resnet_cifar10():
    input = Input(shape=(3, 32, 32))
    conv1 = _conv_bn_relu(nb_filters=32, nb_row=3, nb_col=3, subsample=(2, 2))(input)
    pool1 = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), border_mode="same")(conv1)

    # Build residual blocks..
    block_fn = _basic_block
    n = 2
    block1 = _residual_block(block_fn, nb_filters=32, rep=2 * n, is_first_layer=True)(pool1)
    block2 = _residual_block(block_fn, nb_filters=16, rep=2 * n)(block1)
    block3 = _residual_block(block_fn, nb_filters=8, rep=2 * n)(block2)

    # Classifier block
    pool2 = AveragePooling2D(pool_size=(7, 7), strides=(1, 1), border_mode="same")(block3)
    flatten1 = Flatten()(pool2)
    dense = Dense(output_dim=10, init="he_uniform", activation="softmax")(flatten1)

    model = Model(input=input, output=dense)
    return model

I think I will implement a class to handle building various configurations of resnet to avoid these kind of issues.

raghakot commented 7 years ago

I updated the code to include ResNetBuilder factory class. You can now build your own resnet architecture with variable input sizes and layers