Layer Norm

2023-11-18

参考ConvNeXt中的Layer Normalization(LN) - 海斌的文章 - 知乎
https://zhuanlan.zhihu.com/p/481901798

Layer Norm本来是一个样本norm自己,如图所示:
在这里插入图片描述
也就是说,在[C,H,W]维进行归一化
而ConvNeXt中是这样:
在这里插入图片描述
也就是在C的维度归一化,即单一像素的所有channel做归一化。

两者实现方式上有所不同。
可以用F.layer_norm实现,也可以用nn.layer_norm实现,这里选用F.layer_norm

看ConvNeXt的实现
class LayerNorm2d(nn.LayerNorm):
    """LayerNorm on channels for 2d images.
    Args:
        num_channels (int): The number of channels of the input tensor.
        eps (float): a value added to the denominator for numerical stability.
            Defaults to 1e-5.
        elementwise_affine (bool): a boolean value that when set to ``True``,
            this module has learnable per-element affine parameters initialized
            to ones (for weights) and zeros (for biases). Defaults to True.
    """

    def __init__(self, num_channels: int, **kwargs) -> None:
        super().__init__(num_channels, **kwargs)
        self.num_channels = self.normalized_shape[0]

    def forward(self, x):
        assert x.dim() == 4, 'LayerNorm2d only supports inputs with shape ' \
            f'(N, C, H, W), but got tensor with shape {x.shape}'
        return F.layer_norm(
            x.permute(0, 2, 3, 1), self.normalized_shape, self.weight,
            self.bias, self.eps).permute(0, 3, 1, 2)

LayerNorm2d继承的nn.LayerNorm,在初始化时调用了父类的init函数,我们来看看父类是干了啥?

def __init__(self, normalized_shape: _shape_t, eps: float = 1e-5, elementwise_affine: bool = True,
                 device=None, dtype=None) -> None:
       ***
        self.normalized_shape = tuple(normalized_shape)

实际上这里仅仅是把num_channels,通道数,存入了self.normalized_shape,并且用一个tuple保存。
所以说,关键是forward里面的F.layer_norm

我们看看传入的参数
第一个参数是转置后的x,也就是N,C,H,W转置为N,H,W,C,把通道数放在最后一个维度,过F.layer_normnormalized_shape实际上就是前面init函数里传入的num_channels,就是一个数字。

接下来我们看看F.layer_norm的用法:
其实和nn.layernorm基本是一样的,只是不用事先实例化,这样的话参数要一起传进去。
对于nn.layernorm来说,

args:
normalized_shape (int or list or torch.Size): input shape from an expected input of size
If a single integer is used, it is treated as a singleton list, and this module will
            normalize over the last dimension which is expected to be of that specific size.
        eps: a value added to the denominator for numerical stability. Default: 1e-5

上面这段话的意思就是说,这个normalized_shape可以是一个数,也可以是一个list,如果是一个数,则默认在最后一维归一化,且这个数需要等于最后一维的维度;如果是一个list,则这个list需要匹配从后往前的不同维度的维数
eg.

a.shape = (100. 96, 8, 8)#也就是100个96维的8x8的feature

如果是普通的layer norm,normalized_shape=[96, 8, 8]
如果这个参数是8,则在最后一维进行归一化
如果希望在所有point的channel归一化,如ConvNeXt
则先转置,把channel转到最后一维,然后normalized_shape=num_channel即可

那么ConvNeXt的layer norm如何改成普通的layer norm呢?
如代码所示:

class LayerNorm2d(nn.LayerNorm):
    def __init__(self, num_channels: int, **kwargs) -> None:
        super().__init__(num_channels, **kwargs)
        self.num_channels = self.normalized_shape[0]

    def forward(self, x):
        return F.layer_norm(
            x.permute(0, 2, 3, 1), self.normalized_shape, self.weight,
            self.bias, self.eps).permute(0, 3, 1, 2)

实际上只需要改forward里即可,即不转置,且normalized_shape参数传入x的最后三3维度

class LayerNorm2d(nn.LayerNorm):
    def __init__(self, num_channels: int, **kwargs) -> None:
        super().__init__(num_channels, **kwargs)
        self.num_channels = self.normalized_shape[0]

    def forward(self, x):
        return F.layer_norm(
            x, x.shape[1:], self.weight,
            self.bias, self.eps))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Layer Norm 的相关文章

  • 操作系统系列(二)——进程

    往期地址 操作系统系列一 操作系统概述 本期主题 操作系统进程 文章目录 1 异常 1 前言 异常控制流是什么 2 异常的处理过程 3 异常的分类 4 异常和进程的关系 2 进程 1 进程的概念 2 进程所做的事情 意义 1 逻辑控制流 2
  • Adobe Flash CS6 下载与安装教程

    文章目录 Adobe Flash CS6 简介 一 软件介绍 二 软件特点 三 新增功能 四 安装要求 1 Windows 2 Mac OS 一 Adobe Flash CS6 下载 自取 二 Adobe Flash CS6 安装 Adob

