我想知道如何自定义一个卷积层,其中卷积滤波器由某些函数而不是独立参数决定。我在下面做了一个玩具示例。 a
和 b
是参数。 2X2 过滤器创建为 torch.tensor([[[[a+b, a-b], [a-b,a+b]]]])
。我们可以看到,它是由 a
和 b
决定的,而不是由四个独立的参数决定的。在我的实验中,网络只是由一个这样的过滤器组成。我做了一个简单的学习任务来测试我的代码,其中只有一个训练实例:输入:torch.tensor([[[[1.0, 0],[0,0]]]])
,真实输出:torch.tensor([[2.0]])
。我在下面附上了我的代码和实验。
class MyModel(nn.Module):
def __init__(self):
super(MyModel, self).__init__()
# in my later experiment there might be multiple parameters,
# so I made the generate_parameters() function
a, b = self.generate_parameters()
self.conv = nn.Conv2d(1, 1, 2, bias=False)
kernel = self.generate_kernel(a, b)
self.conv.weight = nn.Parameter(kernel)
def forward(self, x):
x = self.conv(x)
return x
def generate_parameters(self):
a = nn.Parameter(torch.zeros(1, 1))
b = nn.Parameter(torch.zeros(1, 1))
return a, b
def generate_kernel(self, a, b):
return torch.tensor([[[[a+b, a-b], [a-b,a+b]]]])
model = MyModel()
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.1)
inputs, labels = torch.tensor([[[[1.0, 0],[0,0]]]]), torch.tensor([[2.0]])
for epoch in range(10): # loop over the dataset multiple times
for param in model.parameters():
print(param.data, param.size())
# zero the parameter gradients
optimizer.zero_grad()
# forward + backward + optimize
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
实验结果:
epoch: 0 tensor([[[[0., 0.],
[0., 0.]]]]) torch.Size([1, 1, 2, 2])
epoch: 1 tensor([[[[0.4000, 0.0000],
[0.0000, 0.0000]]]]) torch.Size([1, 1, 2, 2])
epoch: 2 tensor([[[[0.7200, 0.0000],
[0.0000, 0.0000]]]]) torch.Size([1, 1, 2, 2])
epoch: 3 tensor([[[[0.9760, 0.0000],
[0.0000, 0.0000]]]]) torch.Size([1, 1, 2, 2])
epoch: 4 tensor([[[[1.1808, 0.0000],
[0.0000, 0.0000]]]]) torch.Size([1, 1, 2, 2])
epoch: 5 tensor([[[[1.3446, 0.0000],
[0.0000, 0.0000]]]]) torch.Size([1, 1, 2, 2])
epoch: 6 tensor([[[[1.4757, 0.0000],
[0.0000, 0.0000]]]]) torch.Size([1, 1, 2, 2])
epoch: 7 tensor([[[[1.5806, 0.0000],
[0.0000, 0.0000]]]]) torch.Size([1, 1, 2, 2])
epoch: 8 tensor([[[[1.6645, 0.0000],
[0.0000, 0.0000]]]]) torch.Size([1, 1, 2, 2])
epoch: 9 tensor([[[[1.7316, 0.0000],
[0.0000, 0.0000]]]]) torch.Size([1, 1, 2, 2])
正如我们所见,经过训练的过滤器与我们预期的不同(它应该是一个对称的 2X2 矩阵)。理想情况下,我认为模型应该只有两个参数 a
和 b
。有什么建议可以修复我的代码或实验吗?谢谢!