从 X 入门Pytorch——BN、LN、IN、GN 四种归一化层的代码使用和原理

Pytorch中四种归一化层的原理和代码使用

    • 前言
    • 1 Batch Normalization(2015年提出)
      • Pytorch官网解释
      • 原理
      • Pytorch代码
      • 示例
    • 2 Layer Normalization(2016年提出)
      • Pytorch官网解释
      • 原理
      • Pytorch代码
      • 示例
    • 3 Instance Normalization(2017年提出)
      • Pytorch官方解释
      • 原理
      • Pytorch代码
      • 示例
    • 4 Group Normalization(2018年提出)
      • Pytorch官方解释
      • 原理
      • Pytorch代码
      • 示例

前言

在训练神经网络时,往往需要标准化(Normalization)输入数据,使得网络的训练更加快速和有效,然而SGD等学习算法会在训练中不断改变网络的参数,隐含层的激活值的分布会因此发生变化,而这一种变化就称为内协变量偏移(Internal Covariate Shift,ICS)

为了减轻ICS问题,Nomalization固定激活函数的输入变量的均值和方差(Nomalization后接激活函数),使得网络的训练更快。其计算方式大白话如下:将输入的数据,按照一定维度进行统计,得到数据的均值和方差,然后对数据结合均值和方差进行计算,将其变化为服从均值为0,方差为1的高斯分布,这样有助于加快网络训练速度。同时为了降低由于数据变化导致降低模型的表达能力,Nomalization提供了两个参数,用来对数据进行仿射变换,让这些数据靠近原始数据(最极限情况是这两个参数又将变换后的数据变为原来的数据)。

以下图片清晰的给出了不同归一化层的区别:

在这里插入图片描述

我当时见过另外一种图,较为抽象,一直没太看懂,当时看到这个图,醍醐灌顶,一下就都通了。

1 Batch Normalization(2015年提出)

Pytorch官网解释

BatchNorm2d

原理

针对输入到BN层的数据X,对所有 batch单个通道做归一化,每个通道都分别做一次,公式如下:
y = x − E [ x ] V a r [ x ] + ϵ ∗ γ + β \mathrm{y}=\frac{\mathrm{x}-\mathrm{E}[\mathrm{x}]}{\sqrt{\mathrm{Var}[\mathrm{x}]+\epsilon}} * \gamma+\beta y=Var[x]+ϵ xE[x]γ+β
其中:

  • E [ x ] \mathrm{E}[\mathrm{x}] E[x] 是向量x的均值
  • V a r [ x ] \mathrm{Var}[\mathrm{x}] Var[x] 是向量x的方差
  • ϵ \epsilon ϵ 为很小的常数,通常为0.00001,防止分母为0
  • γ \gamma γ 为仿射变换参数,模型可学习
  • β \beta β 为放射变换参数,模型可学习

公式中gama之前的数据就是标准化后的数据,满足均值为0,方差为1的高斯分布,便于加快网络训练速度。
但是标准化有可能会降低模型的表达能力,因为网络中的某些隐藏层很有可能就是血需要输入数据是非标准分布的,因此提供gama和beta进行学习,用于恢复网络的表达能力。

Pytorch代码

torch.nn.BatchNorm2d(num_features, eps=1e-5, momentum=0.1, affine=True, track_running_stats=True)
  • num_features: 传入的通道数
  • eps:常数 ϵ \epsilon ϵ, 默认为0.00001
  • monentum:动量参数,用来控制均值和方差的更新
  • affine:仿射变换的开关:默认打开
    • 如果 affine=False,则 γ \gamma γ=1, β \beta β=0,参数不能学习
    • 如果 affine=True, 则 γ \gamma γ, β \beta β可学习
  • track_running_stats: 如果为 True,则统计跟踪 batch 的个数,记录在 num_batches_tracked 中,一般不用管。

示例

import torch
import torch.nn as nn

input = torch.randn(20, 6, 10, 10)
m = nn.BatchNorm2d(6) 

y = m(input)
print(y.shape)

out:
torch.Size([20, 6, 10, 10])

本文介绍的四种归一化层都不改变输入数据的维度大小!!

