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包中的工具来构建神经网络 需要以下几步:

  1. 定义神经网络的权重,搭建网络结构
  2. 遍历整个数据集进行训练
  3. 将数据输入神经网络
  4. 计算loss
  5. 计算网络权重的梯度
  6. 更新网络权重 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