return loss, metric

############################# 
# main function boilerplate #
#############################

if __name__=='__main__':
    # create model
    model = create_convnet_cifar10_model(num_classes=10)
    # declare the model's input dimension
    # Training does not require this, but it is needed for deployment.
    model.update_signature((num_channels, image_height, image_width))

    # criterion function. This is what is being trained trained.
    # Model gets "sandwiched" between normalization (not part of model proper) and criterion.
    criterion = create_criterion_function(model, normalize=lambda x: x / 256)

    # train
    reader = create_reader(os.path.join(data_path, 'train_map.txt'), os.path.join(data_path, 'CIFAR-10_mean.xml'), True)
    train_model(reader, model, criterion, max_epochs=80)

    # save and load (as an illustration)
    path = data_path + "/model.cmf"
    model.save(path)

    # test
    model = Function.load(path)
    reader = create_reader(os.path.join(data_path, 'test_map.txt'), os.path.join(data_path, 'CIFAR-10_mean.xml'), False)
    criterion = create_criterion_function(model, normalize=lambda x: x / 256)
    evaluate(reader, criterion)
 def criterion(x, y):
     z = model(normalize(x))
     ce = cross_entropy_with_softmax(z, y)
     errs = classification_error(z, y)
     return (Function.NamedOutput(loss=ce),
             Function.NamedOutput(metric=errs))