1.1autograd
torch.Tensor是整个package中的核心类,如果将属性.requires_grad设置为True,它将追踪在这个类上定义的所有操作,当代码要进行反向传播的时候,直接调用.backword()就可以自动计算所有的梯度.在这个Tensor上的所有梯度将被累加进属性.grad中。
如果想终止一个Tensor在计算图中的追踪回溯,只需要执行.detach()就可以将该Tensor从计算
图中撤下,在未来的回溯计算中也不会再计算该Tensor。
除了.detach(),如果想终止对计算图的回溯,也就是不再进行方向传播求导数的过程,也可以采
用代码块的方式with torch.no_grad():,这种方式非常适用于对模型进行预测的时候,因为预测阶段不再需要对梯度进行计算.
若不设置则默认为FALSE
x=torch.ones(2,2,requires_grad=True)
若没有进行数学操作则输出为None否则输出上一个是什么操作
print(y.grad_fn)
原地改变属性
a.requires_grad_(True)
梯度
反向传播以.backward()实现
x = torch.ones(3, 3, requires_grad=True)
y = x + 2
loss = y.sum() # 将 y 转换为标量
loss.backward() # 现在可以调用 backward
print(x.grad) # 查看 x 的梯度
查看属性
print(x.requires_grad)
#y = x.detach()的意思是创建一个新的张量y,它与原张量x共享相同的数据,但不需要计算梯度。
y=x.detach()
print(x.eq(y).all())
的True
另一种方法
out.backward()则不进行梯度追踪
with torch.no_grad():
同理
1.2神经网络构建
构建神经网络的典型流程:
1、定义一个可学习参数的神经网络2、遍历训练数据集3、处理输入数据使其流经神经网络4、计算损失值5、将网络参数的梯度进行反向传播6、以一定规则更逊网络的权重
定义实战
import torch
import torch.nn as nn
import torch.nn.functional as F
#定义一个简单的网络
class Net(nn.Module):
def __init__(self):
super(Net,self).__init__()
#定义第一层卷积神经网络,输入通道维度=1,输出通道维度=6,卷积核大小3*3
self.conv1=nn.Conv2d(1,6,3)
#定义第二层卷积神经网络,输入通道维度=6,输出通道维度=16,卷积核大小3*3
self.conv2=nn.Conv2d(6,16,3)
#定义三个全连接层
#因为输入的32*32的
self.fc1=nn.Linear(16*6*6,120)
self.fc2=nn.Linear(120,84)
self.fc3=nn.Linear(84,10)#因为用的数据是十分类
#依次经理5层
def forward(self,x):
#在(2,2)的池化窗口下执行最大池化操作
x=F.max_pool2d(F.relu(self.conv1(x)),2,2 )
x=F.max_pool2d(F.relu(self.conv2(x)),2)
x=x.view(-1,self.num_flat_features(x))#3维设置成2维因为要扔进全连接层
#relu将负值变为0正值不变
x=F.relu(self.fc1(x))
x=F.relu(self.fc2(x))
x=self.fc3(x)
return x
#维度扁平化处理
def num_flat_features(self,x):
#计算size,除了第0维度上的batch_size
size=x.size()[1:]
num_feartures = 1
for s in size:
num_feartures *=s
return num_feartures
net=Net()
print(net)
模型中所有可训练的参数。都可以通过net.parameterts()来获得
params=list(net.parameters())
print(len(params))
print(params[0].size())
torch.nn构建的神经网络只支持mini-batches的输入,不支持单一样本的输入。
比如: nn.Conv2d需要一个4D Tensor,形状为(nSamples,nChamnels, Height, Width).如果
你的输入只有单一样本形式,则需要执行input.unsqueeze(0),主动将3D Tensor扩充成4DTensor.
损失函数
损失函数的输入是一个输入的pair: (output,target),然后计算出一个数值来评估output和target
之间的差距大小.
在torch.nn中有若干不同的损失函数可供使用,比如nn.MSELoss就是通过计算均方差损失来评
估输入和目标值之间的差距.
损失函数模拟
output=net(input)
target=torch.randn(10)
#改为二维向量
target=target.view(1,-1)
print(target)
criterion=nn.MSELoss()
#计算损失值
loss=criterion(output,target)
print(loss)
反向传播
Pytorch中执行反向传播非常简便,全部的操作就是loss.backward()
在执行反向传播之前,要先将梯度清零,否则梯度会在不同的批次数据之间被累加
#先梯度清零
net.zero_grad()
#打印偏执
print('conv1.bias.grad before backward')
print(net.conv1.bias.grad)
#实现反向传播
loss.backward()
print('conv1.bias.grad after backward')
print(net.conv1.bias.grad)
梯度下降
#第一步导入优化器包 optim 中包含若干优化算法,比如SGD,Adam等
import torch.optim as optim
#构建优化器
optimizer=optim.SGD(net.parameters(),lr=0.01)
#第二步优化器梯度清零
optimizer.zero_grad()
#执行网络计算
output=net(input)
loss=criterion(output,target)
#第四步执行反向传播
loss.backward()
#第五步更行参数
optimizer.step()