سلام
بچ نورمالیزیشن یه لایه است و بعد از لایه کانولوشن و قبل از لایه nonlinearity مثل relu قرار میگیره
ساده ترین شکل استفاده ازش اینطوریه :
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
convolution_param {
num_output: 64
pad: 1
kernel_size: 3
stride: 1
bias_term: true
weight_filler {
type: "xavier"
}
}
}
layer {
name: "bn1"
type: "BatchNorm"
bottom: "conv1"
top: "bn1"
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "bn1"
top: "bn1"
}
اما معمولا به اینصورت استفاده میشه (در CAFFE بچ نورمالیزیشن به دو بخش تقسیم شده در حالیکه در مقاله اصلی یکی هست،) و بخش scale بصورت جداگانه پیاده سازی شده. پس پیشفرض اینطور باید استفاده کنید در 99 درصد اوقات:
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
convolution_param {
num_output: 64
pad: 1
kernel_size: 3
stride: 1
bias_term: true
weight_filler {
type: "xavier"
}
}
}
layer {
name: "bn1"
type: "BatchNorm"
bottom: "conv1"
top: "bn1"
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
}
layer {
name: "scale1"
type: "Scale"
bottom: "bn1"
top: "scale1"
scale_param {
bias_term: true
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "scale1"
top: "scale1"
}
در حالتی که بهترین کارایی لازم هست میشه اینطور استفاده کرد :
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
convolution_param {
num_output: 64
pad: 1
kernel_size: 3
stride: 1
bias_term: true
weight_filler {
type: "xavier"
}
}
}
layer {
name: "bn1"
type: "BatchNorm"
bottom: "conv1"
top: "bn1"
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
include {
phase: TRAIN
}
batch_norm_param {
use_global_stats: false
moving_average_fraction: 0.95
}
}
layer {
name: "bn1"
type: "BatchNorm"
bottom: "conv1"
top: "bn1"
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
include {
phase: TEST
}
batch_norm_param {
use_global_stats: true
moving_average_fraction: 0.95
}
}
layer {
name: "scale1"
type: "Scale"
bottom: "bn1"
top: "scale1"
scale_param {
bias_term: true
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "scale1"
top: "scale1"
}
نکته :
در ورژن های جدید کفی میتونید بصورت inplace استفاده کنید که بشدت تو مصرف حافظه صرفه جویی میشه. (تو ورژن های قبلی باگهای مختلفی داشت که بعضی مواقع باعث میشد حتی شبکه کانورج نکنه اما الان اکی شده )
کدهای بالا رو بصورت inplace در پایین میبیند (inplace یعنی عملیات روی همون متغییرها انجام میشه و دیگه متغییر جدید ایجاد نمیشه . هر topیی که برای یک لایه مینویسید (با نام متفاوت) یه متغییر جدید هست. اگر bottom و top یکی باشه یعنی عملیات روی همون متغییر انجام(بصورت درجا یا inplace) میشه و نتیجه در همون متغییر به لایه بعد ارسال میشه)
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
convolution_param {
num_output: 64
pad: 1
kernel_size: 3
stride: 1
bias_term: true
weight_filler {
type: "xavier"
}
}
}
layer {
name: "bn1"
type: "BatchNorm"
bottom: "conv1"
top: "conv1"
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "conv1"
top: "conv1"
}
اما معمولا به اینصورت استفاده میشه (در CAFFE بچ نورمالیزیشن به دو بخش تقسیم شده در حالیکه در مقاله اصلی یکی هست،) و بخش scale بصورت جداگانه پیاده سازی شده. پس پیشفرض اینطور باید استفاده کنید در 99 درصد اوقات:
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
convolution_param {
num_output: 64
pad: 1
kernel_size: 3
stride: 1
bias_term: true
weight_filler {
type: "xavier"
}
}
}
layer {
name: "bn1"
type: "BatchNorm"
bottom: "conv1"
top: "conv1"
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
}
layer {
name: "scale1"
type: "Scale"
bottom: "conv1"
top: "conv1"
scale_param {
bias_term: true
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "conv1"
top: "conv1"
}
در حالتی که بهترین کارایی لازم هست میشه اینطور استفاده کرد :
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
convolution_param {
num_output: 64
pad: 1
kernel_size: 3
stride: 1
bias_term: true
weight_filler {
type: "xavier"
}
}
}
layer {
name: "bn1"
type: "BatchNorm"
bottom: "conv1"
top: "conv1"
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
include {
phase: TRAIN
}
batch_norm_param {
use_global_stats: false
moving_average_fraction: 0.95
}
}
layer {
name: "bn1"
type: "BatchNorm"
bottom: "conv1"
top: "conv1"
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
include {
phase: TEST
}
batch_norm_param {
use_global_stats: true
moving_average_fraction: 0.95
}
}
layer {
name: "scale1"
type: "Scale"
bottom: "conv1"
top: "conv1"
scale_param {
bias_term: true
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "conv1"
top: "conv1"
}