2 Layer Normalization(2016年提出)

Pytorch官网解释

LayerNorm

原理

针对输入到LN层的数据X,对单个Batch中的所有通道数据做归一化,然后每个batch都单独做一次,公式如下:
y = x − E [ x ] V a r [ x ] + ϵ ∗ γ + β \mathrm{y}=\frac{\mathrm{x}-\mathrm{E}[\mathrm{x}]}{\sqrt{\mathrm{Var}[\mathrm{x}]+\epsilon}} * \gamma+\beta y=Var[x]+ϵ xE[x]γ+β
参照Batch Normalization公式和最上面的图进行理解,就是针对不同维度的数据进行标准化,其他的没变。Transformer中使用的就是LayerNorm。

Pytorch代码

torch.nn.LayerNorm(normalized_shape, eps=1e-5, elementwise_affine=True)
  • normalized_shape: 输入数据的维度(除了batch维度),例:数据维度【16, 64, 256, 256】 传入的normalized_shape维度为【64, 256, 256】。
  • eps: 常数,默认值为0.00001
  • elementwise_affine:仿射变换的开关:默认打开
    • 如果 elementwise_affine=False,则 γ \gamma γ=1, β \beta β=0,参数不能学习
    • 如果 elementwise_affine=True, 则 γ \gamma γ, β \beta β可学习

示例

import torch
import torch.nn as nn

ln = nn.LayerNorm([64, 256, 256])
x = torch.randn(16, 64, 256, 256)
y = ln(x)
print(y.shape)

out:
torch.Size([16, 64, 256, 256])

我也是最近才用了这个,因为要事先传入维度大小(C,H,W),所以使用的时候没有BN那么方便,如果想用,需要提前自己计算一下数据到LN这里的维度是多少,然后进行实例化才可以。

3 Instance Normalization(2017年提出)

Pytorch官方解释

InstanceNorm2d

原理

针对输入到IN层的数据X,对单个Batch中的单个通道数据做归一化,然后每个batch每个通道单独做一次,公式如下:
y = x − E [ x ] V a r [ x ] + ϵ ∗ γ + β \mathrm{y}=\frac{\mathrm{x}-\mathrm{E}[\mathrm{x}]}{\sqrt{\mathrm{Var}[\mathrm{x}]+\epsilon}} * \gamma+\beta y=Var[x]+ϵ xE[x]γ+β
公式还是那个公式,理解还是那个理解,请看明白最上面的那种图,就清楚了。

Pytorch代码

torch.nn.InstanceNorm2d(num_features, eps=1e-05, momentum=0.1, affine=False, track_running_stats=False)
  • num_features: 是通道数
  • eps:常数 ϵ \epsilon ϵ, 默认为0.00001
  • monentum:动量参数,用来控制均值和方差的更新
  • affine:仿射变换的开关:默认关闭
    • 如果 affine=False,则 γ \gamma γ=1, β \beta β=0,参数不能学习
    • 如果affine=True, 则 γ \gamma γ, β \beta β可学习

示例

# Without Learnable Parameters
m = nn.InstanceNorm2d(100)
# With Learnable Parameters
m = nn.InstanceNorm2d(100, affine=True)
input = torch.randn(20, 100, 35, 45)
output = m(input)
print(output.shape)

out:
torch.Size([20, 100, 35, 45])

这个初始化只需要传入通道数即可,和BN的实例化方法一样,便于使用!

4 Group Normalization(2018年提出)

Pytorch官方解释

GroupNoem

原理

针对输入到GN层的数据X,对单个Batch中的多个通道数据(一组数据)做归一化,然后每个batch每组数据单独做一次,公式如下:
y = x − E [ x ] V a r [ x ] + ϵ ∗ γ + β \mathrm{y}=\frac{\mathrm{x}-\mathrm{E}[\mathrm{x}]}{\sqrt{\mathrm{Var}[\mathrm{x}]+\epsilon}} * \gamma+\beta y=Var[x]+ϵ xE[x]γ+β
公式还是那个公式,理解还是那个理解,请看明白最上面的那种图,就清楚了。
不是我偷懒,实际情况是,Pytorch官网给出的四个公式也就是一样的!