随机推荐

  • QquickWidget与QML交互 ,自定义信号

    在widget加载QML文件 在加载过程中把qml文件添加到资源文件 在Pro文件中添加 QT quickwidgets Qt qml 下面如何qml中的信号连接呢 查看QQuickWidget类 找到了rootObject 方法 这个返回
  • 华为性格测试的破解方法

    几个原则必须要遵守 1 表现出积极进取 乐观向上 不焦虑不紧张的形象 2 华为喜欢那种喜欢艰苦奋斗的人 所以要能吃苦耐劳不计较报酬 3 华为喜欢中庸 不要表现自己的特性 有自己性格可能会被刷掉 4 华为喜欢稳定的 稳定超过一切包括技术 包括
  • 谷歌chromeos_如何安装Chrome OS系统

    Chrome OS是由Google设计的基于Linux内核的操作系统 它源自免费软件Chromium OS 并使用Google Chrome网络浏览器作为其主要用户界面 因此 Chrome操作系统主要支持Web应用程序 谷歌于2009年7月
  • 修改mysql数据库的时区

    查看数据库时区 mysql gt show variables like time zone Variable name Value system time zone EST time zone SYSTEM 2 rows in set 0
  • 阿里弃用Hibernate,却用MyBatis,竟然是因为这个!

    最近一直在研究MyBatis源码 作为国内经常使用的持久层框架 其内部代码的设计非常优秀 比如在开发过程中 有能力对框架进行深度的定制化开发 解决BUG也更加得心应手 另外学习开发者是如何设计高扩展性 低耦合性的代码 便于在自己的开发场景中
  • 66W真的比60W充电更快吗?基于Charge pump Charger的快充方案分析

    智能手机发展至今 充电功率和电池续航一直是人们最为关注的问题之一 从早期的5V 1A和5V 2A的低瓦数快充 到后来的高压大电流和低压小电流两极分化 不同手机厂商都制定了自己的充电协议 如OPPO的VOOC vivo的Flash Charg
  • 【HBZ分享】Redis的热点key问题

    Redis是如何将数据落在某个Redis节点上的 通过crc16取模 不是hash算法 是校验一种算法 计算该key应该落到哪个hash槽 solt 上 一共16384个hash槽上 这些槽位会均匀分布在每个节点 上 注意 只有主节点才有槽
  • Qt生成随机数

    参考网址 https www it610 com article 5005396 htm https www cnblogs com bingcaihuang archive 2011 02 11 1951401 html 生成随机数主要用
  • vue监听缓存数据(localStorage)

    方法 可以重写localStorage的setItem方法 当调用setItem方法设置新值的时候 会new Event setItemEvent 用window dispatchEvent 这个方法来派发一个事件 让window去监听 以
  • 用Python实现AI声音克隆的原理和代码示例

    声音克隆是一种利用机器学习技术学习特定人说话的声音特征 并以此生成合成音频的技术 通常在语音合成和人机交互等领域有广泛的应用 下面是一个简单的Python实现示例 1 数据收集 首先 需要从多个不同说话人的语音数据集中收集原始音频数据 并将
  • __init__()方法和__new__()方法

    class A object def init self args kwargs print init A def new cls args kwargs print new A s cls return object new cls ar
  • 操作系统哲学原理(14)内存原理-段式内存管理

    说明 该系类文章更多的是从从哲学视角看 操作系统 这门学科 同时也是 操作系统的学习笔记总结 因为博主 这些年主要是以研究安卓系统和 嵌入式Linux为主 因此这个系类文章也是这两个领域不可或缺的基石之一 尤其是对操作系统感兴趣的伙伴可特别
  • 504网关超时怎么解决_什么是504网关超时错误(以及如何解决)?

    504网关超时怎么解决 A 504 Gateway Timeout Error happens when a server that was attempting to load a web page did not get a respo
  • openwrt下使用SDK编译ipk包遇到Package hiOpenwrt is missing dependencies for the following libraries: libc.so.

    openwrt下使用SDK编译ipk包遇到Package hiOpenwrt is missing dependencies for the following libraries libc so 6 问题 缺少 libc so 6 库 但
  • C++:stat函数

    函数原型 int stat const char pathname struct stat statbuf 函数作用 用于获取文件状态信息 使用函数需要包含头文件 include
  • Docker安装Nginx(配置SSL证书)

    1 下载Nginx镜像 拉取镜像 docker pull nginx 查询镜像 docker images 2 创建配置文件 创建挂载目录 mkdir p home nginx conf d mkdir p home nginx confi
  • 用 Pytest+Allure 生成漂亮的 HTML 图形化测试报告

    本篇文章将介绍如何使用开源的测试报告生成框架 Allure 生成规范 格式统一 美观的测试报告 通过这篇文章的介绍 你将能够 将 Allure 与 Pytest 测试框架相结合 如何定制化测试报告内容 执行测试之后 生成 Allure 格式
  • Springboot+Vue前后端分离项目打包并部署到服务器

    一 打包前端项目 打开前端项目 使用npm run build命令进行打包 打包成功后结果如下 这时 该项目目录下有一个build目录是打包好的文件 将该目录下的所有文件复制到后端Springboot项目的resources static目
  • java微服务架构内存,微服务架构下的子服务器内存波动

    springcloud架构下的服务器jvm内存波动是正常的 服务器内存波动 本人验证了eureka 和 nacos 两种注册中心 nacos 最低内存占用为 60M 最高内存占用为 450M 波动值为400M左右 eureka 最低内存占用
  • Layer Norm

    参考ConvNeXt中的Layer Normalization LN 海斌的文章 知乎 https zhuanlan zhihu com p 481901798 Layer Norm本来是一个样本norm自己 如图所示 也就是说 在 C H