From bd7f655e75dc5af83b2a3bf90d7be44267056af8 Mon Sep 17 00:00:00 2001 From: SylviaWhittle Date: Wed, 26 Jun 2024 15:39:36 +0100 Subject: [PATCH] Tidy up manual eval --- src/manual_eval.ipynb | 144 +++++++----------------------------------- 1 file changed, 23 insertions(+), 121 deletions(-) diff --git a/src/manual_eval.ipynb b/src/manual_eval.ipynb index d9c10ed..a5c6b43 100644 --- a/src/manual_eval.ipynb +++ b/src/manual_eval.ipynb @@ -53,7 +53,6 @@ "test_size = int(0.2 * len(image_indexes))\n", "print(f\"Test size: {test_size}\")\n", "\n", - "# Randomly select test_size number of indexes\n", "test_indexes = np.random.choice(image_indexes, test_size, replace=False)\n", "print(f\"Test indexes: {test_indexes}\")" ] @@ -76,18 +75,15 @@ " # false_neg = tf.reduce_sum(y_true) - true_pos\n", " # return 1 - (true_pos + smooth) / (true_pos + false_pos + false_neg + smooth)\n", "\n", - " intersection = tf.reduce_sum(y_true * y_pred)\n", - " print(f\"intersection: {intersection}\")\n", - " union = tf.reduce_sum(y_true) + tf.reduce_sum(y_pred) - intersection\n", - " print(f\"union: {union}\")\n", - " # return 1 - ((intersection + smooth) / (union + smooth))\n", - " intersection_plus_smooth = intersection + smooth\n", - " print(f\"intersection_plus_smooth: {intersection_plus_smooth}\")\n", - " union_plus_smooth = union + smooth\n", - " print(f\"union_plus_smooth: {union_plus_smooth}\")\n", - " intersection_over_union = intersection_plus_smooth / union_plus_smooth\n", - " print(f\"intersection_over_union: {intersection_over_union}\")\n", - " return 1 - intersection_over_union\n", + " assert y_true.shape == y_pred.shape\n", + " assert y_true.dtype == bool\n", + "\n", + " # convert to float\n", + " y_true_float = tf.cast(y_true, tf.float32)\n", + "\n", + " intersection = tf.reduce_sum(y_true_float * y_pred)\n", + " union = tf.reduce_sum(y_true_float) + tf.reduce_sum(y_pred) - intersection\n", + " return 1 - (intersection + smooth) / (union + smooth)\n", "\n", "\n", "def dice_loss_simple(y_true, y_pred, smooth=1e-7):\n", @@ -102,92 +98,15 @@ " # false_neg = tf.reduce_sum(y_true) - true_pos\n", " # return 1 - (2 * true_pos + smooth) / (2 * true_pos + false_pos + false_neg + smooth)\n", "\n", - " intersection = tf.reduce_sum(y_true * y_pred)\n", - " union_double_count = tf.reduce_sum(y_true) + tf.reduce_sum(y_pred)\n", - " return 1 - (2 * intersection + smooth) / (union_double_count + smooth)\n", - "\n", - "\n", - "# test it\n", + " assert y_true.shape == y_pred.shape\n", + " assert y_true.dtype == bool\n", "\n", - "ground_truth = np.zeros((10, 10))\n", - "# ground_truth[2:8, 2:8] = 1\n", - "ground_truth[5, 5:7] = 1\n", - "plt.imshow(ground_truth, cmap=\"gray\")\n", - "plt.show()\n", + " # convert to float\n", + " y_true_float = tf.cast(y_true, tf.float32)\n", "\n", - "prediction = np.zeros((10, 10))\n", - "# prediction[3:7, 3:7] = 1\n", - "prediction[5, 5] = 1\n", - "prediction[5, 6] = 0.8\n", - "prediction[5, 4] = 0.8\n", - "prediction[5, 3] = 0.8\n", - "plt.imshow(prediction, cmap=\"gray\")\n", - "plt.show()\n", - "\n", - "print(\n", - " f\"iou loss: {iou_loss_simple(ground_truth, prediction):>5.2f} iou score: {(1 - iou_loss_simple(ground_truth, prediction)):>5.2f}\"\n", - ")\n", - "print(\n", - " f\"dice loss: {dice_loss_simple(ground_truth, prediction):>5.2f} dice score: {(1 - dice_loss_simple(ground_truth, prediction)):>5.2f}\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def iou_loss(y_true, y_pred, smooth=1e-5):\n", - " \"\"\"Intersection over Union loss function.\n", - "\n", - " Parameters\n", - " ----------\n", - " y_true : tf.Tensor\n", - " True values.\n", - " y_pred : tf.Tensor\n", - " Predicted values.\n", - " smooth : float\n", - " Smoothing factor to prevent division by zero.\n", - "\n", - " Returns\n", - " -------\n", - " iou : tf.Tensor\n", - " The IoU loss.\n", - " \"\"\"\n", - " # Ensure the tensors are of the same shape\n", - " y_true = tf.squeeze(y_true, axis=-1) if y_true.shape[-1] == 1 else y_true\n", - " y_pred = tf.squeeze(y_pred, axis=-1) if y_pred.shape[-1] == 1 else y_pred\n", - " y_true = tf.cast(y_true, tf.float32)\n", - " y_pred = tf.cast(y_pred, tf.float32)\n", - "\n", - " intersection = tf.reduce_sum(y_true * y_pred, axis=(1, 2))\n", - " sum_of_squares_pred = tf.reduce_sum(tf.square(y_pred), axis=(1, 2))\n", - " sum_of_squares_true = tf.reduce_sum(tf.square(y_true), axis=(1, 2))\n", - " # print(f\"intersection: {intersection} union: {sum_of_squares_pred + sum_of_squares_true - intersection}\")\n", - " iou = 1 - (intersection + smooth) / (sum_of_squares_pred + sum_of_squares_true - intersection + smooth)\n", - " # return the mean over all samples in the batch, as a single value\n", - " return float(tf.reduce_mean(iou))\n", - "\n", - "\n", - "# test it\n", - "\n", - "ground_truth = np.zeros((10, 10))\n", - "# ground_truth[2:8, 2:8] = 1\n", - "ground_truth[5, 5:7] = 1\n", - "plt.imshow(ground_truth, cmap=\"gray\")\n", - "plt.show()\n", - "\n", - "prediction = np.zeros((10, 10))\n", - "# prediction[3:7, 3:7] = 1\n", - "prediction[5, 5] = 1\n", - "plt.imshow(prediction, cmap=\"gray\")\n", - "plt.show()\n", - "\n", - "ground_truth = np.expand_dims(ground_truth, axis=0)\n", - "prediction = np.expand_dims(prediction, axis=0)\n", - "\n", - "print(iou_loss(ground_truth, prediction))" + " intersection = tf.reduce_sum(y_true_float * y_pred)\n", + " union_double_count = tf.reduce_sum(y_true_float) + tf.reduce_sum(y_pred)\n", + " return 1 - (2 * intersection + smooth) / (union_double_count + smooth)" ] }, { @@ -212,7 +131,7 @@ " image = np.array(pil_image).astype(np.float32)\n", " pil_mask = Image.fromarray(mask)\n", " pil_mask = pil_mask.resize((512, 512))\n", - " mask = np.array(pil_mask).astype(bool).astype(np.float32)\n", + " mask = np.array(pil_mask).astype(bool)\n", "\n", " # Add batch dimension\n", " image = np.expand_dims(image, axis=0)\n", @@ -231,26 +150,16 @@ " predicted_mask = np.squeeze(predicted_mask, axis=-1)\n", " mask = np.squeeze(mask, axis=-1)\n", "\n", - " print(predicted_mask.shape)\n", - " print(mask.shape)\n", - "\n", - " plt.imshow(predicted_mask, cmap=\"gray\")\n", - " plt.show()\n", - " plt.imshow(mask, cmap=\"gray\")\n", - " plt.show()\n", - "\n", " # Calculate the dice loss\n", - " dice_loss_value = dice_loss_simple(predicted_mask.astype(np.float64), mask.astype(np.float64))\n", - " # print(f\"dice loss: {dice_loss_value}\")\n", + " dice_loss_value = dice_loss_simple(mask, predicted_mask)\n", " dice_totals += dice_loss_value\n", "\n", " # Calculate the iou loss\n", - " iou_loss_value = iou_loss_simple(predicted_mask, mask)\n", - " print(f\"iou loss: {iou_loss_value}\")\n", + " iou_loss_value = iou_loss_simple(mask, predicted_mask)\n", " iou_totals += iou_loss_value\n", "\n", " # Calculate the binary crossentropy loss\n", - " binary_crossentropy_loss_value = tf.reduce_mean(\n", + " binary_crossentropy_loss_value = 1 - tf.reduce_mean(\n", " tf.keras.losses.binary_crossentropy(\n", " mask.astype(np.float32), predicted_mask.astype(np.float32), from_logits=True\n", " )\n", @@ -261,7 +170,6 @@ " f\"Index {test_index} Losses: dice: {dice_loss_value}, iou: {iou_loss_value}, binary_crossentropy: {binary_crossentropy_loss_value}\"\n", " )\n", "\n", - " break\n", "\n", "# Calculate the average losses\n", "average_dice_loss = dice_totals / test_size\n", @@ -270,17 +178,11 @@ "\n", "print(\n", " f\"Average Losses: dice: {average_dice_loss}, iou: {average_iou_loss}, binary_crossentropy: {average_binary_crossentropy_loss}\"\n", + ")\n", + "print(\n", + " f\"Average Scores: dice: {1 - average_dice_loss}, iou: {1 - average_iou_loss}, binary_crossentropy: {1 - average_binary_crossentropy_loss}\"\n", ")" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "model.summary()" - ] } ], "metadata": {