2016년 3월 17일 목요일

pycaffe로 fine-tuning하기

참고: https://github.com/BVLC/caffe/pull/970/files

기본적으로 pretrained network의 weight를 로드할 때는 layer의 이름을 보고 weight를 가져오기때문에,
layer의 name이 동일하면 그 weight를 가져와서 초기값으로 사용.
layer의 name이 없다면, network에 정의된 방식으로 초기값으로 사용.

또한, fine-tuning은 이미 많이 학습이 된 상태임을 가정하기 때문에 stepsize(learning rate)도 작게 설정함.
즉, solver에서 base_lr은 아주 작은 값으로 설정하여 전체적으로는 학습이 조금씩 진행되게 만들지만, 학습이 필요한 layer(초기화된 layer)는 lr_mult로 학습량을 조절함.
ex) <구버전caffe> base_lr: 0.001, blobs_lr: 0.1/학습거의조금, blobs_lr:10/학습필요
ex) <신버전caffe>
  @solver에서 base_lr: 0.001
  @prototxt에서 lr_mult: 0/학습이 안됨, lr_mult: 0.1/학습거의조금, lr_mult: 10/학습필요하기에 많이 됨. (그 layer의 최종 learning rate는 base_lr * lr_mult와 관련됨)
그래서 pretrained net에서 가져온 layer는 lr_mult를 작게줘서 학습이 거의 안되게 만들고, 초기화된 layer는 학습이 많이 되게 만들기위해 lr_mult값을 크게 줌.

예) <https://github.com/BVLC/caffe/blob/master/examples/cifar10/cifar10_full_sigmoid_train_test.prototxt에서 발췌>

layer { name: "conv3"
type: "Convolution"
bottom: "pool2"
top: "conv3"
convolution_param {
num_output: 64
pad: 2
kernel_size: 5
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
}
}
param {
lr_mult: 10
}
param {
lr_mult: 10
}
}

그리고 command 창에서 실행시켜야 할 명령어는 다음과 같다. 학습을 caffemodel에서부터 finetuning하는 경우.
caffe train --solver=%s1 --weights=%s2
%s1에는 solver가 %s2에는 caffemodel이 들어간다.

참고로, solverstate로부터 학습을 resume하는 경우는 weights대신에 snapshot을 쓰면 된다.

참고: 코드 차원에서 fine-tuning
http://nbviewer.jupyter.org/github/BVLC/caffe/blob/tutorial/examples/03-fine-tuning.ipynb