我想定义一个 pytorch 模型,其中一些层是卷积层,其权重是输入的显式函数(具有可学习的参数)。
示例:假设我们有 1 个通道和 1 个小批量 1。 然后给定一个大小为 n 的一维输入向量
x
,我可以将其传递到一维卷积层 nn.Conv1d(1, 1, k, bias = False)
以获得大小为 n-k+1 的输出向量。如果我将卷积层包装到模型中,该模型现在有 k 个可学习参数(一维卷积层的权重)。
现在假设我的输入实际上是一对一维向量
(x, y)
,其中y
的大小为m。
我希望 y “控制”应用于 x 的卷积层的权重,因为卷积层的权重是向量 A * y
,其中 A 是可学习参数的 k×m 矩阵。
问题:我对如何定义
nn.Module
类来满足上述要求感到困惑。
假设我从一个非常简单的模型开始,它仅应用一维卷积层:
import torch
import torch.nn.functional as F
class Conv1dModel(torch.nn.Module):
def __init__(self, kernel_size):
super(Conv1dModel, self).__init__()
self.conv1d = torch.nn.Conv1d(in_channels = 1, out_channels = 1, kernel_size = kernel_size)
def forward(self, x):
output = self.conv1d(x)
return output
然后我想修改卷积层的权重,我可以使用
self.conv1d.weights
访问它。
但这是我的困惑:我认为我可以(应该?)只在初始化方法self.xyz
中修改模块参数(通过__init__
访问),但另一方面为了设置weights = Linear(m,k)(y)
我需要输入向量 y,在初始化时不可用。
如何解决这个难题?
因此,您可以有一个生成一组权重的过程,然后使用
torch.nn.functional.conv1d
函数使用这些权重应用卷积。但我发现这种方法有问题。
对于标准
conv1d
操作,您的输入将具有形状 (batch_size, in_channels, i*W)
,您的体重将具有形状 (out_channels, in_channels, k*W)
。问题是你的输入有批量维度,但你的权重没有。
正如您所描述的,您想要的方法需要为批次中的每个
(x,y)
向量对设置不同的权重。
鉴于所有卷积都是矩阵向量乘法的严格子集,您最好将
[x,y]
连接起来并将它们放入线性层。