Softmax回归的简洁实现

在jupyter notebook中实现了 softmax回归的从零开始实现之后,在 Softmax回归的简洁实现中遇到如下问题,调用之前的train_ch3这个函数报错:AttributeError: module ‘d2l.torch’ has no attribute ‘train_ch3’ ,请问大家是什么原因,如何解决?

去colab试了一下,没有报错,能跑通。怀疑是否是d2l版本问题,colab中d2l版本2.0.0,本地d2l版本1.0.3,教材安装指导版本0.17.6,或者是其他的版本问题?欢迎大神指导回复。

2 Likes

我去教材官网上安装的包,去里面看了现在并没有train_ch3这个封装好的函数了,所以跑不通,估计要换包

1 Like

后续章节里又遇到这个ch3问题。降低python版本和d2l版本与教材一致后,已经可以了。

2 Likes

我自己都蚌埠住了- -

完全用torch重写之后的成果还不错

#!/usr/bin/env python3

import torch
import torchvision
import matplotlib.pyplot as plt
from torch.utils import data
from torchvision import transforms
from torch import nn

def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01)

def get_dataloader_workers():
    return 4

def load_data_fashion_mnist(batch_size, resize=None):
    trans = [transforms.ToTensor()]
    if resize:
        trans.insert(0, transforms.Resize(resize))
    trans = transforms.Compose(trans)
    mnist_train = torchvision.datasets.FashionMNIST(
        root="/tmp", train=True, transform=trans, download=True)
    mnist_test = torchvision.datasets.FashionMNIST(
        root="/tmp", train=False, transform=trans, download=True)
    return (data.DataLoader(mnist_train, batch_size, shuffle=True, num_workers=4),
            data.DataLoader(mnist_test, batch_size, shuffle=False, num_workers=4))

def get_fashion_mnist_labels(labels):
    text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
                   'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
    return [text_labels[int(i)] for i in labels]

def test_images(imgs, labels, preds):
    _, axes = plt.subplots(1, len(imgs))
    for (img, label, pred, ax) in zip(imgs, labels, preds, axes):
        if torch.is_tensor(img):
            ax.imshow(img[0].numpy())
        else:
            ax.imshow(img[0])
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        ax.set_title(label + '\n' + pred)
    plt.show()

if __name__ == "__main__":
    batch_size, lr, num_epochs = 256, 0.1, 10
    net = nn.Sequential(nn.Flatten(), nn.Linear(28 * 28, 10), nn.Softmax(1))
    net.apply(init_weights)
    loss = nn.CrossEntropyLoss()
    trainer = torch.optim.SGD(net.parameters(), lr=lr)
    net.train()
    for i in range(50):
        train_iter, _ = load_data_fashion_mnist(batch_size=batch_size)
        for X, y in train_iter:
            l = loss(net(X), y)
            trainer.zero_grad()
            l.backward()
            trainer.step()
        print(f'epoch {i + 1}, loss {l:f}')
    net.eval()
    _, test_iter = load_data_fashion_mnist(batch_size=batch_size)
    batch = next(iter(test_iter))
    imgs, labels = batch[0], batch[1]
    preds = net(imgs).argmax(axis=1)
    test_images(imgs[:8], get_fashion_mnist_labels(labels[:8]), get_fashion_mnist_labels(preds[:8]))
 
3 Likes

这里取对数要用ln,而你是用lg算的。要证明log(y_hat)==O-max-log(sum of exp),取e为底和取10为底显然不同。但是O-max==0时,恰好等价而已。

我也遇到了同样的问题,在这一行中报错显示除数为零,请问您解决了吗

不用写,直接是个空括号。plt.show()

取多少为底都是差不多的哦,一切的对数都可以看成是以e为底的对数,用换底公式就知道了:
equation

所以换个底数其实只是损失提取了一个常系数 a,原来以 e 为底的损失是 m 的话,现在以 10 为底的损失就可以看成是 m’ = a · m,其中 a = 1 / ln(10),那么就损失的梯度而言,原来的梯度 ∂ m’ = a · ∂ m,那么梯度下降的时候也是一样缺了一个常系数,所以你要是改变底数,实际上也就和调节学习率是一样的道理。

类似的,一切的指数都可以看成是以 e 为底的指数,参考:
[此图省略,新用户只能发一张图,参见下面回复]

再补充纠正一点,torch或者numpy中的log都是以e为底的哦

equation (2)

我正在使用pytorch版代码,而且 torch.cuda.is_available()也已经为true,但是我在运行本节示例代码时仍是在用cpu计算,请问我该如何将softmax的这段示例代码运行在cuda上

这本书写的代码真nm写的是一坨狗屎,完全没有工程化,流程化,体系化的思想和风格。需要看代码的建议去看另一个教程Zero to Mastery Learn PyTorch for Deep Learning

1 Like

我也遇到这个问题。目前不知道怎么解决。。。。

这个d2l中无法查看到train_ch3这个函数 而且之前定义的类也完全查看不到 就是因为d2l版本不对么?

1 Like

我也遇到这个问题,请问怎么解决的??????

解决办法:把缺失的函数补充到d2l对应源码里

找源码方法:pip show d2l, 找到d2l包所在文件夹位置

多次运行报错找不到的代码块,查看是什么函数没有,把那段函数代码复制到源码里(注意:不要用中文字符,可能产生编码错误)

方便期间,汇总一下我这边发现要补充的函数:train_ch3, train_epoch_ch3, evaluate_accuracy
(均在softmax从零开始章节出现)

3 Likes

你好,我补充了这三个函数后还是不行,虽然没报错但训练完后没有图像输出,只有下面输出内容:

我用的环境是pycharm,请问是不是跟这个有关?

我这还补了个Animator类
但是没补之前会报错,可能跟你不是同一个情况

谢谢,这个问题已经解决了,就是Animator类的问题,原始代码中是基于ipython环境的写法,改成d2l.plt.draw()就好了