Tuesday, July 21, 2015

Wednesday, July 8, 2015

[Korean] 컨볼루션 뉴럴 넷 Convolutional Neural Network 자세한 설명

키워드: 딥러닝, 컨볼루션 넷, 컨브넷, cnn, convnet, convolutional neural network, deep learning
참고자료: keras

keras의 예제 파일 중 cifar10.py에 구현된 간단한 컨브넷을 설명드리겠습니다.
우선 이 작업은 손으로 쓴 숫자 0~9를 구분하는 것을 목적으로 합니다. 즉 Hand-written digit recognition task입니다.

모델 부분 코드만 보면 아래와 같습니다.

model = Sequential()
model.add(Convolution2D(32, 3, 3, 3, border_mode='full'))model.add(Activation('relu'))model.add(Convolution2D(32, 32, 3, 3))
model.add(Activation(
'relu'))
model.add(MaxPooling2D(poolsize=(
2, 2)))
model.add(Dropout(
0.25))
model.add(Convolution2D(
64, 32, 3, 3, border_mode='full'))
model.add(Activation(
'relu'))
model.add(Convolution2D(
64, 64, 3, 3))
model.add(Activation(
'relu'))
model.add(MaxPooling2D(poolsize=(
2, 2)))
model.add(Dropout(
0.25))
#------절취선--------
model.add(Flatten())
model.add(Dense(
64*8*8, 256))
model.add(Activation(
'relu'))
model.add(Dropout(0.5))
model.add(Dense(256, 10))
model.add(Activation('softmax'))
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd)

  • 전체 구조
전체 구조를 간단히 설명하면 이렇습니다. ReLU와 드롭아웃은 설명에서 빼겠습니다.
모든 convolutional layer에서 이미지 패치는 3x3입니다.
맥스풀링도 없다고 가정하면 전체 과정은,

- 이미지 파일 로딩 (크기:  32x32, RGB채널)
- 3-32 convolutional layer
- 32-32 conv layer
- 32-64 conv layer
- 64-64 conv layer
- flatten (벡터 형태로 reshape)
- (64*8*8) - 256 fully connected layer
- 256 - 10 fully connected layer
- softmax + making decision
입니다.


  • 파라미터 설명 ---절취선 이전---
model.add(Convolution2D(32, 3, 3, 3, border_mode='full'))
(32, 3, 3, 3, border_mode='full')
- border_mode: full, valid가 있고 그 중간격인 same도 매트랩에선 지원합니다. 자세한 설명 생략. 컨볼루션 할때 이미지 끄트머리; 가장자리를 어떻게 처리할지 하는 내용입니다.
- (32, 3, 3, 3)에서 ...
- - 뒤의 3,3은 이미지 패치 사이즈입니다. 즉 (3, 3) 크기의 패치가 이미지를 쭉 훑고 다니게 됩니다.
- - 앞의 (32, 3)은, 3개 채널의 이미지 stack을 32개의 이미지 stack으로 만들어주겠다는 이야기입니다. 즉, 이 부분에서는 총 32개의 피쳐를 추출하게 됩니다. 그 추출은 (3x3)의 이미지 패치의 값 (=9개의 계수, weight parameter)를 learning하여 사용합니다. 따라서 이 과정을 거치면 32x32의 이미지(의 피쳐)가 32개가 쌓이게 됩니다. 
- - 같은걸 (32, 32)로 또 해줍니다.
- - 이번엔 (32, 64)로 또 해줍니다.
- - 마지막으로 (64, 64)로 또 해줍니다. 이런 과정을 거쳐서 이미지는 Low-level feature (직선, 곡선 등의 단순한 피쳐)에서 high-level feature (눈 모양이 있는지, 얼굴 모양이 있는지 등등..)로 변환됩니다.

"그런데말입니다,"
중간에 Max-Pooling이 두 번 있었죠. 그래서 이미지의 크기는 (32x32)가 아니라 (8x8)이 됩니다.

여기까지를 feature learning이라고 생각할 수 있습니다. 

  • 파라미터 설명 ---절취선 이후---
여기서부터는 classification에 가까운 단계입니다.
앞서 convolutional layer를 여러 단계 거친 결과 8x8 이미지가 총 64개가 쌓여있게 됩니다. 즉 전체 데이타 포인트는 64*8*8=4096개가 됩니다.

Dense(64*8*8, 512) 에서는 입력 4096개, 출력 512개의 fully-connected 레이어를 추가합니다.
Dense(512, 10)는 입력 512개, 출력 10개의 레이어를 추가합니다.
여기서 출력 유닛 10개는 각각 0~9의 숫자를 나타냅니다.
그 뒤엔 softmax로 최종 결과가 나옵니다.


  • 그림으로 이해하기


  • 파라미터 개수
패치 사이즈는 9 (3x3)
스택 사이즈는 (3-32) - (32-32) - (32-64) - (64-64) - now fully connected - ( 64*8*8 - 512) - (512 - 10 )
따라서 각각 단계에서 파라미터 개수는 입력 채널 개수 * 출력 채널 개수 * 이미지 패치 크기 가 됩니다. 숫자로 쓰면,
#parameters: 3*32*9 + 32*32*9 + 32*64*9 + 64*64*9 + (64*8*8*)*512 + 512*10

= 288 + 288 + 576 + 576 + 2097152 + 5120

이 된다. 

해당 코드에서 데이타는 트레이닝에 45000개를 불러오고, 회전해서 x20, 좌우 뒤집어서 x2 등의 데이타 뻥튀기 과정을 거치면 대략 200만개가 된다. 시스템의 파라미터 개수와 데이타 개수를 참고 바람.

------

정리할 겸 작성한 내용이니 틀린 부분이 있다면 알려주세요!