code: def create_model_fn(self):
      def model_fn(features, labels, mode):
          features = tf.layers.flatten(features)
          h1 = tf.layers.dense(features, 64, activation=tf.nn.relu)
          h2 = tf.layers.dense(h1, 64, activation=tf.nn.relu)
          logits = tf.layers.dense(h2, 10)
  
          if (
              mode == tf.estimator.ModeKeys.EVAL
              or mode == tf.estimator.ModeKeys.TRAIN
          ):
              loss = tf.reduce_mean(
                  tf.losses.sparse_softmax_cross_entropy(
                      logits=logits, labels=labels
                  )
              )
              train_op = ZooOptimizer(
                  tf.train.AdamOptimizer()
              ).minimize(loss)
              return tf.estimator.EstimatorSpec(
                  mode, train_op=train_op, predictions=logits, loss=loss
              )
          else:
              return tf.estimator.EstimatorSpec(
                  mode, predictions=logits
              )
  
      return model_fn
  
imports: import pytest
  from test.zoo.pipeline.utils.test_utils import ZooTestCase
  import tensorflow
  from zoo.feature.common import ChainedPreprocessing, FeatureSet
  from zoo.feature.image import *
  from zoo.tfpark import TFDataset, TFEstimator
  from zoo.tfpark import ZooOptimizer
label_desc: Use image node_id 2 for calling the TestTFParkEstimator obj's underlying member method code with example usage: obj.create_model_fn() and returns: model_fn, tf, tf