Save confusion matrix image to Tensorboard

Federico_Vasile: <p>Hi everyone,<br>
let’s suppose I have this simple code that creates a confusion matrix:</p>
<pre><code>import torch
from sklearn.metrics import confusion_matrix

output = torch.randn(1, 2, 4, 4)
pred = torch.argmax(output, 1)
target = torch.empty(1, 4, 4, dtype=torch.long).random_(2)
conf_mat = confusion_matrix(pred.view(-1), target.view(-1))
</code>
</pre>
<p>Is there a way to convert <code>conf_mat</code> to an image and save it to Tensorboard ?<br>
I successfully converted it to an image using mlxtend library, but now I found no way to save it Tensorboard using <code> writer.add_image </code></p>
<pre><code>import matplotlib.pyplot as plt
from mlxtend.plotting import plot_confusion_matrix

fig, ax = plot_confusion_matrix(conf_mat=conf_mat)
plt.show()
</code>
</pre>
<p><code> fig </code> is of type <code>matplotlib.figure.Figure</code> and it should be converted to a torch.tensor or numpy.array since <code>writer.add_image</code> expects one of these as input. I tried some workarounds but none of them worked.<br>
Any suggestions?</p>

ptrblck: <p>Would it be possible to pass <code>conf_mat</code> directly to <code>writer.add_image</code>?<br>
If this method expects a tensor or numpy array, I guess it would be possible or did you get an error?</p>

harsha_g: <p>You should use <code>writer.add_figure</code> instead</p>
<pre><code class="lang-auto">fig = plt.figure()
plt.imshow(conf_mat)

writer.add_figure('my_image', fig)
</code></pre>

Federico_Vasile: <p>Could you provide me an example? I tried but it does not work(the code runs, but on Tensorboard there are no images)</p>

Federico_Vasile: <aside class="quote no-group" data-username="ptrblck" data-post="2" data-topic="86529" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ptrblck/48/1823_2.png" class="avatar"> ptrblck:</div>
<blockquote>
<p>Would it be possible to pass <code>conf_mat</code> directly to <code>writer.add_image</code> ?<br>
If this method expects a tensor or numpy array, I guess it would be possible or did you get an error?</p>
</blockquote>
</aside>
<p>It does not work, I guess the expected tensor should be a tensor representing an image, while <code> conf_mat </code> is a “raw” confusion matrix, e.g.</p>
<pre><code>[[21, 1], 
 [3, 1]]
</code></pre>

harsha_g: <pre><code class="lang-auto"># pip install --upgrade torch
# pip install tensorboard

import matplotlib.pyplot as plt

import tensorboard
import torch

from sklearn.metrics import confusion_matrix
from torch.utils.tensorboard import SummaryWriter

print(torch.__version__) # 1.5.1
print(tensorboard.__version__)  # 2.2.2

writer = SummaryWriter('runs/experiment')

output = torch.randn(1, 2, 4, 4)
pred = torch.argmax(output, 1)
target = torch.empty(1, 4, 4, dtype=torch.long).random_(2)
conf_mat = confusion_matrix(pred.view(-1), target.view(-1))

fig = plt.figure()
plt.imshow(conf_mat)
plt.show()

writer.add_figure('my_fig', fig)
</code></pre>
<p>And here’s the tensorboard snapshot <div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/7/1/71bf888cf6fa1745ef8ec1c323700901bc7171b6.png" data-download-href="https://discuss.pytorch.org/uploads/default/71bf888cf6fa1745ef8ec1c323700901bc7171b6" title="Screen Shot 2020-06-24 at 11.45.25 AM"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/7/1/71bf888cf6fa1745ef8ec1c323700901bc7171b6_2_690x274.png" alt="Screen Shot 2020-06-24 at 11.45.25 AM" data-base62-sha1="gegjnyv65Qp5mOq5XYDnEvNVEKa" width="690" height="274" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/7/1/71bf888cf6fa1745ef8ec1c323700901bc7171b6_2_690x274.png, https://discuss.pytorch.org/uploads/default/optimized/3X/7/1/71bf888cf6fa1745ef8ec1c323700901bc7171b6_2_1035x411.png 1.5x, https://discuss.pytorch.org/uploads/default/original/3X/7/1/71bf888cf6fa1745ef8ec1c323700901bc7171b6.png 2x" data-dominant-color="EFE5DE"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">Screen Shot 2020-06-24 at 11.45.25 AM</span><span class="informations">1275×508 33.4 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>

Federico_Vasile: <p>I tried with your code but it does not work, using same versions.<br>
The code runs correctly and the image is correctly showed on video (via <code> plt.show()</code>) but it does not write the figure to Tensorboard. The strange behavior is that if i try with a random image(taken for example from my dataset), now it writes correctly to Tensorboard. I can’t see where the problem might be.<br>
Anyway, thank you so much for your patience!</p>

harsha_g: <p>Maybe, a simple refresh of the page/board will help <img src="https://discuss.pytorch.org/images/emoji/apple/wink.png?v=9" title=":wink:" class="emoji" alt=":wink:"> ? It was really that simple in my case. I hope you figure out the issue soon.  I am sorry I couldn’t be much helpful.</p>

Federico_Vasile: <p>In case it might be useful for someone, by modifying the previous code in this way works in my case (the previous code worked on Colab but not locally in my case)</p>
<pre><code>import matplotlib.pyplot as plt
plt.switch_backend('agg')

import tensorboard
import torch

from sklearn.metrics import confusion_matrix
from torch.utils.tensorboard import SummaryWriter

print(torch.__version__) # 1.5.1
print(tensorboard.__version__)  # 2.2.2

writer = SummaryWriter('runs/experiment')

output = torch.randn(1, 2, 4, 4)
pred = torch.argmax(output, 1)
target = torch.empty(1, 4, 4, dtype=torch.long).random_(2)
conf_mat = confusion_matrix(pred.view(-1), target.view(-1))

fig = plt.figure()
plt.imshow(conf_mat)

writer.add_figure('my_fig', fig)
writer.close()
</code></pre><code>
</code>
Now the confusion matrix is correctly written on Tensorboard.