code: def convnet_mnist(
      debug_output=False,
      epoch_size=60000,
      minibatch_size=64,
      max_epochs=40,
  ):
      image_height = 28
      image_width = 28
      num_channels = 1
      input_dim = image_height * image_width * num_channels
      num_output_classes = 10
  
      # Input variables denoting the features and label data
      input_var = C.ops.input_variable(
          (num_channels, image_height, image_width), np.float32
      )
      label_var = C.ops.input_variable(num_output_classes, np.float32)
  
      # Instantiate the feedforward classification model
      scaled_input = C.ops.element_times(
          C.ops.constant(0.00390625), input_var
      )
  
      with C.layers.default_options(activation=C.ops.relu, pad=False):
          conv1 = C.layers.Convolution2D((5, 5), 32, pad=True)(
              scaled_input
          )
          pool1 = C.layers.MaxPooling((3, 3), (2, 2))(conv1)
          conv2 = C.layers.Convolution2D((3, 3), 48)(pool1)
          pool2 = C.layers.MaxPooling((3, 3), (2, 2))(conv2)
          conv3 = C.layers.Convolution2D((3, 3), 64)(pool2)
          f4 = C.layers.Dense(96)(conv3)
          drop4 = C.layers.Dropout(0.5)(f4)
          z = C.layers.Dense(num_output_classes, activation=None)(drop4)
  
      ce = C.losses.cross_entropy_with_softmax(z, label_var)
      pe = C.metrics.classification_error(z, label_var)
  
      reader_train = create_reader(
          os.path.join(data_path, "Train-28x28_cntk_text.txt"),
          True,
          input_dim,
          num_output_classes,
      )
  
      # Set learning parameters
      lr_per_sample = [0.001] * 10 + [0.0005] * 10 + [0.0001]
      lr_schedule = C.learning_parameter_schedule_per_sample(
          lr_per_sample, epoch_size=epoch_size
      )
      mms = [0] * 5 + [0.9990239141819757]
      mm_schedule = C.learners.momentum_schedule_per_sample(
          mms, epoch_size=epoch_size
      )
  
      # Instantiate the trainer object to drive the model training
      learner = C.learners.momentum_sgd(
          z.parameters, lr_schedule, mm_schedule
      )
      progress_printer = C.logging.ProgressPrinter(
          tag="Training", num_epochs=max_epochs
      )
      trainer = C.Trainer(z, (ce, pe), learner, progress_printer)
  
      # define mapping from reader streams to network inputs
      input_map = {
          input_var: reader_train.streams.features,
          label_var: reader_train.streams.labels,
      }
  
      C.logging.log_number_of_parameters(z)
      print()
  
      # Get minibatches of images to train with and perform model training
      for epoch in range(max_epochs):  # loop over epochs
          sample_count = 0
          while (
              sample_count < epoch_size
          ):  # loop over minibatches in the epoch
              data = reader_train.next_minibatch(
                  min(minibatch_size, epoch_size - sample_count),
                  input_map=input_map,
              )  # fetch minibatch.
              trainer.train_minibatch(data)  # update model with it
              sample_count += data[
                  label_var
              ].num_samples  # count samples processed so far
  
          trainer.summarize_training_progress()
          z.save(
              os.path.join(
                  model_path, "ConvNet_MNIST_{}.dnn".format(epoch)
              )
          )
  
      # Load test data
      reader_test = create_reader(
          os.path.join(data_path, "Test-28x28_cntk_text.txt"),
          False,
          input_dim,
          num_output_classes,
      )
  
      input_map = {
          input_var: reader_test.streams.features,
          label_var: reader_test.streams.labels,
      }
  
      # Test data for trained model
      epoch_size = 10000
      minibatch_size = 1024
  
      # process minibatches and evaluate the model
      metric_numer = 0
      metric_denom = 0
      sample_count = 0
      minibatch_index = 0
  
      while sample_count < epoch_size:
          current_minibatch = min(
              minibatch_size, epoch_size - sample_count
          )
  
          # Fetch next test min batch.
          data = reader_test.next_minibatch(
              current_minibatch, input_map=input_map
          )
  
          # minibatch data to be trained with
          metric_numer += (
              trainer.test_minibatch(data) * current_minibatch
          )
          metric_denom += current_minibatch
  
          # Keep track of the number of samples processed so far.
          sample_count += data[label_var].num_samples
          minibatch_index += 1
  
      print("")
      print(
          "Final Results: Minibatch[1-{}]: errs = {:0.2f}% * {}".format(
              minibatch_index + 1,
              (metric_numer * 100.0) / metric_denom,
              metric_denom,
          )
      )
      print("")
  
      return metric_numer / metric_denom
  
imports: from __future__ import print_function
  import numpy
  import sys
  import os
  import cntk
label_desc: Use image node_id 2 for calling a global function with example usage: convnet_mnist(debug_output, epoch_size, minibatch_size, max_epochs) and returns: unknown