![](/img/trans.png)
[英]Adding text labels to confusion matrix in Tensorflow for Tensorboard
[英]Tensorflow Confusion Matrix in TensorBoard
我希望在張量板中有一個混淆矩陣的視覺效果。 為此,我正在修改Tensorflow Slim的評估示例: https : //github.com/tensorflow/models/blob/master/slim/eval_image_classifier.py
在此示例代碼中,Accuracy已經提供但是不可能直接添加“confusion matrix”度量標准,因為它不是流式傳輸。
流媒體指標和非流媒體指標有什么區別?
因此,我試圖像這樣添加它:
c_matrix = slim.metrics.confusion_matrix(predictions, labels)
#These operations needed for image summary
c_matrix = tf.cast(c_matrix, uint8)
c_matrix = tf.expand_dims(c_matrix, 2)
c_matrix = tf.expand_dims(c_matrix, 0)
op = tf.image_summary("confusion matrix", c_matrix, collections=[])
tf.add_to_collection(tf.GraphKeys.SUMMARIES, op)
這會在tensorboard中創建一個圖像,但可能存在格式問題。 矩陣應在0-1之間歸一化,以便產生有意義的圖像。
我怎樣才能產生有意義的混淆矩陣? 我該如何處理多批評估過程?
這是我把它放在一起的東西,它運作得相當好。 仍然需要調整一些事情,如刻度線位置等。
這個函數幾乎可以為你做所有事情。
from textwrap import wrap
import re
import itertools
import tfplot
import matplotlib
import numpy as np
from sklearn.metrics import confusion_matrix
def plot_confusion_matrix(correct_labels, predict_labels, labels, title='Confusion matrix', tensor_name = 'MyFigure/image', normalize=False):
'''
Parameters:
correct_labels : These are your true classification categories.
predict_labels : These are you predicted classification categories
labels : This is a lit of labels which will be used to display the axix labels
title='Confusion matrix' : Title for your matrix
tensor_name = 'MyFigure/image' : Name for the output summay tensor
Returns:
summary: TensorFlow summary
Other itema to note:
- Depending on the number of category and the data , you may have to modify the figzie, font sizes etc.
- Currently, some of the ticks dont line up due to rotations.
'''
cm = confusion_matrix(correct_labels, predict_labels, labels=labels)
if normalize:
cm = cm.astype('float')*10 / cm.sum(axis=1)[:, np.newaxis]
cm = np.nan_to_num(cm, copy=True)
cm = cm.astype('int')
np.set_printoptions(precision=2)
###fig, ax = matplotlib.figure.Figure()
fig = matplotlib.figure.Figure(figsize=(7, 7), dpi=320, facecolor='w', edgecolor='k')
ax = fig.add_subplot(1, 1, 1)
im = ax.imshow(cm, cmap='Oranges')
classes = [re.sub(r'([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))', r'\1 ', x) for x in labels]
classes = ['\n'.join(wrap(l, 40)) for l in classes]
tick_marks = np.arange(len(classes))
ax.set_xlabel('Predicted', fontsize=7)
ax.set_xticks(tick_marks)
c = ax.set_xticklabels(classes, fontsize=4, rotation=-90, ha='center')
ax.xaxis.set_label_position('bottom')
ax.xaxis.tick_bottom()
ax.set_ylabel('True Label', fontsize=7)
ax.set_yticks(tick_marks)
ax.set_yticklabels(classes, fontsize=4, va ='center')
ax.yaxis.set_label_position('left')
ax.yaxis.tick_left()
for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
ax.text(j, i, format(cm[i, j], 'd') if cm[i,j]!=0 else '.', horizontalalignment="center", fontsize=6, verticalalignment='center', color= "black")
fig.set_tight_layout(True)
summary = tfplot.figure.to_summary(fig, tag=tensor_name)
return summary
#
以下是您需要調用此函數的其余代碼。
''' confusion matrix summaries ''' img_d_summary_dir = os.path.join(checkpoint_dir, "summaries", "img") img_d_summary_writer = tf.summary.FileWriter(img_d_summary_dir, sess.graph) img_d_summary = plot_confusion_matrix(correct_labels, predict_labels, labels, tensor_name='dev/cm') img_d_summary_writer.add_summary(img_d_summary, current_step)
混淆!!!
以下是我為測試代碼生成並顯示“流式”混淆矩陣的方法(對每個批次進行評估返回的test_op
以進行測試)。
def _get_streaming_metrics(prediction,label,num_classes):
with tf.name_scope("test"):
# the streaming accuracy (lookup and update tensors)
accuracy,accuracy_update = tf.metrics.accuracy(label, prediction,
name='accuracy')
# Compute a per-batch confusion
batch_confusion = tf.confusion_matrix(label, prediction,
num_classes=num_classes,
name='batch_confusion')
# Create an accumulator variable to hold the counts
confusion = tf.Variable( tf.zeros([num_classes,num_classes],
dtype=tf.int32 ),
name='confusion' )
# Create the update op for doing a "+=" accumulation on the batch
confusion_update = confusion.assign( confusion + batch_confusion )
# Cast counts to float so tf.summary.image renormalizes to [0,255]
confusion_image = tf.reshape( tf.cast( confusion, tf.float32),
[1, num_classes, num_classes, 1])
# Combine streaming accuracy and confusion matrix updates in one op
test_op = tf.group(accuracy_update, confusion_update)
tf.summary.image('confusion',confusion_image)
tf.summary.scalar('accuracy',accuracy)
return test_op,accuracy,confusion
通過運行test_op
處理所有數據批處理test_op
,如果您test_op
,可以通過confusion.eval()
或sess.eval(confusion)
查找最終的混淆矩陣(在您的會話中)。
這是適用於tf.contrib.metrics.MetricSpec的東西(當你使用Estimator時)。 它的靈感來自Jerod的答案和metric_op.py源文件。 你得到一個帶有百分比的流式混淆矩陣:
from tensorflow.python.framework import ops,dtypes
from tensorflow.python.ops import array_ops,variables
def _createLocalVariable(name, shape, collections=None,
validate_shape=True,
dtype=dtypes.float32):
"""Creates a new local variable.
"""
# Make sure local variables are added to
# tf.GraphKeys.LOCAL_VARIABLES
collections = list(collections or [])
collections += [ops.GraphKeys.LOCAL_VARIABLES]
return variables.Variable(
initial_value=array_ops.zeros(shape, dtype=dtype),
name=name,
trainable=False,
collections=collections,
validate_shape=validate_shape)
def streamingConfusionMatrix(label, prediction,
weights=None,num_classes=None):
"""
Compute a streaming confusion matrix
:param label: True labels
:param prediction: Predicted labels
:param weights: (Optional) weights (unused)
:param num_classes: Number of labels for the confusion matrix
:return: (percentConfusionMatrix,updateOp)
"""
# Compute a per-batch confusion
batch_confusion = tf.confusion_matrix(label, prediction,
num_classes=num_classes,
name='batch_confusion')
count = _createLocalVariable(None,(),dtype=tf.int32)
confusion = _createLocalVariable('streamConfusion',[num_classes,
num_classes],dtype=tf.int32)
# Create the update op for doing a "+=" accumulation on the batch
countUpdate = count.assign(count + tf.reduce_sum(batch_confusion))
confusionUpdate = confusion.assign(confusion + batch_confusion)
updateOp = tf.group(confusionUpdate,countUpdate)
percentConfusion = 100 * tf.truediv(confusion,count)
return percentConfusion,updateOp
然后,您可以通過以下方式將其用作評估指標:
from tensorflow.contrib import learn,metrics
#[...]
evalMetrics = {'accuracy':
learn.MetricSpec(metric_fn=metrics.streaming_accuracy),
'confusionMatrix':learn.MetricSpec(metric_fn=
lambda
label,prediction,weights=None:
streamingConfusionMatrix(
label,prediction,weights,num_classes=nLabels))}
我建議你使用numpy.set_printoptions(precision = 2,suppress = True)將其打印出來。
Re:你的圖像沒有意義 - 根據tf.summary.image的文檔,uint8值不變(不會被規范化),並在范圍[0,255]中解釋。 您是否嘗試將圖像重新標准化為[0,255]而不是[0,1]?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.