레플리
글 수 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
제목 글쓴이 날짜 조회 수sort
사진 한장으로 딥페이크 영상을 만드는 앱 - Reface 깊은바다 2020-08-18 26955
딥러닝의 종류 간단 설명 file 깊은바다 2017-03-11 25161
YOLO, Object Detection Network - 알고리즘 설명 file 깊은바다 2019-06-02 25054
신경망에 활성화 함수가 필요한 이유 file 깊은바다 2019-05-14 23723
만화 캐릭터를 자동으로 생성하는 서비스 - Waifu file 깊은바다 2019-08-23 20415
DALL.E를 직접 테스트해볼 수 있는 사이트 - DALL.E mini file 깊은바다 2022-05-17 11537
Quick, Draw! - 구글이 만든 그림 맞추기 깊은바다 2017-02-28 10722
퓨샷 러닝(few-shot learning)과 메타 러닝(meta-learning) 깊은바다 2020-06-27 10285
딥러닝 텐서플로를 사용하여 코카콜라 병뚜껑 경품번호 인식 깊은바다 2018-01-23 8607
딥러닝 합성곱 신경망(CNN) 개요 file 깊은바다 2017-03-05 7751
딥러닝 이미지 편집 프로그램 - GAN Paint 깊은바다 2019-01-12 7234
불쾌한 골짜기에서 대유쾌 마운틴으로 - 이미지 생성AI file 깊은바다 2023-03-08 7155
네이버의 손글씨 자동생성 인공지능 file 깊은바다 2019-09-08 7153
텍스트를 이미지로 생성해주는 사이트 - Text2Art (VQGAN-CLIP) file 깊은바다 2021-11-10 6897
딥러닝의 미래는 바로 비지도학습 깊은바다 2019-06-06 6368