code: def cnn_model(logits=False, input_ph=None, img_rows=28, img_cols=28,
                channels=1, nb_filters=64, nb_classes=10):
    
    model = Sequential()
  
    # Define the layers successively (convolution layers are version dependent)
    if tf.keras.backend.image_data_format() == 'channels_first':
      input_shape = (channels, img_rows, img_cols)
    else:
      assert tf.keras.backend.image_data_format() == 'channels_last'
      input_shape = (img_rows, img_cols, channels)
  
    layers = [conv_2d(nb_filters, (8, 8), (2, 2), "same",
                      input_shape=input_shape),
              Activation('relu'),
              conv_2d((nb_filters * 2), (6, 6), (2, 2), "valid"),
              Activation('relu'),
              conv_2d((nb_filters * 2), (5, 5), (1, 1), "valid"),
              Activation('relu'),
              Flatten(),
              Dense(nb_classes)]
  
    for layer in layers:
      model.add(layer)
  
    if logits:
      logits_tensor = model(input_ph)
    model.add(Activation('softmax'))
  
    if logits:
      return model, logits_tensor
    else:
      return model
docs: Defines a CNN model using Keras sequential model
    :param logits: If set to False, returns a Keras model, otherwise will also
                    return logits tensor
    :param input_ph: The TensorFlow tensor for the input
                    (needed if returning logits)
                    ("ph" stands for placeholder but it need not actually be a
                    placeholder)
    :param img_rows: number of row in the image
    :param img_cols: number of columns in the image
    :param channels: number of color channels (e.g., 1 for MNIST)
    :param nb_filters: number of convolutional filters per layer
    :param nb_classes: the number of output classes
    :return: