레플리
글 수 203

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

조회 수 5010 추천 수 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
제목 글쓴이 날짜 조회 수
인공지능 과학자의 꿈, 범용 AI는 가능할까 깊은바다 2021-10-15 865
딥러닝 범용 모델 - Foundation Models 깊은바다 2021-09-06 1317
소프트웨어 개발 경험이 먼저다 - 딥러닝 역시 S/W 기술의 하나일 뿐 깊은바다 2021-07-14 913
제프리 힌튼, 얀 르쿤, 요슈아 벤지오가 말하는 딥러닝의 미래 깊은바다 2021-07-08 871
OpenAI의 CLIP을 사용해서 자연어로 유튜브 영상 검색 깊은바다 2021-07-05 1069
스케치를 사진으로 바꾸어주는 프로그램 - NVIDIA CANVAS 깊은바다 2021-06-25 636
한 단어만으로 텍스트 스타일을 바꿔주는 딥러닝 모델 - TextStyleBrush 깊은바다 2021-06-24 647
GameGAN으로 직접 화면을 생성하는 GTA5 게임 깊은바다 2021-06-20 632
Transformer와 동급의 성능에 속도는 훨씬 빨라진 MLP-Mixer file 깊은바다 2021-06-11 1414
GAN으로 얼굴사진을 생성하는 사이트 - Face Generator file 깊은바다 2021-04-28 2768
말로 설명하여 이미지를 변형하는 GAN - StyleCLIP file 깊은바다 2021-04-04 1803
GPT-3로 광고문구를 만드는 서비스 - Copy.ai 깊은바다 2021-03-22 645
딥러닝의 창시자인 제프리 힌튼이 구글에 합류하게 된 스토리 깊은바다 2021-03-18 415
뉴런 하나로 특정 개념을 표현한다, CLIP 모델에서 개념 뉴런을 발견 file 깊은바다 2021-03-12 568
스냅챕의 디즈니 필터 깊은바다 2021-03-12 528