Softmax回归的简洁实现

取多少为底都是差不多的哦,一切的对数都可以看成是以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()就好了

谢谢老哥(zsbdzsbdzsbdzsbd

所以书里说的“#@save是特殊标记,会把语句保存在对d2l包中”是骗人的啊,还在奇怪这咋实现的

我在本地conda环境下运行notebook, 但是在最后一步训练的时候,ipynb的kernel似乎崩溃了,显示如下信息:

Kernel Restarting
The kernel for softmax-regression-concise.ipynb appears to have died. It will restart automatically.

请问运行这个notebook对硬件的要求是什么。我手上的笔记本有点老了。i7 6代处理器,24G内存,4G英伟达显卡,是否跑得动,谢谢

我也遇到这个问题,是要降低d2l的版本吗

image

在前一章节明明已经保存了train_ch3函数了,为什么在这一章节里还是module ‘d2l.torch’ has no attribute 'train_ch3’呢?我又尝试了重新保存再重新导入d2l包仍然不行。好奇怪。

d2l版本的问题,降低一下版本试试,我之前默认是1.0.3,也提示相关错误,现在换成0.17.0好了

d2l=1.0.3环境下运行代码 d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer) 报错 module 'd2l.torch' has no attribute 'train_ch3'

似乎是新版本的包中缺少了 train_ch3 的相关实现,解决办法是在 d2l 的包中添加相关代码,也就是 3.6中的 evaluate_accurary(), train_epoch_ch3() 和 train_ch3(),具体步骤如下:

  1. 定位到环境下d2l包的位置,我使用conda虚拟环境,名称为d2l,python版本3.11,具体是在 /home/cutelemon6/miniconda3/envs/d2l/lib/python3.11/site-packages/d2l
  2. 删除原来的缓存 rm -r /home/cutelemon6/miniconda3/envs/d2l/lib/python3.11/site-packages/d2l/__pycache__
  3. 如果你使用pytorch,在 torch.py 中添加如下代码
def evaluate_accurary(net, data_iter: torch.utils.data.DataLoader):
    if isinstance(net, torch.nn.Module):
        net.eval()
    metric = Accumulator(2)
    with torch.no_grad():
        for X, y in data_iter:
            metric.add(accuracy(net(X), y), y.numel())
    return metric[0] / metric[1]

def train_epoch_ch3(net, train_iter, loss, updater):
    metrics = Accumulator(3)
    if isinstance(net, torch.nn.Module):
        net.train()
    for X, y in train_iter:
        y_hat = net(X)
        l = loss(y_hat, y)
        if isinstance(updater, torch.optim.Optimizer):
            updater.zero_grad()
            l.mean().backward()
            updater.step()
        else:
            l.sum().backward()
            updater(X.shape[0]) # number of X's samples
        metrics.add(float(l.sum()), accuracy(y_hat, y), y.numel())
        
    return metrics[0] / metrics[2], metrics[1] / metrics[2]

def train_ch3(net, train_iter, test_iter, loss, num_epochs, updater): 
    """训练模型(定义见第3章)"""
    animator = Animator(xlabel='epoch', xlim=[1, num_epochs], ylim=[0.3, 0.9],
                        legend=['train loss', 'train acc', 'test acc'])
    for i in range(num_epochs):
        train_metrics = train_epoch_ch3(net, train_iter, loss, updater)
        test_acc = evaluate_accurary(net, test_iter)
        animator.add(i + 1, train_metrics + (test_acc,))
    train_loss, train_acc = train_metrics
    assert train_loss < 0.5, train_loss
    assert train_acc <= 1 and train_acc > 0.7, train_acc
    assert test_acc <= 1 and test_acc > 0.7, test_acc
  1. 重启jupyter notebook kernel,全部运行代码即可

Hi, the reason why the trainloss is not displayed on the image is because the value of the loss is too large or the value of the loss is too small. You can check the code that calculates the loss to see if the loss added in is too large or too small.