深度卷积神经网络的整体运行流程(以alexnet为例)

0.基础概念(复习一下)

1.小批量随机梯度下降

 

目的: 希望找到最佳的参数,使损失函数最小。

使损失函数对w求导(b就是x等于1的w),一个小批次的/eta(学习率)*小批次的平均梯度(/beta是小批次的样本数量)

遍历完全部批次的为一个epoch

2.反向传播的实现

 一个一个运算子,pytorch是隐式构造

 正向传播

 

 正向传播一般不存在,应为他更新一个参数就要从头算一次,更新大量参数计算量太大

 反向传播复杂度:

时间复杂度 O(n) 计算所有导数 基本上与正向复杂度一致
内存复杂度 O(n) 需要储存所有正向计算的中间值
对比正向传播 :
时间复杂度 O(n) 计算 k 个变量的导数为 O(n*k)
内存复杂度 O(1)
正向传播只储存一个结果(所有中间结果相乘),反向储存所有中间结果
内存是逆向传播的瓶颈
随着层数和批量大小线性增长
有限 GPU 内存 最多 32GB
用算力换内存
只保存一部分中间计算值
当需要时重新计算未保存中间值
放弃一部分中间值

 

 从头部开始第二次正向,反向传播,算是一个小的梯度下降

在PyTorch中有个简单的规定,不让张量对张量求导,只允许标量对张量求导。

import torch
x = torch.arange(4.0)
x.requires_grad_(True) # 等价于x=torch.arange(4.0,requires_grad=True)
x.grad # 默认值是None
y = 2 * torch.dot(x, x)
y
tensor(28., grad_fn=<MulBackward0>)
y.backward()
x.grad
tensor([ 0., 4., 8., 12.])
x.grad == 4 * x
tensor([True, True, True, True])
x.grad.zero_()# _ 的方法通常表示原地操作,一种约定俗成的写法
y = x.sum()
y.backward()
x.grad
tensor([1., 1., 1., 1.])

对x向量开启梯度下降,对y反向传播(y对X求导),把梯度存入x.grad中,shape和x一样。之后清空x.grad 再次记录梯度。

目标量对一个非标量调用backward(),则需要传入一个gradient参数。传入这个参数就是为了把张量对张量的求导转换为标量对张量的求导。

# 对非标量调用backward需要传入一个gradient参数,该参数指定微分函数关于self的梯度。
# 本例只想求偏导数的和,所以传递一个1的梯度是合适的
x.grad.zero_()
y = x * x
# 等价于y.backward(torch.ones(len(x)))
y.sum().backward()
x.grad
tensor([0., 2., 4., 6.])

y现在是一个一维张量了,把所有y对x的导数加在一起就好

把y理解为多个损失函数就好 ,最后加在一起

分离计算

y是作为x的函数计算的,而z则是作为y和x的函数计算的。我们想计算z关于x的梯度,但由于某种原因,希望将y视为一个常数,并且只考虑到x在y被计算后发挥的作用。

这里可以分离y来返回一个新变量u,该变量与y具有相同的值,但丢弃计算图中如何计算y的任何信息。换句话说,梯度不会向后流经u到x。因此,下面的反向传播函数计算z=u*x关于x的偏导数,同时将u作为常数处理,
而不是z=x*x*x关于x的偏导数。(正向传播x>y,x>z,即z对x有两条传播途径,分别是y,2x*x,相加就是结果,现在把对y求导那条路断了,结果只有y了,也就是x^2,也就是u)

x.grad.zero_()
y = x * x
u = y.detach()
z = u * x
z.sum().backward()
x.grad == u
#tensor([True, True, True, True])
x.grad.zero_()
y.sum().backward()
x.grad == 2 * x
#tensor([True, True, True, True])

 自动微分的一个好处

即使构建函数的计算图需要通过Python控制流(例如,条件、循环或任意函数调用),我们仍然可以计算得到的变量的梯度。即使一堆循环,也可以得到变量梯度k(d=ka)

也就是可以把这一堆循环变成一个计算f(a),得到a的梯度

a = torch.randn(size=(), requires_grad=True)
# 使用torch.randn()
函数生成一个随机的标量张量。size=()参数指定了张量的形状为空,表示创建一个标量(0维张量)
d = f(a)
d.backward()

