PyTorch是一个动态的建图的工具。不像Tensorflow那样,先建图,然后通过feed和run重复执行建好的图。相对来说,PyTorch具有更好的灵活性。
参数
pytorch中有两种变量类型,一个是Tensor,一个是Variable。
- Tensor: 就像ndarray一样,一维Tensor叫Vector,二维Tensor叫Matrix,三维及以上称为Tensor
- Variable:是Tensor的一个wrapper,不仅保存了值,而且保存了这个值的creator,需要BP的网络都是Variable参与运算
import torch
x = torch.Tensor(2,3,4) # torch.Tensor(shape) 创建出一个未初始化的Tensor,但是还是可以打印出值的,这个应该是这块内存之前的值
a = torch.rand(2,3,4)#生成01之间随机取值的三维阵
b = torch.rand(2,3,4)
_=torch.add(a,b, out=x) # 使用Tensor()方法创建出来的Tensor用来接收计算结果,当然torch.add(..)也会返回计算结果的
a.add_(b) # 所有带 _ 的operation,都会更改调用对象的值, 例如 a=1;b=2; a.add_(b); a就是3了,没有 _ 的operation就没有这种效果,只会返回运算结果
所有带 _ 的operation,都会更改调用对象的值
检测cuda的代码
torch.cuda.is_available()
自动求导
pytorch的自动求导工具包在torch.autograd中,是其神经网络的核心。这是一个在运行时定义的框架。
torch.Tensor是这个包的核心类。如果设置 .requires_grad 为 True,那么将会追踪所有对于该张量的操作。 当完成计算后通过调用 .backward(),自动计算所有的梯度, 这个张量的所有梯度将会自动积累到 .grad 属性。
要阻止张量跟踪历史记录,可以调用.detach()方法将其与计算历史记录分离,并禁止跟踪它将来的计算记录。
每个张量都有一个.grad_fn属性,这个属性引用了一个创建了Tensor的Function(除非这个张量是用户手动创建的,即,这个张量的 grad_fn 是 None)记录了这个张量的所有操作。
如果需要计算导数,你可以在Tensor上调用.backward()。 如果Tensor是一个标量(即它包含一个元素数据)则不需要为backward()指定任何参数, 但是如果它有更多的元素,你需要指定一个gradient 参数来匹配张量的形状。
from torch.autograd import Variable
x = torch.rand(5)
x = Variable(x,requires_grad = True)
y = x * 2
grads = torch.FloatTensor([1,2,3,4,5])
y.backward(grads)#如果y是scalar(标量)的话,那么直接y.backward(),然后通过x.grad方式,就可以得到var的梯度
x.grad #如果y不是scalar,那么只能通过传参的方式给x指定梯度
####输出
Variable containing:
2
4
6
8
10
[torch.FloatTensor of size 5]
neural networks
使用torch.nn包中的工具来构建神经网络 需要以下几步:
- 定义神经网络的权重,搭建网络结构
- 遍历整个数据集进行训练
- 将数据输入神经网络
- 计算loss
- 计算网络权重的梯度
- 更新网络权重 weight = weight + learning_rate * gradient
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):#需要继承这个类
def __init__(self):
super(Net, self).__init__()
#建立了两个卷积层,self.conv1, self.conv2,注意,这些层都是不包含激活函数的
self.conv1 = nn.Conv2d(1, 6, 5) # 1 input image channel, 6 output channels, 5x5 square convolution kernel
self.conv2 = nn.Conv2d(6, 16, 5)
#三个全连接层
self.fc1 = nn.Linear(16*5*5, 120) # an affine operation: y = Wx + b
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x): #注意,2D卷积层的输入data维数是 batchsize*channel*height*width
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2)) # Max pooling over a (2, 2) window
x = F.max_pool2d(F.relu(self.conv2(x)), 2) # If the size is a square you can only specify a single number
x = x.view(-1, self.num_flat_features(x))
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 = x.size()[1:] # all dimensions except the batch dimension
num_features = 1
for s in size:
num_features *= s
return num_features
net = Net()
net