Skip to content

Caffe Tutorial : 6.Interface (Kor)

HanJiHoon edited this page Jan 24, 2017 · 6 revisions

인터페이스 (Interface)

Caffe는 날마다 변하는 사용법, 연구 코드를 가진 인터페이싱과 신속 시제품화을 위해 커맨드 라인, Python, 그리고 Matlab 인터페이스를 가지고 있다. Caffe는 중심으로 C++ 라이브러리이며 개발을 위한 모듈식의 인터페이스를 노출시키는 반변에, 모든 때마다 관습적 모읍집(custom compilation)을 요청하지는 않는다. cmdcaffe, pycaffe, matcaffe 인터페이스가 당신을 위해 준비됬다.

1. 커맨드라인 (Command Line)

커맨드 라인 인터페이스 - cmdcaffe - 는 모델 트레이닝, 스코어링, 진단들을 위한 Caffe 도구이다. 한번 caffe를 어떠한 도움말 없이 실행시켜보라. 이 도구와 다른 것들은 caffe/build/tools안에서 찾을수 있다. (The following example calls require completing the LeNet / MNIST example first.)

  • Training : "caffe train"은 저장된 스냅샷으로부터 학습을 재개하면서 스크래치로부터 모델과 새로운 데이터와 업무에 잘 조율된 모델을 학습한다.
  • 모든 트레이닝은 -solver solver.prototxt 인수를 통해 solver 구성이 요구된다.
  • 재개하는 것은 해결사 스냅샷을 읽어올려면 -snapshot model_iter_1000.solverstate 인수가 요구된다.
  • 잘 조율시키기 위해서는 모델 초기화를 위해 -weights model.caffemodel가 요구된다. 예시로 다음을 실행시켜볼 수 있다.
# LeNet 트레이닝
caffe train -solver examples/mnist/lenet_solver.prototxt
# GPU 2 상에서 트레이닝
caffe train -solver examples/mnist/lenet_solver.prototxt -gpu 2
# 중간지점 스냅샷으로부터 트레이닝 재개
caffe train -solver examples/mnist/lenet_solver.prototxt -snapshot examples/mnist/lenet_iter_5000.solverstate

잘 조율시키는 것에 대한 예시는 "examples/finetuning_on_flickr_style"을 보라, 하지만 트레이닝은 다음 한줄로 호출한다.

# 스타일을 알아보기위한 잘 조율된 CaffeNet 모델 가중치
caffe train -solver examples/finetuning_on_flickr_style/solver.prototxt -weights models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel
  • Testing : "caffe test"는 테스트 단꼐에서 그들을 가동시킴에 의해 모델을 점수매긴다. 그의 스코어로 망 출력을 보고한다. 망 설계는 정확도 측정이나 출력으로써 손실을 정의해야만 한다. 단위 처리량 점수는 보고된 뒤에 공정의 전체평균이 기록된다.
# 모델 구조 "lenet_train_test.prototxt"에서 정의된 것처럼 유효성 세트상에 훈련된 LeNet model가 점수 매겨진다.
caffe test -model examples/mnist/lenet_train_test.prototxt -weights examples/mnist/lenet_iter_10000.caffemodel -gpu 0 -iterations 100
  • Benchmarking: "caffe time"은 타이밍과 동일화를 통해 계층간 계층의 모델 실행을 밴치마킹한다. 이것은 시스템 수행을 체크하고 모델을 대한 상대적 실행 시간을 측정하는데 유용하다.
# (These example calls require you complete the LeNet / MNIST example first.)
# 10번 반복을 위한 CPU 상의 LeNet 트레이닝 시간을 측정 
caffe time -model examples/mnist/lenet_train_test.prototxt -iterations 10
# 디폴트 50 반복을 위한 GPU상의 LeNet 트레이닝 시간을 측정
caffe time -model examples/mnist/lenet_train_test.prototxt -gpu 0
# 10번 반복에 대한 첫 GPU 상에서 주어지는 가중치로 구성된 모델 설계 시간을 측정
time a model architecture with the given weights on the first GPU for 10 iterations
caffe time -model examples/mnist/lenet_train_test.prototxt -weights examples/mnist/lenet_iter_10000.caffemodel -gpu 0 -iterations 10
  • Diagnostics: "caffe device_query"은 언급에 대한 GPU 디테일과 다중 GPU 기계에서 주어진 장치상에서 실행하기 위한 장치 순서를 체크하는 것을 보고한다.
# 첫번째 장치에 대하여 물어본다.
caffe device_query -gpu 0
  • Parallelism: "-gpu"는 다중 GPU 상에서 돌아가는 ID들의 리스트를 컴마로 나눌수 있는 Caffe 도구이다. 해결사와 망은 각각의 GPU에 대하여 인스턴스화되어지고, 일회 처리량의 크기는 효율적으로 GPU의 수에 의하여 곱해진다.단일 GPU 트레이닝을 재생산하기 위해서는 네트워크 정의에 맞추어 일회 처리량 사이즈를 줄여야 한다.