Pytorch代码

torch.nn.GroupNorm(num_groups, num_channels, eps=1e-05, affine=True)
  • num_groups: 需要将Batch中的通道分为几组
  • num_channels: 传入的数据通道数
  • eps:常数 ϵ \epsilon ϵ, 默认为0.00001
  • affine:仿射变换的开关:默认打开
    • 如果 affine=False,则 γ \gamma γ=1, β \beta β=0,参数不能学习
    • 如果affine=True, 则 γ \gamma γ, β \beta β可学习

示例

import torch
import torch.nn as nn

input = torch.randn(20, 6, 10, 10)

m3 = nn.GroupNorm(3, 6)  # 分成3组
m6 = nn.GroupNorm(6, 6)   # 分成6组,这个就和IN一样了
m1 = nn.GroupNorm(1, 6)  # 分成1组,这个就和LN一样了

y1 = m1(input)
y3 = m3(input)
y6 = m6(input)
print(y1.shape)
print(y3.shape)
print(y6.shape)

out:
torch.Size([20, 6, 10, 10])
torch.Size([20, 6, 10, 10])
torch.Size([20, 6, 10, 10])

参考:

https://blog.csdn.net/qq_33236581/article/details/124016573
https://zhuanlan.zhihu.com/p/470260895

如果感觉有用,就及时收藏点赞,否则后期又要翻找,跟着我,一步一步学CV

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

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

相关文章

AJAX,Axios,JSON简单了解

一. AJAX简介概念: AJAX(Asynchronous JavaScript And XML): 异步的JavaScript 和XMLAJAX作用:1.与服务器进行数据交换: 通过AJAX可以给服务器发送请求,并获取服务器响应的数据使用了AJAX和服务器进行通信,就可以使用 HTMLAJAX来替换JSP页面了2.异步交互…

ChatGPT文心一言逻辑大比拼(一)

❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博…

静态通讯录,适合初学者的手把手一条龙讲解

数据结构的顺序表和链表是一个比较困难的点,初见会让我们觉得有点困难,正巧C语言中有一个类似于顺序表和链表的小程序——通讯录。我们今天就来讲一讲通讯录的实现,也有利于之后顺序表和链表的学习。 目录 0.通讯录的初始化 1.菜单的创建…

python例程:五子棋(控制台版)程序

目录《五子棋(控制台版)》程序使用说明程序示例代码可执行程序及源码下载路径《五子棋(控制台版)》程序使用说明 在PyCharm中运行《五子棋(控制台版)》即可进入如图1所示的系统主界面。 图1 游戏主界面 具…

一个比较全面的C#公共帮助类

上次跟大家推荐过2个C#开发工具箱:《推荐一个不到2MB的C#开发工具箱,集成了上千个常用操作类》、《推荐一个.Net常用代码集合,助你高效完成业务》。 今天再给大家推荐一个,这几个部分代码功能有重合的部分,大家可以根…

静态版通讯录——“C”

各位CSDN的uu你们好呀,之前小雅兰学过了一些结构体、枚举、联合的知识,现在,小雅兰把这些知识实践一下,那么,就让我们进入通讯录的世界吧 实现一个通讯录: 可以存放100个人的信息每个人的信息:名…

FPGA打砖块游戏设计(有上板照片)VHDL

这是一款经典打砖块游戏,我们的努力让它更精致更好玩,我们将它取名为打砖块游戏(Flyball),以下是该系统的一些基本功能:  画面简约而经典,色彩绚丽而活泼,动画流畅  玩家顺序挑战3个不同难度的级别,趣味十足  计分功能,卡通字母数字  4条生命值,由生命条显示…

智能扑克牌识别软件(Python+YOLOv5深度学习模型+清新界面)

摘要:智能扑克牌识别软件利用视觉方法检测和识别日常扑克牌具体花色与数字,快速识别牌型并标注结果,帮助计算机完成扑克牌对战的前期识别步骤。本文详细介绍基于深度学习的智能扑克牌识别软件,在介绍算法原理的同时,给…

[数据结构]排序算法

