import torch
from torch import nn
from torch.nn import functional as F #F里定义了一些没有包括参数的函数
#pytorch里面怎么样构造层。
#nn.Sequential定义了一个特殊的model,在pytorch中,任何一个层或者一个神经网络都是model的子类。
net=nn.Sequential(nn.Linear(20,256),torch.nn.ReLU(),nn.Linear(256,10))
X=torch.rand(2,20)
net(X)
#自定义一个MLP,nn.model的子类,继承自nn.model的子类。
class MLP(nn.Module):
#定义需要的类和参数
def __init__(self):
super().__init__() #调用父类,model的init函数,把一些所需要的内部参数全部设好,之后在初始化weight、别的地方就能全部弄好???
self.hidden=nn.Linear(20,256)
self.out=nn.Linear(256,10)
def forward(self,x):
return self.out(F.relu(self.hidden(X)))
#net.__call__()调用了forward
net=MLP()
net(X)
class MySquential(nn.Module):
def __init__(self,*args): #*args里面所有的传入的层叫做block
super.__init__() #父类的初始化函数
for block in args:
self._modules[block]=block #_modules是一个特殊的容器,放在里面的都是需要的层。按序的字典,按顺序插入层,自己本身作为key,
def forward(self,X): #给定输入X,对所有model的values按序
for block in self._module.values():
X=block(X)
return X
net =MySquential(nn.Linear(20,256),nn.ReLU(),nn.Linear(256,10))
net(X)
#当Sequential不能完全满足需求时,用以下方式构造函数。且在init和forward里面可做自定义的计算。
class FixedHiddenMLP(nn.Module):
def __init__(self):
super().__init__()
self.rand_weight=torch.rand((20,20),requires_grad=False) #直接生成rand_weight,这个weight不参与训练,因为不会计算梯度。
self.linear=nn.Linear(20,20) #
def forward(self,X): #在forward里写任何需要的函数
X=self.linear(X)
X=F.relu(torch.mm(X,self.rand_weight)+1)
X=self.linear(X)
while X.abs().sum()>1:
X/=2
return X.sum()
net=FixedHiddenMLP()
net(X)
#各种方法灵活嵌套使用
class NestMLP(nn.Module):
def __init__(self):
super().__init__()
self.net=nn.Sequential(nn.Linear(20,64),nn.ReLU(),nn.Linear(64,31),nn.ReLU())
self.linear=nn.Linear(32,16)
def forward(self,X):
return self.linear(self.net(X))
chimera=nn.Sequential(NestMLP(),nn.Linear(16,32),FixedHiddenMLP)
chimera(X)