title: Passing `training=true` when using Tensorflow 2's Keras Functional API
body: <p>When operating in graph mode in TF1, I believe I needed to wire up <code>training=True</code> and <code>training=False</code> via feeddicts when I was using the functional-style API. What is the proper way to do this in TF2?</p>
  
  <p>I believe this is automatically handled when using <code>tf.keras.Sequential</code>. For example, I don't need to specify <code>training</code> in the following example from the <a href="https://www.tensorflow.org/guide/migrate" rel="noreferrer">docs</a>:</p>
  
  <pre><code>model = tf.keras.Sequential([
      tf.keras.layers.Conv2D(32, 3, activation='relu',
                             kernel_regularizer=tf.keras.regularizers.l2(0.02),
                             input_shape=(28, 28, 1)),
      tf.keras.layers.MaxPooling2D(),
      tf.keras.layers.Flatten(),
      tf.keras.layers.Dropout(0.1),
      tf.keras.layers.Dense(64, activation='relu'),
      tf.keras.layers.BatchNormalization(),
      tf.keras.layers.Dense(10, activation='softmax')
  ])
  
  # Model is the full model w/o custom layers
  model.compile(optimizer='adam',
                loss='sparse_categorical_crossentropy',
                metrics=['accuracy'])
  
  model.fit(train_data, epochs=NUM_EPOCHS)
  loss, acc = model.evaluate(test_data)
  print("Loss {:0.4f}, Accuracy {:0.4f}".format(loss, acc))
  </code></pre>
  
  <p>Can I also assume that keras automagically handles this when training with the functional api? Here is the same model, rewritten using the function api:</p>
  
  <pre><code>inputs = tf.keras.Input(shape=((28,28,1)), name="input_image")
  hid = tf.keras.layers.Conv2D(32, 3, activation='relu',
                             kernel_regularizer=tf.keras.regularizers.l2(0.02),
                             input_shape=(28, 28, 1))(inputs)
  hid = tf.keras.layers.MaxPooling2D()(hid)
  hid = tf.keras.layers.Flatten()(hid)
  hid = tf.keras.layers.Dropout(0.1)(hid)
  hid = tf.keras.layers.Dense(64, activation='relu')(hid)
  hid = tf.keras.layers.BatchNormalization()(hid)
  outputs = tf.keras.layers.Dense(10, activation='softmax')(hid)
  model_fn = tf.keras.Model(inputs=inputs, outputs=outputs)
  
  # Model is the full model w/o custom layers
  model_fn.compile(optimizer='adam',
                loss='sparse_categorical_crossentropy',
                metrics=['accuracy'])
  
  model_fn.fit(train_data, epochs=NUM_EPOCHS)
  loss, acc = model_fn.evaluate(test_data)
  print("Loss {:0.4f}, Accuracy {:0.4f}".format(loss, acc))
  </code></pre>
  
  <p>I'm unsure if <code>hid = tf.keras.layers.BatchNormalization()(hid)</code> needs to be <code>hid = tf.keras.layers.BatchNormalization()(hid, training)</code>?</p>
  
  <p>A colab for these models can be found <a href="https://gist.github.com/justincosentino/d36d66cddb1d606f72818c63d90d5147" rel="noreferrer">here</a>.</p>