Debugging Tensorboard und Scikit-Learn-Metriken für eine Verwirrungsmatrix
Posted: 15 May 2025, 21:18
Ich versuche einen 3D -CNN zu erstellen, der Bilder klassifiziert. In diesem Beispiel werden ungefähr 900 Bilder angezeigt und festgelegt, was 0 ist und was ist. Hier ist Teil der Ausgabe einer Epoche < /p>
Dieses Segment ist die in meinem Code verwendete Rückruffunktion, die das obige Bild ausgab (Entschuldigung für die Unordnung meines Codes im Voraus): < /p>
class ConfusionMatrixCallback(Callback):
def __init__(self, log_dir, val_dataset, threshold=0.5, debug=False):
super().__init__()
self.log_dir = log_dir
self.val_dataset = val_dataset
self.threshold = threshold
self.debug = debug
self.writer = tf.summary.create_file_writer(os.path.join(log_dir, "custom_metrics"))
self.auc_metric = AUC(name='AUC')
self.precision_metric = Precision(name='Precision')
self.recall_metric = Recall(name='Recall')
def on_epoch_end(self, epoch, logs=None):
all_probs = []
all_labels = []
for batch_x, batch_y in self.val_dataset:
preds = self.model(batch_x, training=False)
all_probs.append(preds.numpy())
all_labels.append(batch_y.numpy())
all_probs = np.concatenate(all_probs)
all_labels = np.concatenate(all_labels)
y_true = np.argmax(all_labels, axis=1)
y_scores = all_probs[:, 1] # class 1 probabilities
y_pred = (y_scores > self.threshold).astype(int) # Apply threshold (e.g. 0.5)
# Sklearn AUC
auc_sklearn = roc_auc_score(y_true, y_scores)
print("DEBUG: y_true dtype and shape:", y_true.dtype, y_true.shape)
print("DEBUG: y_scores dtype and shape:", y_scores.dtype, y_scores.shape)
y_true_tf = tf.convert_to_tensor(y_true, dtype=tf.int32)
y_scores_tf = tf.convert_to_tensor(y_scores, dtype=tf.float32)
print("DEBUG: Tensor y_true:", y_true_tf[:10].numpy())
print("DEBUG: Tensor y_scores:", y_scores_tf[:10].numpy())
self.auc_metric.reset_state()
self.auc_metric.update_state(all_labels, all_probs)
auc_tf = self.auc_metric.result().numpy()
# Other metrics
self.precision_metric.reset_state()
self.recall_metric.reset_state()
self.precision_metric.update_state(all_labels, all_probs)
self.recall_metric.update_state(all_labels, all_probs)
precision_tf = self.precision_metric.result().numpy()
recall_tf = self.recall_metric.result().numpy()
f1_tf = 2 * precision_tf * recall_tf / (precision_tf + recall_tf + 1e-7)
# Confusion Matrix Calculation (Directly from Softmax Predictions)
# Match TensorFlow metrics logic (i.e., binary threshold for class 1)
y_true = np.argmax(all_labels, axis=1)
y_pred = (y_scores >= self.threshold).astype(int)
# Confusion Matrix
cm = confusion_matrix(y_true, y_pred)
print("Sklearn precision:", precision_score(y_true, y_pred))
print("Sklearn recall: ", recall_score(y_true, y_pred))
print("Sklearn confusion matrix:\n", confusion_matrix(y_true, y_pred))
print("TF precision: ", precision_tf)
print("TF recall: ", recall_tf)
# Log confusion matrix image
cm_image = plot_cm_image(cm, class_names=["HC", "PD"])
with self.writer.as_default():
tf.summary.image("Confusion Matrix", cm_image, step=epoch)
if self.debug:
print(f"\n--- Epoch {epoch + 1} (TF Validation Stats) ---")
print(f"AUC (TF): {auc_tf:.4f}")
print(f"Precision: {precision_tf:.4f}, Recall: {recall_tf:.4f}, F1: {f1_tf:.4f}")
print("Confusion Matrix:\n", cm)
print("Manually computed precision:", precision_score(y_true, y_pred))
print("Manually computed recall: ", recall_score(y_true, y_pred))
with self.writer.as_default():
tf.summary.scalar("Val AUC (TF)", auc_tf, step=epoch)
tf.summary.scalar("Val Precision", precision_tf, step=epoch)
tf.summary.scalar("Val Recall", recall_tf, step=epoch)
tf.summary.scalar("Val F1", f1_tf, step=epoch)
tf.summary.image("Confusion Matrix", cm_image, step=epoch)
self.writer.flush()
print("\nFull Validation Data Debug:")
print("y_true (class labels):")
print(y_true.tolist())
print("\ny_scores (predicted prob for class 1):")
print(y_scores.tolist())
print(f"\ny_pred (predicted class with threshold={self.threshold}):")
print(y_pred.tolist())
for i, (batch_x, batch_y) in enumerate(self.val_dataset):
preds = self.model(batch_x, training=False)
predicted_classes = tf.argmax(preds, axis=1).numpy()
true_classes = tf.argmax(batch_y, axis=1).numpy()
# Print batch-level predictions
print(f"\n[Epoch {epoch+1}] Batch {i+1}:")
print(f"Predicted classes: {predicted_classes.tolist()}")
print(f"True labels: {true_classes.tolist()}")
correct = (predicted_classes == true_classes)
accuracy = np.mean(correct)
precision = precision_score(true_classes, predicted_classes, zero_division=0)
recall = recall_score(true_classes, predicted_classes, zero_division=0)
print(f"Accuracy: {accuracy:.4f}")
print(f"Precision: {precision:.4f}")
print(f"Recall: {recall:.4f}")
confusion_matrix_callback = ConfusionMatrixCallback(
log_dir=log_dir,
val_dataset=val_dataset,
threshold=0.5,
debug=True
)
< /code>
Bitte lassen Sie mich wissen, ob ich etwas erwähnen oder einfügen muss, um dieses Debuggen zu erleichtern. Ich schätze jede und alle Hilfe im Voraus!
Dieses Segment ist die in meinem Code verwendete Rückruffunktion, die das obige Bild ausgab (Entschuldigung für die Unordnung meines Codes im Voraus): < /p>
class ConfusionMatrixCallback(Callback):
def __init__(self, log_dir, val_dataset, threshold=0.5, debug=False):
super().__init__()
self.log_dir = log_dir
self.val_dataset = val_dataset
self.threshold = threshold
self.debug = debug
self.writer = tf.summary.create_file_writer(os.path.join(log_dir, "custom_metrics"))
self.auc_metric = AUC(name='AUC')
self.precision_metric = Precision(name='Precision')
self.recall_metric = Recall(name='Recall')
def on_epoch_end(self, epoch, logs=None):
all_probs = []
all_labels = []
for batch_x, batch_y in self.val_dataset:
preds = self.model(batch_x, training=False)
all_probs.append(preds.numpy())
all_labels.append(batch_y.numpy())
all_probs = np.concatenate(all_probs)
all_labels = np.concatenate(all_labels)
y_true = np.argmax(all_labels, axis=1)
y_scores = all_probs[:, 1] # class 1 probabilities
y_pred = (y_scores > self.threshold).astype(int) # Apply threshold (e.g. 0.5)
# Sklearn AUC
auc_sklearn = roc_auc_score(y_true, y_scores)
print("DEBUG: y_true dtype and shape:", y_true.dtype, y_true.shape)
print("DEBUG: y_scores dtype and shape:", y_scores.dtype, y_scores.shape)
y_true_tf = tf.convert_to_tensor(y_true, dtype=tf.int32)
y_scores_tf = tf.convert_to_tensor(y_scores, dtype=tf.float32)
print("DEBUG: Tensor y_true:", y_true_tf[:10].numpy())
print("DEBUG: Tensor y_scores:", y_scores_tf[:10].numpy())
self.auc_metric.reset_state()
self.auc_metric.update_state(all_labels, all_probs)
auc_tf = self.auc_metric.result().numpy()
# Other metrics
self.precision_metric.reset_state()
self.recall_metric.reset_state()
self.precision_metric.update_state(all_labels, all_probs)
self.recall_metric.update_state(all_labels, all_probs)
precision_tf = self.precision_metric.result().numpy()
recall_tf = self.recall_metric.result().numpy()
f1_tf = 2 * precision_tf * recall_tf / (precision_tf + recall_tf + 1e-7)
# Confusion Matrix Calculation (Directly from Softmax Predictions)
# Match TensorFlow metrics logic (i.e., binary threshold for class 1)
y_true = np.argmax(all_labels, axis=1)
y_pred = (y_scores >= self.threshold).astype(int)
# Confusion Matrix
cm = confusion_matrix(y_true, y_pred)
print("Sklearn precision:", precision_score(y_true, y_pred))
print("Sklearn recall: ", recall_score(y_true, y_pred))
print("Sklearn confusion matrix:\n", confusion_matrix(y_true, y_pred))
print("TF precision: ", precision_tf)
print("TF recall: ", recall_tf)
# Log confusion matrix image
cm_image = plot_cm_image(cm, class_names=["HC", "PD"])
with self.writer.as_default():
tf.summary.image("Confusion Matrix", cm_image, step=epoch)
if self.debug:
print(f"\n--- Epoch {epoch + 1} (TF Validation Stats) ---")
print(f"AUC (TF): {auc_tf:.4f}")
print(f"Precision: {precision_tf:.4f}, Recall: {recall_tf:.4f}, F1: {f1_tf:.4f}")
print("Confusion Matrix:\n", cm)
print("Manually computed precision:", precision_score(y_true, y_pred))
print("Manually computed recall: ", recall_score(y_true, y_pred))
with self.writer.as_default():
tf.summary.scalar("Val AUC (TF)", auc_tf, step=epoch)
tf.summary.scalar("Val Precision", precision_tf, step=epoch)
tf.summary.scalar("Val Recall", recall_tf, step=epoch)
tf.summary.scalar("Val F1", f1_tf, step=epoch)
tf.summary.image("Confusion Matrix", cm_image, step=epoch)
self.writer.flush()
print("\nFull Validation Data Debug:")
print("y_true (class labels):")
print(y_true.tolist())
print("\ny_scores (predicted prob for class 1):")
print(y_scores.tolist())
print(f"\ny_pred (predicted class with threshold={self.threshold}):")
print(y_pred.tolist())
for i, (batch_x, batch_y) in enumerate(self.val_dataset):
preds = self.model(batch_x, training=False)
predicted_classes = tf.argmax(preds, axis=1).numpy()
true_classes = tf.argmax(batch_y, axis=1).numpy()
# Print batch-level predictions
print(f"\n[Epoch {epoch+1}] Batch {i+1}:")
print(f"Predicted classes: {predicted_classes.tolist()}")
print(f"True labels: {true_classes.tolist()}")
correct = (predicted_classes == true_classes)
accuracy = np.mean(correct)
precision = precision_score(true_classes, predicted_classes, zero_division=0)
recall = recall_score(true_classes, predicted_classes, zero_division=0)
print(f"Accuracy: {accuracy:.4f}")
print(f"Precision: {precision:.4f}")
print(f"Recall: {recall:.4f}")
confusion_matrix_callback = ConfusionMatrixCallback(
log_dir=log_dir,
val_dataset=val_dataset,
threshold=0.5,
debug=True
)
< /code>
Bitte lassen Sie mich wissen, ob ich etwas erwähnen oder einfügen muss, um dieses Debuggen zu erleichtern. Ich schätze jede und alle Hilfe im Voraus!