pytorch学习系列(1)

所需包:

import torch 
from torch.autograd import Variable
import torch.nn.functional as F

Torch中有两个关键的对象:tensor、Variable:

tensor在概念上与numpy数组相同,Tensor是n维数组。可以利用gpu加速数值计算,要在gpu上运行pytorch张量,在构造张量时使用device参数将张量放置在gpu上。而Variable 就是一个存放会变化的值的地理位置. 里面的值会不停的变化. 就像一个裝鸡蛋的篮子, 鸡蛋数会不停变动. 那谁是里面的鸡蛋呢, 自然就是 Torch 的 Tensor 咯. 如果用一个 Variable 进行计算, 那返回的也是一个同类型的 Variable.

Variable 计算时, 它在背景幕布后面一步步默默地搭建着一个庞大的系统, 叫做计算图. 这个图是用来干嘛的? 原来是将所有的计算步骤 (节点) 都连接起来, 最后进行误差反向传递的时候, 一次性将所有 variable 里面的修改幅度 (梯度) 都计算出来, 而 tensor 就没有这个能力啦.

搭建网络的两种方式:

# method 1
"""
继承 torch.nn.Module。
	类初始化中定义神经网络结构(运用torch.nn.Linear(参数1,参数2) 方法)
		参数1:该层的输入个数,参数2:该层的输出个数)
	forward(self, x):数据在神经网络中前向传播的方式(激活函数)
"""
class Net(torch.nn.Module):
    def __init__(self, n_feature, n_hidden, n_output):
        super(Net, self).__init__()
        self.hidden = torch.nn.Linear(n_feature, n_hidden)
        self.predict = torch.nn.Linear(n_hidden,n_output)


    def forward(self, x):
        x = F.relu(self.hidden(x))
        x = self.predict(x)
        return x
net1 = Net(n_feature=2, n_hidden=10, n_output=2)

# method 2
"""
直接用 torch.nn.Sequential() 定义神经网络
"""
net2 = torch.nn.Sequential(
    torch.nn.Linear(2, 10),
    torch.nn.ReLU(),
    torch.nn.Linear(10,2)
)

梯度下降:

"""
torch.optim 中包含各种梯度优化算法
loss_func 为损失函数(可以自定义)
"""
optimizer = torch.optim.SGD(net.parameters(), lr=0.2)  # 传入 net 的所有参数, 学习率
loss_func = torch.nn.CrossEntropyLoss()      # 预测值和真实值的误差计算公式 (均方差)

for t in range(100):
    out = net1(x)     # 喂给 net 训练数据 x, 输出预测值

    loss = loss_func(out, y)     # 计算两者的误差

    optimizer.zero_grad()   # 清空上一步的残余更新参数值
    loss.backward()         # 误差反向传播, 计算参数更新值
    optimizer.step()        # 将参数更新值施加到 net 的 parameters 上

各参数查询:

# 方式1:
for name, param in net2.named_parameters():
    print(name, '      ', param.size())
    print(param)
# 查询结果
"""
0.weight        torch.Size([10, 2])
Parameter containing:
tensor([[-0.7049, -0.6348],
        [-0.5914, -0.4052],
        [-0.2657,  0.5081],
        [ 0.6619, -0.5481],
        [ 0.2796, -0.2228],
        [-0.5388,  0.4968],
        [-0.5802,  0.3272],
        [-0.4182,  0.6781],
        [ 0.2926, -0.2694],
        [ 0.5293,  0.4075]], requires_grad=True)
0.bias        torch.Size([10])
Parameter containing:
tensor([ 0.0947,  0.2482, -0.0632,  0.2567, -0.5968, -0.3379, -0.4139, -0.5255,
        -0.3742,  0.2094], requires_grad=True)
2.weight        torch.Size([2, 10])
Parameter containing:
tensor([[-0.0459,  0.0186,  0.2408,  0.1489, -0.1909,  0.0724,  0.0287, -0.1703,
          0.1541,  0.0073],
        [ 0.1033,  0.0548,  0.2328,  0.0375,  0.1667,  0.1612, -0.2217,  0.3012,
         -0.2340,  0.1900]], requires_grad=True)
2.bias        torch.Size([2])
Parameter containing:
tensor([ 0.3007, -0.2703], requires_grad=True)

Process finished with exit code 0

"""

