human
4. Convolution Neural Network"
Please write code following the instructions in jupyter notebook style.

=====
What is a code to 4?
assistant
#Here is code to 4.

## Log class
### https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/Callback
class CollectBatchStats(tf.keras.callbacks.Callback):
    def __init__(self):
        self.batch_losses = []
        self.batch_val_losses = []
        self.batch_acc = []
        self.batch_val_acc = []
    
    def on_epoch_end(self, epoch, logs=None):
        self.batch_losses.append(logs['loss'])
        self.batch_acc.append(logs['accuracy'])
        self.batch_val_losses.append(logs['val_loss'])
        self.batch_val_acc.append(logs['val_accuracy'])
        self.model.reset_metrics()

cnn_model = tf.keras.Sequential([
        tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=image_batch.shape[1:]),
        tf.keras.layers.MaxPooling2D((2, 2)),
        tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
        tf.keras.layers.MaxPooling2D((2, 2)),
        tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
        tf.keras.layers.Flatten(),
        tf.keras.layers.Dense(64, activation='relu'),
        tf.keras.layers.Dense(train_data.num_classes)])

cnn_model.summary()

base_learning_rate = 0.001

cnn_model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=base_learning_rate),
                  loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),
                  metrics=['accuracy'])

steps_per_epoch = np.ceil(train_data.samples/train_data.batch_size) # train all dataset per epoch
epochs = 25*2
cnn_callback = CollectBatchStats()

cnn_history = cnn_model.fit(train_data,
                            epochs=epochs,
                            steps_per_epoch=steps_per_epoch,
                            validation_data=validation_data,
                            callbacks=[cnn_callback])

# Draw learning curves chart
acc = cnn_callback.batch_acc
val_acc = cnn_callback.batch_val_acc
loss = cnn_callback.batch_losses
val_loss = cnn_callback.batch_val_losses

fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(2, 1, 1)
ax.plot(acc, label='Training Accuracy')
ax.plot(val_acc,...