使用pytorch构建一个神经网络、损失函数、反向传播、更新网络参数
- 关于torch.nn:
- 使用Pytorch来构建神经网络, 主要的工具都在torch.nn包中.
- nn依赖于autograd来定义模型, 并对其自动求导.
构建神经网络的典型流程:
- 定义一个拥有可学习参数的神经网络
- 遍历训练数据集
- 处理输入数据使其流经神经网络
- 计算损失值
- 将网络参数的梯度进行反向传播
- 以一定的规则更新网络的权重
- 我们首先定义一个Pytorch实现的神经网络:
# 导入若干工具包
import torch
import torch.nn as nn
import torch.nn.functional as F# 定义一个简单的网络
class Net(nn.Module):def __init__(self):super().__init__()# 定义第一层卷积神经网络,输入通道维度为1,输出通道维度为6,卷积核大小为3*3self.conv1 = nn.Conv2d(1, 6, 3)# 定义第二层卷积神经网络,输入通道为6,输出通道维度为16,卷积核大小为3*3self.conv2 = nn.Conv2d(6, 16, 3)# 定义三层全连接层网络self.fc1 = nn.Linear(16 * 6 * 6, 120)self.fc2 = nn.Linear(120, 84)self.fc3 = nn.Linear(84, 10) # 最终输出的结果要分为10类def forward(self, x):# 注意:任何卷积层后面要加激活层、池化层# 在(2,2)的池化窗口下执行最大池化操作x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))x = F.max_pool2d(F.relu(self.conv2(x)), 2)# 经过卷积层的处理后,张量要进入全连接层,进入前需要调整张量的形状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 xdef num_flat_features(self, x):# 计算size,除了第0个维度上的batch_sizesize = x.size()[1:]num_features = 1for s in size:num_features *= sreturn num_featuresnet = Net()
print(net)
运行效果:
- 注意:
- 模型中所有的可训练参数, 可以通过net.parameters()来获得.
print(net.parameters()) # <generator object Module.parameters at 0x00000167595C8C48>
params = list(net.parameters())
print(len(params))
# for i in params:
# print(i)
print(params[0].size())
- 假设图像的输入尺寸为32 * 32:
# 假设图像的输入尺寸为32 * 32
input_value = torch.randn(1, 1, 32, 32)
output = net(input_value)
print(output)
- 有了输出张量后, 就可以执行梯度归零和反向传播的操作了.
net.zero_grad()
output.backward()
- 注意:
- torch.nn构建的神经网络只支持mini-batches的输入, 不支持单一样本的输入.
- 比如: nn.Conv2d 需要一个4D Tensor, 形状为(nSamples, nChannels, Height, Width). 如果你的输入只有单一样本形式, 则需要执行input.unsqueeze(0), 主动将3D Tensor扩充成4D Tensor.
损失函数
损失函数的输入是一个输入的pair: (output, target), 然后计算出一个数值来评估output和target之间的差距大小.
在torch.nn中有若干不同的损失函数可供使用, 比如nn.MSELoss就是通过计算均方差损失来评估输入和目标值之间的差距.
- 通过loss.backward()进行反向传播计算时, 整张计算图将对loss进行自动求导, 所有属性requires_grad=True的Tensors都将参与梯度求导的运算, 并将梯度累加到Tensors中的.grad属性中.
- 应用nn.MSELoss计算损失的一个例子
target = torch.randn(10)
# 改变target的形状为二维张量,为了和output匹配
target = target.view(1, -1) # 第一个维度设置为1,第二个维度自动适配维度为10
criterion = nn.MSELoss()loss = criterion(output, target)
print(loss)
- 关于方向传播的链条: 如果我们跟踪loss反向传播的方向, 使用.grad_fn属性打印, 将可以看到一张完整的计算图如下:
input -> conv2d -> relu -> maxpool2d -> conv2d -> relu -> maxpool2d-> view -> linear -> relu -> linear -> relu -> linear-> MSELoss-> loss
- 当调用loss.backward()时, 整张计算图将对loss进行自动求导, 所有属性requires_grad=True的Tensors都将参与梯度求导的运算, 并将梯度累加到Tensors中的.grad属性中.
print(loss.grad_fn) # MseLoss
print(loss.grad_fn.next_functions[0][0]) # Linear
print(loss.grad_fn.next_functions[0][0].next_functions[0][0]) # ReLU
反向传播(backpropagation)
- 在Pytorch中执行反向传播非常简便, 全部的操作就是loss.backward().
- 在执行反向传播之前, 要先将梯度清零, 否则梯度会在不同的批次数据之间被累加.
- net.zero_grad()
- loss.backward()
- 执行一个反向传播的小例子:
# Pytorch中执行梯度清零的代码
net.zero_grad()print('conv1.bias.grad before backward')
print(net.conv1.bias.grad)# Pytorch中执行反向传播的代码
loss.backward()print('conv1.bias.grad after backward')
print(net.conv1.bias.grad)
更新网络参数
- 更新参数最简单的算法就是SGD(随机梯度下降).
- 具体的算法公式表达式为: weight = weight - learning_rate * gradient
- 首先用传统的Python代码来实现SGD如下:
learning_rate = 0.01
for f in net.parameters():f.data.sub_(f.grad.data * learning_rate)
- 然后使用Pytorch官方推荐的标准代码如下:
# 首先导入优化器的包, optim中包含若干常用的优化算法, 比如SGD, Adam等
import torch.optim as optim# 通过optim创建优化器对象
optimizer = optim.SGD(net.parameters(), lr=0.01)# 将优化器执行梯度清零的操作
optimizer.zero_grad()output = net(input_value)
loss = criterion(output, target)# 对损失值执行反向传播的操作
loss.backward()
# 参数的更新通过一行标准代码来执行
optimizer.step()
参数的更新方法:
- 定义优化器来执行参数的优化与更新.
- optimizer = optim.SGD(net.parameters(), lr=0.01)
- 通过优化器来执行具体的参数更新.
- optimizer.step()
使用pytorch构建一个神经网络、损失函数、反向传播、更新网络参数相关推荐
- 快速入门PyTorch(2)--如何构建一个神经网络
2019 第 43 篇,总第 67 篇文章 本文大约 4600 字,阅读大约需要 10 分钟 快速入门 PyTorch 教程第二篇,这篇介绍如何构建一个神经网络.上一篇文章: 快速入门Pytorch( ...
- 深度学习笔记--pytorch从梯度下降到反向传播BP到线性回归实现,以及API调用和手写数据集的实现
梯度下降和反向传播 目标 知道什么是梯度下降 知道什么是反向传播 1. 梯度是什么? 梯度:是一个向量,导数+变化最快的方向(学习的前进方向) 回顾机器学习 收集数据 x x x ,构建机器学习模型 ...
- 深度学习与计算机视觉教程(4) | 神经网络与反向传播(CV通关指南·完结)
作者:韩信子@ShowMeAI 教程地址:https://www.showmeai.tech/tutorials/37 本文地址:https://www.showmeai.tech/article-d ...
- Andrej Karpathy | 详解神经网络和反向传播(基于micrograd)
只要你懂 Python,大概记得高中学过的求导知识,看完这个视频你还不理解反向传播和神经网络核心要点的话,那我就吃鞋:D Andrej Karpathy,前特斯拉 AI 高级总监.曾设计并担任斯坦福深 ...
- 【中英字幕】Andrej Karpathy | 详解神经网络和反向传播(基于micrograd)- 知识点目录
[中英字幕]Andrej Karpathy | 详解神经网络和反向传播(基于micrograd) 00:00:00 介绍 00:00:25 micrograd概述 00:08:08 只有一个输入的简单 ...
- 机器学习笔记丨神经网络的反向传播原理及过程(图文并茂+浅显易懂)
文章目录 一.前言 二.神经网络的前向传播原理 1. 单个神经元的计算 2. 神经元在神经网络中的计算 三.反向传播算法内容(请静下心,一步一步的看) Step1 计算误差 Step2 更新权重 四. ...
- 神经网络之反向传播算法(均方根反向传播算法RMSProp)
文章目录 均方根反向传播算法(RMSProp) 1.算法原理 2.算法实现 2.1 训练过程 2.2 测试过程及结果 3.参考源码及数据集 均方根反向传播算法(RMSProp) 自适应梯度算法(Ada ...
- 深度学习与自然语言处理教程(3) - 神经网络与反向传播(NLP通关指南·完结)
作者:韩信子@ShowMeAI 教程地址:https://www.showmeai.tech/tutorials/36 本文地址:https://www.showmeai.tech/article-d ...
- 卷积神经网络(CNN)反向传播算法推导
作者丨南柯一梦宁沉沦@知乎(已授权) 来源丨https://zhuanlan.zhihu.com/p/61898234 编辑丨极市平台 导读 在本篇文章中我们将从直观感受和数学公式两方面来介绍CNN反 ...
最新文章
- python functools.wraps functools.partial实例解析
- Android对应用程序签名
- Asp.Net Core 工作单元 UnitOfWork UOW
- php实时股票,php基于curl实现的股票信息查询类实例
- yum删除mysql数据库_MySQL数据库之Centos中彻底删除Mysql(rpm、yum安装的情况)
- 戴尔笔记本怎么重装系统win11,win11系统安装方法
- sklearn中的xgboost_RF/GBDT/XGBoost/LightGBM简单总结
- js去除字符串空格(空白符)
- 数字电视 机顶盒原理
- 比CMD更强大的命令行:WMIC后渗透利用(系统命令)
- js拆分百分数_一组数据百分比的优化算法(js)
- itext 导出pdf 图片太大
- SQL注入-二次注入和多语句注入
- Linux学习笔记:联想拯救者Y7000进BIOS
- 什么是HTML?HTML怎么学?HTML基础教程
- 微软MSDN原版系统下载
- python依赖包turbojpeg(PyTurboJPEG)安装
- #Sora#peewee管理数据库——笔记
- 如何用好MindManager中的时间轴模板
- 360系统急救箱扫服务器,今晚使用360系统急救箱扫描系统发现问题,之后windows 更新不能启动了...
热门文章
- ONNX 浅析:如何加速深度学习算法工程化?
- 32岁程序员面试被拒:比又穷又忙更可怕的,是2020年你还不懂...
- 语音识别大牛Daniel Povey为何加入小米?“手机+AIoT”强大生态,开源战略是关键...
- 心酸科研路:3年前CVPR论文,仅被引用11次,如今成就黑洞照片!
- GitHub超全机器学习工程师成长路线图,开源两日收获3700+Star!
- 滴滴裁员补偿丰厚,员工称裁出幸福感?
- 何恺明、吴育昕最新成果:用组归一化替代批归一化
- Python超过R,成为数据科学和机器学习的首选语言!
- 图片提取文字功能很神奇?Java几行代码搞定它!
- 平滑迁移 Dubbo 服务的思考