old_contents: model = Sequential()
  model.add(Dense(hidden_dim, input_dim=input_dim,
                  activation="tanh"))
  model.add(Dense(output_dim, activation="softmax"))
  model.add(Activation("softmax"))
  
  optimizer = optimizers.SGD(lr=0.1, momentum=0.9, nesterov=True)
  model.compile(optimizer=optimizer, loss='categorical_crossentropy',
                metrics=['accuracy'])
  history = model.fit(X_train, Y_train, validation_split=0.2,
                      epochs=15, batch_size=32)
  
  fig, (ax0, ax1) = plt.subplots(nrows=2, sharex=True, figsize=(12, 6))
  history_df = pd.DataFrame(history.history)
  history_df["epoch"] = history.epoch
  history_df.plot(x="epoch", y=["loss", "val_loss"], ax=ax0)
  history_df.plot(x="epoch", y=["accuracy", "val_accuracy"], ax=ax1);
  
  
  # Analysis:
  #
  # Setting the learning rate value to a small value (e.g. lr=0.001 on
  # this dataset) makes the model train much slower (it has not
  # converged yet after 15 epochs).
  #
  # Using momentum tends to mitigate the small learning rate / slow
  # training problem a bit.
  #
  # Setting the learning rate to a very large value (e.g. lr=10)
  # makes the model randomly bounce around a good local
  # minimum and therefore prevent it to reach a low training loss even
  # after 30 epochs.
new_contents: model = Sequential()
  model.add(Dense(hidden_dim, input_dim=input_dim,
                  activation="tanh"))
  model.add(Dense(output_dim, activation="softmax"))
  
  optimizer = optimizers.SGD(lr=0.1, momentum=0.9, nesterov=True)
  model.compile(optimizer=optimizer, loss='categorical_crossentropy',
                metrics=['accuracy'])
  history = model.fit(X_train, Y_train, validation_split=0.2,
                      epochs=15, batch_size=32)
  
  fig, (ax0, ax1) = plt.subplots(nrows=2, sharex=True, figsize=(12, 6))
  history_df = pd.DataFrame(history.history)
  history_df["epoch"] = history.epoch
  history_df.plot(x="epoch", y=["loss", "val_loss"], ax=ax0)
  history_df.plot(x="epoch", y=["accuracy", "val_accuracy"], ax=ax1);
  
  
  # Analysis:
  #
  # Setting the learning rate value to a small value (e.g. lr=0.001 on
  # this dataset) makes the model train much slower (it has not
  # converged yet after 15 epochs).
  #
  # Using momentum tends to mitigate the small learning rate / slow
  # training problem a bit.
  #
  # Setting the learning rate to a very large value (e.g. lr=10)
  # makes the model randomly bounce around a good local
  # minimum and therefore prevent it to reach a low training loss even
  # after 30 epochs.
  
subject: Remove leftover line in solution for 01_keras