我们现在可以分析上面定义的f函数。 请注意,它在其输入a中是分段线性的。 换言之,对于任何a,存在某个常量标量k,使得f(a)=k*a,其中k的值取决于输入a,因此可以用d/a验证梯度是否正确。

a.grad == d / a

输出结果:

tensor(True)

3.DataLoader

 data.DataLoader得到一个数据迭代器对象,小批次取出数据

import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter



#train=True 时,表示加载训练数据集;而当 train=False 时,表示加载测试数据集。
# 准备的测试数据集  数据放在了CIFAR10文件夹下
test_data = torchvision.datasets.CIFAR10("./CIFAR10",
 train=False, transform=torchvision.transforms.ToTensor())
test_loader = DataLoader(dataset=test_data, batch_size=4, 
shuffle=True, num_workers=0, drop_last=False)
#创建一个迭代器对象,test_loader,遍历数据,每次4张
# 测试数据集中第一张图片及target
img, target = test_data[0]
print(img.shape)
print(target)

# 在定义test_loader时,设置了batch_size=4,表示一次性从数据集中取出4个数据
for data in test_loader:
    imgs, targets = data
    print(imgs.shape)
    print(targets)

# 在定义test_loader时,设置了batch_size=4,表示一次性从数据集中取出4个数据
writer = SummaryWriter("logs")
for epoch in range(2):
    step = 0
    for data in test_loader:
        imgs, targets = data
        writer.add_images("Epoch: {}".format(epoch), imgs, step)
        step = step + 1
writer.close()

 

4.线性模型和非线性模型

softmax回归中,虽然加入了softmax,但是大小的顺序并没有改变,仍是线性模型,然而我们可以很容易找出违反单调性的例子。

例如,对猫和狗的图像进行分类:增加位置(13,17)处像素的强度是否总是增加(或降低)图像描绘狗的似然?对线性模型的依赖对应于一个隐含的假设,即区分猫和狗的唯一要求是评估单个素的强度。在一个倒置图像后依然保留类别的世界里,这种方法注定会失败。所以,这里的线性很荒谬

 因此,我们可以通过在网络中加入一个或多个隐藏层来克服线性模型的限制,使其能处理更普遍的函数关系类型。

5.激活函数

如果没有激活函数,在添加隐藏层之后,我们没有好处! 

因为仿射函数的仿射函数本身就是仿射函数,但是我们之前的线性模型已经能够表示
任何仿射函数。

 为了发挥多层架构的潜力,我们需要非线性的激活函数

即使是网络只有一个隐藏层,给定足够的神经元和正确的权重,我们可以对任意函数建模,尽管实际中学习该函数是很困难的。而且,虽然一个单隐层网络能学习任何函数,但并不意味着我们应该尝试使用单隐藏层网络来解决所有问题。事实上,通过使用更深(而不是更广)的网络,我们可以更容易地逼近许多函数。

6.欠拟合和过拟合

模型不能降低训练误差,这可能意味着模型过于简单(即表达能力不足),无法捕获试图学习的模式。此外,由于我们的训练和验证误差之间的泛化误差很小,我们有理由相信可以用一个更复杂的模型降低训练误差。这种现象被称为欠拟合(underfitting)。
另一方面,当我们的训练误差明显低于验证误差时要小心,这表明严重的过拟合(overfitting)。注意,过拟合并不总是一件坏事。特别是在深度学习领域,众所周知,最好的预测模型在训练数据上的表现往往比在保留(验证)数据上好得多。最终,我们通常更关心验证误差,而不是训练误差和验证误差之间的差距。

7.权重衰减(weight decay)(L 2 正则化)

 lambd = 0禁用权重衰减后运行这个代码。注意,这里训练误差有了减少,但测试误差没有减少,
这意味着出现了严重的过拟合。减少过拟合

 8.暂退法(Dropout) 

 经典泛化理论认为,为了缩小训练和测试性能之间的差距,应该以简单的模型为目标。简单性以较小维度的形式展现。此外,正如权重衰减(L 2 正则化)时,参数的范数也代表了一种有用的简单性度量。

简单性的另一个角度是平滑性,即函数不应该对其输入的微小变化敏感。即当我们对图像进行分类时,我们预计向像素添加一些随机噪声应该是基本无影响的。

在训练过程中,在计算后续层之前向网络的每一层注入噪声。因为当训练一个有多层的深层网络时,注入噪声只会在输入‐输出映射上增强平滑性。这个想法被称为暂退法(dropout)。

