Note-归一化层和前向源码

news2024/11/19 17:52:32

本专栏主要是深度学习/自动驾驶相关的源码实现,获取全套代码请参考

目录

  • 简介
  • BN层
    • 计算过程
    • 参数说明
    • 验证
    • 问题:bn层前面的cov不需要bia的原因
  • LN层
    • 计算过程
    • 参数说明
    • 验证
    • 问题:transfomer用LN而不是BN的原因

简介

深度学习中常见的归一化层包括批量归一化(Batch Normalization)、层归一化(Layer Normalization)、实例归一化(Instance Normalization)、组归一化(Group Normalization)。
在这里插入图片描述
批量归一化(Batch Normalization):BN专注于标准化任何特定层的输入(即来自先前层的激活)。标准化输入意味着网络中任何层的输入应具有大约为零的均值和单位方差。BN通过减去当前mini-batch中的输入均值并除以标准差来变换当前mini-batch中的每个输入。此外,BN引入了两个可学习的参数γ和β,用于缩放和平移归一化后的值,以保留原有学习来的特征,同时完成归一化操作,加速训练。
层归一化(Layer Normalization):LN在通道方向上对CHW进行归一化,主要对RNN作用明显。
实例归一化(Instance Normalization):IN在图像像素上对HW进行归一化,主要用于风格化迁移。
组归一化(Group Normalization):GN将通道分组,然后再进行归一化。
这些归一化层的作用主要包括提高优化效率、缓解内部协变量偏移问题、作为正则化方法和提高泛化能力等。但它们也有各自的缺点,例如BN需要较大的批量大小才能有效地逼近小批量的总体均值和方差,这使得BN在训练网络用于对象检测、语义分割等应用时较为困难。

BN层

计算过程

假设输入shape为[4,3,240,240]
BN归一化相当于作用在通道维度上,一共3次归一化,分别求通道1、2、3的4张240x240照片的均值和方差,也就是分别计算3次[4,240,240]数据的均值和方差。

参数说明

主要包含4个参数:均值μ和方差σ²,缩放和平移变量 γ 和 β
均值和方差在训练过程统计得到,可以通过设置momentum值,进行增量式统计,即
x n = ( 1 − m o m e n t u m ) ∗ x n − 1 + m o m e n t u m ∗ x x_n = (1-momentum)*x_{n-1} + momentum* x xn=(1momentum)xn1+momentumx
在测试过程:拿上面训练的结果使用
缩放和平移变量 γ 和 β通过学习得到

验证

def my_bn(input: torch.Tensor, weight=None, bia=None):
    channels = input.size(1)
    num = input.size(0) * input.size(2) * input.size(3)
    output = deepcopy(input)
    # c个均值 c个标准差 c维度gamma c维theta  前两个统计得到,后两个学习得到
    exs = []
    dxs = []
    gamma = torch.ones(size=(channels,))
    theta = torch.zeros(size=(channels,))
    if weight:
        gamma = weight
    if bia:
        theta = bia
    # 按照通道遍历计算
    for channel in range(channels):
        ex = input[:, channel, :, :].sum() / num
        exs.append(ex)
        dx = torch.pow(torch.pow(input[:, channel, :, :] - ex, 2).sum() / num, 0.5)
        dxs.append(dx)
        output[:, channel, :, :] = (output[:, channel, :, :] - ex) / (dx + 0.00001)  # 0.00001 for zero denominator
        output[:, channel, :, :] = gamma[channel] * output[:, channel, :, :] + theta[channel]
    return output


if __name__ == '__main__':
    bn = nn.BatchNorm2d(3)
    input = torch.randn(size=(2, 3, 5, 5))
    output = bn(input)
    output_mybn = my_bn(input)

输出结果一致,说明计算过程没有问题

问题:bn层前面的cov不需要bia的原因

每一个卷积核的bia会使得cov输出对应通道的x都变成x+bia
bn层计算当前通道时均值变成mean+bia,标准差不变
z = γ ∑ ( x + b i a − m e a n − b i a ) 2 v a r + θ z = γ ∑ ( x − m e a n ) 2 v a r + θ z=\gamma \frac{\sum (x+bia-mean-bia)^2}{var}+ \theta \newline z=\gamma \frac{\sum (x-mean)^2}{var}+ \theta \newline z=γvar(x+biameanbia)2+θz=γvar(xmean)2+θ
所以cov的bia没用作用

LN层

计算过程

Layer Normalization目前在transfomer框架中大量运用.
假设输入shape为[4,3,240,240]
LN归一化相当于作用在样本数量上,一共4次归一化,分别求照片1、2、3、4的均值和方差,也就是计算4次[3,240,240]数据的均值和方差。

