레플리
글 수 203

텐서플로우에서 딥러닝 CNN으로 숫자 인식 구현

조회 수 5013 추천 수 0 2017.03.11 12:20:03


http://bcho.tistory.com/1156

 

 

 

지난번에는 MNIST 숫자 이미지 데이터를 소프트맥스로만 학습을 하였습니다. 이번에는 딥러닝의 합성곱 신경망(Convolutional  Neural Network)으로 구현해보겠습니다. CNN에 대한 자세한 설명은 아래 링크를 참조하세요.

 

http://aidev.co.kr/deeplearning/782

 

 

 

Screen_Shot_2017-01-09_at_2.05.42_PM.png

 

CNN의 위의 그림과 같이 합성곱 레이어와 완전연결 레이어로 구성되어 있습니다. 합성곱 레이어의 역할은 다음과 같습니다.

 

Convolutional filter

-> 입력을 필터와 합성곱하여 특징을 추출하고 Feature Map을 생성

 

ReLu

-> 활성함수로 기존 신경망에서 사용하던 시그모이드 대신 사용

 

MaxPool

-> 피처맵의 크기를 줄임

 

 

 

완전연결 레이어는 합성곱 레이어에서 특징들을 뽑아낸 피처맵을 입력으로 하여 기존 다층 신경망과 동일한 방법으로 학습을 합니다. 이렇게 저수준의 특징에서 반복적으로 고수준의 특징을 만들면 복잡한 데이터도 쉽게 학습이 됩니다.

 

CNN의 가장 큰 특징은 필터를 자동으로 학습하여 생성한다는 것입니다. 다만 필터의 개수와 합성곱 레이어를 어떻게 배치할 것인가는 데이터에 맞게 직접 조정해야 합니다.

 

이전 소프트맥스만 사용하여 학습할때는 정확도가 90%정도였습니다. 하지만 CNN으로 동일한 학습을 했을때 정확도가 97%로 높이 향상되었습니다.

 

 

 

텐서플로우 소스코드는 아래와 같습니다.

 

---------------------------------------------------------------------------

import tensorflow as tf

import numpy as np

from tensorflow.examples.tutorials.mnist import input_data

 

 

#-----------------------------

# 초기화

#-----------------------------

 

# 그래프 변수값들을 초기화

tf.reset_default_graph() 

 

# 랜덤 초기화

np.random.seed(20160704)

tf.set_random_seed(20160704)

 

# 숫자 이미지 데이터 로드

mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)

 

 

 

#-----------------------------

# 첫번째 레이어 정의

#-----------------------------

 

# 첫번째 레이어 필터 개수

num_filters1 = 32

 

# 입력값 플레이스홀더 설정

x = tf.placeholder(tf.float32, [None, 784])

 

# 1차원 배열인 입력을 28x28 행렬로 변환

x_image = tf.reshape(x, [-1,28,28,1])

 

# 가중치 변수 설정

W_conv1 = tf.Variable(tf.truncated_normal([5,5,1,num_filters1], stddev=0.1))

 

# 합성곱 가설 설정

h_conv1 = tf.nn.conv2d(x_image, W_conv1, strides=[1,1,1,1], padding='SAME')

 

# 편향값 변수 설정

b_conv1 = tf.Variable(tf.constant(0.1, shape=[num_filters1]))

 

# ReLU 활성함수 설정

h_conv1_cutoff = tf.nn.relu(h_conv1 + b_conv1)

 

# 풀링 설정

h_pool1 = tf.nn.max_pool(h_conv1_cutoff, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')

 

 

 

#-----------------------------

# 두번째 레이어 정의

#-----------------------------

 

# 두번째 레이어 필터 개수

num_filters2 = 64

 

# 가중치 변수 설정

W_conv2 = tf.Variable(tf.truncated_normal([5,5,num_filters1,num_filters2], stddev=0.1))

 

# 합성곱 가설 설정

h_conv2 = tf.nn.conv2d(h_pool1, W_conv2, strides=[1,1,1,1], padding='SAME')

 

# 편향값 변수 설정

b_conv2 = tf.Variable(tf.constant(0.1, shape=[num_filters2]))

 

# ReLU 활성함수 설정

h_conv2_cutoff = tf.nn.relu(h_conv2 + b_conv2)

 

# 풀링 설정

h_pool2 = tf.nn.max_pool(h_conv2_cutoff, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')

 

 

 

#-----------------------------

# 완전연결 레이어 정의

#-----------------------------

 

# 두번째 레이어의 출력을 1차원 배열로 변경

h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*num_filters2])

 

# 입력 노드의 개수

num_units1 = 7*7*num_filters2

 

# 히든 노드의 개수

num_units2 = 1024

 

# 가중치 변수 설정

w2 = tf.Variable(tf.truncated_normal([num_units1, num_units2]))

 

# 편향값 변수 설정

