可以灵活的构造各种函数,方便使用
##层与块
import torch
from torch import nn
from torch.nn import functional as F
net = nn.Sequential(nn.Linear(20,256),nn.ReLU(),nn.Linear(256,10))
x = torch.rand(2,20)
# print(x)
##自定义块
class MLP(nn.Module):##MLP是Module的一个子类
def __init__(self):
super().__init__()##调用父类的特征
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 = MLP()
# print(net(x))
##顺序块
class Mysequential(nn.Module):
def __init__(self,*args):###*args是收集参数,相当于把若干个参数打包成一个来传入
super().__init__()
for block in args:
#_module的类型是字典,会自动帮你识别层
#__init__函数将每个模块逐个添加到有序字典_modules中。
self._modules[block] = block
#一种前向传播函数,用于将输入按追加块的顺序传递给块组成的“链条”
def forward(self,x):
for block in self._modules.values():
x=block(x)
return x
net = Mysequential(nn.Linear(20,256),nn.ReLU(),nn.Linear(256,10))
print(net(x))
参数管理
- 访问参数,用于调试、诊断和可视化;
- 参数初始化;
- 在不同模型组件间共享参数。
##参数管理
import torch
from torch import nn
net = nn.Sequential(nn.Linear(4,8),nn.ReLU(),nn.Linear(8,1))
x= torch.rand(size=(2,4))##(批次,维度)
# print(net(x))
def block1():
return nn.Sequential(nn.Linear(4,8),nn.ReLU(),nn.Linear(8,4),nn.ReLU())
def blok2():
net = nn.Sequential()
for i in range(4):
net.add_module(f'block{i}',block1())
return net
qiantaonet = nn.Sequential(blok2(),nn.Linear(4,1))
# print(qiantaonet(x))
# print(qiantaonet)
def normal(m):
if m ==nn.Linear:
nn.init.normal_(m.weight,mean=0,std=0.01)##对线性层权重进行处理
nn.init.zeros_(m.bias)#对偏差置为0
net.apply(normal)
# print(net[0].weight.data[0],net[0].bias.data[0])
##参数绑定 可以共享权重
share = nn.Linear(8,8)
net = nn.Sequential(nn.Linear(4,8),nn.ReLU(),share,nn.ReLU(),share,nn.ReLU(),nn.Linear(8,1))
net(x)
print(net[2].weight.data[0]==net[4].weight.data[0])
net[2].weight.data[0,0] = 100
print(net[2].weight.data[0]==net[4].weight.data[0])
自定义层
- 我们可以通过基本层类设计自定义层。这允许我们定义灵活的新层,其行为与深度学习框架中的任何现有层不同。
- 在自定义层定义完成后,我们就可以在任意环境和网络架构中调用该自定义层。
- 层可以有局部参数,这些参数可以通过内置函数创建。
##自定义层
import torch
from torch import nn
import torch.nn.functional as F
class cl(nn.Module):
def __init__(self):
super().__init__()
def forward(self,x):
return x-x.mean()
layer = cl()
# print(layer(torch.FloatTensor([1,2,3,4,5])))
##自定义线性层
class mylinear(nn.Module):
def __init__(self,input,output):
super().__init__()
self.weight = nn.Parameter(torch.randn(input,output))
self.bias = nn.Parameter(torch.zeros(output,))
def forward(self,x):
linear = torch.matmul(x,self.weight.data)+self.bias.data
return F.relu(linear)
nyl = mylinear(5,3)
# print(nyl.weight)
print(nyl(torch.rand(2,5)))
读写文件
save
和load
函数可用于张量对象的文件读写。- 我们可以通过参数字典保存和加载网络的全部参数。
- 保存架构必须在代码中完成,而不是在参数中完成。
import torch
from torch import nn
from torch.nn import functional as F
x= torch.arange(4)
torch.save(x,'x-file')
x2= torch.load('x-file')
print(x2)
y = torch.zeros(4)
torch.save([x,y],'x-file')
x2,y2 = torch.load('x-file')
print(x2,y2)
mydict = {'x':x,'y':y}
torch.save(mydict,'mydict')
mydict2 = torch.load('mydict')
print(mydict2)
##加载和保存模型参数
class MlP(nn.Module):
def __init__(self):
super().__init__()
self.hidden = nn.Linear(20,256)
self.output = nn.Linear(256,10)
def forward(self,x):
return self.output(F.relu(self.hidden(x)))
net = MlP()
x = torch.rand(size=(2,20))
y =net(x)
torch.save(net.state_dict(), 'mlp.params')
##实例化多层感知机模型备份,直接读取文件储存参数
clone = MlP()
clone.load_state_dict(torch.load('mlp.params'))#torch.load只是把数据加载了,load_state_dict是把数据按照字典查找填到模型中
clone.eval()#eval()是将模型设为评估模式,返回值是self,也就是模型本身,此处应该就是为了返回这个模型看一下
#不再训练更改梯度
print(clone(x)==y)
Gpu
import torch
from torch import nn
# print(torch.device('cpu'))
# print(torch.cuda.device('cuda'))
#
#
# print(torch.cuda.device_count())
##如果存在GPU就返回gpu{i},不存在就返回cpu
def try_pu(i=0):
if torch.cuda.device_count()>=i+1:
return torch.device(f'cuda:{i}')
return torch.device('cpu')
#返回所有的gpu
def try_all_gpu():
device = [torch.device(f'cuda:{i}') for i in range(torch.cuda.device_count())]
return device if device else [torch.device('cpu')]
print(try_pu(),try_all_gpu())
#储存在gpu上
x = torch.ones(2,3,device=try_pu())
print(x)
#神经网络与gpu
net = nn.Sequential(nn.Linear(3,1))
net = net.to(device=try_pu())
print(net(x))