IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 卷积神经网络学习:使用pytorch反向传播 -> 正文阅读

[人工智能]卷积神经网络学习:使用pytorch反向传播

1.pytorch自动求导机制

在Pytorch中,Tensor是其最重要的数据类型。

每个Tensor都有一个requires_grad参数,代表这个Tensor是否会被跟踪自动微分。

这里我们先介绍一个简单的前向计算的例子:

import torch
# requires_grad代表此Tensor会被跟踪自动微分
x = torch.tensor([[1,2],[3,4]],dtype=torch.double,requires_grad=True)
y = x + 2
z = y * y * 3
out = z.mean()

上述计算的输入量为二维矩阵 x ,输出为标量 out ,对于这个公式,如何求解out对输入量 x 的导数呢?

在 Pytorh 中只需要如下代码,无需进行任何手工数学推导:

out.backward()
# 这里就是out对x的导数,out必须是标量,会自动求得y关于x的导数
print(x.grad)
tensor([[4.5000, 6.0000],
        [7.5000, 9.0000]], dtype=torch.float64)

需要注意的是,上述例子中 out 为标量。

如果 out 为一个向量或者Tensor,在反向传播时需要传入一个系数矩阵,backward 方法会对 out 加权求和成一个标量,再进行反向传播。

在实际应用中,我们的 loss_function 一般也是标量。

#雅各比向量,y不是标量
x = torch.tensor([1, 2, 3], dtype=torch.double, requires_grad=True)

y = x * 2
while y.data.norm() < 1000:
    y = y * 2


print(y)

#这里y不是标量,所以求导是针对y中每个元素做一次求导,并且需要传入一个系数
v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)
print(x.grad)

?2.利用Pytorch进行反向传播和梯度下降

这里我们介绍一下如何使用Pytoch定义一个numpy定义的两层神经网络模型并对数据进行拟合。在Pytorch中只需要一行代码即可完成反向传播。

import torch
#numpy 两层神经网络
# N为训练数据个数,D_in为输入层大小,H为隐藏层大小,D_out为输出层大小
# 我们定义一个输入层为1000维向量,隐藏层为100个神经元,输出层层10个神经元的神经网络
N, D_in, H, D_out = 64, 1000, 100, 10

# 随机创建训练数据
x = torch.randn(N,D_in)
y = torch.randn(N,D_out)

w1 = torch.randn(D_in,H,requires_grad = True)
w2 = torch.randn(H,D_out,requires_grad = True)

lr = 1e-6
for it in range(500):
    # 前向传播
    y_pred = x.mm(w1).mm(w2)
    
    # loss
    loss = (y_pred - y).pow(2).sum() # 计算损失
    print("\r epoch={} loss={}".format(it,loss), end=' ')
    
    # 反向传播
    loss.backward()
    
    # 如果计算需要求导,那就无法赋值,所以这里必须使用no_grad
    with torch.no_grad():
        w1 -= lr * w1.grad
        w2 -= lr * w2.grad
        # 清空导数,否者下次反向传播求得的导数会累加到这里
        w1.grad.zero_()
        w2.grad.zero_()

上面这种写法还是非常接近于 Numpy 的写法,我们只是将 Numpy 矩阵运算换成了 Pytoch 的 Tensor 运算,并且利用了 Pytorch 的自动求导机制来求解梯度。

实际在 Pytorch 中,有更加优雅的写法,我们可以使用 optimizer 来进行梯度下降,使用它内置的 MSELoss 来实现均方差损失函数:

?

N, D_in, H, D_out = 64, 1000, 100, 10

# 随机创建训练数据(在Pytorch中,一般把batch放在第一个维度,这一点与上面的不同)
x = torch.randn(N,D_in)
y = torch.randn(N,D_out)

model = torch.nn.Sequential(
    torch.nn.Linear(D_in,H),
    torch.nn.Linear(H, D_out),
)

# 定义学习率
lr = 1e-4

loss_fn = torch.nn.MSELoss(reduction='sum')

# 梯度下降策略
optimizer = torch.optim.Adam(model.parameters(),lr=lr)
for it in range(500):
    y_pred = model(x) # 前向传播
    
    loss = loss_fn(y_pred,y)
    print("\r epoch={} loss={}".format(it,loss), end=' ')
    
    # 注意这一步不能少
    optimizer.zero_grad()
    loss.backward()
    
    optimizer.step()

在实际应用中,我们可以将前向传播过程封装成一个类,下面介绍两种以对象形式实现前向传播,并使用自动求导 optimizer 来实现模型的梯度下降的方法:

方式1.使用 Sequential

N, D_in, H, D_out = 64, 1000, 100, 10

# 随机创建训练数据
x = torch.randn(N,D_in)
y = torch.randn(N,D_out)

# 方式1,使用Sequential(序列)函数来构建我们的model
model = torch.nn.Sequential(
    torch.nn.Linear(D_in,H),
    torch.nn.Linear(H, D_out),
)

#torch.nn.init.normal_(model[0].weight)

lr = 1e-4

loss_fn = torch.nn.MSELoss(reduction='sum')

# 梯度下降策略
optimizer = torch.optim.Adam(model.parameters(),lr=lr)
for it in range(500):
    y_pred = model(x) #model.forward()
    
    loss = loss_fn(y_pred,y)
    print("\r epoch={} loss={}".format(it,loss), end=' ')
    
    optimizer.zero_grad()
    loss.backward()
    
    optimizer.step()

方式2.继承 torch.nn.Module

N, D_in, H, D_out = 64, 1000, 100, 10

# 随机创建训练数据
x = torch.randn(N,D_in)
y = torch.randn(N,D_out)

# 方式2,实现自己的类,继承torch.nn.Module
class TwoLayerNet(torch.nn.Module):
    def __init__(self, D_in, H, D_out):
        super(TwoLayerNet,self).__init__()
        self.linear1 = torch.nn.Linear(D_in, H, bias=False)
        self.linear2 = torch.nn.Linear(H, D_out, bias=False)
    
    def forward(self, X):
        y_pred = self.linear2(self.linear1(X))
        return y_pred
    
model = TwoLayerNet(D_in, H, D_out)

lr = 1e-4

loss_fn = torch.nn.MSELoss(reduction='sum')
optimizer = torch.optim.Adam(model.parameters(),lr=lr)
for it in range(500):
    y_pred = model(x) #model.forward()
    
    loss = loss_fn(y_pred,y)
    print("\r epoch={} loss={}".format(it,loss), end=' ')
    
    optimizer.zero_grad()
    loss.backward()
    
    optimizer.step()

?

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-08-29 09:05:19  更:2021-08-29 09:05:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 17:44:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码