MXBoard — 助力 MXNet 数据可视化

mxboard还会更新吗

刚用py3.6试了下没问题。这是启动tensorboard的时候挂了还是logging的时候挂了?tensorboard和TensorFlow的版本是多少?升级到最新版看看?

你好,我的图片数据在通过数据增强后,data数值出现了负数,导致在使用add_image出错,是数据增强方式不对么?我该怎样才能更好的可视化训练中的效果图呢?

数据增强的时候因为输入了mean和std,所以图片被normalize了,增强的结果本身没有错。你需要把增强后的图片denormalize回去,再传给add_image就可以了。其实就是在im = aug(im)后面做一次 im * std + mean,然后再改成NCHW的格式传给add_image

谢谢你的回答,但是由于我是在epoch下记录add_image的,按你的意思就是将过程逆过来,所以我在add_image前进行了以下修改,
%E5%9B%BE%E7%89%87
但是出现了错误mxnet.base.MXNetError: [09:54:35] src/imperative/./imperative_utils.h:70: Check failed: inputs[i]->ctx().dev_mask() == ctx.dev_mask() (1 vs. 2) Operator dot require all inputs live on the same context. But the first argument is on gpu(0) while the 2-th argument is on cpu(0)
这种情况我该怎么继续去修改呢?

有三个错误需要纠正下:

  1. data[0]在GPU上,需要先copy到CPU上,data[0].copyto(mx.cpu()),然后才能跟mean和std做运算。
  2. data[0]跟std不是dot,应该先把data[0]的shape变成(10, 160, 160, 3),然后乘以std,这里的乘法用到了broadcast multiply。运算完了后把结果再变成NCHW传给add_image。
  3. std, mean应该是shape=(3,)。

看一下normalize的源代码应该有助于理解。

非常感谢你的指导,我现在将过程修改成这样可对?

但是还是出现了ValueError: expected non-negative min value from img, while received -0.07052838802337646,数据这样倒回去还是出现负值,

,这就有点头大了

改成下面的试试

p = data[0].copyto(mx.cpu())  #p是NCHW格式
p = nd.transpose(p, (0, 2, 3, 1))  #变成NHWC格式
std = nd.array([0.229, 0.224, 0.225])
mean = nd.array([0.485, 0.456, 0.406])
p = p * std + mean
assert p.min().asscalar() >= 0.0
assert p.max().asscalar() <= 1.0
p = nd.transpose(p, (0, 3, 1, 2 ))  #恢复成NCHW格式
sw.add_image('data_batch', p, epoch)

非常感谢,我查看了下tensorboard,写入文件的全是原始图片,要是想保存卷基层(以及视觉注意)输出图片的话还需要做哪些修改呢?

Gluon似乎目前还没有很好的办法保存卷几层的中间输出,你可以在论坛上另外提这个问题。

Symbol API的话可以用monitor得到中间输出。参考

非常感谢你,结合你给的demo和我参考的模型代码,我发现我的代码里用net.save_parameters直接保存的模型(官网说 this method only saves parameters, not model structure.),而demo里可视化结果用的是weight和bias分别保存的param文件,这两者之间可以转化么?(我用net.collect_params()查看了一下网络里的参数,里面包含了每层的weight和bias),如果不能转化,我需要怎么做才可以得到像你给的demo里那样可视化天鹅的卷积层效果图呢?在网上找到这块的资料相对较少了,还是来这里问问看…

demo里的weight和bias是我手动存成两个文件的,你用gluon api存下来的.params文件包含了所有的weights和bias,你需要根据model structure选出所需的layer,然后通过layer找到所需的weight和bias的名字,就可以从.params文件里把他们找出来了。

我怎样才可以从我直接保存的.params文件里剥离出我想要的层的weight和bias呢?

你需要把模型的结构导出,用export函数。

然后找到所需要的layer和layer对应的input data和weight的名字,然后从.params文件里把名字对应的ndarray取出来。

或者可以把模型的网络图通过mxboard画出来,找到对应的layer,layer的metadata里应该有输入data和weight的名字,你试试看吧。

你好,首先灰常谢谢你一直给我答疑解惑.其实我代码是这样的
`import os
import mxnet as mx
from tqdm import tqdm
from mxnet.gluon.data import DataLoader
from mxnet import image, nd, gluon, metric as mtc
from net.attention_net import get_attention_cifar
import matplotlib.pyplot as plt

val_auglist = image.CreateAugmenter(data_shape=(3, 160, 160),
mean=nd.array([0.485, 0.456, 0.406]),
std=nd.array([0.229, 0.224, 0.225]))

def transform_val(im, label):
im = im.astype(‘float32’) / 255
for aug in val_auglist:
im = aug(im)
im = nd.transpose(im, (2, 0, 1))
return im, label

batch_size = 10
ctx = mx.gpu()

val_set = gluon.data.vision.ImageRecordDataset (‘dataset/valid.rec’, transform=transform_val)
val_data = DataLoader(val_set, batch_size, False, num_workers=2)

net = get_attention_cifar(4, num_layers=56) ####网络模型
net.load_parameters(“models/best-0.985000-attention56-model-epoch-93-Vanilla.params”, ctx=ctx) ###导入训练保存的模型参数
net.hybridize()

params = net.collect_params()
params_names = params.keys() ####得到各层名字

print(params)

print(params_names)

print(net.features[3]._name)

w1 = net.collect_params(‘attentionnetcifar0_conv0_weight’) ####这个attentionnetcifar0_conv0_weight是我的卷基层第一层卷积的名字,只是拿他来测试下
print(w1) ####查看具体数值
exit()

#######################
准备可视化指定层卷积后的图
#######################

metric = mtc.Accuracy()
cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss()
val_loss = 0

for i, batch in tqdm(enumerate(val_data)):
data = batch[0].as_in_context(ctx)
labels = batch[1].as_in_context(ctx)
outputs = net(data)
metric.update(labels, outputs)

_, val_acc = metric.get()
print(val_acc)’
这样还需要怎么单独导出我的模型结构呢?这一块真的不是很熟…

如果你已经拿到了第一个卷积层的weight(假设没有bias),再把第一个卷积层的参数取出,就是kernel size, num_filter这些,然后用mx.nd.Convolution直接作用在input data上就可以得到输出结果,对每个feature map都可以画一张图片。

真的很谢谢reminisce,最后再问一句,假如我的操作不是单单一个卷机层,而是一个残差单元块(里面包括了不同size的卷积层和归一化),这样的话我怎么输入图片可视化这个结果呢?还有demo里天鹅的可视化操作可以在训练时就写入文件么,还是只能在训练完再从保存的模型参数里剥离出想可视化的层呢?大神,有这块完整的实例么,现在论文实验到了一个关键点…

有个比较hacky的办法,就是在所需要保存输出结果的block的forward函数里把输出结果存到mxboard里去。

参照 https://zh.mxnet.io/blog/mxboard中的 MNIST中的样例,用resnet18来训练cifar10,loss,acc都能在mxboard上成功显示。但
grads = [i.grad() for i in net.collect_params().values()] 报错如下

RuntimeError: Cannot get gradient array for Parameter ‘hybridsequential2_batchnorm0_running_mean’ because grad_req=‘null’

添加了BN就会出错。

running_mean是没有gradient的。在call i.grad()之前先检查下i有没有gradient,没有的话就跳过就可以了,注意跳过的param的相应的param name也不要加进去。