Skip to content

Caffe Example : 8.Siamese Network Training with Caffe (Kor)

HanJiHoon edited this page Dec 31, 2016 · 3 revisions

Caffe를 이용한 샴 네트워크 학습하기 (Siamese Network Training with Caffe)

이 예시는 Caffe에서 샴 네트워크를 사용하여 모델을 학습하기위해 우리가 가중치 공유와 대조하는 손실함수을 어떻게 사용할 수 있는지를 보여준다.

우리는 Caffe를 성공적으로 컴파일 했다고 가정할 것이다. 아니라면, 설치페이지ㄹ를 참고하길 바란다. 이 예시는 MNIST 입문서을 기반으로 구축한다. 그래서 계속하기전에, 이걸 먼저 읽고 오는게 좋을것이다.

이 가이드는 모든 경로들을 명시하고 모든 명령어들은 Caffe root 디렉토리에서 실행되어진다고 가정한다.

데이터세트 준비하기(Prepare Datasets)

당신은 처음에 MNIST 웹사이트에서 데이터를 다운로드받고 전환할 필요가 있다. 이를위해서는, 간단히 다음과 같은 명령어를 실행하라:

./data/mnist/get_mnist.sh
./examples/siamese/create_mnist_siamese.sh

이 명령어를 실행한후 두개의 데이터세트 ./examples/siamese/mnist_siamese_train_leveldb와 ./examples/siamese/mnist_siamese_test_leveldb가 있을 것이다.

모델(The Model)

처음에, 우리는 샴 네트워크를사용해 학습하기를 원하는 모델을 정의할 것이다. 우리는 ./examples/siamese/mnist_siamese.prototxt에 정의된 컨볼루션 망을 사용할 것이다. 이 모델은 거의 정확하게 LeNet 모델과 일치하는데, 오직 한가지 다른점은 2차원 벡터를 생성하는 선형 "특징" 계층으로 10개의 숫자 클래스 이상의 가능성을 생산하는 상위 계층을 대체해온것이다.

layer {
  name: "feat"
  type: "InnerProduct"
  bottom: "ip2"
  top: "feat"
  param {
    name: "feat_w"
    lr_mult: 1
  }
  param {
    name: "feat_b"
    lr_mult: 2
  }
  inner_product_param {
    num_output: 2
  }
}

샴 네트워크 정의 (Define the Siamese Network)

이 섹션에서는 우린 학습에 사용될 샴 네트워크를 정의할 것이다. 도출되는 네트워크는 ./examples/siamese/mnist_siamese_train_test.prototxt에 정의되어져있다. In this section we will define the siamese network used for training. The resulting network is defined in ./examples/siamese/mnist_siamese_train_test.prototxt.

데이터 쌍 읽어들이기(Reading in the Pair Data)

우리는 초기에 우리가 생성한 LevelDB 데이터 베이스로부터 읽은 데이터계층을 가지고 시작한다. 이 데이터 베이스의 각각 내용은 한 쌍의 이미지들 (pair_data)에 대한 이미지와 이미지들이 같은 클래스에인지 다른 클래스들에 걸려있는지 말해주는 이진수 라벨(sim)을 포함하고 있다.

layer {
  name: "pair_data"
  type: "Data"
  top: "pair_data"
  top: "sim"
  include { phase: TRAIN }
  transform_param {
    scale: 0.00390625
  }
  data_param {
    source: "examples/siamese/mnist_siamese_train_leveldb"
    batch_size: 64
  }
}

데이터베이스에 같은 blob속에다 한 쌍에 이미지를 포장하기위해 우리는 한 채널당 하나의 이미지로 포장한다. 우리는 이러한 두개의 이미지를 나누어서 작업할 수 있는것을 원하기 때문에, 우리는 데이터 계층 다음에 자르기 계층(slice layer)을 추가한다. 이는 pair_data를 가지고와서 채널의 차원수에 따라 pair_data를 잘라서 우리가 데이터내 단일 이미지와 data_p속 데이터의 쌍으로 된 이미지를 가진다

layer {
  name: "slice_pair"
  type: "Slice"
  bottom: "pair_data"
  top: "data"
  top: "data_p"
  slice_param {
    slice_dim: 1
    slice_point: 1
  }
}

샴 망의 두번째 사이드 구축(Building the Second Side of the Siamese Net)

이제 우리는 data_p에서 작동하고 feat_p를 처리하는 두번째 결로를 생성할 필요가있다. 이 결로는 정확히 처음과 다르지 않다. 그래서 우리는 그냥 이를 복사하고 붙여넣기할 수 있다. 그러고나면 기존의 것과 쌍으로 된(paired) 계층들을 차별하기위해 _p를 붙여줌으로써 우리는 각각의 계층, 입력, 그리고 출력의 이름을 바꿔야한다.

대조하는 손실 함수 추가하기(Adding the Contrastive Loss Function)

네트워크를 학습하기위해서 우리는 Raia Hadsell, Sumit Chopra, 그리고 Yann LeCun이 저술한 "변하지않는 맵핑을 학습함으로 차원가능성 제거하기(Dimensionality Reduction by Learning an Invariant Mapping)"에서 제시했던 대조하는 손실함수를 최적화할 것이다. 이 손실함수는 매치되지 못하는 쌍들을 밀어냄과 동시에 특징 공간에서 서로를 가깝게하기위해 쌍을 매칭하도록 돕는다. 이러한 비용 함수는 CONTRASTIVE_LOSS계층에서 수행된다.

layer {
    name: "loss"
    type: "ContrastiveLoss"
    contrastive_loss_param {
        margin: 1.0
    }
    bottom: "feat"
    bottom: "feat_p"
    bottom: "sim"
    top: "loss"
}

해결사 정의하기(Define the Solver)

알맞는 모델 파일에 이를 지적하기만 해주면 해결사를 정의하기위해 특별히 해줄일은 없다. 해결사는 ./examples/siamese/mnist_siamese_solver.prototxt에 정의되어있다.

모델 학습 및 실험(Training and Testing the Model)

모델 학습은 당신이 네트워크 정의 protobuf와 해결사 protobuf 파일들을 작성해온 후라면 간단하다. 간단히 ./examples/siamese/train_mnist_siamese.sh를 실행시켜주면 된다.

./examples/siamese/train_mnist_siamese.sh

결과 플라팅(Plotting the results)

처음에 우리는 .prototxt 파일들에 정의된 DAGs를 그려주는 다음의 명령어들을 실행시켜줌으로써 모델과 샴 네트워크를 그릴수있다.

./python/draw_net.py \
    ./examples/siamese/mnist_siamese.prototxt \
    ./examples/siamese/mnist_siamese.png

./python/draw_net.py \
    ./examples/siamese/mnist_siamese_train_test.prototxt \
    ./examples/siamese/mnist_siamese_train_test.png

다음으로, 우리는 학습된 모델을 불러서 iPython 노트북을 사용한 특징들을 플라팅할 수 있다.

ipython notebook ./examples/siamese/mnist_siamese.ipynb
Clone this wiki locally