GroupBN

Group Normalization

一. 论文简介

主要做的贡献如下(可能之前有人已提出):

  1. 类似BN的一种归一化,使用group进行归一化

二. 模块详解

2.1 BN的做法

  1. X X X 为输入的 b a t c h batch batch 数据, μ B 、 σ B \mu_B、\sigma_B μBσB 为当前 b a t c h batch batch 的均值和方差, r u n n i n g _ u 、 r u n n n i g _ σ running\_u、runnnig\_\sigma running_urunnnig_σ 为滑动平均(全局)的均值和方差(初始化为0和1), β 、 γ \beta、\gamma βγ 为梯度更新的均值和方差
  2. 通过输入 X X X 计算当前均值和方差 μ B 、 σ B \mu_B、\sigma_B μBσB
  3. 使用 μ B 、 σ B \mu_B、\sigma_B μBσB 归一化当前输入 X X X
  4. 通过 m o v i n g _ m o m e n t u m moving\_momentum moving_momentum 和当前均值和方差更新全局均值和方差
  5. 使用梯度更新的均值和方差还原输入的 X X X
  6. 下面的图不全,仅仅包含一部分,请参考代码
# 参考https://blog.youkuaiyun.com/weixin_40123108/article/details/83509838
def batch_norm_1d(x, gamma, beta, is_training, moving_mean, moving_var, moving_momentum=0.1):
    eps = 1e-5
    x_mean = torch.mean(x, dim=0, keepdim=True) # 保留维度进行 broadcast
    x_var = torch.mean((x - x_mean) ** 2, dim=0, keepdim=True)
    if is_training:
        x_hat = (x - x_mean) / torch.sqrt(x_var + eps)
        moving_mean[:] = moving_momentum * moving_mean + (1. - moving_momentum) * x_mean
        moving_var[:] = moving_momentum * moving_var + (1. - moving_momentum) * x_var
    else:
        x_hat = (x - moving_mean) / torch.sqrt(moving_var + eps)
    return gamma.view_as(x_mean) * x_hat + beta.view_as(x_mean)

2.2 GN的做法

  • 整体思想看下图一目了然
  • 论文给的代码中没有滑动平均,由于和 B a t c h Batch Batch 无关,所以不需要滑动平均。因为如果使用滑动平均,不如直接在 b a t c h batch batch 上平均,反正也算是多个数(见下图四,在N上取平均近似等于滑动平均)
# TF 版本源论文
def GroupNorm(x, gamma, beta, G, eps=1e5):
    # x: input features with shape [N,C,H,W]
    # gamma, beta: scale and offset, with shape [1,C,1,1] # G: number of groups for GN
    N, C, H, W = x.shape
    x = tf.reshape(x, [N, G, C // G, H, W])
    mean, var = tf.nn.moments(x, [2, 3, 4], keep dims=True) x = (x − mean) / tf.sqrt(var + eps)
    x = tf.reshape(x, [N, C, H, W]) return x ∗ gamma + beta
# pytorch版本:https://zhuanlan.zhihu.com/p/56219719
import numpy as np
import torch
import torch.nn as nn


class GroupNorm(nn.Module):
    def __init__(self, num_features, num_groups=32, eps=1e-5):
        super(GroupNorm, self).__init__()
        self.weight = nn.Parameter(torch.ones(1,num_features,1,1))
        self.bias = nn.Parameter(torch.zeros(1,num_features,1,1))
        self.num_groups = num_groups
        self.eps = eps

    def forward(self, x):
        N,C,H,W = x.size()
        G = self.num_groups
        assert C % G == 0

        x = x.view(N,G,-1)
        mean = x.mean(-1, keepdim=True)
        var = x.var(-1, keepdim=True)

        x = (x-mean) / (var+self.eps).sqrt()
        x = x.view(N,C,H,W)
        return x * self.weight + self.bias
  • 看论文试验,针对大网络小 b a t c h batch batch 有作用,正常网络单GPU大于32还是使用BN比较好

三. 参考文献

python+opencv简谱识别音频生成系统源码含GUI界面+详细运行教程+数据 一、项目简介 提取简谱中的音乐信息,依据识别到的信息生成midi文件。 Extract music information from musical scores and generate a midi file according to it. 二、项目运行环境 python=3.11.1 第三方库依赖 opencv-python=4.7.0.68 numpy=1.24.1 可以使用命令 pip install -r requirements.txt 来安装所需的第三方库。 三、项目运行步骤 3.1 命令行运行 运行main.py。 输入简谱路径:支持图片或文件夹,相对路径或绝对路径都可以。 输入简谱主音:它通常在第一页的左上角“1=”之后。 输入简谱速度:即每分钟拍数,同在左上角。 选择是否输出程序中间提示信息:请输入Y或N(不区分大小写,下同)。 选择匹配精度:请输入L或M或H,对应低/中/高精度,一般而言输入L即可。 选择使用的线程数:一般CPU核数相同即可。虽然python的线程不是真正的多线程,但仍能起到加速作用。 估算字符上下间距:这简谱中符号的密集程度有关,一般来说纵向符号越稀疏,这个值需要设置得越大,范围通常在1.0-2.5。 二值化算法:使用全局阈值则跳过该选项即可,或者也可输入OTSU、采用大津二值化算法。 设置全局阈值:如果上面选择全局阈值则需要手动设置全局阈值,对于.\test.txt中所提样例,使用全局阈值并在后面设置为160即可。 手动调整中间结果:若输入Y/y,则在识别简谱后会暂停代码,并生成一份txt文件,在其中展示识别结果,此时用户可以通过修改这份txt文件来更正识别结果。 如果选择文件夹的话,还可以选择所选文件夹中不需要识别的文件以排除干扰
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值