【问题标题】:loss.backward() no grad in pytorch NNloss.backward() 在pytorch NN中没有毕业
【发布时间】:2021-12-31 12:32:35
【问题描述】:

代码在 loss.backward() 中给出错误 错误是: untimeError:张量的元素 0 不需要 grad 并且没有 grad_fn

for epoch in range(N_EPOCHS):
    model.train()
    for i,(im1, im2, labels) in enumerate(train_dl):
        i1 = torch.flatten(im1,1)
        i2 = torch.flatten(im2,1)
        inp = torch.cat([i1,i2],1)
        
        b_x = Variable(inp) # batch x
        b_y = Variable(labels) # batch y
        y_ = model(b_x).squeeze()
        y_ = (y_>0.5).float()
        
        print(y_)
        print(l)
        loss = criterion(y_,b_y)
        print(loss.item())
        loss.backward()
        optimizer.step()

【问题讨论】:

  • y_ > 0.5
  • 实际上,我给输入和输出连接的 2 个扁平图像是它们是否属于同一个人。
  • 这就是我做阈值处理的原因。
  • y_.shape 是什么? criterion 是什么?
  • y_ 是 [100,1] 张量,标签是 [100] 大小张量,因此我挤压了 y_,我删除了 y_ = (y_>0.5) 并删除了错误。但我的数据在第一批并没有过拟合

标签: machine-learning neural-network pytorch


【解决方案1】:
y_ = (y_>0.5).float()

具有零梯度,直觉上是因为“参数的微小变化导致值绝对没有变化(想象y_ 的变化很小,它不会影响y_ 的值。

【讨论】:

  • 我没明白你所说的“导致完全没有变化”是什么意思??
  • 模型返回概率,因此我们进行了阈值处理以使其为零或一。
  • 想想任何接近 0.7 的 y_。如果您将其更改一个很小的 ​​epsilon,y_ 会有什么不同吗?不,它会一直为 1。这是“绝对没有变化”,一种直观的方式来思考为什么梯度会为 0(甚至没有实现)。您不能同时使用阈值和(至少是幼稚的)基于梯度的学习。您可以在计算评估指标时使用阈值,但不能使用您想要区分的损失。这就是我们最小化交叉熵而不是最大化准确性等的原因。
  • 我的意思是“*resulting y_”当然会有所不同。
【解决方案2】:

根据 OP 在评论中提供的其他信息,这里的正确方法只是删除该行

y_ = (y_>0.5).float()

【讨论】:

    猜你喜欢
    • 2020-04-02
    • 2020-09-20
    • 1970-01-01
    • 2019-04-28
    • 2019-05-27
    • 1970-01-01
    • 2016-07-30
    • 2018-07-20
    • 1970-01-01
    相关资源
    最近更新 更多