深度学习特征归一化方法——BN、LN、IN、GN

前言

最近看到Group Normalization的论文,主要提到了四个特征归一化方法:Batch NormLayer NormInstance NormGroup Norm。此外,论文还提到了Local Response Normalization(LRN)Weight Normalization(WN)Batch Renormalization(BR)

国际惯例,参考博客:

Group Normalization论文

Group_Normalization-Tensorflow

GN的tensorflow官方实现

动机

BN是在小批数据中用均值和方差归一化,能够保证很深的网络能够收敛,但是BN需要足够大的batch size,比较小的batch对批量数据的统计特征估算不准确,降低BNbatch size 就会提升模型误差。

Group的思想有很多:AlexNet将模型部署到两块GPUResNeXt测试了depthwidthgroups对网络的效果,建议在相似计算消耗的前提下,较大的group能提升准确率;MobileNetXception测试了depth-wise卷积的效果,也就是group数与channel数相同;ShuffleNet尝试了交换group特征,即channel随机交换。这些方法都包括将channel划分为不同的group,所以作者就想到了groupNormalization

作者认为,DNN的channels特征并非是非结构化的,比如第一层卷积,其中一个滤波器与他的水平翻转滤波器,对同一张图片的响应,可能得到相似的分布。如果第一层卷积近似学习到了这对滤波器,那么这些滤波器对应的channel就可以被一起归一化了。文章还说明了,除了类似这样的卷积核可以导致group,其它的比如频率、形状、亮度、纹理等,都可能具有联系,都可以被group

理论

通常归一化的标准公式就是:
x^=x−μiσi\hat{x}=\frac{x-\mu_i}{\sigma_i} x^=σixμi
其中μ\muμ是均值,σ\sigmaσ是方差,假设均值和方差都是从集合SiS_iSi中计算得到的,那么
μi=1m∑k∈Sixkσi=1m∑k∈Si(xk−μi)2+ϵ\begin{aligned} \mu_i &= \frac{1}{m}\sum_{k\in S_i} x_k \\ \sigma_i &=\sqrt{\frac{1}{m}\sum_{k \in S_i}(x_k-\mu_i)^2 + \epsilon} \end{aligned} μiσi=m1kSixk=m1kSi(xkμi)2+ϵ
假设其中某个卷积层的特征图树木为(N,C,H,W)(N,C,H,W)(N,C,H,W),分别代表批中样本索引、特征图通道索引、特征图高、宽,设它们的索引是(Ni,Cj,H,W)(N_i,C_j,H,W)(Ni,Cj,H,W)代表第iii个样本的第jjj个特征图。

那么

  • Batch Norm对应的计算均值和方差的数据集合为:Si={k∣kC=Ci}S_i= \{k|k_C=C_i\}Si={kkC=Ci} ;意思是将当前批所有数据的具有相同通道索引的特征图划分为一组,每组单独归一化,这样组集合就是:
    (N,C1,H,W),(N,C2,H,W),⋯,(N,Cj,H,W),⋯(N,C_1,H,W),(N,C_2,H,W),\cdots,(N,C_j,H,W),\cdots(N,C1,H,W),(N,C2,H,W),,(N,Cj,H,W),
  • Layer Norm对应的计算均值和方差的数据集合为:Si={k∣kN=Ni}S_i= \{k|k_N = N_i \}Si={kkN=Ni};意思是将当前批每个数据的所有通道划分为一组,每组单独归一化,这样组集合就是:
    (N1,C,H,W),(N2,C,H,W),⋯,(Ni,C,H,W),⋯(N_1,C,H,W),(N_2,C,H,W),\cdots,(N_i,C,H,W),\cdots(N1,C,H,W),(N2,C,H,W),,(Ni,C,H,W),
  • Instance Norm对应的计算均值和方差的数据集合为:S={k∣kn=Ni,kC=Cj}S=\{k|k_n=N_i,k_C=C_j\}S={kkn=Ni,kC=Cj};意思是将当前批每个数据的每个通道单独划分一组,也就是每个特征图自己归一化,这样组集合就是:
    (N1,C1,H,W),(N2,C1,H,W),⋯,(Ni,Cj,H,W),⋯(N_1,C_1,H,W),(N_2,C_1,H,W),\cdots,(N_i,C_j,H,W),\cdots(N1,C1,H,W),(N2,C1,H,W),,(Ni,Cj,H,W),
  • Group Norm对应的计算均值和方差的数据集合为:S={k∣kN=Ni,⌊kCC/G⌋=⌊CiC/G⌋}S=\{k| k_N=N_i, \lfloor \frac{k_C}{C/G} \rfloor = \lfloor \frac{C_i}{C/G} \rfloor \}S={kkN=Ni,C/GkC=C/GCi};意思是将每个样本对应的所有通道划分为GGG组,每组单独归一化,假设每组被划分后有两个通道,组集合就是:
    第一组:(N1,C1,H,W),(N1,C2,H,W)(N_1,C_1,H,W),(N_1,C_2,H,W)(N1,C1,H,W),(N1,C2,H,W)
    ⋮\vdots
    第p组:(Ni,Cj,H,W),(Ni,Cj+1,H,W)(N_i,C_j,H,W),(N_i,C_{j+1},H,W)(Ni,Cj,H,W),(Ni,Cj+1,H,W)
    ⋮\vdots

