• GAN이란?
  • GAN의 학습방법

포스팅 목적: 의학도나 방사선사들의 훈련에는 많은 영상이 필요하나, 구조적 법적 문제로 대량의 영상을 공유하기가 쉽지 않습니다. 데이터의 양이 적어 해결되지 않는 문제들을 개선하고자 공부하였고 이 내용을 포스팅합니다. 

 

reference: 

논문: Towards generative adversarial networks as a new paradigm for radiology education

참고 영상: 

tv.naver.com/v/1947034

 

1시간만에 GAN(Generative Adversarial Network) 완전 정복하기

NAVER Engineering | 발표자: 최윤제(고려대 석사과정) 발표일: 2017.5. Generative Adversarial Network(GAN)은 2014년 Ian Goodfellow에 의해 처음으로 제안되었으며, 적대적 학습을 통해 실제 데이터의 분포를 추정하

tv.naver.com

1. GAN이란?

 

GAN(Generative Adversarial Network)로 적대적 생성 모델이라고 합니다. 

 

하나씩 뜯어서 보자면, 생성모델이라는 관점에서 

머신러닝에서 만들어내는 예측 결과나, continuous variable의 interval prediction값이 아닌(가장 높은 확률 혹은 likelihood를 찾아내는 행위), 데이터의 형태를 만들어내는 모델입니다. 

데이터의 형태는 분포 혹은 분산을 의미하고 데이터의 형태를 만들어 낸다는 것은 '실제적인 형태'를 갖춘 데이터를 만든다는 뜻입니다.  

 

Ian Goodfellow 의 논문에 수록된 그림. 

 

위 그림에서 보듯이, 기존에 분포를 학습해서 데이터의 형태를 찾아나가고 이를 만들어 내는 것입니다. 

 

또한, 적대적 생성의 의미 측면에서는,

GAN의 핵심 아이디어로, 각각의 역할을 가진 두개의 모델로 진짜같은 가짜를 생성해주는 능력을 키워주는 것을 의미합니다. 

예를 들어, 위조범이 가짜 지폐를 만들어내고, 경찰은 가짜지폐를 찾아내는 역할을 합니다. 더욱 더 서로가 위조지폐를 정교하게 만들고, 만들어진 위조지폐를 정확히 찾아내는 것으로 서로 적대적으로 능력을 키워주고 있습니다. 

이런 아이디어에서부터 '적대적'이라는 용어가 붙게 되었습니다. 

 

