https://zh-v2.d2l.ai/chapter_deep-learning-computation/custom-layer.html
你好。我发现 named_parameters() 方法会自动捕捉到 MyLinear 类中定义的 weight 和 bias 参数, 请问 PyTorch 是如何发现这些参数的呢?
因为你使用了 pytorch的接口函数,比如 nn.Parameter nn.Linera nn.conv2d …
猜测是Module的相关方法,会分析类中类型为Parameter类型的参数,把这些成员标记为该module的参数,key值就是成员名。
记得应该是在nn.Module里面的__setattr__里面有,会对这些东西自动分类并放到模型的OrderedDict里
第一问,不知道对不对,请大家指正。
class sumyk(nn.Module):
def init(self,xi,xj):
super().init()
self.weight = nn.Parameter(torch.randn(xi.shape[1],xj.shape[0]))
def forward(self,xi,xj):
return torch.matmul(torch.matmul(xi,self.weight.data),xj)
第二问求助
我觉得是nn.module捕捉的,parameter只不过data和梯度值写入了一下
一个可能正确的实现
题1
class DimensionReduction(nn.Module):
def __init__(self, i, j, k):
super(DimensionReduction, self).__init__()
self.net = nn.Conv2d(in_channels=1, out_channels=k, kernel_size=(i, j))
def forward(self, X, Y):
# 先用X和Y做矩阵乘法构成i*j矩阵,
# 再用卷积层快捷地实现计算功能
matrix = torch.bmm(x, torch.transpose(y, 1, 2))
matrix = matrix.unsqueeze(1) # B*1*i*j
return self.net(matrix) # B*5*i*j
myNet1 = DimensionReduction(2, 3, 5)
x = torch.ones(1, 2, 1) # B*i*1
y = torch.rand(1, 3, 1) # B*j*1
print(myNet1(x, y))
题2
class HalfFFT(nn.Module):
def __init__(self):
super(HalfFFT, self).__init__()
def forward(self, X):
"""
Compute FFT and return half of it
:param X: size = B*L
:return: size = B*round(L/2)
"""
half_len = round(X.shape[1]/2)
X_f = torch.fft.fft(X)
return X_f[:, :half_len]
myNet2 = HalfFFT()
print(myNet2(torch.rand(2, 3)))
题一你再看下公式,你的实现和公式完全不一样
y = torch.sum(torch.mm(x.T,x)*w,dim=[1,2])
是因为weight和bias是nn.Parameter类的实例
#练习1可能的答案
class DemensionReduction(nn.Module):
def init(self,in_units, units):
super().init()
self.weight = nn.Parameter(torch.randn(in_units*in_units, units))
def forward(self, X):
Y = torch.matmul(X[0,:].reshape(-1,1),X[0,:].reshape(1,-1)).reshape(1,-1)
Z = torch.matmul(Y,self.weight)
for i in range(1,X.shape[0]):
Y = torch.matmul(X[i,:].reshape(-1,1),X[i,:].reshape(1,-1)).reshape(1,-1)
Z = torch.cat((Z,torch.matmul(Y,self.weight)),0)
return Z
dem = DemensionReduction(20,1)
X = torch.randn(5,20)
dem(X)
class Layer(nn.Module):
def init(self,k,i,j):
super(Layer, self).init()
self.weight=torch.randn(k,i,j)
def forward(self,xi,xj):
return torch.sum(torch.matmul(self.weight,torch.matmul(xi,xj),))
k,i,j=5,2,2
net=Layer(k,i,j)
print(net(torch.randn(2).reshape(2,1),torch.randn(2).reshape(1,2)))
不知道是否正确
这个可以看 python 元编程的内容,在没有看源码的情况下,猜测应该使用了 Python 的 MetaClass。