V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
LeeReamond
V2EX  ›  Python

Pytorch 中正确的使用 softmax 的方法是什么?

  •  
  •   LeeReamond · 2021-11-18 18:29:39 +08:00 · 2176 次点击
    这是一个创建于 1090 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,初学者,看官网的 tutorials 中的 quick start ,它是定义了一个长相为这样的网络

            self.linear_relu_stack = nn.Sequential(
                nn.Linear(28*28, 512),
                nn.ReLU(),
                nn.Linear(512, 512),
                nn.ReLU(),
                nn.Linear(512, 10)
            )
    

    输出类别为 10 类,然后反向传播的代码是

    pred = model(X)
    loss = loss_fn(pred, y)
    
    # Backpropagation
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    

    loss_fn 是nn.CrossEntropyLoss()交叉熵,那么这个输出类别似乎是没有通过 softmax 直接就输入交叉熵了吗?

    如果要 softmax+交叉熵的话,是应该在定义网络的时候,在最后的 fc 后面再加一个 nn.Softmax(),还是说写成下面这样:

    pred = nn.Softmax(model(X))
    loss = loss_fn(pred, y)
    

    这个样子?谢谢大家

    7 条回复    2021-11-19 09:56:27 +08:00
    raycool
        1
    raycool  
       2021-11-18 18:38:12 +08:00
    没记错的话好像 CrossEntropyLoss 是先调用了 softmax
    oblivious
        2
    oblivious  
       2021-11-18 18:40:15 +08:00   ❤️ 1
    不需要加 nn.Softmax ,nn.CrossEntropyLoss 在计算 loss 的时候,会帮你把最后一层的输入做 softmax ,你可以仔细阅读 https://pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html#torch.nn.CrossEntropyLoss 的计算 loss 的公式。
    houshuu
        3
    houshuu  
       2021-11-18 18:42:23 +08:00
    因为 CrossEntropyLoss 融合了 LogSoftmax 和 NLLLoss.
    可以看看[官方文档]( https://pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html), 这个问题算是老生常谈了.
    LeeReamond
        4
    LeeReamond  
    OP
       2021-11-18 19:00:25 +08:00
    @houshuu
    @oblivious
    @raycool 大佬们知不知道现在常用的激活函数是什么?我看一些文章写 elu 效果不错,可以在 elu 后不用接 nb 层以起到减小模型的目的,如果想要在网络里面自己调整激活函数(比如用一个经典的 resnet18 模型,然后想要改一改激活函数的话)有什么文章可以指导这种修改逻辑吗?

    还有就是我想学习经典模型的话,我看 torchvision 里面有一些预训练好的模型,但是数量比较少,我看类似 resnet34 和 resnet50 这种都没有,我想学习 resnet34 的参数,网上写的比较详细的文章不是很好搜
    oblivious
        5
    oblivious  
       2021-11-18 20:12:10 +08:00
    @LeeReamond 常用的激活函数:relu……

    有时候会试试 gaussian relu
    houshuu
        6
    houshuu  
       2021-11-18 20:17:59 +08:00
    @LeeReamond ReLU 依旧是最常用的, 但是我这两年挺爱用 Leaky ReLU 的. 网上也有不少关于激活函数的对比文章, 个人觉得还是需要针对不同任务, 不同知识领域来选用. 但是差别很大倒是也没有.
    linbo0518
        7
    linbo0518  
       2021-11-19 09:56:27 +08:00 via iPhone
    具体为什么 torch 里这么写,其实主要是 softmax 中有 exp ,本身有数值稳定性的问题,ce loss 里有 log ,两个函数可以抵消,整合到一起又更好的数值稳定性,torch 里叫 logsoftmax
    具体可以参考这篇 blog: https://freemind.pluskid.org/machine-learning/softmax-vs-softmax-loss-numerical-stability/
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3556 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 00:09 · PVG 08:09 · LAX 16:09 · JFK 19:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.