pytorch入门二 使用pyplot动态展示函数拟合过程

相关知识:

  • 均方损失函数

loss(xi,yi)=(xi-yi)^2
这里 loss, x, y 的维度是一样的,可以是向量或者矩阵,i 是下标。

很多的 loss 函数都有 size_average 和 reduce 两个布尔类型的参数。因为一般损失函数都是直接计算 batch 的数据,因此返回的 loss 结果都是维度为 (batch_size, ) 的向量。

(1)如果 reduce = False,那么 size_average 参数失效,直接返回向量形式的 loss
(2)如果 reduce = True,那么 loss 返回的是标量
   a)如果 size_average = True,返回 loss.mean();
   b)如果 size_average = False,返回 loss.sum();


注意:默认情况下, reduce = True,size_average = True

  • pytorch中model.modules()model.children()的区别

model.modules()和model.children()均为迭代器,对于模型

model = torch.nn.Sequential(
    torch.nn.Linear(1, 5),
    torch.nn.Tanh(),
    torch.nn.Linear(5, 1),
    )

输出对比如下:

print(list(model.modules()))
print(list(model.children()))

modules()函数:

[Sequential(
  (0): Linear(in_features=1, out_features=5, bias=True)
  (1): Tanh()
  (2): Linear(in_features=5, out_features=1, bias=True)
), Linear(in_features=1, out_features=5, bias=True), Tanh(), Linear(in_features=5, out_features=1, bias=True)]

children()函数:

[Linear(in_features=1, out_features=5, bias=True), Tanh(), Linear(in_features=5, out_features=1, bias=True)]

 

  • python操作符@
python 3.5以后,@是一个操作符,表示矩阵-向量乘法
  • torch.t()

torch的矩阵转置函数,例如  2*3   ->  3*2

import torch
import matplotlib.pyplot as plt

w = 2
b = 1
noise = torch.rand(100, 1)
# 因为输入层格式要为(-1, 1),所以这里将(100)的格式转成(100, 1)
x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1)
# 拟合分布在y=2x+1上并且带有噪声的散点
y = w*x + b + noise
#自定义的网络,带有2个全连接层和一个tanh层
model = torch.nn.Sequential(
    torch.nn.Linear(1, 5),
    torch.nn.Tanh(),
    torch.nn.Linear(5, 1),
    )
# 定义损失函数为均方差
loss_fun = torch.nn.MSELoss()
# 使用adam作为优化器更新网络模型的权重,学习率为0.001
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# 开启图形交互
plt.ion()
for _ in range(10000):
    ax = plt.axes()
    # 前向传播
    output = model(x)
    # 数据向后传播(经过网络层的一次计算)
    loss = loss_fun(output, y)
    # 计算损失值
    #print("before zero_grad:{}".format(list(model.children())[0].weight.grad))
    #print("-"*100)

    # 优化器清空梯度
    # 通过注释地方可以对比发现执行zero_grad方法以后倒数梯度将会被清0
    # 如果不清空梯度的话,则会不断累加梯度,从而影响到当前梯度的计算
    model.zero_grad()
    #print("after zero_grad:{}".format(list(model.children())[0].weight.grad))
    #print("-"*100)

    # 向后传播,计算当前梯度,如果这步不执行,那么优化器更新时则会找不到梯度
    loss.backward()

    #通过比较会发现,经过backward得到的梯度跟执行model.zero_grad()之前的梯度是一致的
    #print("after backward:{}".format(list(model.children())[0].weight.grad))
    #print("-" * 100)

    # 优化器更新梯度参数,如果这步不执行,那么因为梯度没有发生改变,loss会一直计算最开始的那个梯度
    optimizer.step()

    if _ % 100 == 0:
        #清屏
        plt.cla()
        #画点
        plt.scatter(x.data.numpy(), y.data.numpy())
        #画线
        plt.plot(x.data.numpy(), output.data.numpy(), 'b-', lw=2)
        #写文本
        plt.text(0.60, -0.5, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 10, 'color':  'red'})
        plt.pause(0.1)
        #t()函数是torch的矩阵转置函数,
        #python 3.5以后,@是一个操作符,表示矩阵-向量乘法, 好骚的操作
        print("w:", list(model.children())[0].weight.t() @ list(model.children())[-1].weight.t())
        # 通过这句可以查看权值变化,可以发现最后收敛到2附近

#关闭图形交互
plt.ioff()

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值