0

我正在尝试建立一个网络,其中一层从实数映射到 {0, 1}(即使输出二进制)。

我试过的

虽然我能够找到它torch.ge提供了这样的功能,但每当我想训练在网络 PyTorch 中断之前发生的任何参数时。

我也一直在尝试寻找 PyTorch/autograd 中是否有任何方法可以手动覆盖模块的派生。更具体地说,在这个原因中,我只想通过 torch.ge 传递导数,而不改变它。

最小的例子

这是我制作的一个最小示例,它使用 PyTorch 中的典型神经网络训练结构。

import torch
import torch.nn as nn
import torch.optim as optim


class LinearGE(nn.Module):
    def __init__(self, features_in, features_out):
        super().__init__()
        self.fc = nn.Linear(features_in, features_out)

    def forward(self, x):
        return torch.ge(self.fc(x), 0)


x = torch.randn(size=(10, 30))
y = torch.randint(2, size=(10, 10))

# Define Model
m1 = LinearGE(30, 10)

opt = optim.SGD(m1.parameters(), lr=0.01)

crit = nn.MSELoss()

# Train Model
for x_batch, y_batch in zip(x, y):
    # zero the parameter gradients
    opt.zero_grad()

    # forward + backward + optimize
    pred = m1(x_batch)
    loss = crit(pred.float(), y_batch.float())
    loss.backward()
    opt.step()

我遇到的

当我运行上面的代码时,会发生以下错误:

File "__minimal.py", line 33, in <module>
    loss.backward()
...
RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn

这个错误是有道理的,因为torch.ge函数是不可微的。但是,由于MaxPool2D也是不可微的,我相信有一些方法可以减轻 PyTorch 中的不可微性。

如果有人可以向我指出任何可以帮助我为自定义模块实现自己的反向传播或任何避免此错误消息的方式的来源,那就太好了。

谢谢!

4

1 回答 1

1

我注意到的两件事

  1. 如果您的输入 x 为 10x30(10 个示例,30 个特征)并且输出节点的数量为 10,则参数矩阵为 30x10。预期输出矩阵为 10x10(10 个示例 10 个输出节点)

  2. ge= 大于等于。如代码所示, x >= 0 元素明智。我们可以使用relu。

class LinearGE(nn.Module):
    def __init__(self, features_in, features_out):
        super().__init__()
        self.fc = nn.Linear(features_in, features_out)
        self.relu = nn.ReLU(inplace=True)

    def forward(self, x):
        return self.relu(self.fc(x))

或者torch.max

torch.max(self.fc(x), 0)[0]
于 2019-10-23T20:37:07.333 回答