参数说明

主要包含4个参数:均值μ和方差σ²,缩放和平移变量 γ 和 β
均值和方差在正向传播时统计得到,训练测试一样,无需momentum值
缩放和平移变量 γ 和 β通过学习得到

验证

def my_ln(input: torch.Tensor, weight=None, bia=None):
    batchs = input.size(0)
    num = input.size(1) * input.size(2) * input.size(3)
    output = deepcopy(input)
    # c个均值 c个标准差 c维度gamma c维theta  前两个统计得到,后两个学习得到
    exs = []
    dxs = []
    gamma = torch.ones(size=(batchs,))
    theta = torch.zeros(size=(batchs,))
    if weight:
        gamma = weight
    if bia:
        theta = bia
    # 按照batch遍历计算
    for batch in range(batchs):
        ex = input[batch,:, :, :].sum() / num
        exs.append(ex)
        dx = torch.pow(torch.pow(input[batch,:, :, :] - ex, 2).sum() / num, 0.5)
        dxs.append(dx)
        output[batch,:, :, :] = (output[batch,:, :, :] - ex) / (dx + 0.00001)  # 0.00001 for zero denominator
        output[batch,:, :, :] = gamma[batch] * output[batch,:, :, :] + theta[batch]
    return output


if __name__ == '__main__':
    ln = nn.LayerNorm((3, 5, 5))
    input = torch.randn(size=(2, 3, 5, 5))
    output = ln(input)
    output_myln = my_ln(input)

输出结果一致,说明计算过程没有问题

问题:transfomer用LN而不是BN的原因

CV使用BN是认为rgb维度的信息不具有关联性,如果对channel维度也归一化会造成信息损失;认为图片之间因为有物理意义的约束,样本之间具有相似性,所以使用BN。
而同理nlp领域认为不同句子直接不具有关联性,batch维度归一化导致句子信息丢失;而句子内部具有关联性,所以使用LN.
那么VIT呢?

如需获取全套代码请参考

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

应急响应-流量分析

在应急响应中,有时需要用到流量分析工具,。当需要看到内部流量的具体情况时,就需要我们对网络通信进行抓包,并对数据包进行过滤分析,最常用的工具是Wireshark。 Wireshark是一个网络封包分析软件。网络封包分析软件的…

Redis面试(二)

1.Redis集群了解吗 前面说到了主从同步存在高可用和分布式问题,哨兵机制解决了高可用问题,而集群就是终极方案,一举解决高可用 和分布式问题。 1.数据分区:数据分区或称数据分片是集群最核心的功能,集群将数据分散到…

【人工智能】鲁滨逊归结原理-Python实现

一、实验目的 了解鲁滨逊归结算法原理,利用Python编写程序,实现鲁滨逊归结算法。 二、实验原理 鲁滨逊归结原理又称为消解原理,是鲁滨逊提出的一种证明子句集不可满足性,从而实现定理证明的一种理论及方法。它是机器定理证明的基…

项目解决方案:市小区高清视频监控平台联网整合设计方案(上)

目 录 一、项目需求 1.1业务需求 1.2技术需求 1.3 环境要求 1.3.1 硬件要求 1.3.2 技术服务要求 二、系统设计方案 2.1 视频监控平台基础功能设计 2.2 视频资源及联网设备编码与管理设计 2.2.1 全省现有联网视频资源属性 2.2.2 视频资源编码具体格…

任务修复实例(1)

实例1 任务名:增强防御(quest_template.id 8490) 涉及的两个数据表分别为 smart_script 和 creature_summon_groups smart_script Reactstate 取值参考源码 UnitDefines.h 的 ReactStates 定义,其中:0为被动&#…

第18章_JDK8-17新特性(下)(新语法结构,API的变化,其它结构变化,小结与展望)

文章目录 第18章_JDK8-17新特性(下)6. 新语法结构6.1 Java的REPL工具: jShell命令6.2 异常处理之try-catch资源关闭6.3 局部变量类型推断6.4 instanceof的模式匹配6.5 switch表达式6.6 文本块6.7 Record6.8 密封类 7. API的变化7.1 Optional类…

[docker] Docker镜像的创建以及Dockerfile的使用

一、Dokcer镜像的创建 创建镜像有三种方法,分别为基于已有镜像创建、基于本地模板创建以及基于Dockerfile创建。 1.1 基于现有镜像创建 (1)首先启动一个镜像,在容器里做修改docker run -it --name web centos:7 /bin/bash …

Docker 基础篇