当然,为了弥补损失掉的表达能力,上述所有的Normalization方法都必须学习一个线性变换:
yi=γxi^+βy_i=\gamma \hat{x_i}+\betayi=γxi^+β

其中γ\gammaγβ\betaβ是可训练的缩放与偏移值,是针对每个通道的。

代码

第三方实现

github上有人在tensorflow中实现过,戳这里

def group_norm(x, G=32, eps=1e-5, scope='group_norm') :with tf.variable_scope(scope) :N, H, W, C = x.get_shape().as_list()G = min(G, C)x = tf.reshape(x, [N, H, W, G, C // G])mean, var = tf.nn.moments(x, [1, 2, 4], keep_dims=True)x = (x - mean) / tf.sqrt(var + eps)gamma = tf.get_variable('gamma', [1, 1, 1, C], initializer=tf.constant_initializer(1.0))beta = tf.get_variable('beta', [1, 1, 1, C], initializer=tf.constant_initializer(0.0))x = tf.reshape(x, [N, H, W, C]) * gamma + betareturn x

调用方法也很简单:

from ops import *x = conv(x)x = group_norm(x) 

tensorflow官方实现

官方实现戳这里

定义的函数:

def group_norm(inputs,groups=32,channels_axis=-1,reduction_axes=(-3, -2),center=True,scale=True,epsilon=1e-6,activation_fn=None,param_initializers=None,reuse=None,variables_collections=None,outputs_collections=None,trainable=True,scope=None,mean_close_to_zero=False):

分组的核心代码:

# Manually broadcast the parameters to conform to the number of groups.params_shape_broadcast = ([1] * len(axes_before_channels) +[groups, channels // groups] +[1] * len(axes_after_channels))# Reshape the input by the group within the channel dimension.inputs_shape = (axes_before_channels + [groups, channels // groups] +axes_after_channels)inputs = array_ops.reshape(inputs, inputs_shape)

可以发现,不管是个人实现,还是官方实现,最主要的就是对channels进行groups分组。

后记

GN主要就是针对batch size时,BN归一化不准确而提出的,如果我们的机器能满足batch size足够大,那就没必要用GN了。

博客已同步至微信公众号,不定时更新计算机视觉、机器学习、深度学习理论与代码实现,有问题欢迎评论或者微信公众号私聊
在这里插入图片描述

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

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

相关文章

【TensorFlow-windows】keras接口——利用tensorflow的方法加载数据

前言 之前使用tensorflow和keras的时候,都各自有一套数据读取方法,但是遇到一个问题就是,在训练的时候,GPU的利用率忽高忽低,极大可能是由于训练过程中读取每个batch数据造成的,所以又看了tensorflow官方的…

骨骼动画——论文与代码精读《Phase-Functioned Neural Networks for Character Control》

前言 最近一直玩CV,对之前学的动捕知识都忘得差不多了,最近要好好总结一下一直以来学习的内容,不能学了忘。对2017年的SIGGRAPH论文《Phase-Functioned Neural Networks for Character Control》进行一波深入剖析吧,结合源码。 额…

颜色协调模型Color Harmoniztion

前言 最近做换脸,在肤色调整的那一块,看到一个有意思的文章,复现一波玩玩。不过最后一步掉链子了,有兴趣的可以一起讨论把链子补上。 主要是github上大佬的那个复现代码和原文有点差异,而且代码复杂度过高&#xff0…

Openpose推断阶段原理

前言 之前出过一个关于openpose配置的博客,不过那个代码虽然写的很好,而且是官方的,但是分析起来很困难,然后再opencv相关博客中找到了比较清晰的实现,这里分析一波openpose的推断过程。 国际惯例,参考博…

换脸系列——眼鼻口替换

前言 想着整理一下换脸相关的技术方法,免得以后忘记了,最近脑袋越来越不好使了。应该会包含三个系列: 仅换眼口鼻;换整个面部;3D换脸 先看看2D换脸吧,网上已经有现成的教程了,这里拿过来整理一…

换脸系列——整脸替换

前言 前面介绍了仅替换五官的方法,这里介绍整张脸的方法。 国际惯例,参考博客: [图形算法]Delaunay三角剖分算法 维诺图(Voronoi Diagram)分析与实现 Delaunay Triangulation and Voronoi Diagram using OpenCV (…

3D人脸重建——PRNet网络输出的理解

前言 之前有款换脸软件不是叫ZAO么,分析了一下,它的实现原理绝对是3D人脸重建,而非deepfake方法,找了一篇3D重建的论文和源码看看。这里对源码中的部分函数做了自己的理解和改写。 国际惯例,参考博客: 什…

tensorflow官方posenet模型解析

前言 tensorflow官方有个姿态估计项目,这个输入和openpose还有点不一样,这里写个单人情况下的模型输出解析方案。 国际惯例,参考博客: 博客: 使用 TensorFlow.js 在浏览器端上实现实时人体姿势检测 tensorflow中posnet的IOS代…

tensorflow2安装时候的一个dll找不到的错误

电脑环境: vs2015python3.7.6,使用anaconda安装的CUDA 10.1cuDnn 7.6.5tensorflow2.1.0 错误内容 File "C:\Users\zb116\anaconda3\lib\imp.py", line 242, in load_modulereturn load_dynamic(name, filename, file)File "C:\Users\z…

PCA、SVD、ZCA白化理论与实现

简介 在UFLDL中介绍了主成分分析这一块的知识,而且当时学机器学习的时候,老师是将PCA和SVD联系起来将的,同时UFLDL也讲到了使用PCA做数据白化whitening处理,这个词经常在论文里面看到。 国际惯例,参考博客&#xff1…

OpenCV使用Tensorflow2-Keras模型

前言 最近工作上需要在C上快速集成Tensorflow/Keras训练好的模型,做算法验证。首先想到的就是opencv里面的dnn模块了,但是它需要的格式文件比较郁闷,是pb格式的模型,但是keras通常保存的是h5文件,查阅了很多资料&…

3D人脸表情驱动——基于eos库

前言 之前出过三篇换脸的博文,遇到一个问题是表情那一块不好处理,可行方法是直接基于2D人脸关键点做网格变形,强行将表情矫正到目标人脸,还有就是使用PRNet的思想,使用目标人脸的顶点模型配合源人脸的纹理&#xff0c…

3D姿态估计——ThreeDPose项目简单易用的模型解析

前言 之前写过tensorflow官方的posenet模型解析,用起来比较简单,但是缺点是只有2D关键点,本着易用性的原则,当然要再来个简单易用的3D姿态估计。偶然看见了ThreeDPose的项目,感觉很强大的,所以把模型扒下来…

简易的素描图片转换流程与实现

前言 之前经常在网上看到用PS实现真实图片到素描图片的转换,但是流程都大同小异,身为一只程序猿,必须来个一键转化额。 国际惯例,参考博客: Photoshop基础教程:混合模式原理篇 颜色减淡的原理讲解以及应…

一个简单好用的磨皮祛斑算法理论和python实现

前言 最近看了一个磨皮算法祛斑感觉效果不错,效果图看文末就行,个人觉得效果非常不错滴。 国际惯例,参考博客: 磨皮算法的源码:YUCIHighPassSkinSmoothing How To Smooth And Soften Skin With Photoshop 图像算法…

OpenVINO——配置与道路分割案例

前言 最近看到了一个深度学习库OpenVINO,专门用于Intel硬件上部署深度学习模型,其内置了非常非常多使用的预训练模型,比如道路分割、人脸提取、3D姿态估计等等。但是配置和调用有点小恶心,这里以道路分割为例,展示如何…

图像颜色迁移《color transfer between images》

前言 前段时间,在深度学习领域不是有个比较火的方向叫风格迁移的嘛,对于我这种不喜欢深度学习那种不稳定结果的人来说,还是想看看传统图像处理领域有什么类似的技术,发现了一个颜色迁移的算法,很久前的论文了。 国际…

ColorSpace颜色空间简介

前言 如果看过之前的介绍的图像颜色迁移《color transfer between images》和颜色协调模型Color Harmoniztion就会发现,大部分图像处理算法虽然输入输出是RGB像素值,但是中间进行算法处理时很少直接更改RGB值,而是转换到其它空间&#xff0c…

Ogre共享骨骼与两种骨骼驱动方法

前言 最近业务中用到Ogre做基于3D关键点虚拟角色骨骼驱动,但是遇到两个问题: 身体、头、眼睛、衣服等mesh的骨骼是分开的,但是骨骼结构都是一样的,需要设置共享骨骼驱动的时候可以直接修改骨骼旋转量,或者将旋转量存…

仿射变换和透视变换

前言 在前面做换脸的博客中提到了使用仿射变换和透视变换将两张不同的人脸基于关键点进行对齐,保证一张人脸贴到另一张人脸时,大小完全一致;所以有必要理解一下这两个概念的区别,由于以实用性为目的,所以所有的图像算…