해당 포스트는 책 “골빈해커의 3분 딥러닝 텐서플로맛”의 11장 “구글의 핵심 이미지 인식 모델 Inception”을 학습하고 내용을 정리한 글입니다.


인셉션(Inception)

  • 구글이 만든 공개 모델
  • 이미지 인식 모델
  • 이미지 인식 대회인 ILSVRC에서 2014년 우승

  • 인셉션은 기본적으로 작은 컨볼루션 계층을 매우 많이 연결한 것
  • 위 그림에서 보듯이 구성이 꽤 복잡해 구현하기가 조금 까다로움
  • 하지만 구글이 텐서플로로 구현해 공개하고 있음
  • 또 그 모델을 다양한 목적에 쉽게 활용할 수 있도록 간단한 스크립트까지 제공

  • 이번 장에서는 이 스크립트를 사용해 꽃 사진을 학습시키고 꽃의 종류를 알아내는 간단한 스크립트를 작성하고 테스트 해봄



11.1 자료 준비

  • 두 개의 자료 다운로드 필요
    (1) 학습을 위한 꽃 사진
    (2) 일정한 기준에 따라 사진을 학습시키는 스크립트
  • 이 두 자료 모두 텐서플로의 홈페이지에 있으며 아래의 링크에서 다운로드 가능
  • 꽃 사진
    다운로드
  • 학습 스크립트
    다운로드
  • 학습 자료와 학습시킨 모델을 저장할 디렉토리를 workspace라는 이름으로 생성
  • 그런 다음 꽃 사진을 workspace 디렉토리에 위치시키고, 학습 스크립트는 현재 디렉토리에 저장
  • 구성된 디렉토리 구조는 아래와 같음
/retrain.py
/workspace
            /flower_photos
                            /daisy
                            /dandelion
                            /roses
                            /sunflowers
                            /tulips
  • 꽃의 이름별로 디렉토리가 나뉘어 있음
  • retrain.py 스크립트는 디렉토리 이름을 레이블(꽃 이름)로 하여 각 디렉토리에 있는 사진들을 학습



11.2 학습시키기

  • retrain.py 스크립트로 꽃 사진들을 학습시킴
  • 터미널(명령 프롬프트)에서 retrain.py 파일이 있는 위치에서 다음 명령어 실행
python retrain.py \
--bottleneck_dir=./workspace/bottlenecks \
--model_dir=./workspace/inception \
--output_graph=./workspace/flowers_graph.pb \
--output_labels=./workspace/flowers_labels.txt \
--image_dir=./workspace/flower_photos \
--how_many_training_steps 1000

스크립트에 사용한 옵션들의 의미

  • --bottleneck_dir
    학습할 사진을 인셉션용 학습 데이터로 변환해서 저장해둘 디렉토리
  • --model_dir
    인셉션 모델을 내려받을 경로
  • --output_graph
    학습된 모델(.pb)을 저장할 경로
  • --output_labels
    레이블 이름들을 저장해 둘 파일 경로
  • --image_dir
    원본 이미지 경로
  • --how_many_training_steps
    반복 학습 횟수
  • 스크립트를 실행하면 다음 메시지와 함께 학습이 이루어짐
2019-02-28 22:42:31.908401: Step 970: Train accuracy = 95.0%
2019-02-28 22:42:31.908401: Step 970: Cross entropy = 0.239813
2019-02-28 22:42:32.054013: Step 970: Validation accuracy = 89.0% (N=100)
2019-02-28 22:42:33.561979: Step 980: Train accuracy = 91.0%
2019-02-28 22:42:33.561979: Step 980: Cross entropy = 0.291035
2019-02-28 22:42:33.710549: Step 980: Validation accuracy = 86.0% (N=100)
2019-02-28 22:42:35.189594: Step 990: Train accuracy = 97.0%
2019-02-28 22:42:35.190591: Step 990: Cross entropy = 0.219651
2019-02-28 22:42:35.346176: Step 990: Validation accuracy = 85.0% (N=100)
2019-02-28 22:42:36.664649: Step 999: Train accuracy = 95.0%
2019-02-28 22:42:36.665663: Step 999: Cross entropy = 0.217191
2019-02-28 22:42:36.810285: Step 999: Validation accuracy = 88.0% (N=100)
Final test accuracy = 88.7% (N=708)
Converted 2 variables to const ops.



