工具使用-pytorch使用visdom绘图、检测训练过程

发布 : 2019-06-21 浏览 :

visdom的更能很强的大,支持各种交互,目前只记录下我用到的部分功能。后续用到新的功能再进行添加。

安装

1
2
# 支持python2.7/3, 可以在conda环境中安装
pip install visdom

用法

首先需要启动visdom服务器:

1
python -m visdom.server

然后可以通过访问127.0.0.1:8097浏览器访问visdom, 如果是在远程服务器上运行的visdom, 则可以使用9087端口访问, 比如172.18.32.133:8097

若上述操作不起作用, 则将以下行添加到本地:

~/.ssh/config:LocalForward

127.0.0.1:8097 127.0.0.1:8097

用法示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
import time
import visdom
import matplotlib
import torch as t
import numpy as np

matplotlib.use("Agg")
from matplotlib import pyplot as plt

def vis_image(img, ax=None):
"""Visualize a color image
img: RGB format with values between [0, 255], 3 x H x W, array
ax: matplotlib.axes.Axis, where to display the img
return: returns the Axes object with the plot for further tweaking
"""
if ax is None:
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
img = img.transpose((1, 2, 0)) # CHW => HWC
ax.imshow(img.astype(np.uint8))
return ax

def vis_bbox(img, bbox, label=None, score=None, gt=False, ax=None):
"""Visualize bounding boxes inside image.
"""
if label is not None and not len(bbox) == len(label):
raise ValueError('The length of label must be same as that of bbox')
if score is not None and not len(bbox) == len(score):
raise ValueError('The length of score must be same as that of bbox')

# Returns newly instantiated matplotlib.axes.Axes object if ax is None
ax = vis_image(img, ax=ax)
# If there is no bounding box to display, visualize the image and exit.
if len(bbox) == 0:
return ax
if gt: # whether containing gt-boxes in bbox
n = int(len(bbox)/2)
else:
n = len(bbox)
for i, bb in enumerate(bbox):
if i<n:
color = 'blue' # groudtruth
else:
color = 'red'
xy = (bb[1], bb[0])
height = bb[2] - bb[0]
width = bb[3] - bb[1]
ax.add_patch(plot.Rectangle(
xy, width, height, fill=False, edgecolor=color, linewidth=2))
caption = list()
if label is not None:
lb = label[i]
caption.append(str(lb).zfill(3))
if score is not None:
sc = score[i]
caption.append('{:.2f}'.format(sc))

if len(caption) > 0:
ax.text(bb[1], bb[0],
': '.join(caption),
style='italic',
bbox={'facecolor': 'white', 'alpha': 0.5, 'pad': 0})
return ax

def fig2data(fig):
"""
brief Convert a Matplotlib figure to a 4D numpy array with RGBA
channels and return it
@param fig: a matplotlib figure
@return a numpy 3D array of RGBA values
"""
# draw the renderer
fig.canvas.draw()

# Get the RGBA buffer from the figure
w, h = fig.canvas.get_width_height()
buf = np.fromstring(fig.canvas.tostring_argb(), dtype=np.uint8)
buf.shape = (w, h, 4)

# canvas.tostring_argb give pixmap in ARGB mode. Roll the ALPHA channel to have it in RGBA mode
buf = np.roll(buf, 3, axis=2)
return buf.reshape(h, w, 4)

def fig4vis(fig):
"""
convert figure to ndarray
"""
ax = fig.get_figure()
img_data = fig2data(ax).astype(np.int32)
plot.close()
# HWC->CHW
return img_data[:, :, :3].transpose((2, 0, 1)) / 255.

def visdom_bbox(*args, **kwargs):
fig = vis_bbox(*args, **kwargs)
data = fig4vis(fig) # 将生成数据转换成可保存的格式
return data

class Visualizer(object):
"""
wrapper for visdom
you can still access naive visdom function by
self.line, self.scater,self._send,etc.
due to the implementation of `__getattr__`
"""

