用numpy库手写算子三: BN
前言
我们经常可以调用pytorch,tensorflow库等来实现我们的神经网络,但是有的时候需要开发自己的框架,这个时候就得了解每一个算子的计算规则,了解这些计算规则也有助于我们了解他们的计算特性,然后就可以在底层优化上面有一定的针对性。
BN
Batch_norm的基本运算是在channel的粒度上做了数据的归一化。因为每层的数据的范围和feature_map的数据范围是不一样的,因此如果不归一化,数据的范围会越差越大。
输入说明
对于BN的正向而言:
x表示正向的输入(本层的feature_map),默认的数据布局为(N,C,H,W),N代表batch_size,C代表input_channel,H代表input_height,W代表input_width。
gamma表示的是放缩因子,默认的数据布局为(C,),代表的是channel i 的数据应该*gamma[i]。
beta表示的是偏移因子,默认的数据布局为(C,),代表的是channel i的数据应该+beta[i]。
running_mean代表的是数据的均值,默认的数据布局为(C,)。代表的是本批的数据中,经过计算后的channel i的数据的均值应该running_var[i]。 running_var代表的是数据的方差,默认的数据布局为(C,)。代表的是本批的数据中,经过计算后的channel i的数据的方差应该running_mean[i]。
eps = 1e-5,这个目的是为了保证除数不为0,因为你计算出来的方差有可能为0.
momentum = 0.9,这个参数主要是作为重新计算running_mean和running_var的时候,加权平均的系数。
mode有两种模式分别是"train"和"test"。这两种模式分别对应pytorch中的.train()和.eval()模式。"train"和"test"的唯一区别就是在于数据减去均值,除以方差的时候,均值和方差的选择问题。
- 对于train模式来说,每次减去的均值和除掉的方差,是要根据你训练过程中的数据,重新计算然后具体而定的。在计算完本次训练过程中的均值和方差,然后根据momentum系数,动态的加权平均running_mean和running_var这两个数值。
- 对于test模式来说,每次减去的均值和除掉的方差是不变化的,也就是读入初始模型中自带的running_mean和running_var。
具体的代码见下。
总体代码
def bn_forward_naive(x, gamma, beta, running_mean, running_var, mode = "trian", eps = 1e-5, momentum =