11.3 예측 스크립트

  • 예측 스크립트 predict.py를 간략화한 버전을 작성하면서 어떤 내용으로 채워져 있는 지 확인

11.3.1 라이브러리 Import

import tensorflow as tf
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import sys
  • matplotlib 라이브러리 : 맨 마지막에 예측 결과가 맞는 지 눈으로 확인할 수 있도록 이미지 출력하는 데 사용

NOTE

  • 이미지 처리에 pillow 라이브러리가 필요

11.3.2 옵션 및 기본값 설정

  • 텐서플로의 모듈 app.flags를 사용해 스크립트에서 받을 옵션과 기본값 설정
  • tf.app 모듈을 사용하면 터미널(명령 프롬프트)에서 입력받는 옵션을 쉽게 처리할 수 있음
tf.app.flags.DEFINE_string("output_graph", "./workspace/flowers_graph.pb", "학습된 신경망이 저장된 위치")
tf.app.flags.DEFINE_string("output_labels", "./workspace/flowers_labels.txt", "학습할 레이블 데이터 파일")
tf.app.flags.DEFINE_boolean("show_image", True, "이미지 추론 후 이미지를 보여줍니다.")

FLAGS = tf.app.flags.FLAGS
  • retrain.py 로 학습을 진행하면 workspace 디렉토리의 flowers_labels.txt 파일에 꽃의 이름들을 전부 저장함
  • 한 줄에 하나씩 들어가 있고, 줄 번호를 해당 꽃 이름의 인덱스로 하여 학습을 진행
    (정확히는 인덱스는 줄번호 -1, 배열의 인덱스는 0부터 시작하기 때문)
# flowers_labels.txt
daisy
dandelion
roses
sunflowers
tulips

예측 후 출력하는 값

  • 모든 인덱스에 대해 총합이 1인 확률을 나열한 softmax 값
#   daisy      dandelion      roses     sunflowers     tulips
[ 0.65098846   0.1175265   0.01479027   0.20992769   0.00676709]

11.3.3 꽃 이름 가져오기

  • 테스트 결과를 확인할 때 사용하기 위해 파일에 담긴 꽃 이름들을 가져와 배열로 저장
  • 이름을 출력하는 데 사용할 것

11.3.4 신경망 그래프 생성

  • retrain.py를 실행해 학습이 끝나면 flowers_graph.pb 파일이 생성됨
  • 학습 결과를 프로토콜 버퍼(Protocol Buffers)라는 데이터 형식으로 저장해 둔 파일
  • 꽃 사진 예측을 위해 이 파일을 읽어 들여 신경망 그래프를 생성할 것

11.3.5 모델 예측 텐서 지정

  • 읽어 들인 신경망 모델에서 예측에 사용할 텐서 지정
  • 저장되어 있는 모델에서 최종 출력층은 final_result:0이라는 이름의 텐서임
  • 이 텐서를 가져와 예측에 사용

11.3.6 이미지를 예측 모델에 입력

  • 예측 스크립트 실행 시 주어진 이름의 이미지 파일을 읽어 들인 뒤, 그 이미지를 예측 모델에 넣어 예측을 실행
  • 코드의 DecodeJpeg/contents:0은 이미지 데이터를 입력값으로 넣을 플레이스홀더의 이름

  • 프로토콜 버퍼 형식으로 저장되어 있는 다른 모델들도 이와 같은 방법으로 읽어 들여 사용할 수 있음

11.3.7 예측 결과 출력

  • 앞에서 읽어 온 레이블(꽃 이름)들에 해당하는 모든 예측 결과를 출력