目录 常用排序算法的实现:: 1.排序的概念及其运用 2.插入排序 3.希尔排序 4.选择排序 5.冒泡排序 6.堆排序 7.快速排序 8.归并排序 9.排序算法复杂度及稳定性分析 10.排序选择题练习 常用排序算法的实现:: 1.排序的概念及其运用…

【C语言蓝桥杯每日一题】——排序

【C语言蓝桥杯每日一题】—— 排序😎前言🙌排序🙌总结撒花💞😎博客昵称:博客小梦 😊最喜欢的座右铭:全神贯注的上吧!!! 😊作者简介&am…

【千题案例】TypeScript获取两点之间的距离 | 中点 | 补点 | 向量 | 角度

我们在编写一些瞄准、绘制、擦除等功能函数时,经常会遇到计算两点之间的一些参数,那本篇文章就来讲一下两点之间的一系列参数计算。 目录 1️⃣ 两点之间的距离 ①实现原理 ②代码实现及结果 2️⃣两点之间的中点 ①实现原理 ②代码实现及结果 3…

当下的网络安全行业前景到底怎么样?还能否入行?

前言网络安全现在是朝阳行业,缺口是很大。不过网络安全行业就是需要技术很多的人达不到企业要求才导致人才缺口大常听到很多人不知道学习网络安全能做什么,发展前景好吗?今天我就在这里给大家介绍一下。网络安全作为目前比较火的朝阳行业&…

给程序加个进度条吧,1行Python代码,快速添加~

大家好,这里是程序员晚枫。 你在写代码的过程中,有没有遇到过以下问题? 已经写好的程序,想看看程序执行的进度? 在写代码批量处理文件的时候,如何显示现在处理到第几个文件了? &#x1f446…

真要被00后职场整顿了?老员工纷纷表示真的干不过.......

最近聊到软件测试的行业内卷,越来越多的转行和大学生进入测试行业。想要获得更好的待遇和机会,不断提升自己的技能栈成了测试老人迫在眉睫的问题。 不论是面试哪个级别的测试工程师,面试官都会问一句“会编程吗?有没有自动化测试…

dfs和bfs能解决的问题

一.理解暴力穷举之dfs和bfs暴力穷举暴力穷举是在解决问题中最常用的手段,而dfs和bfs算法则是这个手段的两个非常重要的工具。其实,最简单的穷举法是直接遍历,如数列求和,遍历一个数组即可求得所问答案,这与我在前两篇博…

【lwIP(第二章)】以太网DMA

目录一、以太网DMA描述符简介二、以太网DMA描述符结构三、如何追踪描述符总结一、以太网DMA描述符简介 发送:不需要CPU的参与下,把描述符指向的缓冲区数据传输到Tx FIFO当中 接收:不需要CPU的参与下,将Rx FIFO中的数据传输到描述符…

3 天交付新需求?极狐GitLab APP 「极限编程 XP」实践

近日,中移物联网有限公司、北京青云科技股份有限公司联合举办的 “2023 云原生重庆站技术分享会” 如期召开。会上,极狐(GitLab) 高级解决方案架构师刘剑桥带来《云原生极限编程 101》主题分享。本文整理自演讲内容,你可以阅读到:…

java调用chatgpt接口,实现专属于自己的人工智能助手

文章目录前言导包基本说明请求参数响应参数创建请求和响应的VO类代码编写使用最后说明前言 今天突然突发奇想,就想要用java来调用chatget的接口,实现自己的聊天机器人,但是网上找文章,属实是少的可怜(可能是不让发吧)。找到了一些…

【数据结构与算法】什么是双向链表?并用代码手动实现一个双向链表

文章目录一、什么是双向链表二、双向链表的简单实现一、什么是双向链表 我们来看一下这个例子: 在一个教室里,所有的课桌排成一列,如图 相信在你们的读书生涯中,老师肯定有要求你们记住自己的前后桌是谁。所以该例子中&#x…

J 砍竹子

砍竹子 【问题描述】 这天,小明在砍竹子,他面前有 n 棵竹子排成一排,一开始第 i 棵竹子的高度为 hi . 他觉得一棵一棵砍太慢了,决定使用魔法来砍竹子。魔法可以对连续的一段相同高度的竹子使用,假设这一段竹子的高度…