0

I am trying to train a 3D convolutional neural network using 3D spatial data. The network trains ok but when I check its accuracy I get the following error: ValueError: Shape of labels 64 does not match shape of predictions 1. I do not know why the shape of my labels is 64 (my batch_size) and not just a single classification. I have attached my code (which is just slightly modified from the mxnet 2d convnet tutorial). How can I fix my network's output?

train_data = mx.gluon.data.DataLoader(train_dataset, batch_size= 64,shuffle= True, num_workers = cpucount)
test_data = mx.gluon.data.DataLoader(test_dataset,batch_size= 64,shuffle= True, num_workers = cpucount)

batch_size = 64
num_inputs = 2541
num_outputs = 2
num_fc = 512
net = gluon.nn.Sequential()
with net.name_scope():
    net.add(gluon.nn.Conv3D(channels=1, kernel_size=3,   activation='relu'))
    net.add(gluon.nn.MaxPool3D(pool_size=2, strides=2))
    net.add(gluon.nn.Conv3D(channels=1, kernel_size=3, activation='relu'))
    net.add(gluon.nn.MaxPool3D(pool_size=2, strides=2))

    net.add(gluon.nn.Flatten())

    net.add(gluon.nn.Dense(num_fc, activation="relu"))
    net.add(gluon.nn.Dense(num_outputs))

net.collect_params().initialize(mx.init.Xavier(magnitude=2.24),   ctx=ctx)
softmax_cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss()
trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': .1})

def evaluate_accuracy(data_iterator, net):
acc = mx.metric.Accuracy()
for i, (data, label) in enumerate(data_iterator):
    data = data.as_in_context(ctx)
    label = label.as_in_context(ctx)
    output = net(data)
    predictions = nd.argmax(output)
    acc.update(preds=predictions, labels=label)
return acc.get()[1]

epochs = 1
smoothing_constant = .01

for e in range(epochs):
for i, (data, label) in enumerate(train_data):
    data = data.as_in_context(ctx)
    label = label.as_in_context(ctx)
    with autograd.record():
        output = net(data)
        loss = softmax_cross_entropy(output, label)
    loss.backward()
    trainer.step(data.shape[0])

    ##########################
    #  Keep a moving average of the losses
    ##########################
    curr_loss = nd.mean(loss).asscalar()
    moving_loss = (curr_loss if ((i == 0) and (e == 0))
                   else (1 - smoothing_constant) * moving_loss + smoothing_constant * curr_loss)

test_accuracy = evaluate_accuracy(test_data, net)
train_accuracy = evaluate_accuracy(train_data, net)
print("Epoch %s. Loss: %s, Train_acc %s, Test_acc %s" % (e, moving_loss, train_accuracy, test_accuracy))
accAscrub
  • 609
  • 1
  • 6
  • 11

1 Answers1

0

the shape of your label should be your batch size. since your batch size determines how much data goes through the network every forward pass. The shape of your predictions should also be your batch size. The error seems to becoming from the nd.argmax call which I believe is computing the argmax across all the data points instead of for each data point.

You should explicitly specify the axis you want to perform the argmax operation on i.e change the code in your eval_accuracy function to:

predictions = nd.argmax(output, axis=1)
label = label.reshape(predictions.shape)
acc.update(preds=predictions, labels=label)
sad-
  • 101
  • 2
  • If you just pass in `acc.update(preds=output, labels=label)` it should also work as acc.update does argmax for you. – sad- Sep 10 '18 at 18:56