GAN 모델을 가장 쉽게 설명할 수 있는 그림. [출처 :  https://files.slack.com/files-pri/T25783BPY-F9SHTP6F9/picture2.png?pub_secret=6821873e68]

 

2. GAN의 학습방법

 

Discriminator는 CNN판별기처럼 네트워크 구성할 수 있습니다. Disciminator로 진짜 이미지는 1, 그렇지 않은 것은 0으로 학습을 시키고, z라는 랜덤백터를 넣어 Genarative학습을 시킨 이미지가 이미 학습된 D에 들어갔을때, 오로지 진짜 이미지로 판별할 수 있도록, G를 학습시키는 것입니다. 

 

G는 random한 noise를 생성해내는 vector z를 noise input으로 받고 D가 판별해내는 real image를 output으로 하는 neural network unit을 생성합니다. 

GAN의 코어 모델은 D와 G두개이고, mnist이미지를 real image로 D한테 '진짜'임을학습시키고, 

vector z와 G에 의해 생성된 Fake Image가 가짜라고 학습을 시켜 총 두번의 학습을 거칩니다. 

이때, 따로 학습되는 것이 아니라 1번의 과정에서 real image와 fake image를 D의 x input으로 합쳐서 학습합니다. 

 

3. GAN을 이용해 영상 이미지를 만들고 AUC를 비교해보자. 

 

Real image만 사용했을때, AUC가 0.99정도 나왔고, 그 외에 GAN으로 만들어진 sample들로 학습했을때와, real과 gan을 적절히 섞어서 학습했을때 높은 AUC를 끌어낼 수 있었습니다. 

 

 

reference논문을 요약하자면, 

'데이터분석 > 딥러닝' 카테고리의 다른 글

CNN으로 개와 고양이 분류하기  (1) 2020.02.25
MNIST를 이용해 간단한 CNN만들기  (2) 2020.02.12
배치학습 vs 온라인학습  (0) 2020.02.12

1. Data Set

Kaggle의 개와 고양이 컬러 이미지를 아래 경로로 다운로드 받는다.

https://www.kaggle.com/tongpython/cat-and-dog

 

2. Data Argumentation

 

데이터 학습량을 늘려서 데이터가 변조되었을 때 모델이 이를 잘 캐치할 수 있도록 모델강화를 위해

데이터를 회전, 좌우반전, 이동, 역전등으로 이미지를 바꿀 것이다.

이때, 케라스에서 제공하는 이미지 제너레이터를 사용한다. 

 

tensorflow.keras.preprocessing.image에 ImageDataGenerator를 우선 로드하고

traning과 test set 폴더를 가지고 있는 cat-and-dog폴더까지 path를 지정해주자. 

 

데이터는 training set과 test set으로 나눠져 있으며 그 안에 고양이와 강아지 이미지가 각각 다른 파일에 존재한다. 

import os
from tensorflow.keras.preprocessing.image import ImageDataGenerator

rootPath = 'C:/Users/USER-PC/Documents/Kaggle_dataanalysis/cat-and-dog'

이제 ImageDataGenerator를 사용해서 이미지를 이리저리 굴려서 만들것이다. 

rescale, shear_range, zoom_range등의 옵션을 설정해줘서 해당 데이터 전처리를 하려고 한다. 

imageGenerator = ImageDataGenerator(rescale=1./255,
                                    rotation_range=20,
                                    width_shift_range=0.1,
                                    height_shift_range=0.1,
                                    brightness_range=[.2,.2],
                                    horizontal_flip=True,
                                    validation_split=.1)

rescale: 원래 이미지에 입력된 값만큼 이미지의 크기에 곱해서 조율함.

rotation_range: 지정된 각도 범위에서 임의로 원본 이미지를 회전.

width_shift_range: 지정된 수평방향 내에서 임의로 원본 이미지를 좌우로 이동.

height_shift_range: 지정된 수직방향 내에서 임의로 원본 이미지를 상하로 이동.

brightness_range: 이미지 밝기를 랜덤하게 주는 것.

horizontal_flip: 수평방향으로 뒤집기

validation_split: 주어진 데이터셋을 test와 training으로 나누는 비율.

 

*MNIST데이터를 사용할때는 손글씨이기 때문에 수평반전이 일어나면 안된다!

 

3. Data spliting

 

flow_from_directory함수를 사용해서 이미지 데이터들이 들어있는 directory 자체를 불러와서 training set과 validation set을 나눠준다. 

 

target_size option으로 읽어올 이미지의 크기를 정해주는데 우리는 64*64 사이즈로 읽어온다. 

subset은 위에서 validation_split으로 선정한 trainig과 validation의 비율만큰 이미지를 가지고 온다.

 

trainGen = imageGenerator.flow_from_directory(os.path.join(rootPath,'training_set'),
                                              target_size=(64,64),
                                              subset='training')

validationGen = imageGenerator.flow_from_directory(os.path.join(rootPath,'training_set'),
                                                  target_size=(64,64),
                                                  subset='validation')

 

4. Model setting

 

우리는 Sequential model을 사용해서 레이어를 선형으로 연결해서 구성할 것이다. 

Sequential은 첫번째레이어의 입력 형태에 대한 정보를 필요로 하지만 그 후에는 자동으로 형태를 추정하여 형태 정보를 갖고올 필요가 없다.

그리고 Add 메소드로 여러개의 레이어 추가가 가능하다.

 

우선 Sequential과 Layers를 불러온다. 

from tensorflow.keras.models import Sequential
from tensorflow.keras import layers

model = Sequential()

우리는 

Layers를 이용해 inputlayer에 우리가 읽어드려온 64*64 image 형태 정보를 준다.

Conv2D를 사용해 16개의 각각 3*3의 Convolution fiter를 적용해 줄 것이고, 

Maxpooling은 2*2사이즈로 수행 할 것이다.

Dropout할 비율을 0.3으로 정해주었다.

model.add(layers.ImputLayer(input_shape=(64,64,3)))
model.add(layers.Conv2D(16,(3,3),(1,1),'same',activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(rate=0.3))

model.add(layers.Conv2D(32, (3, 3), (1, 1), 'same', activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(rate=0.3))

model.add(layers.Conv2D(64, (3, 3), (1, 1), 'same', activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(rate=0.3))

 

컨볼루션이나 맥스풀링을 하면서 주요특징이 추출되고 이런 작업은 이차원에서 진행이 되지만 

fullyconnected layer로 넘겨주기 위해서는 2차원 자료를 1차원자료로 변환하는 작업이 필요한데, 이 때 사용하는 것이 flatten()이다. 

Dense로 512개의 유닛을 가진 fully connected layer를 모델에 추가하고 , 256개의 fully connected layer를 또 하나 추가한다. 2개의 출력 유닛을 가진 sigmoid 층을 연결한다. 

model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(2, activation='sigmoid'))

model.summary()

이미지 데이터 1차원으로 압축

5. Trainig Process

 

model의 compile함수를 사용해서 실제 학습을 시킬 것이다.

optimizeradam을 사용할 것이다.

 

머신러닝 딥러닝에서 흔히 사용하는 optimizer는 SGD, Momentum, NAG, Adagrad, RMSprop, Adam 등 여러가지가 있는데 우리는 Adam을 사용 할 것이다. 

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

Adam?

Adam은 Momentum과 RMSprop를 합친 경사하강법이다.

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

우리는 개와 고양이의 문제인 이분법이기 때문에 loss함수를 binary_crossentropy로 설정해주었다. 

 

Metric은 학습 평가 기준을 말한다. 

우리가 흔하게 아는 'accuracy'로 설정한 경우, 클래스분류 문제에서 categorical_accuracy()함수를 사용해서 정확도를 계산한다. 또한, 사용자 정의 매트릭을 만들어서 사용할 수도 있다. 

사용자 정의 매트릭스를 사용하기 위해서는 아래의 링크를 참고하면 좋을 것이다.

https://tykimos.github.io/2017/09/24/Custom_Metric/

 

클래스별로 학습과정 살펴보기

fit() 함수 로그에는 기본적으로 손실값과 정확도가 표시됩니다. 이진분류 모델에서는 정확도값 하나만 보더라도 학습이 제대로 되고 있는 지 알 수 있지만, 다중클래스분류 문제에서는 클래스별로 학습이 제대로 되고 있는 지 확인하기 위해서는 정확도값 하나로는 부족함이 많습니다. 이진분류 문제에서 클래스간 불균형이 있을 경우에도 정확도값 하나로는 판단할 수가 없습니다. 본 장에서는 학습 중에 클래스별로 정밀도(precision)와 재현율(recall)을 살펴볼

tykimos.github.io

다시 정리해보면 optimizer는 adam, loss는 binary_crossentropy, metrics는 'acc'를 코드에 반영할 것이다. 

model.compile(
    optimizer='adam',
    loss='binary_crossentropy', 
    metrics=['acc'],
)

케라스에서 모델을 학습시킬때는 fit()함수를 사용하는데, 제너레이터로 생성된 배치학습을 시킬 경우, fit_generator()를 사용한다. 

우선 training시킬 데이터를 넣어주고, epoch을 이용해 전체 훈련 데이터셋의 학습 반복 횟수를 지정한다.

steps_per_epoch을 이용해 한 epoch에 사용한 스텝수를 지정한다. 

validation_data에 만들어진 검증데이터셋 제너레이터를 넣어주고,

validation_steps를 이용해 epoch종료 때마다 검증 스텝수를 지정한다. 

epochs = 32
history = model.fit_generator(
    trainGen, 
    epochs=epochs,
    steps_per_epoch=trainGen.samples / epochs, 
    validation_data=validationGen,
    validation_steps=trainGen.samples / epochs,
)

 

6. Visualization and estimation the result

 

Keras에는 모델 학습 시 fit()함수를 많이 사용한다고 언급했습니다. 이 때, 리턴갑으로 학습 이력 정보를 리턴할 수 있다. 

각 epoch마다 loss(훈련 손실값), acc(훈련 정확도), val_loss(검증 손실값), val_acc(검증 정확도)들이 저장되어 있다. 

 

각 loss, acc, val_loss, val_acc를 불러와서 epoch별로 loss와 val_loss의 경향, acc와 val_acc의 경향을 알아보고자한다.

import matplotlib.pyplot as plt

def show_graph(history_dict):
    accuracy = history_dict['acc']
    val_accuracy = history_dict['val_acc']
    loss = history_dict['loss']
    val_loss = history_dict['val_loss']

    epochs = range(1, len(loss) + 1)
    
    plt.figure(figsize=(16, 1))
    
    plt.subplot(121)
    plt.subplots_adjust(top=2)
    plt.plot(epochs, accuracy, 'ro', label='Training accuracy')
    plt.plot(epochs, val_accuracy, 'r', label='Validation accuracy')
    plt.title('Trainging and validation accuracy and loss')
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy and Loss')

    plt.legend(loc='upper center', bbox_to_anchor=(0.5, -0.1),
              fancybox=True, shadow=True, ncol=5)
#     plt.legend(bbox_to_anchor=(1, -0.1))

    plt.subplot(122)
    plt.plot(epochs, loss, 'bo', label='Training loss')
    plt.plot(epochs, val_loss, 'b', label='Validation loss')
    plt.title('Training and validation loss')
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.legend(loc='upper center', bbox_to_anchor=(0.5, -0.1),
          fancybox=True, shadow=True, ncol=5)
#     plt.legend(bbox_to_anchor=(1, 0))

    plt.show()
show_graph(history.history)

 

 

test set도 generator를 이용해서 gestGenerator를 만든다. 이전에 trainig data를 1/255로 rescale해주었기 때문에, 

test set도 똑같이 rescale해준다. 하지만 다른 이미지 조정은 해주지 않는다. 

testGenerator = ImageDataGenerator(
    rescale=1./255
)

testGen = imageGenerator.flow_from_directory(
    os.path.join(rootPath, 'test_set'),
    target_size=(64, 64),
)

model.evaluate_generator(testGen)

7. Prediction

 

이제 모델로 예측을 해보려고 한다. 

class는 '고양이'와 '개' binary이다. 

from tensorflow.keras.preprocessing.image import array_to_img
import numpy as np

cls_index = ['고양이', '개']

imgs = testGen.next()
arr = imgs[0][0]
img = array_to_img(arr).resize((128, 128))
plt.imshow(img)
result = model.predict_classes(arr.reshape(1, 64, 64, 3))
print('예측: {}'.format(cls_index[result[0]]))
print('정답: {}'.format(cls_index[np.argmax(imgs[1][0])]))

 

요약

1. trainig 과 validation, test data로 분류

2. 새로운 이미지가 들어와도 학습할 수 있도록 image argumentation 수행 (이미지 좌우반전, 회전, 이동, 밝기조절 등 tensorflow.keras.imagegenerator 이용해서)

3. sequential과 layer를 이용해, input layer를 주고 convolutional layer 사이즈 입력, maxpooling 사이즈 입력, drop out 비율 입력

4. fullyconnected layer로 연결하기 전에 2차원으로 나온 특성을 1차원으로 압축

5. 가장 많이 사용되는 adam을 이용해 최적화 진행

6. 테스트

 

옵티마이저에 대한 적절하고 쉬운 설명: 

https://needjarvis.tistory.com/685

'데이터분석 > 딥러닝' 카테고리의 다른 글

GAN 모델이란?  (2) 2021.04.06
MNIST를 이용해 간단한 CNN만들기  (2) 2020.02.12
배치학습 vs 온라인학습  (0) 2020.02.12

tensorflow의 examples들 중 mnist를 이용해서 간단한 CNN을 구축해 볼 것이다.

우리는 0~9까지 이미지를 구별해 내는 CNN 모델을 구축할 것이다.

이미 만들어진 코드를 참고하여 수행과정에서 나올 수 있는 에러와 추가 설명을 부가하여 설명한다.

 

우선 첫번째로 데이터 셋을 불러온다.

 

1. MNIST 데이터 셋 불러오기

import tensorflow as tf
import tensorflow.examples.tutorials.mnist.input_data as input_data 

가끔 tensorflow의 example module을 불러올 때, tf를 정상적으로 다운로드 받음에도 불구하고

대표적인 'no moduled'에러 같은것이 발생한다.

이유는 tf 버전이 2.0이상이면 tutorial module을 자동으로 다운받지 않기 때문이다.  

그래서 1.14.0버전을 사용할 것을 권장한다.

 

mnist = input_data.read_data_sets('MNIST_data',one_hot=True, reshape=False)

MNIST_data인 data set을 읽어올때는 이미지 그대로 불러오기 위해 reshape=False(numpy에 있는 함수)로 지정해주고 

one_hot coding 형태로 읽어온다.

읽어온 이미지의 사이즈는 28*28*1 이다. 

 

 

One hot incoding은 특정 상수값으로 표현된 Y를 Matrix 형태로 바꿔주는 방법이다.

One hot incoding

 

2. CNN 모델 설정하기

CNN 모델 설정

좋은 모델을 만드는 것은 여러 방법이 있지만 가장 간단히 표현하기 위해

Convultion layer를 2번 거치고 Fully connected Layer로 0~9사이의 값을 판별할 것 이다.

 

CNN의 특징은 일반 뉴럴네트워크를 수행하기 이전에 이미지로부터 Feature를 먼저 뽑아내어서 이를 전달해

NN를 수행하는 것 이다.

Convolution을 수행하는 계층은 크게 두가지로 구성되어져 있다.

(1) Convolution layer는 이미지로부터 특징을 추출하는 Filter 기능을 한다. 

(2) 필터값을 비선형값으로 바꿔주는 Activation 함수로 이루어진다.

 

일단 이미지를 4부분으로 쪼개어서 28*28*1의 이미지를 14*14*4의 형태로만들어 주고 

이를 한번 더 수행해 7*7*8의 형태로 바꾸어 줄 것 이다.

 

 

X= tf.placeholder(tf.float32, shape=[None,28,28,1])
Y_Label = tf.placeholder(tf.float32, shape=[None,10])

입력 데이터는 학습을 위해 계속해서 업데이트 해줘야 하고 

Y_Label 또한 미리 정한 결과를 계속 직접 넣어줄 것이다. 

 

tensorflow에서 데이터 입력 받는 방법중에서 상수와 변수를 입력받는 방법도 있지만

데이터의 형태만 지정하고 실제 데이터는 실행단계에서 입력받을 수 있도록 해주는 방법이 있다.

그것이 placeholder()함수인데

사용법은 아래와 같다.

 

 

placeholder 사용법

데이터의 타입을 무조건 지정해주고 입력데이터의 형태를 주어야한다.

 

우리의 예제에서는 shape이 [None, 28,28,1]의 형태를 띄고 있는데

맨 앞의 None은 앞으로 우리가 배치수행을 할 것이기 때문에 None으로 배치수행할만큼의 데이터 공간을 미리 확보해 주는 것이다.

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

* 배치수행이란? 우리가 일반적으로 작업을 수행할때 모두 데이터를 불러놓고 수행하는 방식을 말한다.

온라인 수행은 필요한 데이터를 매번 불러오는 것인데 실제 데이터분석필드에서는 데이터를 불러오기만 해도 

메모리를 모두 할당하고 있는 경우가 많기 떄문에 온라인 수행이 당연해졌다.

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

 

3. Convolution layer 생성

 

Convolution + Relu + Maxpooling을 거쳐 28*28*1을 14*14*4의 형태로 변형할 것이다.

 

convolution 후 relu activation 수행, maxpooling을 마지막으로 수행

 

우선 kernel과 bias값을 생성하고 convolution lyaer, activation function, pooling을 수행하는 코드를 작성해 볼 것이다.

Kernel1 = tf.Variable(tf.truncated_normal(shape=[4,4,1,4],stddev=0.1))

kernel은 filter와 같은데 filter는 이미지 특징을 찾아내기 위한 공용 파라메터이다.

일반적으로 4*4나 3*3과 같은 정사각 행렬로 정의하고 

지정된 간격대로 순회하며 채널별로 합성곱을 하는 과정을 convolution이라고 한다.

그리고 convolution을 적용한 input image의 결과물을 Feature Map 또는 activation map이라고 부른다. 

filter를 이용한 convolution과정

filter가 되어줄 variable을 위와같이 설정한 뒤,  kernel을 사용해 convolution한 뒤 같은 사이즈만큼 더해주기 위한 변수를 만들어야한다.

4장을 만들어 주었기 때문에 사이즈는 4로 설정해주어야 한다.

Bias1 = tf.Variable(tf.truncated_normal(shape=[4],stddev=0.1))

 이제 실제 Convolution과정을 수행해보아야 하는데 

아래의 코드를 수행해준다.

Conv1 = tf.nn.conv2d(X, Kernel1, strides = [1,1,1,1],padding='SAME')+ Bias1

입력된 이미지 X에 만들어준 필터 Kernel1을 Convolution 곱해주는데 

filter가 이동하는 간격을 의미한는 stride를 설정하고, 데이터 손실이 얼마나 있을지 고려해 padding을 'SAME'으로 한다. stride는 주로 중앙에 2값을 이용한다. 예를 들어, 2칸씩 이동하는게 목적이라면

stride =[1,2,2,1]의 형태로 준다.

특히 padding을 하는 이유는, 실제 원본의 사이즈 (예를 들면, 5*5)보다 filter를 적용하고 나서 이미지가 

3*3으로 줄어들 수가 있는데 이떄 데이터 손실이 나기 때문에 이부분을 보정해주기 위해서 사용된다.

원래 이미지 주변의 0 값을 넣어주어 입력값의 크기를 인위적으로 키워서 결과값이 작아지는 것을 막는다. 

또한 오버피팅도 방지하는데 원본 데이터에 0값을 넣어 원래의 특성을 희석시켜서 

머신러닝이 트레이닝값에만 정확히 맞아들어가는 것을 방지한다.

Activation1 = tf.nn.relu(Conv1)

convolution을 하고나면 feature맵은 정량적인 값을 갖게 되는데 이를 특징이 '있다 없다'로 표현하기 위해 비선형화를 시키려고 한다. 그것이 activation 함수이다. 

activation함수로 여러가지를 쓰는데 주로 relu함수를 사용한다. 이유는 backpropagation이 제대로 작동하지 않아 에러가 희석되는 현상 ( gradient vanishing)이 일어나기 때문이다. 

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

 

4. Fully connected layer 만들기

 

이제 Convolution + Activation Function + Pooling을 모두 수행하여 하나의 layer를 만들고 

우리가 목표했던 2 convolution layer를 거치기 위해 동일한 layer하나를 더 만들어 준다. 

Kernel2 = tf.Variable(tf.truncated_normal(shape=[4,4,4,8],stddev=0.1))
Bias2 = tf.Variable(tf.truncated_normal(shape=[8],stddev=0.1))
Conv2 = tf.nn.conv2d(Pool1, Kernel2, strides = [1,1,1,1],padding='SAME')+ Bias2
Activation2 = tf.nn.relu(Conv2)
Pool2 =tf.nn.max_pool(Activation2, ksize =[1,2,2,1],strides = [1,2,2,1], padding='SAME')

 

마지막으로 convoultion과정을 거친 layer를 기존의 뉴럴네트워크에 넣어 분류한다. 실제로 어떤 이미지인지 판별해주는 구간을 만드는 것이다.

W1 = tf.Variable(tf.truncated_normal(shape=[8*7*7,10]))
B1 = tf.Variable(tf.truncated_normal(shape=[10]))
Pool2_flat = tf.reshape(Pool2,[-1,8*7*7])
OutputLayer = tf.matmul(Pool2_flat,W1)+B1

*matmul 함수: 삼차원 텐서 사이의 행렬곱을 수행해주는 함수 

 

W1과 B1은 일반적인 머신러닝에서 볼 수 있는 단순선형관계를 위한 변수들이다. 

W1d은 8*8*7을 10개 받는 variable이며, B1은 output을 10개로 받기 위해 10개의 Bias를 생성한다.

우선 OuputLayer를 보면 선형관계식으로 나타내는 것을 볼 수있다. 이는 일반적인 머신러닝과 같이 

가장 단순한 선형관계로 설명하려는 목적을 갖고 있기 때문에 '입력값 * W1 + B1'의 형태를 띄는 것이다.

 

 

CNN의 최종모델

위 그림은 우리가 수행한 전체적인 모델 구축과정인데 CNN의 가장 큰 특징인 Dropout Layer를 짚고 넘어가도록 하겠다.

* Dropout Layer란 Fully-connected Layer와 Softmax Function사이의 계층으로 오버피팅을 막기위해

뉴럴 네트워크가 학습중일때 랜덤하게 뉴런을 꺼서 학습을 방해함으로써 학습이 학습용 데이터에 치우치는 현상을 막는다.

 

5. Loss function과 Optimizer설정

 

모델을 학습시킨 후 결과값이 실제값과 얼마나 차이가 나는지 확인하기 위하여 Loss값을 계산해 줍니다.

Loss = tf.reduce_mean(tf.nn.sortmax_cross_entropy_with_logits(labels=Y_label, logits=OupputLayer))

reduce_mean: 열의 평균을 구해주는 함수

softmax_cross_entropy_with_logits: multiclassification에서 사용되는 softmax와 cross_entropy가 내장된 함수, labels= 실제값, logits은 모델의 output값을 주면 된다.

 

*softmax는 multiclassification를 할때 입력받은 값을 0~1사이의 값으로 바꿔주고 총합이 1이 되도록 만드는 함수이다.

분류하고 싶은 class개수만큼 만들어지고 가장 큰 출력값을 받은 것이 확률이 가장 크다.

*cross_entropy는 분류모델에서 사용되는 loss function의 한 종류이다.

 

train_step = tf.train.AdamOptimizer(0.005).minimize(Loss)

Loss함수를 정의하고 Optimization 과정을 거쳐 Loss를 최소화 시켜주어 우리 모델을 최적화할 것이다.

correct_prediction = tf.equal(tf.argmax(OutputLayer,1),tf.argmax(Y_Label,1))
accuracy=tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

그리고 실제 값과 모델이 학습한 값이 동일한지 correct_prediction으로 해주고, 

accuracy에서는 맞거나 틀린것들에 대한 평균을 내준다.

 

6. Run

with tf.Session() as sess:
    print('start....')
    sess.run(tf.global_variables_initializer())
    for i in range(10000):
        trainingData, Y = mnist.train.next_batch(64)
        sess.run(train_step, feed_dict={X:trainingData, Y_Label:Y})
        if i%100:
            print(sess.run(accuracy, feed_dict={X:mnist.test.images, Y_Label:mnist.test.labels}))

C에서 이루어지는 연산이므로 Sess를 얻어와서 진행을 하고 변수들을 tf.global_variables_initializer()을 사용해서 꼭 초기화해주어야 합니다. 

 

위의 코드는 10000번의 학습으로 64개의 배치크기만큼 가져오고 100번마다 test데이터셋을 통해 정확도를 확인한 것입니다. 

 

 

 

 

출처페이지는 

https://coderkoo.tistory.com/13

 

간단한 CNN(Convolutional neural network) 만들어보기

텐서플로우로 간단한 CNN(Convolutional neural network) 만들어보기 이번 글에서는 MNIST 데이터 셋을 이용해서 텐서플로우에서 CNN을 구성해봅니다. 즉, MNIST 데이터셋을 읽어와서 필기체숫자가 0~9 중 무엇인..

coderkoo.tistory.com

 

'데이터분석 > 딥러닝' 카테고리의 다른 글

GAN 모델이란?  (2) 2021.04.06
CNN으로 개와 고양이 분류하기  (1) 2020.02.25
배치학습 vs 온라인학습  (0) 2020.02.12

일반적으로 대중화된, 아이리스 데이터 등으로 데스크탑에서 손쉽게 돌려볼 수 있는 머신러닝 자료들은 데이터를 통째로 IDE로 불러들인 다음 메모리상에 올려두고 작업하는 방식이었을 것이다. 모델을 학습함에 있어서도 모든 트레이닝 데이터셋의 결과값을 한번에 구한 뒤, 데이터셋과 쌍이 맞는 레이블과의 차이를 구해서 비용함수를 한번에 개선하는 방식의 학습을 n-iterative 하게 진행하였을 것이다. 하지만 머신러닝을 진행함에 있어서 데이터의 크기는 언제든지 늘어나게 된다. 아마 실전의 대부분은, 한 개의 데스크탑에서 불러올 수 없는 양의 데이터가 대부분일 것이다. 이런 경우 R 혹은 Python등의 툴로는 데이터를 메모리에 올려놓고 한번에 처리하기가 힘들어진다. 그렇게 되면 모델을 학습하는 경우에도 트레이닝 데이터를 쪼개서 여러 번 넣어야 하고, 프로그래머 식으로 말하자면 전자는 for loop를 한번 돌지만 후자는 '트레이닝 데이터들' 이라는 loop가 하나 더 생기는 것이라고 할 수 있다. 전자의 경우를 일괄 처리 방식, 일명 batch 방식이라고 한다. 후자는 online processing 혹은 mini batch라고 한다. 딥러닝의 영역으로 들어가게 된다면, 데이터의 양이 기하급수적으로 증가하기 때문에(딥러닝까지 가지 않더라도) mini batch 시스템을 이용하여 모델을 학습하는 것은 거의 필수적인 일이 되어버렸다.

'데이터분석 > 딥러닝' 카테고리의 다른 글

GAN 모델이란?  (2) 2021.04.06
CNN으로 개와 고양이 분류하기  (1) 2020.02.25
MNIST를 이용해 간단한 CNN만들기  (2) 2020.02.12

+ Recent posts