# train on GPUs 0 & 1 (doubling the batch size)
caffe train -solver examples/mnist/lenet_solver.prototxt -gpu 0,1
# train on all GPUs (multiplying batch size by number of devices)
caffe train -solver examples/mnist/lenet_solver.prototxt -gpu all

2. Python

파이썬 인터페이스(pycaffe)는 caffe 모듈이며 이 스크립트는 caffe/python 안에 있다. 이는 모델을 호출하기위해 카페를 불러오고, 정방향과 역방향 과정을 수행하고, IO를 다루고, 네트워크를 시각화 하며, 심지어 모델을 해결해주는 도구이다. 모든 모델 데이터, 유도체들, 파라미터는 읽고 쓰기를 위해 제공된다.

  • caffe.Net은 호출하기, 구성하기 그리고 모델 작동에 있어 아주 중요한 인터페이스이다. caffe.Classifier와 caffe.Detector가 일반적 업무를 위한 편리한 인터페이스를 제공한다.
  • caffe.SGDSolver는 해결해주는 인터페이스를 제공한다.
  • caffe.io는 조기처리와 프로토콜 버퍼로 입력 / 출력을 다룬다.
  • caffe.draw는 네트워크 구조를 시각화한다.
  • Caffe blobs들은 사용의 편리한과 효율성을 위해 numpy ndarrays로써 제공되어진다.

튜토리얼 IPython 노트북은 caffe/example에서 찾을수 있다 : caffe/examples의 iPython notebook을 실행하라. 개발자에게는, docstrings참조는 전체 코드에서 찾아볼 수 있다.

make pycaffe로 pycaffe를 컴파일하라. PYTHONPATH=/path/to/caffe/python:$PYTHONPATH를 호출하거나 caffe에 추가함으로써 당신의 파이썬 위치에 모듈 디렉토리를 추가하라.

3. MATLAB

MATLAB 인터페이스 (matcaffe)는 당신의 matlab 코드에 caffe를 합칠 수 있는 caffe/matlab에 있는 caffe의 패키지이다. MatCaffe에서 당신은 다음과 같은것을 할 수 있다.

  • Matlab에 다중 망을 만들 수 있다.
  • 정방향과 역방향 연산을 할 수 있다.
  • 네트워크 안에 있는 어떤 계층이든 혹은 계층속의 어떠한 파라미터 blob에 접속 할 수 있다.
  • 네트워크 속에 어떠한 blob든에 데이터를 가져올수도, 설정할수 있으며, 입력 blob나 출력 blob들에 저항적이지도 않다.
  • 파일에 네트워크의 파라미터를 저장하고 파일로부터 파라미터를 불러올수도 있다.
  • network와 blob를 재구성할 수 있다.
  • 네트워크 파라미터를 수정할 수 있으며, 네트워크 수술이 가능하다.
  • 학습을 위해 Matlab에서 다중 해결사를 만들 수 있다.
  • 해결사의 스냅샷으로부터의 학습을 재개할 수 있다.
  • 해결사 내에서 학습 망과 실험 망에 접촉할 수 있다.
  • 반복의 특정한 위치에서 시작할수 있고 Matlab에서 역으로 가게 조종할 수 있다.
  • 그래디언트 단계에서 Matlab 코드를 임의적으로 섞을 수 있다. ILSVRC 이미지 분류화 데모버전은 caffe/matlab/demo/classification_demo.m에 있다.(BVLC CaffeNet 실행하기 위해 Model Zoo에서 이를 다운로드 받을 필요가 있다.)

MatCaffe 구축하기

make all matcaffe명령어로 MatCaffe를 구축하고, 그 후레는 make mattest를 사용해서 테스트할 수 있다.

일반적 문제: 만약 make mattest 실행중에 libstdc++.so.6:version 'GLIBCXX_3.4.15' not found와 같은 에러 메세지가 실행되면, 보통 당신의 Matlab의 runtime 라이브러리들이 당신의 compile-time 라이브러리와 맞지 않다는 것을 의미한다. Matlab을 시작하기 전에, 다음과 같은 사항을 해줄 필요가 있다.

export LD_LIBRARY_PATH=/opt/intel/mkl/lib/intel64:/usr/local/cuda/lib64
export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libstdc++.so.6

혹시 이미 동일한 것들이 당신의 시스템상에 설치되어 있다면, 다시 문제가 고쳐졌는지 보기위해 make mattest을 실행해보라. 이 문제는 때때로 시작하는 동안에 Matlab이 당신의 LD_LIBRARY_PATH 환경변수에 덮어쓸 수도 있기 때문에 좀 더 복잡하다. 당신은 이 런타임 라이브러리를 보기위해 !ldd ./matlab/+caffe/private/caffe_.mexa64을 실행할 수 있다. (mex extension은 사용자 시스템에 따라 차이가 날 수 있다.) 그리고 compile_time 라이브러리에 LD_PRELOAD 환경변수를 호출함으로써 compile_time 라이브러리를 미리 불러올 수 있다.