b2 = tf.Variable(tf.constant(0.1, shape=[num_units2]))

 

# 입력과 가중치를 곱하여 행렬 계산

hidden2 = tf.nn.relu(tf.matmul(h_pool2_flat, w2) + b2)

 

# 드롭아웃 확률 플레이스홀더 설정

keep_prob = tf.placeholder(tf.float32)

 

# 드롭아웃 설정

hidden2_drop = tf.nn.dropout(hidden2, keep_prob)

 

# 드롭아웃 가중치 변수 설정

w0 = tf.Variable(tf.zeros([num_units2, 10]))

 

# 드롭아웃 편향값 설정

b0 = tf.Variable(tf.zeros([10]))

 

# 드롭아웃 가중치 행렬 계산

k = tf.matmul(hidden2_drop, w0) + b0

 

# 최종적으로 소프트맥스를 사용하여 결과값 출력

p = tf.nn.softmax(k)

 

 

 

#-----------------------------

# 학습 설정

#-----------------------------

 

# 이미지 입력의 실제 결과 레이블(0~9 숫자를 대표) 플레이스홀더 설정

t = tf.placeholder(tf.float32, [None, 10])

 

# 소프트맥스 크로스 엔트로피로 출력값과 실제값의 차이 계산

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(k,t))

 

# 경사하강법 대신 AdamOptimizer로 loss가 낮게 되도록 훈련 설정

train_step = tf.train.AdamOptimizer(0.0001).minimize(loss)

 

# 정확도 계산

correct_prediction = tf.equal(tf.argmax(p, 1), tf.argmax(t, 1))

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

 

 

 

#-----------------------------

# 학습 수행

#-----------------------------

 

# 세션 초기화

sess = tf.InteractiveSession()

sess.run(tf.global_variables_initializer())

 

# 50개씩 데이터를 랜덤추출해 1000번 학습 반복

i = 0

for _ in range(1000):

    i += 1

    batch_xs, batch_ts = mnist.train.next_batch(50)

    sess.run(train_step, feed_dict={x:batch_xs, t:batch_ts, keep_prob:0.5})

 

    # 100번 마다 정확도 출력

    if i % 100 == 0:

        loss_vals, acc_vals = [], []

 

        for c in range(4):

            start = len(mnist.test.labels) / 4 * c

            end = len(mnist.test.labels) / 4 * (c+1)

 

            loss_val, acc_val = sess.run([loss, accuracy],

                feed_dict={x:mnist.test.images[start:end],

                           t:mnist.test.labels[start:end],

                           keep_prob:1.0})

 

            loss_vals.append(loss_val)

            acc_vals.append(acc_val)

 

        loss_val = np.sum(loss_vals)

        acc_val = np.mean(acc_vals)

        print ('Step: %d, Loss: %f, Accuracy: %f' % (i, loss_val, acc_val))

 

# 세션 종료

sess.close()

---------------------------------------------------------------------------

 

 

 

< 인공지능 개발자 모임 >

- 페이스북 그룹에 가입하시면 인공지능에 대한 최신 정보를 쉽게 받으실 수 있습니다.

https://www.facebook.com/groups/AIDevKr/

 

List of Articles
제목 글쓴이 날짜 조회 수sort
사진을 복원하는 딥러닝 모델 - DFDNet 깊은바다 2020-08-24 1229
모두를 위한 머신러닝/딥러닝 강의 깊은바다 2016-04-03 1225
쉽게 씌어진 GAN 깊은바다 2018-04-11 1224
빈 주차공간을 찾아서 알려주는 인공지능 만든 개발자 깊은바다 2019-02-09 1210
AutoML을 이용한 Architecture Search 소개 및 NASNet 논문 리뷰 깊은바다 2019-08-18 1207
텐서플로우 기초 이해하기 깊은바다 2017-03-11 1205
GAN으로 만든 가짜 사진과 진짜 사진을 맞추는 사이트 file 깊은바다 2019-03-04 1205
Text-to-Image 모델을 정리한 글 - The State of AI and Art 2022 깊은바다 2022-10-06 1204
Stable Diffusion으로 만든 뮤직비디오 영상 깊은바다 2022-09-25 1136
10분안에 배우는 머신러닝 - GAN 알고리즘 원리와 응용분야 깊은바다 2019-04-01 1132
최초로 인간 수준의 크기를 가진 중국의 딥러닝 모델 - BaGuaLu file 깊은바다 2022-06-23 1117
OpenAI의 CLIP을 사용해서 자연어로 유튜브 영상 검색 깊은바다 2021-07-05 1099
말로 영상을 생성하는 딥러닝 모델 - CogVideo file 깊은바다 2022-05-30 1071
내가 말하는 걸 보여줘, DALL-E 깊은바다 2021-11-11 1062
인공신경망 학습 레시피 - 안드레이 카파시의 딥러닝 실전 노하우 깊은바다 2019-04-27 1052