def __init__(self, env='default', **kwargs):
self.vis = visdom.Visdom(env=env, use_incoming_socket=False, **kwargs)
self._vis_kw = kwargs

# e.g.('loss',23) the 23th value of loss
self.index = {}
self.log_text = ''

def reinit(self, env='default', **kwargs):
"""
change the config of visdom
"""
self.vis = visdom.Visdom(env=env, **kwargs)
return self

def plot(self, name, y, showlegend=False, **kwargs):
""" plot line
name: the name of variable
y: the current value of variable
showlenged: whether show variable's lengend
Example:
self.plot('loss',1.00)
"""
x = self.index.get(name, 0)
self.vis.line(Y=np.array([y]), X=np.array([x]),
win=name,
opts=dict(title=name, showlegend=showlegend),
update=None if x == 0 else 'append',
**kwargs
)
self.index[name] = x + 1


def plot_many(self, d):
"""
plot multi values
@params d: dict (name,value) i.e. ('loss',0.11)
"""
for k, v in d.items():
if v is not None:
self.plot(k, v)

def img(self, name, img_, **kwargs):
"""
self.img('input_img',t.Tensor(64,64))
self.img('input_imgs',t.Tensor(3,64,64))
self.img('input_imgs',t.Tensor(100,1,64,64)) 100张灰度图像
self.img('input_imgs',t.Tensor(100,3,64,64),nrows=10)
!!don't ~~self.img('input_imgs',t.Tensor(100,64,64),nrows=10)~~!!
"""
self.vis.images(t.Tensor(img_).cpu().numpy(),
win=name,
opts=dict(title=name),
**kwargs
)

def img_many(self, d):
for k, v in d.items():
self.img(k, v)

def log(self, info, win='log_text'):
"""
self.log({'loss':1,'lr':0.0001})
"""
self.log_text += ('[{time}] {info} <br>'.format(
time=time.strftime('%m%d_%H%M%S'), \
info=info))
self.vis.text(self.log_text, win)

def __getattr__(self, name):
return getattr(self.vis, name)

def state_dict(self):
return {
'index': self.index,
'vis_kw': self._vis_kw,
'log_text': self.log_text,
'env': self.vis.env
}

def image_bbox(self, name, image, bbox, label=None, score=None, gt=False, ax=None):
img_data = visdom_bbox(image, bbox, label=label, score=score, gt=gt)
self.img(name, img_data)

def load_state_dict(self, d):
self.vis = visdom.Visdom(env=d.get('env', self.vis.env), **(self.d.get('vis_kw')))
self.log_text = d.get('log_text', '')
self.index = d.get('index', dict())
return self

def img_heatmap(self, name, X):
"""heatmaps
X: H x W, array
"""
self.vis.heatmap(X, win=name)

if __name__ == '__main__':
vis = Visualizer()
import torch
img = torch.randn(35, 1, 40, 60)
print(torch.max(img[0]))
vis.img('test3', img)
vis.img('test2', img, nrow=10)
vis.log('test', win='test')
import numpy as np
img = np.random.rand(3,100, 120)
bbox = np.array([[20, 30, 30, 60], [30, 40, 70, 80]])
label = np.array([0, 1])
vis.image_bbox('image_bbox', img, bbox, label=label)
vis.img_heatmap('heatmap', np.random.rand(180, 240))

p0_1 = np.random.rand(10)
p0_2 = np.random.rand(10)
for i in range(10):
vis.plot('precision', [p0_1[i], p0_2[i]], showlegend=True)

example

本文作者 : zhouzongwei
原文链接 : http://yoursite.com/2019/06/21/visdom/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

知识 & 情怀 | 赏或者不赏,我都在这,不声不响

微信扫一扫, 以资鼓励

微信扫一扫, 以资鼓励

支付宝扫一扫, 再接再厉

支付宝扫一扫, 再接再厉

留下足迹