维度变化问题
如果要让通道实现变化可以这样
## 将通道按组拆分
x=x.view(b,c/g,,g,h,w)
## 位置换
x=x.transpose(1,2).contiguous()
##重新变化原来的维度
x=x.view(b,c,h,w)
模型保存问题
可以保存模型也可以只保存参数,放我们同时保存了模型时,在加载模型的时候需要原模型的对象,
也就是不能单独导入。当只保存了参数时也就是torch.save(m.state_dict(),'./test_mode_load.pt')
当载入的时候只要参数字典匹配就可以,即使有其他的变量都无所谓
class mode(torch.nn.Module):
def __init__(self):
super(mode,self).__init__()
self.l1=torch.nn.Linear(2,1)
def forward(self,x):
return self.l1(x)
m=mode()
torch.save(m.state_dict(),'./test_mode_load.pt')
class mode1(torch.nn.Module):
def __init__(self):
super(mode1,self).__init__()
self.x=12
self.se=13 ##即使有其他变量也可以成功加载
self.l1=torch.nn.Linear(2,1)
def forward(self,x):
return self.l1(x)
m1=mode1()
m1.load_state_dict(torch.load('./test_mode_load.pt'))
GPU爆炸问题
在使用GPU中需要要保证数据核模型都在GPU上,使用多GPU时,将数据和模型都放在GPU0上 模型和数据会被自动发放到各个
GPU上数据会呗平分,然后计算获得结果,收集到GPU0上更新模型。
GPU显存的释放是自动完成的,当变量不再使用时现存会自动释放,所以在计算损失值得时候可以将数据再放到CPU上算,
torch.cuda.device(0) #这个得作用是将执行过程在GPU0上执行,
with torc.cuda.device(0):
设备选择
a=torch.device('cpu')
a=torch.device('cuda:0')
mode.to(a)
mode.to('cpu')
mode.to('cuda:0')
mode.cuda(0)
mode.cpu()
多GPU
其实原理很简单通过 nn.DataParallel(mode,device=[])
就可以将模型加载到多GPU上
数据会平分,计算后会整合到指定GPU上
冻结部分网络
import torch
import torch.nn as nn
class mode_(nn.Module):
def __init__(self):
super(mode_,self).__init__()
self.l1=nn.Linear(3,2)
self.l2=nn.Linear(2,1)
def forward(self,x):
return self.l2(self.l1(x))
a=torch.rand(1,3)
mode=mode_()
mode.l1.weight.requires_grad=False #设置某个参数冻结不可求导
mode.zero_grad() #梯度清空
out=mode(a)
out.backward() #求导
for i in mode.parameters(): #导数
print(i.grad)
for i in mode.parameters(): #更新前参数
print(i)
ops=torch.optim.SGD(mode.parameters(),lr=1) #被冻结的导数不可更新
ops.step()
for i in mode.parameters(): #更新后参数
print(i)
构建一个简单的神经网络
通过一个神经网络学习一个函数,该函数是 y=x**2+x
如何不可描述的函数都可以通过全连接网络表达 。反正大家都不知道里面具体的数学含义。
就是干呗。最终的问题还是将实际问题抽象化。
首先导入需要的包
import torch
import torch.nn as nn
import torch.utils.data
构建数据集
x=torch.rand(1000,1)
y=x**2+x
创建模型和标准格式数据集
class fun(torch.nn.Module):
def __init__(self):
super(fun,self).__init__()
self.l1=nn.Linear(1,100)
self.l2=nn.Linear(100,100)
self.l3=nn.Linear(100,1)
self.si=nn.Sigmoid()
self.re=nn.ReLU()
def forward(self,x):
out=self.l1(x)
#out=self.re(out)
out=self.l2(out)
#out=self.re(out)
out=self.l3(out)
#out=self.re(out)
return out
class data(torch.utils.data.Dataset):
def __init__(self,x,y):
self.x=x
self.y=y
def __getitem__(self,ind):
return self.x[ind], self.y[ind]
def __len__(self):
return len(self.x)
创建优化器和实例化模型
mode=fun()
ops=torch.optim.SGD(mode.parameters(),lr=0.01)
loss_fun=nn.MSELoss()
开始训练
for i in range(10):
print("第{}epoch".format(i))
k=0
for i ,j in datatrain:
if k%50==0:
print("第{}batch".format(k))
out=mode(i) #模型输入
#print(out)
loss=loss_fun(out,j) #损失计算
print("损失:{}".format(loss))
k=k+1
# Zero gradients, perform a backward pass, and update the weights.
ops.zero_grad()
loss.backward()
ops.step()
测试
x=torch.rand(3,1)
print(x**2+x)
mode(x)
##主要问题
匹配标准格式的数据集和模型输入
首先确定输入格式,同事模型的格式需要确定
模型构建需要继承父类的初始化函数也就是
spuer(fun,self).__init__()