구축과 테스트를 성공적으로 마친후에, caffe root forder에서 matlab를 실행하고 다음과 같은 명령어를 Matlab 명령창에 실행함에 의해 위치를 탐색하는 패키지를 matlab에 추가하라.

addpath ./matlab

savepath를 실행함으로써 당신의 Matlab 탐색 위치를 저장할 수 있어서 MatCaffe를 매번 사용할 때 마다 다시 위와 같은 명령어를 실행할 필요가 없다.

MatCaffe 사용하기

MatCaffe는 PyCaffe의 사용법과 매우 유사하다.

아래와 같은 예시는 자세한 사용법을 알려주며 당신이 caffe root folder에서 Matlab을 실행하고 Model Zoo에서 BVLC CaffeNet를 설치했다고 가정한다.

model = './models/bvlc_reference_caffenet/deploy.prototxt';
weights = './models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel';

모드와 장치 설정

모드와 장치는 항상 당신이 망이나 해결사를 만들기 전에 설정되어있어야만 한다.

CPU 사용시:

caffe.set_mode_cpu();

GPU 사용시나 해당 GPU의 gpu_id 명시시:

caffe.set_mode_gpu();
caffe.set_device(gpu_id);
네트워크를 만들고 그의 계층과 blob에 접근하기

네트워크 생성:

net = caffe.Net(model, weights, 'test'); % create net and load weights
혹은
net = caffe.Net(model, 'test'); % create net but not load weights
net.copy_from(weights); % load weights

그리고 이는 다음과 같이 Net 오브젝트를 생성하고,

Net with properties:

           layer_vec: [1x23 caffe.Layer]
            blob_vec: [1x15 caffe.Blob]
              inputs: {'data'}
             outputs: {'prob'}
    name2layer_index: [23x1 containers.Map]
     name2blob_index: [15x1 containers.Map]
         layer_names: {23x1 cell}
          blob_names: {15x1 cell}

두개의 containers.Map 오브젝트는 계층이나 blob의 인덱스를 그 이름으로 찾기에 유용하다.

당신은 이제 이 네트워크에 모든 blob를 접근했다. 모든 것에 blob '데이터'를 채우기 위해서는:

net.blobs('data').set_data(ones(net.blobs('data').shape));

10으로 blob내의 모든 값들을 곱하기 위해서는:

net.blobs('data').set_data(net.blobs('data').get_data() * 10);
Matlab은 1개의 인덱스만 달려져있고 열우선적이기 때문에 주의해야하고, Matlab 내에서 일반적 4 blob 차원은 [width, height, channels, num]이며, width가 제일 먼저오는 차원이다. 따라서 이미지가 BGR 채널에 있다는 것을 유의해야한다.

또한, Caffe는 단정도 float data를 사용한다. 만약 데이터가 단일이 아니라면, set_data가 자동적으로 단일로 데이터들을 변환시켜줄 것이다. 당신은 또한 모든 계층에 접근해왔다, 따라서 당신은 네트워크 수술(network surgery)을 진행할 수 있다. conv1 파라미터에 10을 곱하기 위해서는:

net.params('conv1', 1).set_data(net.params('conv1', 1).get_data() * 10); % set weights
net.params('conv1', 2).set_data(net.params('conv1', 2).get_data() * 10); % set bias

대체적으로는 다음과 같은 것도 사용할 수 있다.

net.layers('conv1').params(1).set_data(net.layers('conv1').params(1).get_data() * 10);
net.layers('conv1').params(2).set_data(net.layers('conv1').params(2).get_data() * 10);

당신이 방금 수정한 네트워크를 저장하기 위해서는:

net.save('my_net.caffemodel');

(String 타입으로) 계층의 타입을 얻기위해서는:

layer_type = net.layers('conv1').type;

정방향과 역방향

정방향 과정은 net.forward 혹은 net.forward_prefilled으로 처리되어질 수 있다. net.forward 함수는 입력 blob(들)의 데이터를 담고있는 N-D배열의 셀형식의 배열을 가져와서 출력 blob(들)로부터의 데이터를 담고있는 셀형식의 배열로 내보낸다. net.forward_prefilled 함수는 정방향 과정중동안에 입력 blob들에 존재하는 데이터를 사용하는데 어떠한 입력도 취하지않으며 출력도 생산하지 않는다. data = rand(net.blobs('data').shape);와 같이 입력 blob에 대해 몇몇 데이터를 생성한 후에, 다음을 실행할 수 있다.