在标准暂退法正则化中,每个中间活性值h以暂退概率p由随机变量h ′ 替换 

 

 测试时(预测时)不用暂退法。给定一个训练好的模型和一个新的样本,我们不会丢弃任何节点,因此不需要标准化。

9.卷积输入通道和输出通道

 1.构建alexnet网络

import torch
from torch import nn
from d2l import torch as d2l
net = nn.Sequential(
# 这里使用一个11*11的更大窗口来捕捉对象。
# 同时,步幅为4,以减少输出的高度和宽度。
# 另外,输出通道的数目远大于LeNet
nn.Conv2d(1, 96, kernel_size=11, stride=4, padding=1), nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2),
# 减小卷积窗口,使用填充为2来使得输入与输出的高和宽一致,且增大输出通道数
nn.Conv2d(96, 256, kernel_size=5, padding=2), nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2),
# 使用三个连续的卷积层和较小的卷积窗口。
# 除了最后的卷积层,输出通道的数量进一步增加。
# 在前两个卷积层之后,汇聚层不用于减少输入的高度和宽度
nn.Conv2d(256, 384, kernel_size=3, padding=1), nn.ReLU(),
nn.Conv2d(384, 384, kernel_size=3, padding=1), nn.ReLU(),
nn.Conv2d(384, 256, kernel_size=3, padding=1), nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Flatten(),
# 这里,全连接层的输出数量是LeNet中的好几倍。使用dropout层来减轻过拟合
nn.Linear(6400, 4096), nn.ReLU(),
nn.Dropout(p=0.5),
nn.Linear(4096, 4096), nn.ReLU(),
nn.Dropout(p=0.5),
# 最后是输出层。由于这里使用Fashion-MNIST,所以用类别数为10,而非论文中的1000
nn.Linear(4096, 10))

X = torch.randn(1, 1, 224, 224)
for layer in net:
X=layer(X)
print(layer.__class__.__name__,'output shape:\t',X.shape)

Conv2d output shape: torch.Size([1, 96, 54, 54])
ReLU output shape: torch.Size([1, 96, 54, 54])
MaxPool2d output shape: torch.Size([1, 96, 26, 26])
Conv2d output shape: torch.Size([1, 256, 26, 26])
ReLU output shape: torch.Size([1, 256, 26, 26])
MaxPool2d output shape: torch.Size([1, 256, 12, 12])
Conv2d output shape: torch.Size([1, 384, 12, 12])
ReLU output shape: torch.Size([1, 384, 12, 12])
Conv2d output shape: torch.Size([1, 384, 12, 12])
ReLU output shape: torch.Size([1, 384, 12, 12])
Conv2d output shape: torch.Size([1, 256, 12, 12])
ReLU output shape: torch.Size([1, 256, 12, 12])
MaxPool2d output shape: torch.Size([1, 256, 5, 5])
Flatten output shape: torch.Size([1, 6400])
Linear output shape: torch.Size([1, 4096])
ReLU output shape: torch.Size([1, 4096])
Dropout output shape: torch.Size([1, 4096])
Linear output shape: torch.Size([1, 4096])
ReLU output shape: torch.Size([1, 4096])
Dropout output shape: torch.Size([1, 4096])
Linear output shape: torch.Size([1, 10])

2.读取数据集 

batch_size = 128
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224)

3.训练数据集

