MxnetError: Error in operator pool92_fwd: [19:56:02] src/operator/nn/pooling.cc:145: Check failed: param.kernel[1] <= dshape[3] + 2 * param.pad[1] kernel size (2) exceeds input (1 padded to 1)
I am porting a Unet keras implementation to mxnet. My shapes now match.
Keras:
conv1 Tensor("activation_5/Relu:0", shape=(32, 101, 101, 16), dtype=float32)
pool1 Tensor("dropout_1/cond/Merge:0", shape=(32, 50, 50, 16), dtype=float32)
conv2 Tensor("activation_10/Relu:0", shape=(32, 50, 50, 32), dtype=float32)
pool2 Tensor("dropout_2/cond/Merge:0", shape=(32, 25, 25, 32), dtype=float32)
conv3 Tensor("activation_15/Relu:0", shape=(32, 25, 25, 64), dtype=float32)
pool3 Tensor("dropout_3/cond/Merge:0", shape=(32, 12, 12, 64), dtype=float32)
conv4 Tensor("activation_20/Relu:0", shape=(32, 12, 12, 128), dtype=float32)
pool4 Tensor("dropout_4/cond/Merge:0", shape=(32, 6, 6, 128), dtype=float32)
convm Tensor("activation_25/Relu:0", shape=(32, 6, 6, 256), dtype=float32)
deconv4 Tensor("conv2d_transpose_1/BiasAdd:0", shape=(32, 12, 12, 128), dtype=float32)
uconv4 Tensor("dropout_5/cond/Merge:0", shape=(32, 12, 12, 256), dtype=float32)
uconv4 Tensor("activation_30/Relu:0", shape=(32, 12, 12, 128), dtype=float32)
deconv3 Tensor("conv2d_transpose_2/BiasAdd:0", shape=(32, 25, 25, 64), dtype=float32)
uconv3 Tensor("dropout_6/cond/Merge:0", shape=(32, 25, 25, 128), dtype=float32)
uconv3 Tensor("activation_35/Relu:0", shape=(32, 25, 25, 64), dtype=float32)
deconv2 Tensor("conv2d_transpose_3/BiasAdd:0", shape=(32, 50, 50, 32), dtype=float32)
uconv2 Tensor("concatenate_3/concat:0", shape=(32, 50, 50, 64), dtype=float32)
uconv2 Tensor("activation_40/Relu:0", shape=(32, 50, 50, 32), dtype=float32)
deconv1 Tensor("conv2d_transpose_4/BiasAdd:0", shape=(32, 101, 101, 16), dtype=float32)
uconv1 Tensor("concatenate_4/concat:0", shape=(32, 101, 101, 32), dtype=float32)
uconv1 Tensor("activation_45/Relu:0", shape=(32, 101, 101, 16), dtype=float32)
output_layer Tensor("activation_46/Sigmoid:0", shape=(32, 101, 101, 1), dtype=float32)
Mxnet:
conv1 [(32, 16, 101, 101)]
pool1 [(32, 16, 50, 50)]
conv2 [(32, 32, 50, 50)]
pool2 [(32, 32, 25, 25)]
conv3 [(32, 64, 25, 25)]
pool3 [(32, 64, 12, 12)]
conv4 [(32, 128, 12, 12)]
pool4 [(32, 128, 6, 6)]
convm (32, 256, 6, 6)
deconv4 [(32, 128, 12, 12)]
uconv4 [(32, 256, 12, 12)]
uconv4 [(32, 128, 12, 12)]
deconv3 [(32, 64, 25, 25)]
uconv3 [(32, 128, 25, 25)]
uconv3 [(32, 64, 25, 25)]
deconv2 [(32, 32, 50, 50)]
uconv2 [(32, 64, 50, 50)]
uconv2 [(32, 32, 50, 50)]
deconv1 [(32, 16, 101, 101)]
uconv1 [(32, 32, 101, 101)]
uconv1 [(32, 16, 101, 101)]
output_layer [(32, 1, 101, 101)]
However, the dimension check in the subject shows up when calling fit. I am trying to debug from source but when building master, it thinks it is using cuda-9.2. I am assuming I can’t build master for cuda-9.1?
I am new to mxnet so maybe there is something obviously wrong that I am doing and just haven’t experienced yet. Here is my model source:
def build_model(input_layer, start_neurons, DropoutRatio = 0.5):
# 101 -> 50
k_size = (3, 3)
same_padding = (k_size[0]//2, k_size[1]//2)
#input_layer = mx.sym.transpose(input_layer, [0, 3, 1, 2])
conv1 = mx.gluon.nn.Conv2D(start_neurons * 1, kernel_size=k_size, padding=same_padding)(input_layer)
#print('conv1', conv1.infer_shape(data=(32, 1, 101, 101))[1])
conv1 = residual_block(conv1,start_neurons * 1)
#print('conv1', conv1.infer_shape(data=(32, 16, 101, 101))[1])
conv1 = residual_block(conv1,start_neurons * 1, True)
print('conv1', conv1.infer_shape(data=(32, 1, 101, 101))[1])
pool1 = mx.gluon.nn.MaxPool2D()(conv1) #(2, 2)
#print('pool1', pool1.infer_shape(data=(32, 16, 101, 101))[1])
pool1 = mx.gluon.nn.Dropout(DropoutRatio/2)(pool1)
print('pool1', pool1.infer_shape(data=(32, 1, 101, 101))[1])
# 50 -> 25
conv2 = mx.gluon.nn.Conv2D(start_neurons * 2, kernel_size=k_size, padding=same_padding)(pool1)
conv2 = residual_block(conv2,start_neurons * 2)
conv2 = residual_block(conv2,start_neurons * 2, True)
print('conv2', conv2.infer_shape(data=(32, 1, 101, 101))[1])
pool2 = mx.gluon.nn.MaxPool2D()(conv2)
pool2 = mx.gluon.nn.Dropout(DropoutRatio)(pool2)
print('pool2', pool2.infer_shape(data=(32, 1, 101, 101))[1])
# 25 -> 12
conv3 = mx.gluon.nn.Conv2D(start_neurons * 4, kernel_size=k_size, padding=same_padding)(pool2)
conv3 = residual_block(conv3,start_neurons * 4)
conv3 = residual_block(conv3,start_neurons * 4, True)
print('conv3', conv3.infer_shape(data=(32, 1, 101, 101))[1])
pool3 = mx.gluon.nn.MaxPool2D()(conv3)
pool3 = mx.gluon.nn.Dropout(DropoutRatio)(pool3)
print('pool3', pool3.infer_shape(data=(32, 1, 101, 101))[1])
# 12 -> 6
conv4 = mx.gluon.nn.Conv2D(start_neurons * 8, kernel_size=k_size, padding=same_padding)(pool3)
conv4 = residual_block(conv4,start_neurons * 8)
conv4 = residual_block(conv4,start_neurons * 8, True)
print('conv4', conv4.infer_shape(data=(32, 1, 101, 101))[1])
pool4 = mx.gluon.nn.MaxPool2D()(conv4)
pool4 = mx.gluon.nn.Dropout(DropoutRatio)(pool4)
print('pool4', pool4.infer_shape(data=(32, 1, 101, 101))[1])
# Middle
convm = mx.gluon.nn.Conv2D(start_neurons * 16, kernel_size=k_size, padding=same_padding)(pool4)
convm = residual_block(convm,start_neurons * 16)
convm = residual_block(convm,start_neurons * 16, True)
convm_output_shape = convm.infer_shape(data=(32, 1, 101, 101))[1][0]
print('convm', convm_output_shape)
# 6 -> 12
#same_padding_22_stride = \
# calc_same_padding(convm_output_shape[2], convm_output_shape[3],
# k_size[0], k_size[1], (2, 2))
deconv4 = mx.gluon.nn.Conv2DTranspose(start_neurons * 8, kernel_size=k_size, strides=(2, 2),
padding=(1, 1), output_padding=(1, 1))(convm)
# strides=(2, 2)
uconv4 = mx.sym.concat(deconv4, conv4,dim=1) #concatenate([deconv4, conv4])
uconv4 = mx.gluon.nn.Dropout(DropoutRatio)(uconv4)
print('deconv4', deconv4.infer_shape(data=(32, 1, 101, 101))[1])
print('uconv4', uconv4.infer_shape(data=(32, 1, 101, 101))[1])#(32, 128, 12, 12)
uconv4 = mx.gluon.nn.Conv2D(start_neurons * 8, kernel_size=k_size, padding=same_padding)(uconv4)
uconv4 = residual_block(uconv4,start_neurons * 8)
uconv4 = residual_block(uconv4,start_neurons * 8, True)
print('uconv4', uconv4.infer_shape(data=(32, 1, 101, 101))[1])
#print('uconv4', uconv4.infer_shape(data=(32, 16, 101, 101))[1])
# 12 -> 25
#deconv3 = Conv2DTranspose(start_neurons * 4, (3, 3), strides=(2, 2), padding="same")(uconv4)
deconv3 = mx.gluon.nn.Conv2DTranspose(start_neurons * 4, kernel_size=k_size,
strides=(2, 2))(uconv4) # padding="valid"
uconv3 = mx.sym.concat(deconv3, conv3,dim=1)
uconv3 = mx.gluon.nn.Dropout(DropoutRatio)(uconv3)
print('deconv3', deconv3.infer_shape(data=(32, 1, 101, 101))[1])
print('uconv3', uconv3.infer_shape(data=(32, 1, 101, 101))[1])
uconv3 = mx.gluon.nn.Conv2D(start_neurons * 4, kernel_size=k_size, padding=same_padding)(uconv3)
uconv3 = residual_block(uconv3,start_neurons * 4)
uconv3 = residual_block(uconv3,start_neurons * 4, True)
print('uconv3', uconv3.infer_shape(data=(32, 1, 101, 101))[1])
#print('uconv3', uconv3.infer_shape(data=(32, 16, 101, 101))[1])
# 25 -> 50
deconv2 = mx.gluon.nn.Conv2DTranspose(start_neurons * 2, kernel_size=k_size, strides=(2, 2),
padding=(1, 1), output_padding=(1, 1))(uconv3)
uconv2 = mx.sym.concat(deconv2, conv2,dim=1)
print('deconv2', deconv2.infer_shape(data=(32, 1, 101, 101))[1])
print('uconv2', uconv2.infer_shape(data=(32, 1, 101, 101))[1])
uconv2 = mx.gluon.nn.Dropout(DropoutRatio)(uconv2)
uconv2 = mx.gluon.nn.Conv2D(start_neurons * 2, kernel_size=k_size, padding=same_padding)(uconv2)
uconv2 = residual_block(uconv2,start_neurons * 2)
uconv2 = residual_block(uconv2,start_neurons * 2, True)
print('uconv2', uconv2.infer_shape(data=(32, 1, 101, 101))[1])
#print('deconv2', deconv2.infer_shape(data=(32, 16, 101, 101))[1])
#print('uconv2', uconv2.infer_shape(data=(32, 16, 101, 101))[1])
# 50 -> 101
#deconv1 = Conv2DTranspose(start_neurons * 1, (3, 3), strides=(2, 2), padding="same")(uconv2)
deconv1 = mx.gluon.nn.Conv2DTranspose(start_neurons * 1,
kernel_size=k_size, strides=(2, 2))(uconv2)
uconv1 = mx.sym.concat(deconv1, conv1,dim=1)
print('deconv1', deconv1.infer_shape(data=(32, 1, 101, 101))[1])
print('uconv1', uconv1.infer_shape(data=(32, 1, 101, 101))[1])
uconv1 = mx.gluon.nn.Dropout(DropoutRatio)(uconv1)
uconv1 = mx.gluon.nn.Conv2D(start_neurons * 1, kernel_size=k_size, padding=same_padding)(uconv1)
uconv1 = residual_block(uconv1,start_neurons * 1)
uconv1 = residual_block(uconv1,start_neurons * 1, True)
print('uconv1', uconv1.infer_shape(data=(32, 1, 101, 101))[1])
#print('deconv1', deconv1.infer_shape(data=(32, 16, 101, 101))[1])
#print('uconv1', uconv1.infer_shape(data=(32, 16, 101, 101))[1])
#uconv1 = Dropout(DropoutRatio/2)(uconv1)
#output_layer = Conv2D(1, (1,1), padding="same", activation="sigmoid")(uconv1)
k_size = (1, 1)
same_padding = (k_size[0]//2, k_size[1]//2)
output_layer_noActi = mx.gluon.nn.Conv2D(1, (1,1), padding=same_padding)(uconv1)
output_layer = mx.gluon.nn.Activation('sigmoid')(output_layer_noActi)
print('output_layer', output_layer.infer_shape(data=(32, 1, 101, 101))[1])
return output_layer
....
print(mx.__version__)
input_layer = mx.sym.Variable('data')
label_layer = mx.sym.Variable('softmax_label')#Input((img_size_target, img_size_target, 1))
output_layer = build_model(input_layer, 16,0.5)
data_names = ('data',)
label_names = ('softmax_label',)
#devs = mx.cpu() if args.gpus is None or args.gpus is '' else [
# mx.gpu(int(i)) for i in args.gpus.split(',')]
module = mx.mod.Module(output_layer,
data_names=data_names, label_names=label_names, context=mx.gpu())
#model1 = Model(input_layer, output_layer)
epochs = 50
batch_size = 32
train_iter = mx.io.NDArrayIter(
x_train, y_train, batch_size, shuffle=True)
valid_iter = mx.io.NDArrayIter(
x_valid, y_valid, batch_size)
batches_per_epoch = x_train.shape[0]//batch_size
progress_bar = mx.callback.ProgressBar(total=batches_per_epoch)
log_valid_metrics = mx.callback.LogValidationMetricsCallback()
module.fit(train_data = train_iter,
eval_data = valid_iter,
eval_metric = 'ce', #'acc',
kvstore = 'local',
optimizer = 'adam', #args.optimizer,
optimizer_params = { 'learning_rate': 0.01 }, #args.lr },
initializer = mx.initializer.Uniform(0.1),
num_epoch = epochs,
batch_end_callback = [progress_bar,
mx.callback.Speedometer(batch_size, batches_per_epoch)],
epoch_end_callback = [log_valid_metrics])
print(module.summary())
The dshape[2] being used is 1. However, the input shape (what dshape is a copy of from src/operator/nn/pooling.cc:~145) should maybe be much larger given the dimension sizes of conv1, conv2, conv3, conv4 above? I can post the full stack trace if it’ll be useful.