前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >论文阅读 - Group Normalization

论文阅读 - Group Normalization

作者头像
AIHGF
修改2020-06-12 16:23:06
1.2K0
修改2020-06-12 16:23:06
举报
文章被收录于专栏:AIUAI

原文: 论文阅读 - Group Normalization - AIUAI

题目:Group Normalization - ECCV2018 作者:Yuxin Wu,Kaiming He 团队:FAIR

<Group Normalization for Mask R-CNN - Detectron>

Batch Normalization(BN) 是沿着 batch 维度进行归一化,其受限于 batch size;当 batch size 很小时,BN 会得到不准确的统计估计,会导致模型误差明显增加. 一般每块 GPU 上 batchsize=32 最合适.

但对于目标检测,语义分割,视频场景等,输入图像比较大,而限于显卡显存的限制,导致无法设置较大的 batchsize,如 Mask R-CNN 中,由于图像的分辨率较大,batchsize 只能是 1 或 2.

另一方面,BN 在 batch 维度归一化时,由于 batch 维度并不是固定的,比如,模型训练和测试时的不一致. 往往是在训练集上计算均值(mean) 和方差(variance);而在测试集上直接采用. 如果训练集和测试集的数据分布存在差异时,预训练的均值和方差并不能真实反映测试集.

Group Normalization(GN) 则是提出的一种 BN 的替代方法,其是首先将 channels 划分为多个 groups,再计算每个 group 内的均值和方法,以进行归一化.

GN 的计算与 batchsize 无关,且对于不同的 batchsize ,精度都比较稳定. 另外,GN 易于从 pre-trained 模型进行 fine-tuning.

GN 和 BN 对比如图:

横轴 - 每块 GPU 的 batchsize;纵轴 - 误差率. 在batchsize 较小时,如 batchsize=2, GN 误差率比 BN 小了 10% 左右.

1. GN 数学描述

特征归一化方法:BatchNorm(BN), LayerNorm(LN), InstanceNorm(IN), GroupNorm(GN).

G=C 时,GN 等价于 IN. G=1 时,GN 等价于 LN.

torch.nn.GroupNorm(num_groups, num_channels, eps=1e-05, affine=True)

2. GN 实现

GroupNorm Op - group_norm_op.h GroupNorm Op - group_norm_op.cc GroupNorm Op - group_norm_op.cu

2.1 TensorFlow 实现

代码语言:javascript
复制
def GroupNorm(x, gamma, beta, G, eps=1e-5):
    # x: 输入特征,shape:[N, C, H, W]
    # gamma, beta: scale 和 offset,shape: [1, C, 1, 1]
    # G: GN 的 groups 数
    
    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

类似的:

代码语言:javascript
复制
def GroupNorm(x,G=32,eps=1e-5): 
    N,H,W,C=x.shape 
    x=tf.reshape(x,[tf.cast(N,tf.int32),
                    tf.cast(H,tf.int32),
                    tf.cast(W,tf.int32),
                    tf.cast(G,tf.int32),
                    tf.cast(C//G,tf.int32)]) 
    mean,var=tf.nn.moments(x,[1,2,4],keep_dims=True) 
    x=(x-mean)/tf.sqrt(var+eps) 
    
    x=tf.reshape(x,[tf.cast(N,tf.int32),
                    tf.cast(H,tf.int32),
                    tf.cast(W,tf.int32),
                    tf.cast(C,tf.int32)]) 
    gamma = tf.Variable(tf.ones(shape=[1,1,1,tf.cast(C,tf.int32)]), name="gamma") 
    beta = tf.Variable(tf.zeros(shape=[1,1,1,tf.cast(C,tf.int32)]), name="beta") 	
    return x * gamma + beta

2.2 CS231n 作业 - GN 实现

CS231n 作业 - ConvolutionalNetworks.ipynb From: CS231n Group Normalization (分组归一化)

代码语言:javascript
复制
# GN forward
def spatial_groupnorm_forward(x, gamma, beta, G, gn_param): 
    out, cache = None, None 
    eps = gn_param.get('eps',1e-5) 
    
    N,C,H,W = x.shape 
    x_group = np.reshape(x, (N, G, C//G, H, W)) #按 G 将C分组 
    mean = np.mean(x_group, axis=(2,3,4), keepdims=True) #均值 
    var = np.var(x_group, axis=(2,3,4), keepdims=True) #方差 
    x_groupnorm = (x_group-mean)/np.sqrt(var+eps) #归一化 
    x_norm = np.reshape(x_groupnorm, (N,C,H,W)) #还原维度 
    out = x_norm * gamma + beta # 还原C 
    cache = (G, x, x_norm, mean, var, beta, gamma, eps) 
    return out, cache 

# GN backward 
def spatial_groupnorm_backward(dout, cache): 
    dx, dgamma, dbeta = None, None, None 
    
    N,C,H,W = dout.shape 
    G, x, x_norm, mean, var, beta, gamma, eps = cache 
    
    # dbeta,dgamma 
    dbeta = np.sum(dout, axis=(0,2,3), keepdims=True) 
    dgamma = np.sum(dout*x_norm, axis=(0,2,3), keepdims=True) 
    
    # 计算dx_group,(N, G, C // G, H, W) 
    # dx_groupnorm 
    dx_norm = dout * gamma 
    dx_groupnorm = dx_norm.reshape((N, G, C // G, H, W)) 
    # dvar 
    x_group = x.reshape((N, G, C // G, H, W)) 
    dvar = np.sum(dx_groupnorm * -1.0 / 2 * (x_group - mean) / (var + eps) ** (3.0 / 2), axis=(2,3,4), keepdims=True) 
    # dmean 
    N_GROUP = C//G*H*W 
    dmean1 = np.sum(dx_groupnorm * -1.0 / np.sqrt(var + eps), axis=(2,3,4), keepdims=True) 
    dmean2_var = dvar * -2.0 / N_GROUP * np.sum(x_group - mean, axis=(2,3,4), keepdims=True) 
    dmean = dmean1 + dmean2_var 
    # dx_group 
    dx_group1 = dx_groupnorm * 1.0 / np.sqrt(var + eps) 
    dx_group2_mean = dmean * 1.0 / N_GROUP 
    dx_group3_var = dvar * 2.0 / N_GROUP * (x_group - mean) 
    dx_group = dx_group1 + dx_group2_mean + dx_group3_var 
    
    # 还原C得到dx 
    dx = dx_group.reshape((N, C, H, W)) 
    
    return dx, dgamma, dbeta

3. Results

Related

[1] - FAIR何恺明等人提出组归一化:替代批归一化,不受批量大小限制 - 机器之心

[2] - 超越何恺明等组归一化 Group Normalization,港中文团队提出自适配归一化取得突破

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018年10月31日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. GN 数学描述
  • 2. GN 实现
    • 2.1 TensorFlow 实现
      • 2.2 CS231n 作业 - GN 实现
      • 3. Results
      • Related
      相关产品与服务
      批量计算
      批量计算(BatchCompute,Batch)是为有大数据计算业务的企业、科研单位等提供高性价比且易用的计算服务。批量计算 Batch 可以根据用户提供的批处理规模,智能地管理作业和调动其所需的最佳资源。有了 Batch 的帮助,您可以将精力集中在如何分析和处理数据结果上。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档