一. TypeError: ‘method’ object is not iterable
1. 错误提示 && 部分代码
错误提示:
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-40-9ae7d7a05a23> in <module> 4 # 从数值标签到文本标签 5 true_labels = d2l.get_fashion_mnist_labels(y.asnumpy()) ----> 6 pred_labels = d2l.get_fashion_mnist_labels(net(X).argmax(axis=1).asnumpy) 7 titles = [true + '\n' + pred for true, pred in zip(true_labels, pred_labels)] 8 D:\anaconda\lib\site-packages\d2lzh\utils.py in get_fashion_mnist_labels(labels) 183 text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat', 184 'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot'] --> 185 return [text_labels[int(i)] for i in labels] 186 187 TypeError: 'method' object is not iterable
通常错误提示还是非常有用的,可以有效地帮助我们地定位bug的位置。
部分代码段:
for X, y in test_iter: break # 从数值标签到文本标签 true_labels = d2l.get_fashion_mnist_labels(y.asnumpy()) pred_labels = d2l.get_fashion_mnist_labels(net(X).argmax(axis=1).asnumpy) titles = [true + '\n' + pred for true, pred in zip(true_labels, pred_labels)] d2l.show_fashion_mnist(X[0:9], titles[0:9])
2. 消灭bug
我看着这个报错,当时就懵了,没看懂它啥意思。后来仔细检查代码发现,原来是调用一个函数asnumpy时,函数名后面的()掉了。于是原本我想调用的函数,被认作了一个对象,作为参数传递给了另一个函数,然后进一步引发了类型错误(TypeError)。
加上缺失的()后,一切正常。程序跑起来了:
二. 自动求梯度,求函数值了吗?
代码:
num_epochs = 3 lr = 0.1 # 用于训练模型 def train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, params=None, lr=None, trainer=None): for epoch in range(num_epochs): train_l_sum, train_acc_sum, n = 0.0, 0.0, 0 for X, y in train_iter: with autograd.record(): y_hat = net(X) l = loss(y_hat, y).sum() l.backward() d2l.sgd(params, lr, batch_size) y = y.astype('float32') train_l_sum += l.asscalar() train_acc_sum += (y_hat.argmax(axis=1) == y).sum().asscalar() n += y.size test_acc = evaluate_accuracy(test_iter, net) print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f' % (epoch + 1, train_l_sum / n, train_acc_sum / n, test_acc))
我对于这段代码一直有些困惑,主要在train_l_sum += l.asscalar()这一语句。这里使用了变量l的值,用于计算模型在训练集上的损失。但是l的值是哪里来的?
我们看下面这段代码:
%matplotlib inline import d2lzh as d2l from mxnet import gluon, autograd, nd X = nd.array([2, 3, 4]) X.attach_grad() with autograd.record(): y = X ** 2 # y.backward() y, X.grad
输出:
原来在使用mxnet的自动求梯度的过程中,在y = X ** 2这一步,也就已经求出了y的值。它不仅仅是表示要求导的一个函数表达式,同时也是一个赋值语句。
小结
在一些小错误费上很多时间,真的划不来。
下次不要再这么马虎了啊。
经常有一些问题,想明白了之后,只感觉之前自己好傻。