기본적으로 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>
@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