def train_ch6(net, train_iter, test_iter, num_epochs, lr, device):
    """用GPU训练模型(在第六章定义)"""
    def init_weights(m):
        if type(m) == nn.Linear or type(m) == nn.Conv2d:
            nn.init.xavier_uniform_(m.weight)
    net.apply(init_weights)
    print('training on', device)
    net.to(device)
    optimizer = torch.optim.SGD(net.parameters(), lr=lr)
    loss = nn.CrossEntropyLoss()
    animator = d2l.Animator(xlabel='epoch', xlim=[1, num_epochs],
                            legend=['train loss', 'train acc', 'test acc'])
    timer, num_batches = d2l.Timer(), len(train_iter)
    for epoch in range(num_epochs):
        # 训练损失之和,训练准确率之和,样本数
        metric = d2l.Accumulator(3)
        net.train()
        for i, (X, y) in enumerate(train_iter):
            timer.start()
            optimizer.zero_grad()
            X, y = X.to(device), y.to(device)
            y_hat = net(X)
            l = loss(y_hat, y)
            l.backward()  #把梯度下降值存到grad里
            optimizer.step()#-grad更新参数
            with torch.no_grad():
                metric.add(l * X.shape[0], d2l.accuracy(y_hat, y), X.shape[0])
            timer.stop()
            train_l = metric[0] / metric[2]
            train_acc = metric[1] / metric[2]
            if (i + 1) % (num_batches // 5) == 0 or i == num_batches - 1:
                animator.add(epoch + (i + 1) / num_batches,
                             (train_l, train_acc, None))
        test_acc = evaluate_accuracy_gpu(net, test_iter)
        animator.add(epoch + 1, (None, None, test_acc))
    print(f'loss {train_l:.3f}, train acc {train_acc:.3f}, '
          f'test acc {test_acc:.3f}')
    print(f'{metric[2] * num_epochs / timer.sum():.1f} examples/sec '
          f'on {str(device)}')
lr, num_epochs = 0.01, 10
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/565109.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

hexo配置教程、主题使用及涉及的技术学习

一、背景 最近,一直想做一个属于自己的网站.可以从零开始搭建一个网站,顺便可以把日常中学到的技术用于实战,还可以顺便记录自己的所思所感,记录成长的过程. 方案 一开始的方案是从零开始,模仿常见个人博客的设计,基于vueSpringbootMySQL的去实现网站. 新建项目之后,发现vu…

【网络原理】UDP协议的报文结构 及 校验和字段的错误检测机制(CRC算法、MD5算法)

目录 UDP协议 UDP协议的报文结构及注意事项 UDP报文结构中的校验和字段 1. 校验和主要校验的内容 2. UDP校验和的实现方式 3. CRC&#xff08;循环冗余校验&#xff09;算法 4. MD5&#xff08;Message Digest Algorithm 5&#xff09; UDP协议 上一篇文章提过&#xf…

Linux cmake 初窥【1】

1.开发背景 linux 下编译程序需要用到对应的 Makefile&#xff0c;用于编译应用程序&#xff0c;但是 Makefile 的语法过于繁杂&#xff0c;甚至有些反人类&#xff0c;所以这里引用了cmake&#xff0c;cmake 其中一个主要功能就是用于生成 Makefile&#xff0c;cmake 的语法更…

吴恩达深度学习 (week5,6)

文章目录 一、训练开发测试集二、机器学习基础三、 正则化初步介绍四、Dropout 正则化五、其他正则化方法六、归一化输入介绍七、梯度消失与梯度爆炸八、神经网络的权重初始化九、梯度数值逼近和检验十、上述学习总结第一题 划分训练/开发/测试集第二题 开发和测试集分布第三题…

谷粒商城学习笔记

1.系统架构 2.环境准备 21.安装Linux 1.VirtualBox: https://download.virtualbox.org/virtualbox/6.0.10/VirtualBox-6.0.10-132072-Win.exe 2.安装 Vagrant 1).Vagrant 下载地址: https://releases.hashicorp.com/vagrant/2.2.5/vagrant_2.2.5_x86_64.msi https://www…

Obsidian 快速安装

看网上Obsidian 很好用&#xff0c;但自己下载总是中断&#xff0c;烦的要死&#xff0c;一度以为要开魔法…… 直到我找到了这个网站Thoughts (teambition.com) yeah~ 亲测有效&#xff0c;大概不到2min吧. 快速开始~&#xff0c;成功水了一片

海外服务器被恶意攻击怎么办

如果您的海外服务器遭受了恶意攻击&#xff0c;以下是一些应对措施和步骤&#xff0c;立即隔离服务器。如果您察觉到服务器受到恶意攻击&#xff0c;立即隔离服务器&#xff0c;将其与网络隔离&#xff0c;以防止攻机进一步扩散。通知服务器提供商&#xff0c;以便他们能够提供…

大小写不规范引起的LVS问题

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 往期文章链接: LVS常见问题解析 综合网表不规范,大小写混用常导致LVS问题,比如两个端口clk和CLK只有大小写区别,PR工具是可以识别为两个端口的,只不过Calibre LVS默认不区分大小写,会报错。 …

第二部分-Foundation基础-学习导航

专题地址&#xff1a;MacOS一站式程序开发系列专题 第一部分&#xff1a;基础入门-学习导航 ObjectiveC-第一部分-基础入门-学习导航 第二部分&#xff1a;Foundation基础学习导航 Foundation框架-13-数据对象&#xff1a;主要讲述NSRange, NSString, NSValue, NSNull, NSD…

从旺店通·企业奇门到用友BIP通过接口配置打通数据

从旺店通企业奇门到用友BIP通过接口配置打通数据 接入系统&#xff1a;旺店通企业奇门 旺店通是北京掌上先机网络科技有限公司旗下品牌&#xff0c;国内的零售云服务提供商&#xff0c;基于云计算SaaS服务模式&#xff0c;以体系化解决方案&#xff0c;助力零售企业数字化智能化…

CLAHE算法上新

加入我们的FPGA实现CLAHE算法课程&#xff0c;探索图像增强的前沿技术&#xff01; [课程名称]&#xff1a; FPGA实现对比度受限自适应直方图均衡化&#xff08;CLAHE&#xff09;算法 [授课方式]&#xff1a; 录播课程 互动讨论 实践操作 在线答疑 课程简介&#xff1a; 在…

Vue2之组件通信(爆肝)

大家有什么想看的可以在评论区留言&#xff0c;我尽量满足&#xff0c;感谢大家&#xff01; 组件通信是vue中一个非常重要的内容&#xff0c;我们需要掌握好组件通信&#xff0c;那么让我为大家介绍几种组件通信的方式吧&#xff01; 一、props 这是父传子的方式&#xff0…

贪吃蛇代码实现

一.基本信息 实现目标&#xff1a;使用C语言在Windows环境的控制台中实现贪吃蛇游戏 游戏运行&#xff1a; 地图绘制基本玩法提示信息游戏的开始与结束 基本玩法&#xff1a; 通过上下左右键控制蛇的移动蛇可以加速减速吃掉食物可以得分并增加蛇的长度可以自动暂停 游戏结…

Macs Fan Control Pro for Mac:全面优化Mac风扇控制软件

Macs Fan Control Pro for Mac是一款专为苹果电脑用户设计的风扇控制软件&#xff0c;旨在通过精确的风扇速度调节&#xff0c;全面优化Mac的散热性能&#xff0c;确保系统始终运行在最佳状态。 Macs Fan Control Pro for Mac中文版下载 该软件具备实时监控功能&#xff0c;能够…

HarmonyOS ArkUI实战开发-NAPI异步编程

笔者在前 5 小节里讲述了在 OpenHarmony 上通过 NAPI 的方式实现了 JS 调用 C的能力&#xff0c;但是这些实现都是同步的&#xff0c;本节笔者简单介绍一下 NAPI 的异步实现。 约定编程规范 ArkUI 开发框架对外提供的 API 命名是需遵守一定规范的&#xff0c;以 ohos.display…

初学python记录:力扣39. 组合总和

题目&#xff1a; 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限…

【STM32】嵌入式实验二 GPIO 实验:数码管

实验内容&#xff1a; 编写程序&#xff0c;在数码管上显示自己的学号。 数码管相关电路&#xff1a; PA7对应的应该是段码&#xff0c;上面的图写错了。 注意&#xff1a;选中数码管是低电平选中&#xff1b;并且用74HC595模块驱动输出的段码&#xff0c; 这个模块的学习可以…

echarts折线图默认不显示数据圆点,鼠标划上之后折线图才显示圆点

只需要设置showSymbol为false就可以了&#xff0c;表示只在 tooltip hover 的时候显示。 代码如下&#xff1a; option {tooltip: {trigger: axis},xAxis: {type: category,data: [Mon, Tue, Wed, Thu, Fri, Sat, Sun]},yAxis: {type: value},series: [{data: [150, 230, 224…

【智能算法】寄生捕食算法(PPA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2020年&#xff0c;AAA Mohamed等人受到自然界乌鸦-布谷鸟-猫寄生系统启发&#xff0c;提出了寄生捕食算法&#xff08;Parasitism – Predation Algorithm, PPA&#xff09;。 2.算法原理 2.1算法…

HTML使用jQuery实现两个点击按钮,分别控制改文本字体颜色和字体大小

jQuery 简介 jQuery 是一个广泛使用的 JavaScript 库&#xff0c;旨在简化对 HTML 文档的操作、事件处理、动画效果和 AJAX 等操作。 案例源码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name&q…