NOTE

  • 확률이 가장 높은 결과 하나만 출력하려면 해당 코드 대신 다음 코드 사용
print('=== 예측 결과 ===')
top_result = int(np.argmax(prediction[0]))
name = labels[top_result]
score = prediction[0][top_result]
print(' %s (%.2f%%)' % (name, score * 100))

11.3.8 이미지 출력

  • 주어진 이름의 이미지 파일을 matplotlib 모듈을 이용해 출력
def main(_):

    # 11.3.3 꽃 이름 가져오기
    labels = [line.rstrip() for line in tf.gfile.GFile(FLAGS.output_labels)]

    # 11.3.4 신경망 그래프 생성
    with tf.gfile.FastGFile(FLAGS.output_graph, 'rb') as fp:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(fp.read())
        tf.import_graph_def(graph_def, name='')

    # 11.3.5 모델 예측 텐서 지정
    with tf.Session() as sess:
        logits = sess.graph.get_tensor_by_name('final_result:0')

        # 11.3.6 이미지를 예측 모델에 입력
        image = tf.gfile.FastGFile(sys.argv[1], 'rb').read()
        prediction = sess.run(logits, {'DecodeJpeg/contents:0': image})  

    # 11.3.7 예측 결과 출력
    print('=== 예측 결과 ===')
    for i in range(len(labels)):
        name = labels[i]
        score = prediction[0][i]
        print(' %s (%.2f%%)' % (name, score * 100))

    # 11.3.8 이미지 출력
    if FLAGS.show_image:
        img = mpimg.imread(sys.argv[1])
        plt.imshow(img)
        plt.show()

11.3.9 main() 함수 실행

  • 스크립트 실행 시 주어진 옵션들과 함께 main() 함수 실행하는 코드 작성
if __name__ == "__main__" :
    tf.app.run()
  • 터미널(명령 프롬프트)에서 위의 코드를 포함한 predict.py 스크립트 파일이 위치한 곳에서 아래 명령어 실행
python predict.py workspace/flower_photos/roses/3065719996_c16ecd5551.jpg

11.3.10 전체 코드

# 11.3.1
import tensorflow as tf
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import sys

# 11.3.2
tf.app.flags.DEFINE_string("output_graph", "./workspace/flowers_graph.pb", "학습된 신경망이 저장된 위치")
tf.app.flags.DEFINE_string("output_labels", "./workspace/flowers_labels.txt", "학습할 레이블 데이터 파일")
tf.app.flags.DEFINE_boolean("show_image", True, "이미지 추론 후 이미지를 보여줍니다.")

FLAGS = tf.app.flags.FLAGS

def main(_):

    # 11.3.3
    labels = [line.rstrip() for line in tf.gfile.GFile(FLAGS.output_labels)]

    # 11.3.4
    with tf.gfile.FastGFile(FLAGS.output_graph, 'rb') as fp:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(fp.read())
        tf.import_graph_def(graph_def, name='')

    # 11.3.5
    with tf.Session() as sess:
        logits = sess.graph.get_tensor_by_name('final_result:0')

        # 11.3.6
        image = tf.gfile.FastGFile(sys.argv[1], 'rb').read()
        prediction = sess.run(logits, {'DecodeJpeg/contents:0': image})  

    # 11.3.7
    print('=== 예측 결과 ===')
    for i in range(len(labels)):
        name = labels[i]
        score = prediction[0][i]
        print(' %s (%.2f%%)' % (name, score * 100))

    # 11.3.8
    if FLAGS.show_image:
        img = mpimg.imread(sys.argv[1])
        plt.imshow(img)
        plt.show()

# 11.3.9
if __name__ == "__main__" :
    tf.app.run()



11.4 더 보기

  • 텐서플로 모델 저장소에는 이외에도 다양한 모델이 공개되어 있음
  • ex) 물체 검출 API(Object Detection API) 모델 : 그림에서 물체를 검출해 그 종류와 확률을 표시해줌

태그:

카테고리:

업데이트:

댓글남기기