<jupyter_start><jupyter_text>Train the modelNow, all that is left to do is to compile and train the model. The loss being used here is `losses.SparseCategoricalCrossentropy(from_logits=True)`. The reason to use this loss function is because the network is trying to assign each pixel a label, just like multi-class prediction. In the true segmentation mask, each pixel has either a {0,1,2}. The network here is outputting three channels. Essentially, each channel is trying to learn to predict a class, and `losses.SparseCategoricalCrossentropy(from_logits=True)` is the recommended loss for such a scenario. Using the output of the network, the label assigned to the pixel is the channel with the highest value. This is what the create_mask function is doing.<jupyter_code>def weighted_dsc(y_true, y_pred):
    smooth = 1
    total_pixels = 128 * 128 * 1
    weights = total_pixels / (K.sum(y_true, axis=(0, 1, 2)) + smooth)
    intersection = K.sum(y_true * y_pred, axis=(0, 1, 2))
    union = K.sum(y_true + y_pred, axis=(0, 1, 2))
    w_intersection = K.sum(intersection * weights)
    w_union = K.sum(union * weights)
    
    return (2 * w_intersection + smooth) / (w_union + smooth)


def weighted_dsc_loss(y_true, y_pred):
    return 1 - weighted_dsc(y_true, y_pred)
K.clear_session()

model = unet_model()
model.compile(optimizer='adam',
              loss=weighted_dsc_loss,
              metrics=['accuracy'])<jupyter_output><empty_output><jupyter_text>Have a quick look at the resulting model architecture:<jupyter_code>tf.keras.utils.plot_model(model, show_shapes=True)
show_a_prediction()<jupyter_output><empty_output><jupyter_text>Let's observe how the model improves while it is training. To accomplish this task, a callback function is defined below.<jupyter_code>class DisplayCallback(tf.keras.callbacks.Callback):
    def on_epoch_end(self, epoch, logs=None):
        IPython.display.clear_output(wait=True)
        show_a_prediction()
        print ('\nSample Prediction after epoch {}\n'.format(epoch+1))
EPOCHS = 3
STEPS_PER_EPOCH = 1
VALIDATION_STEPS = 1

model_history = model.fit(training_dataset, epochs=EPOCHS,
                          steps_per_epoch=STEPS_PER_EPOCH,
                          validation_steps=VALIDATION_STEPS,
                          validation_data=validation_dataset,
                          callbacks=[DisplayCallback()])
loss = model_history.history['loss']
val_loss = model_history.history['val_loss']

epochs = range(EPOCHS)

plt.figure()
plt.plot(epochs, loss, 'r', label='Training loss')
plt.plot(epochs, val_loss, 'bo', label='Validation loss')
plt.title('Training and Validation Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss Value')
plt.ylim([0, 1])
plt.legend()
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10133912414042708, 'fraction_numerical': 0.010133912414042706, 'mean_word_length': 4.234848484848484, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '546555', 'license': 'Apache-2.0', 'n_tokens_mistral': 923, 'n_tokens_neox': 880, 'n_words': 247, 'path': 'prototyping/auto-segmentation/sb/04-mini-data/051-tf-tutorial-based.ipynb', 'repo_name': 'dg1an3/pymedphys', 'size': '2763'}