5.4.1 不带参数的层
import torch
import torch.nn.functional as F
from torch import nn
class CenteredLayer(nn.Module):
def __init__(self):
super().__init__()
def forward(self, X):
return X - X.mean() # 仅作减去均值的操作
layer = CenteredLayer()
layer(torch.FloatTensor([1, 2, 3, 4, 5])) # 可以正常运行
tensor([-2., -1., 0., 1., 2.])
net = nn.Sequential(nn.Linear(8, 128), CenteredLayer()) # 可以将其组合进更复杂的模型中
Y = net(torch.rand(4, 8))
Y.mean() # 均值为0,可以说明正常(由于浮点数特性,无法严格为0)
tensor(2.3283e-09, grad_fn=<MeanBackward0>)
5.4.2 带参数的层
class MyLinear(nn.Module): # 手动实现一波线性层
def __init__(self, in_units, units): # 输入数 输出数
super().__init__()
# 初始化权重和偏置
self.weight = nn.Parameter(torch.randn(in_units, units))
self.bias = nn.Parameter(torch.randn(units,))
def forward(self, X):
linear = torch.matmul(X, self.weight.data) + self.bias.data # 进行矩阵运算
return F.relu(linear)
linear = MyLinear(5, 3)
linear.weight, linear(torch.rand(2, 5)) # 测试正常
(Parameter containing:
tensor([[ 0.1349, -1.0820, -0.8273],
[-0.2127, -1.0748, -0.5577],
[-0.9080, 0.5133, -0.4401],
[-0.4881, -0.8850, -0.0289],
[-0.0330, -1.4289, -0.6820]], requires_grad=True),
tensor([[2.6406, 0.0000, 0.0000],
[1.7090, 0.0000, 0.0000]]))
net = nn.Sequential(MyLinear(64, 8), MyLinear(8, 1)) # 可正常组合使用
net(torch.rand(2, 64))
tensor([[0.0000],
[2.0065]])
练习
(1)设计一个接收输入并计算张量降维的层,它返回 \(y_k=\sum_{i,j}W_{ijk}x_ix_j\)。
class DimensionalityReductionTensors(nn.Module):
def __init__(self, in_units):
super().__init__()
self.weight = nn.Parameter(torch.randn(in_units, in_units, in_units)) # 初始化权重
def forward(self, X):
y = torch.zeros_like(X)
for k in range(0, X.shape[0]):
for i in range(0, X.shape[0]):
for j in range(0, X.shape[0]):
y[k] += self.weight[i][j][k] * X[i] * X[j]
return y
layer = DimensionalityReductionTensors(3)
layer.weight, layer(torch.rand(3, 1)) # 测试正常
(Parameter containing:
tensor([[[-0.3133, 0.6214, 0.6835],
[-0.0720, 0.8630, 1.1317],
[-0.5848, -0.9351, -0.5103]],
[[ 0.2724, 0.3710, -0.6909],
[ 1.1569, 0.8924, -0.2694],
[-0.2803, -1.0708, 0.5445]],
[[-0.4135, 1.2961, -0.2054],
[-0.5572, 1.0026, 0.7997],
[ 0.3076, 0.4108, 0.4654]]], requires_grad=True),
tensor([[0.3252],
[0.6745],
[0.1474]], grad_fn=<CopySlices>))
(2)设计一个返回输入数据的傅里叶系数前半部分的层。
class FirstHalfFouriercoefficient(nn.Module):
def __init__(self):
super().__init__()
def forward(self, X):
FFT = torch.fft.fft(X)
return FFT[:, :round(X.shape[1]/2)]
layer = FirstHalfFouriercoefficient()
layer(torch.rand(3, 7)) # 测试正常
tensor([[ 3.9421+0.0000j, -0.2037+0.1165j, -0.6413-1.0152j, -0.4512-0.3608j],
[ 3.5853+0.0000j, -0.4951-0.8863j, -0.0675+0.4883j, 0.6614+0.0268j],
[ 4.0120+0.0000j, 0.9124+0.1392j, -0.5101+0.0387j, 0.9813+0.3515j]])
标签:__,5.4,nn,自定义,self,torch,0.0000,Pytorch,units
From: https://www.cnblogs.com/AncilunKiang/p/17700585.html