# 方式2:
for para in net2.parameters():
    print(para)
# 查询结果
"""
Parameter containing:
tensor([[ 0.1706, -0.4231],
        [ 0.4497, -0.0862],
        [ 0.1231, -0.3239],
        [-0.0792, -0.1556],
        [ 0.1046, -0.5814],
        [ 0.0565, -0.5718],
        [ 0.0987,  0.0800],
        [ 0.4584, -0.4975],
        [ 0.0628,  0.5513],
        [-0.3645, -0.2172]], requires_grad=True)
Parameter containing:
tensor([ 0.3361, -0.2579,  0.0663,  0.4646,  0.2084,  0.3714,  0.0222, -0.3350,
        -0.4999,  0.6187], requires_grad=True)
Parameter containing:
tensor([[-0.1687,  0.3051, -0.2822,  0.1395, -0.2506,  0.1312,  0.1133, -0.1629,
         -0.2704,  0.1717],
        [ 0.2736,  0.1654, -0.0341,  0.2944,  0.0261,  0.2097, -0.1472, -0.2728,
          0.2833,  0.1071]], requires_grad=True)
Parameter containing:
tensor([-0.2113,  0.2869], requires_grad=True)
"""

神经网络的存储:

#两种存储方法
torch.save(net1,'net.pkl')
torch.save(net1.state_dict(),'net_params.pkl')

命令1:存储整个训练好的神经网络

命令2:仅存储神经网络中的参数

加载神经网络:

def restore_net():
    """
    存储命令1对应的加载方法
    """
    net2 = torch.load('net.pkl')

def restore_params():
    """
    存储命令2对应的加载方法
    	加载前需要构建同样的神经网络
    (此方式的加载速度相对较快)
    """
    net3 = torch.nn.Sequential(
        torch.nn.Linear(1, 10),
        torch.nn.ReLU(),
        torch.nn.Linear(10, 1)
    )
    net3.load_state_dict(torch.load('net_params.pkl'))

批数据训练模型:

import torch
import torch.utils.data as Data

BATCH_SIZE = 5

x = torch.linspace(1, 10, 10)       # x data (torch tensor)
y = torch.linspace(10, 1, 10)       # y data (torch tensor)

torch_dataset = Data.TensorDataset(x,y)
loader = Data.DataLoader(
    dataset=torch_dataset, # 数据总量
    batch_size=BATCH_SIZE, # 每批数据的数量
    shuffle=True,  # 是否打乱
    num_workers=2, # 线程数
)

if __name__ == "__main__":
    """
    10个数据每份5个,分两份
    """
    for epoch in range(3):
        for step, (batch_x, batch_y) in enumerate(loader):
            print('Epoch: ', epoch, '| Step: ', step, '| batch x: ',
                  batch_x.numpy(), '| batch y: ', batch_y.numpy())

注意事项:代码中的Data.DataLoader中如果设置了num_workers属性 那么必须加上 (if name == “main”:)要不然会报错

Optimizer 优化器:

本文主要比较了四种优化算法:

opt_SGD = torch.optim.SGD(net_SGD.parameters(), lr=LR)
opt_Momentum = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.8)
opt_RMSprop = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.9)
opt_Adam = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.9, 0.99))

在这里插入图片描述

SGD 是最普通的优化器, 也可以说没有加速效果, 而 MomentumSGD 的改良版, 它加入了动量原则. 后面的 RMSprop 又是 Momentum 的升级版. 而 Adam 又是 RMSprop 的升级版. 不过从这个结果中我们看到, Adam 的效果似乎比 RMSprop 要差一点. 所以说并不是越先进的优化器, 结果越佳. 我们在自己的试验中可以尝试不同的优化器, 找到那个最适合你数据/网络的优化器.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值