Pytorch 基础(1)

自动求梯度 Autograd

  • Tensor 设定属性 .requires_gradTrue,那么在利用这个张量计算得到其他张量,对结果张量调用 .backward() 来计算所有的梯度时,梯度会保存到 .grad

  • 如果不想张量被继续追踪求梯度,可以用 .detach() 或者用 with torch.no_grad() 包裹住代码,这种方法在评估模型的时候很常用,因为在评估模型时,我们并不需要计算可训练参数requires_grad=True的梯度。

  • Function 类和 Tensor类共同组成==计算图==(记录着计算过程的有向无环图),Tensor.grad_fn ,这个属性可以得知某个张量是否是通过某些运算得到的

  • 使用 标量.backward() 不需要向 .backward() 里面传入指定的求导变量,我们应该有意识地回避张量对张量求导,我们应该只允许标量对张量求导(求导结果是和自变量同形的张量),所以我们必要时要把张量通过将所有张量的元素加权求和的方式转换为标量

  • grad 在反向传播的过程中是累加的,所以每进行一次反向传播之前,都需要使用tensor.grad.data.zero() 把梯度清零

  • 如果我们想要修改tensor的数值,但是又不希望被autograd记录(即不会影响反向传播),那么我么可以对tensor.data进行操作

Pytorch的基本使用

读取数据

使用 data 包来读取数据, 由于 data 常用作变量名,我们将导入的data模块用Data代替

import torch.utils.data as Data

batch_size = 0
dataset = Data.TensorDataset(features, labels)
data_iter = Data.DataLoader(dataset, batch_size, shuffle=True)

for X, y in data_iter:
	pass

定义模型

torch.nn 模块,nn 就是neural networks,nn 的核心数据结构是 nn.Modulenn.Module既可以表示神经网络中的某个层,也可以表示多层的神经网络。在自定义网络/层的时候,常用的做法是集成 nn.Module,自定义的网络/层中应该包含返回输出forward 方法

class LinearNet(nn.Module):
    def __init__(self, n_feature):
        super(LinearNet, self).__init__()
        self.linear = nn.Linear(n_feature, 1)
        
    # forward 定义前向传播
    def forward(self, x):
        y = self.linear(x)
        return y

使用 nn.Sequential 搭建网络, Sequential是一个有序的容器,网络层将按照在传入Sequential的顺序依次被添加到计算图中。

# 写法一
net = nn.Sequential(
    nn.Linear(num_inputs, 1)
    # 此处还可以传入其他层
    )

# 写法二
net = nn.Sequential()
net.add_module('linear', nn.Linear(num_inputs, 1))
# net.add_module ......

# 写法三
from collections import OrderedDict
net = nn.Sequential(OrderedDict([
          ('linear', nn.Linear(num_inputs, 1))
          # ......
        ]))

print(net)
print(net[0])

注意:torch.nn仅支持输入一个batch的样本不支持单个样本输入,如果只有单个样本,可使用input.unsqueeze(0)来添加一维。

可以通过net.parameters()来查看模型所有的可学习参数,此函数将返回一个生成器。

for param in net.parameters():
    print(param)

初始化模型参数

from torch.nn import init

init.normal_(net[0].weight, mean=0, std=0.01)
init.constant_(net[0].bias, val=0)  # 也可以直接修改bias的data: net[0].bias.data.fill_(0)

定义损失函数

loss = nn.MSELoss()

定义优化算法

import torch.optim as optim

optimizer = optim.SGD(net.parameters(), lr=0.03)
print(optimizer)

我们还可以为不同子网络设置不同的学习率,这在finetune时经常用到。例:

optimizer =optim.SGD([
                # 如果对某个参数不指定学习率,就使用最外层的默认学习率
                {'params': net.subnet1.parameters()}, # lr=0.03
                {'params': net.subnet2.parameters(), 'lr': 0.01}
            ], lr=0.03)

Tensor 的常用操作

根据特定下标张量取出某个张量的对应值

y_hat = torch.tensor([[0.1, 0.3, 0.6], [0.3, 0.2, 0.5]])
y = torch.LongTensor([0, 2])
y_hat.gather(1, y.view(-1, 1))
import torch
torch.matmul(A, B) # 矩阵乘法

PyTorch 中,一般函数加下划线代表直接在原来的 Tensor 上修改

tensor.scatter_()

scatter_(input, dim, index, src)将src中数据根据index中的索引按照dim的方向填进input中

神经网络过拟合问题应对策略

权重衰减

使用正则项,来约束模型的参数对应的权重,在优化器里面设置weight_decay参数

optimizer_w = torch.optim.SGD(params=[net.weight], lr=lr, weight_decay=wd) # 对权重参数衰减

丢弃法

dropout

深度学习基础概念

正向传播

正相传播是指:对神经网络沿着从输入层到输出层的顺序,一次计算并存储模型的中间变量(包括输出)

反向传播

反向传播是计算神经网络参数梯度的方法

计算图

模型构造

区别与前面使用构造 Sequential 实例来构建网络,使用 Moudule 类来构建网络更加灵活。

模型构建方法:

继承Moudle 类来构造模型

使用 Moudle 的子类: SequentialModuleListModuleDict

如:

net = nn.ModuleList([nn.Linear(784, 256), nn.ReLU()])

模型参数的访问、初始化、共享

print(net.parameters())
print(net.named_parameters())

你可能感兴趣的:(深度学习)