res = net.forward({data});
prob = res{1};
혹은
net.blobs('data').set_data(data);
net.forward_prefilled();
prob = net.blobs('prob').get_data();

역방향 과정도 비슷하게 net.backward 이나 net.backward_prefilled를 사용하며 get_diff와 set_diff로 get_data와 set_data를 대체한다. prob_diff = rand(net.blobs('prob').shape);와 같이 출력 blob에 대한 몇몇 그래디언트를 생성한후에, 다음을 실행할 수 있다.

res = net.backward({prob_diff});
data_diff = res{1};
혹은
net.blobs('prob').set_diff(prob_diff);
net.backward_prefilled();
data_diff = net.blobs('data').get_diff();
하지만 위와같은 역방향 연산은 올바른 결과를 가지지 못하는데, 이는 Caffe가 네트워크는 역방향 연산을 필요로 하지 않다고 결정하기 때문이다. 올바른 역방향처리 결과를 얻기위해서는, 당신의 네트워크 prototxt에서 'force_backward: true'를 설정해줄 필요가 있다.

정방향 혹은 역방향 과정을 모두 수행한 후에, 또한 내부 blob들에서 data나 diff를 취할수 있다. 예를들면, 정방향 과정후의 pool5의 feature를 추출하기 위해서는:

pool5_feat = net.blobs('pool5').get_data();

재구성

10 대신에 1개 이미지를 하나씩 처리하고싶다고 가정하자:

net.blobs('data').reshape([227 227 3 1]); % reshape blob 'data'
net.reshape();

이러면 전체 네트워크가 재구성되며, net.blobs('prob').shape는 [1000 1]; 될 것이다.

학습

당신이 우리의 ImageNET Tutorial에 따라 학습lmdbs와 유효 lmdbs를 생성해봤다고 가정하자. 해결사를 생성하고 ILSVRC 2012 분류화 데이터세트에 대해 훈련시키기 위해서는:

solver = caffe.Solver('./models/bvlc_reference_caffenet/solver.prototxt');

이는 해결사 오브젝트를 다음과 같이 생성한다.

Solver with properties:

          net: [1x1 caffe.Net]
    test_nets: [1x1 caffe.Net]

학습하기 위해서는 :

solver.solve();

혹은 단 1000번 반복으로만 학습하기위해서는 (그래서 당신은 더 많은 반복으로 훈력시키기전에 망에 무언가를 할 수 있다.)

solver.step(1000);

반복수를 얻기위해서는:

iter = solver.iter();

해당 네트워크를 얻기위해서는:

train_net = solver.net;
test_net = solver.test_nets(1);

“your_snapshot.solverstate” 스냅샷부터 재개하기 위해서는:

solver.restore('your_snapshot.solverstate');

입력과 출력

caffe.io 클래스는 기본 입력 함수인 load_image와 read_mean를 제공한다. 예를들면, ILSVRC 2012 mean file를 읽기 위해서는(./data/ilsvrc12/get_ilsvrc_aux.sh로 실행해서 당신이 이미지망 예시 예비파일을 다운로드를 받아놨다고 가정한다.):

mean_data = caffe.io.read_mean('./data/ilsvrc12/imagenet_mean.binaryproto');

Caffe의 예시 이미지를 읽고 width = 256; height = 256;를 원한다고 가정하여 [width, height]를 재설정하기 위해서는:

im_data = caffe.io.load_image('./examples/images/cat.jpg');
im_data = imresize(im_data, [width, height]); % resize using Matlab's imresize
width가 가장먼저오는 차원이며 BGR 채널인것을 잘 생각해야하며, 이는 Matlab에 이미지로 저장되는 일반적 방법과는 다르다.

만약 caffe.io.load_image을 사용하기를 원치않고, 당신이 직접 이미지를 불러오기를 원한다면, 다음을 할 수 있다:

im_data = imread('./examples/images/cat.jpg'); % read image
im_data = im_data(:, :, [3, 2, 1]); % convert from RGB to BGR
im_data = permute(im_data, [2, 1, 3]); % permute width and height
im_data = single(im_data); % convert to single precision

또한, 당신은 아마 이미지로부터 크롭을 취함에 의해 입력을 어떻게 마련하는지 보기위해서 caffe/matlab/demo/classification_demo.m를 한번 볼 수 있다.

우리는 어떻게 Matlab으로 HDF5 데이터가 읽고 쓰이는지 caffe/matlab/hdf5creation에 보여준다. 우리는 데이터 출력에 대한 여분의 함수를 제공하지않으며 이는 Matlab 그자체만으로 이미 꽤 강력한 출력이기 때문이다.

망과 해결사 초기화

모든 해결사와 당신이 만든 항상 작동하는 망들을 초기화하기 위해서는 caffe.reset_all()을 호출할 수 있다.

Clone this wiki locally