Pytorch 에서 Batch Normalization layer 가 밟 은 구 덩이 를 해결 합 니 다.
8717 단어 PytorchBatchNormalizationlayer
Pytorch 의 BN 층 의 운동량 이 부 드 럽 고 흔히 볼 수 있 는 운동량 계산 방식 은 반대 이 며,기본 momentum=0.1 입 니 다.
BN 계층 의 표현 식 은 다음 과 같 습 니 다.
그 속γ화해시키다β배 울 수 있 는 인자 입 니 다.Pytorch 에서 BN 층 의 클래스 인 자 는 다음 과 같 습 니 다.
CLASS torch.nn.BatchNorm2d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
매개 매개 매개 변수 의 구체 적 인 의 미 는 문 서 를 참조 합 니 다.주의해 야 할 것 은 affine 이 BN 층 의 인 자 를 정의 한 것 입 니 다.γ화해시키다β배 울 수 있 는 지 여부(배 울 수 없 는 기본 값 은 상수 1 과 0).2.BN 층 에 통계 데이터 수치,즉 평균 값 과 분산 이 포함 되 어 있 음 을 주의 하 십시오.
track_running_stats C a boolean value that when set to True, this module tracks the running mean and variance, and when set to False, this module does not track such statistics and always uses batch statistics in both training and eval modes. Default: True
훈련 과정 에서 model.train(),train 과정의 BN 의 통계 수치 인 평균 값 과 방 차 는 현재 batch 데 이 터 를 통 해 추정 된다.
그리고 테스트 시 model.eval()후 trackrunning_stats=True,모델 이 현재 사용 하고 있 는 통계 데 이 터 는 Running status 에 있 는 것 입 니 다.즉,지수 감쇠 규칙 을 통 해 현재 의 수 치 를 축적 하 는 것 입 니 다.그렇지 않 으 면 현재 batch 데이터 에 기반 한 추정 치 를 사용 합 니 다.
3.BN 계층 의 통계 업데이트
모든 훈련 단계 모델.train()후의 forward()방법 에서 자동 으로 이 루어 집 니 다.경사도 계산 과 역방향 전파 에서 optim.step()를 업데이트 하 는 것 이 아 닙 니 다.
4.BN 및 그 통계 동결
위의 분석 을 통 해 알 수 있 듯 이 정확 한 BN 동결 방식 은 모델 훈련 시 BN 을 따로 골 라 서 eval(model.train()이후 트 레이 닝 상 태 를 덮어 쓰 는 것)으로 재 설정 하 는 것 이다.
해결 방안:
You should use apply instead of searching its children, while named_children() doesn't iteratively search submodules.
def set_bn_eval(m):
classname = m.__class__.__name__
if classname.find('BatchNorm') != -1:
m.eval()
model.apply(set_bn_eval)
또는 module 의 train()방법 을 다시 쓰 십시오.
def train(self, mode=True):
"""
Override the default train() to freeze the BN parameters
"""
super(MyNet, self).train(mode)
if self.freeze_bn:
print("Freezing Mean/Var of BatchNorm2D.")
if self.freeze_bn_affine:
print("Freezing Weight/Bias of BatchNorm2D.")
if self.freeze_bn:
for m in self.backbone.modules():
if isinstance(m, nn.BatchNorm2d):
m.eval()
if self.freeze_bn_affine:
m.weight.requires_grad = False
m.bias.requires_grad = False
5. Fix/frozen Batch Norm when training may lead to RuntimeError: expected scalar type Half but found Float해결 방법:
import torch
import torch.nn as nn
from torch.nn import init
from torchvision import models
from torch.autograd import Variable
from apex.fp16_utils import *
def fix_bn(m):
classname = m.__class__.__name__
if classname.find('BatchNorm') != -1:
m.eval()
model = models.resnet50(pretrained=True)
model.cuda()
model = network_to_half(model)
model.train()
model.apply(fix_bn) # fix batchnorm
input = Variable(torch.FloatTensor(8, 3, 224, 224).cuda().half())
output = model(input)
output_mean = torch.mean(output)
output_mean.backward()
Please do
def fix_bn(m):
classname = m.__class__.__name__
if classname.find('BatchNorm') != -1:
m.eval().half()
Reason for this is, for regular training it is better (performance-wise) to use cudnn batch norm, which requires its weights to be in fp32, thus batch norm modules are not converted to half in network_to_half. However, cudnn does not support batchnorm backward in the eval mode , which is what you are doing, and to use pytorch implementation for this, weights have to be of the same type as inputs.추가:딥 러 닝 요약:pytorch 로 dropout 와 Batch Normalization 을 할 때 주의해 야 할 부분,tensorflow 로 dropout 와 BN 을 할 때 주의해 야 할 부분
pytorch 로 dropout 와 BN 을 만 들 때 주의해 야 할 부분.
pytorch 드 롭 아웃 하기:
바로 train 때 dropout 를 사용 하고 훈련 할 때 dropout 를 사용 하지 않 습 니 다.
pytorch 에 서 는 net.eval()을 통 해 전체 네트워크 파 라 메 터 를 고정 시 킵 니 다.이 는 전방 향 파 라 메 터 를 업데이트 하지 않 고 dropout,BN 파라미터 가 고정 되 지 않 으 며 이론 적 으로 모든 vaidation set 에 net.eval()을 사용 해 야 합 니 다.
net.train()은 경사도 계산 에 포함 시 키 겠 다 고 밝 혔 다.
net_dropped = torch.nn.Sequential(
torch.nn.Linear(1, N_HIDDEN),
torch.nn.Dropout(0.5), # drop 50% of the neuron
torch.nn.ReLU(),
torch.nn.Linear(N_HIDDEN, N_HIDDEN),
torch.nn.Dropout(0.5), # drop 50% of the neuron
torch.nn.ReLU(),
torch.nn.Linear(N_HIDDEN, 1),
)
for t in range(500):
pred_drop = net_dropped(x)
loss_drop = loss_func(pred_drop, y)
optimizer_drop.zero_grad()
loss_drop.backward()
optimizer_drop.step()
if t % 10 == 0:
# change to eval mode in order to fix drop out effect
net_dropped.eval() # parameters for dropout differ from train mode
test_pred_drop = net_dropped(test_x)
# change back to train mode
net_dropped.train()
pytorch 배치 Normalization:net.eval()전체 네트워크 매개 변수 고정,BN 매개 변수 고정,movingmean 과 movingvar,이 걸 모 르 면 다음 그림 을 보 세 요.
if self.do_bn:
bn = nn.BatchNorm1d(10, momentum=0.5)
setattr(self, 'bn%i' % i, bn) # IMPORTANT set layer to the Module
self.bns.append(bn)
for epoch in range(EPOCH):
print('Epoch: ', epoch)
for net, l in zip(nets, losses):
net.eval() # set eval mode to fix moving_mean and moving_var
pred, layer_input, pre_act = net(test_x)
net.train() # free moving_mean and moving_var
plot_histogram(*layer_inputs, *pre_acts)
moving_mean 과 movingvartensorflow 로 dropout 와 BN 을 만 들 때 주의해 야 할 부분.
dropout 와 BN 은 모두 training 의 매개 변 수 를 가지 고 있 습 니 다.train 인지 test 인지 테스트 인지 테스트 를 나타 내 는데 test 의 dropout 는 dropout 가 아니 라 BN 은 BN 의 매개 변 수 를 고정 시 켰 습 니 다.
tf_is_training = tf.placeholder(tf.bool, None) # to control dropout when training and testing
# dropout net
d1 = tf.layers.dense(tf_x, N_HIDDEN, tf.nn.relu)
d1 = tf.layers.dropout(d1, rate=0.5, training=tf_is_training) # drop out 50% of inputs
d2 = tf.layers.dense(d1, N_HIDDEN, tf.nn.relu)
d2 = tf.layers.dropout(d2, rate=0.5, training=tf_is_training) # drop out 50% of inputs
d_out = tf.layers.dense(d2, 1)
for t in range(500):
sess.run([o_train, d_train], {tf_x: x, tf_y: y, tf_is_training: True}) # train, set is_training=True
if t % 10 == 0:
# plotting
plt.cla()
o_loss_, d_loss_, o_out_, d_out_ = sess.run(
[o_loss, d_loss, o_out, d_out], {tf_x: test_x, tf_y: test_y, tf_is_training: False} # test, set is_training=False
)
# pytorch
def add_layer(self, x, out_size, ac=None):
x = tf.layers.dense(x, out_size, kernel_initializer=self.w_init, bias_initializer=B_INIT)
self.pre_activation.append(x)
# the momentum plays important rule. the default 0.99 is too high in this case!
if self.is_bn: x = tf.layers.batch_normalization(x, momentum=0.4, training=tf_is_train) # when have BN
out = x if ac is None else ac(x)
return out
BN 의 training 매개 변수 가 train 일 때 BN 의 매개 변 수 는 변 할 수 있다 는 것 을 의미 할 뿐 BN 이 스스로 moving 을 업데이트 하 는 것 은 아 닙 니 다.mean 과 movingvar,이 동작 은 이전에 업 데 이 트 된 op 이기 때문에 train 을 하기 전에 moving 를 확보 해 야 합 니 다.mean 과 movingvar 업데이트,moving 업데이트mean 과 movingvar 의 조작 은 tf.GraphKeys.UPDATEOPS
# !! IMPORTANT !! the moving_mean and moving_variance need to be updated,
# pass the update_ops with control_dependencies to the train_op
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.control_dependencies(update_ops):
self.train = tf.train.AdamOptimizer(LR).minimize(self.loss)
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Pytorch는 cpu와 gpu의 사용을 어떻게 전환하는지 상세히 설명합니다.앞에서 말했듯이pytorch에서 서버에 있는 gpu가 점용될 때 우리는 먼저 cpu로 코드를 디버깅하고 싶을 때가 많다. 그러면 gpu와 cpu의 전환이 필요하다. 장치를 가변 매개 변수로 사용하려면argparse를...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.