상세 컨텐츠

본문 제목

[Deep Learning - 딥러닝]MNIST Classification - 손글씨 분류기 소스 구현

Artificial Intelligence

by [성운] 2019. 9. 19. 22:12

본문

이번 포스팅은 MNIST 구현에 대해서 알아보겠습니다. MNIST 정의는 https://ynebula.tistory.com/43 포스팅을 참고바랍니다.

 

Archtecture

이미지 데이터의 크기가 28*28 입니다. 딥러닝 구현이므로 은닉층을 2개로 구성하고 번째 필터는 32 번째 필터는 64개로 구성합니다. 은닉층 활성화 함수를 ReLU 사용하며, 분류를 위해 Softmax() 함수를 사용합니다.

 

Souce 구현

컨볼루션 계층을 구현하기 위해 다음 라이브러리 임포트가 필요합니다.

텐서플로 1.7.0 버전에서부터는 샘플 데이터를 다운로드하는 기능이 제외될 예정이라는 경고가 발생합니다. 대신 케라스(Keras)를 사용하여 MNIST 데이터를 다운받습니다.

배치 데이터를 만들기 위해 파이썬 제너레이터 함수를 정의합니다.

훈련 이미지 데이터를 넣을 플레이스홀더를 2차원 텐서로 만듭니다. 텐서 x 이미지를 784픽셀을 실수로 저장하는 벡터로 사용됩니다. None이라고 지정한 것은 어떤 크기나 가능하다는 뜻으로서, 여기에서는 학습 과정에 사용될 이미지의 개수가 것입니다. y_ 실제 레이블을 담는 프레이스홀더 입니다. x 이미지 사이즈인 28x28x1 크기로 차원을 변경합니다.

행렬 W와 편향 b와 정의하는 함수를 구현합니다. 가중치는 표준편차를 0.1로 갖는 난수로 초기화하여 Varialbe 타입으로 리턴합니다. 편향은 작은 양수(0.1)로 초기화하고 Varialbe 타입으로 리턴합니다.

2D 컨볼루션과 맥스풀링을 정의하는 함수를 구현합니다. 텐서플로에서는 컨볼루션 관련 함수를 제공합니다. 함수명 끝 2d는 차원을 뜻합니다. stride 1로 하고 패딩은 0으로 하는 컨볼루션 레이어를 만드는 함수를 정의합니다.

strides 옵션 NHWC의 정의는 다음과 같습니다.

N: number of images in the batch

H: height of the image

W: width of the image

C: number of channels of the image (ex: 3 for RGB, 1 for grayscale...)

padding은 경계 처리 방법을 정이하는 옵션으로 다음 두 가지가 있습니다.

valid: 유효한 영역만 출력이 됩니다. 따라서 출력 이미지 사이즈는 입력 사이즈보다 작습니다.

same: 출력 이미지 사이즈가 입력 이미지 사이즈와 동일합니다.

이 예제는 윈도 크기가 5x5 32개의 필터를 사용합니다. 따라서 우리는 구조가 [5,5,1,32]인 가중치 행렬 W를 저장할 텐서를 정의해야 합니다. 처음 두 개의 차원은 윈도의 크기이며 세 번째는 컬러 채널로 우리 예제에서는 1입니다. 마지막 차원은 얼마나 많은 특징을 사용할 것인지를 정의하는 것입니다. 편향은 필터수인 32로 정의합니다.

첫 번째 컨볼루션 레이어를 만들기 위해 학습 데이터(x_image)에 대해 합성곱을 적용하고 편향을 더해줍니다(목표함수 수행). 그리고 활성화 함수로 ReLU(Rectified Linear Unit)를 적용합니다. 다음으로 출력 값을 구하기 위해 맥스 풀링을 적용합니다. 그리고 2x2 맥스 풀링 레이어를 위한 함수를 정의합니다.

활성화 함수를 수행한 다음 마지만 차원이 1에서 32로 변경 되었습니다. 특징맵의 수를 의미합니다. SAME 패딩이므로 컨볼루션으로는 차원이 변경되지 않고 풀링 단계에서 스트라이드에 따라 차원이 반으로 줄어듭니다.

두 번째 은닉층 컨볼루션 레이어와 풀링 레이어를 구현하겠습니다. 5 * 5 윈도에 64개의 필터를 갖는 두 번째 합성곱 계층을 만들겠습니다. 이때는 이전 계층의 출력 값의 크기(32)를 채널의 수로 넘겨야 합니다(특징맵 수). SAME 패딩이므로 콘볼루션으로는 차원이 변경되지 않고 풀링 단계에서 스트라이드에 따라 차원이 반으로 줄어든다. 14x14 크기 행렬인 h_pool1에 스트라이드 1 5x5 윈도를 적용하여 합성곱 계층을 만들었고, 맥스 풀링까지 거쳐 크기는 7x7이 됩니다.

소프트맥스 함수를 적용을 위해 출력 값 h_pool2 Fully Connected를 연산합니다. 1024개의 노드를 사용하겠습니다. 즉 가중치는 [이미지 사이즈 * 필터 수, 노드 수] 이고 편향은 [노드 수] 개 입니다.

소프트맥스 함수는 이미지를 직렬화해서(1차원으로 변환) 벡터 형태로 입력해야 합니다. tf.reshape()함수를 사용해서 h_pool2을 직렬화 시킵니다. 그리고 W_fc1 Fully Connected를 수행하고 편향을 더하고 ReLU 활성화 함수로  적용합니다.

다음 단계는 드롭아웃(dropout)이라는 기법을 통해 신경망에서 필요한 매개변수 수를 줄이는 것입니다. 텐서플로에서 제공하는 tf.nn.dropout 함수를 사용하여 드롭아웃을 적용합니다(드롭아웃 자세한 내용은 https://ynebula.tistory.com/36 참고바랍니다). rate는 비활성되는(discard) 노드의 수를 설정하는 파라메터로 플래이스홀더 변수를 이용해 다음과 같이 구현합니다.

마지막으로 소프트맥스 레이어를 추가합니다. Fully Connected 연산을 수행을 위해 가중치와 편향을 정의해야 합니다. 가중치는 이전 계층 수 1024와 정답 수 10로 이루어지며 편향은 정답 수 10으로 정의합니다. Fully Connected를 수행하고 Softmax 활성화 함수를 적용합니다.

모델평가를 위한 비용함수는 Cross Entropy를 사용하고, 최적화 알고리즘은 ADAM을 사용합니다(텐서틀로 API 문서에 따르면 ADAM 최적화 알고리즘이 특정한 장점을 가지고 있다고 가이드 함).

세션을 시작하고 변수를 초기화 합니다. 훈련은 10,000번 반복을 수행합니다. 또한 feed_dict 인수로 플래이스홀더로 선언한 Dropout 계층에 노드 비활성화 확률 값인 keep_prob feed_dict 인수로 전달합니다.

마지막으로 최종 정확도를 출력합니다.

 

Source

다음 링크를 참고하시면 전체 소스 확인할 수 있습니다.

https://github.com/ynebula/First-Contact-with-Books/blob/master/Tensorflow/ConvolutionNeuralNet.ipynb

 

글이 도움되셨다면 공감 부탁 드립니다.

감사합니다.

 

[Reference]

텐서플로 첫걸음

관련글 더보기

댓글 영역