目录 一、Docker 简介 1. Docker 2. Linux 容器 3. 传统虚拟机和容器的对比 4. Docker 的作用 5. Docker 的基本组成(Docker 三要素) 6. Docker 工作原理 7. Docker 架构 8. Docker 下载 二、Docker 安装 1. CentOS Docker 安装 2. CentOS8 …

03 Verilog HDL 语法

Verilog HDL(Hardware Description Language)是在 C 语言的基础上发展起来的一种硬件描述语言(用它可以表示逻辑电路图、逻辑表达式、数字逻辑系统所完成的逻辑功能等)具有灵活性高、易学易用等特点。Verilog HDL 可以在较短的时间…

Edius 9.0 下载安装教程,附安装包和工具,轻松解决软件安装

前言 Edius是一款非线性视频编辑软件,它可以帮助用户快速编辑一切,支持更多格式、更多分辨率而无需等待,无论是纪录片还是4K影视制作,软件都能很好的驾驭,是用户最喜欢的后期制作专业工具。 准备工作 1、Win7及以上…

如何做一个合格的产品经理

如何做一个合格的产品经理 如何做一个合格的产品经理 一、了解市场需求 产品经理的核心工作之一是了解市场需求。为了确保产品的成功,你需要密切关注市场动态,了解用户需求,分析竞争对手,并预测未来趋势。通过市场调查、用户访…

第十八回 林冲水寨大并火 晁盖梁山小夺泊-FreeBSD/Ubunut使用ssh的scp传输文件

何涛在得到知府命令后,带领官兵出发前往石碣村捉拿强盗。在接近石碣村时,他们遇到了一些打渔的人,得知阮小五、阮小七两兄弟在湖中居住,非乘船不能到达。何涛决定所有人都下马,一起乘船前往湖中寻找阮家兄弟。 在行船…

C++中的指针空值nullptr

一、nullptr的引入 在C98中,通常是用NULL或者0对指针变量进行初始化 int* p1 NULL; int* p2 0; NULL其实一个宏,本质是0,在传统C头文件stddef.h中给可以看到如下代码 #ifndef NULL #ifdef __cplusplus #define NULL 0 #else #define …

Unity 解释器模式(实例详解)

文章目录 示例1:基础解释器结构示例2:小于表达式(LessThanExpression)示例3:逻辑或表达式(OrExpression)示例4:逻辑非表达式(NotExpression)示例5&#xff1a…

SpringBoot整合Xxl-Job实现异步任务调度中心

目录 一、下载 1、源码 2、项目结构 3、模块说明 二、部署任务调度中心 1、创建数据库xxl-job 2、配置数据库 3、启动admin模块 4、打开任务调度中心 三、SpringBoot整合xxl-job 1、导入依赖 2、配置yml文件 3、配置类 4、启动项目 5、任务配置 6、测试 一、下…

【VS Code+Verilog+Vivado使用】(2)基本设置

文章目录 2 基本设置2.1 字体大小2.2 Tab大小2.3 选中高亮2.4 文件编码 2 基本设置 2.1 字体大小 方法1:VS Code左下角 > 管理 > 设置,搜索"font size",点击左侧"字体",根据需要设置"editor.fon…

vivado 配置内存IP

配置内存IP UltraScale体系结构内存IP支持DDR3和DDR4 SDRAM的配置,QDRIIPLUS SRAM和RLDRAM3型接口。截至2015.3,内存IP已被拆分基于内存接口标准和工具流,将其划分为不同的IP。“自定义IP”对话框框包含基本和高级配置选项,其中包…

Pyecharts魔法笔:探索多彩K线图的绘制与定制

标题:Pyecharts绘制多种炫酷K线图参数说明代码实战 在数据可视化领域,K线图是股票市场中常用的一种图表类型,用于展示一段时间内的开盘价、收盘价、最高价和最低价。Pyecharts是一个强大的Python可视化库,支持绘制各种图表&#…

贪吃蛇项目

引言: 本文章使用C语言在Windows环境的控制台中模拟实现经典小游戏贪吃蛇。 实现基本功能: 1.贪吃蛇地图绘制。 2.蛇吃食物的功能(上、下、左、右方向键控制蛇的动作) 3.蛇撞墙死亡 4.蛇咬到自己死亡 5.计算得分 6.蛇加速…

2024年数学建模美赛C题(预测 Wordle)——思路、程序总结分享

1: 问题描述与要求 《纽约时报》要求您对本文件中的结果进行分析,以回答几个问题。 问题1:报告结果的数量每天都在变化。开发一个模型来解释这种变化,并使用您的模型为2023年3月1日报告的结果数量创建一个预测区间。这个词的任何属性是否会…