본문 바로가기

코딩/텐서플로우

비전공자의 코딩 독학 - 파이썬&텐서플로우(6) <예제2 신경망>

반응형

안녕하세요.

오늘의 파이썬 코딩 독학 주제는 신경망 예제 풀이입니다.

 

 

1. 추가로 필요한 라이브러리

오늘은 텐서플로우 외에 추가로 numpy라는 라이브러리가 필요합니다.

numpy는 행렬형태의 데이터를 조작, 연산하는데 필수적으로 쓰이는 라이브러리입니다.

 

 

2. 전체 소스코드

import tensorflow as tf
import numpy as np

#자료형 설정 ex) [여성, 남성]
x_data = np.array([
    [1, 0], 
    [0, 0], 
    [1, 1], 
    [0, 1], 
    [1, 1], 
    [0, 1]])
#자료형 설정 ex) [유아기, 청년기, 장년기]    
y_data = np.array([
    [0, 0, 0], 
    [0, 0, 1], 
    [0, 0, 0], 
    [1, 0, 0],
    [1, 0, 0],
    [0, 0, 1]])

#플레이스홀더 설정
X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)

#가중치와 편향값 설정
W = tf.Variable(tf.random_uniform([2, 3], -1., 1.))
b = tf.Variable(tf.zeros([3]))

#활성화 함수 설정
Relu = tf.add(tf.matmul(X, W), b)
Relu = tf.nn.relu(Relu)

#출력값 다듬기
model = tf.nn.softmax(Relu)

#비용함수 설정
cost = tf.reduce_mean(-tf.reduce_sum(Y * tf.log(model), axis = 1))

#경사하강법으로 최적화
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
train_op = optimizer.minimize(cost)

#세션 초기화
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

#학습을 200번 진행
for step in range(200):
    sess.run(train_op, feed_dict={X: x_data, Y: y_data})

    # 학습 50번당 1번씩 손실값을 출력
    if (step + 1) % 50 == 0:
        print(step + 1, sess.run(cost, feed_dict={X: x_data, Y: y_data}))

#학습결과 확인
predict = tf.argmax(model, axis=1)
actval = tf.argmax(Y, axis=1)
print("예상:", sess.run(predict, feed_dict={X: x_data}))
print("실제:", sess.run(actval, feed_dict={Y: y_data}))

#정확도 출력
corr = tf.equal(predict, actval)
accu = tf.reduce_mean(tf.cast(corr, tf.float32))
print("Accuracy: %.2f" % sess.run(accu * 100, feed_dict={X: x_data, Y: y_data}))

 

 

2. 소스코드의 목적

해당 소스코드는 성별에 따라

유아기인지 청년기인지 장년기인지

예측해주는 신경망을 만드는 예제입니다.

 

ReLU함수를 사용하여 학습을 진행하며

역시 최적의 W와 b값을 찾아주는게 목표입니다.

 

 

3. 데이터 설정방식

우선 성별을 구분하는 특징데이터를 구성해줍니다.

여성, 남성의 순서로 해당 성별이면 1의 값을 가집니다.

예를 들어 [0, 0] 형태의 데이터는 여성도, 남성도 아니라는 뜻이며

[0, 1] 형태의 데이터는 남성이라는 뜻입니다.

 

다음으로 각 데이터가 어떤 연령층인지를 나타내는 분류데이터를 구성해줍니다.

순서대로 유아층, 청년층, 장년층을 의미하며

각 연령층에 해당하면 1, 해당하지 않으면 0의 값을 가집니다.

예를 들면 [1, 0, 0] 형태의 데이터는 유아층에 속한다는 뜻이고

[0, 0, 1] 형태의 데이터는 장년층이라는 뜻입니다.

 

이와 같은 데이터 형태를 원 핫 인코딩(One Hot Encoding)이라고 부릅니다.

원 핫 인코딩이란 데이터가 가질 수 있는 값들을 일렬로 배열한 후

거기서 표현하려는 값이 속한 인덱스의 원소만 1로 표기하고,

나머지 원소는 모두 0으로 표현하는 형태입니다.

 

 

4. 소스코드 설명

(1) 필요한 라이브러리를 탑재합니다.

import tensorflow as tf
import numpy as np

 

 

(2) 학습을 위한 데이터를 구성합니다.

x_data = np.array([
    [0, 0], 
    [1, 0], 
    [1, 1], 
    [0, 0], 
    [0, 0], 
    [0, 1]])
y_data = np.array([
    [1, 0, 0],
    [0, 1, 0],
    [0, 0, 1],
    [1, 0, 0],
    [1, 0, 0],
    [0, 0, 1]])

 

 

(3) 플레이스 홀더를 생성합니다.

X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)

 

 

(4) 임의의 W와 b값을 입력받습니다.

W = tf.Variable(tf.random_uniform([2, 3], -1., 1.))
b = tf.Variable(tf.zeros([3]))

여기서 tf.zeros(shape, dtype, name)함수는 모든 원소의 값이 0인 텐서를 생성합니다.

본 코드에서는 3개의 요소를 가진 변수로 설정해주었습니다.

 

 

(5) 활성화 함수를 구성해줍니다.

Relu = tf.add(tf.matmul(X, W), b)
Relu = tf.nn.relu(Relu)

여기서는 ReLU함수를 활성화함수로 사용합니다

 

 

(6) 신경망을 통해 출력된 값을 다듬어줍니다.

model = tf.nn.softmax(Relu)

model 변수에는 softmax함수를 사용하여 다듬어진 출력값(예측값)을 대입해줍니다.

여기서 tf.nn.softmax()함수는 배열 내의 결과값들의 전체 합이 1이 되도록 만들어주는 함수입니다.

 

 

(7) 비용함수를 설정합니다.

cost = tf.reduce_mean(-tf.reduce_sum(Y * tf.log(model), axis = 1))

비용함수는 교차엔트로피(Cross Entropy) 함수를 사용해줍니다.

교차엔트로피 함수는 예측값과 실제값 사이의 확률 분포 차이를 계산해주는 함수이며

계산 순서는 다음과 같습니다.

(a) tf.log()함수를 이용해 model 값에 로그를 취한 후 Y를 곱해줍니다.

(b) reduce_sum() 함수를 이용해 각 데이터의 행별로 값을 더해줍니다.

(c) reduce_mean() 함수를 이용해 배열 안 값의 평균을 내줍니다.

이렇게 계산해주면 교차엔트로피 값이 나오게 됩니다.

 

위에 쓰인 redue_ 함수들은 텐서의 차원을 줄여주는 함수입니다.

언더바(_)뒤의 단어는 차원을 축소하는 방법을 의미하며

축(Axis)값에 1을 입력하면 주어진 텐서의 첫번째 차원의 값들을 모두 더해

그 차원을 없애준다는 뜻입니다.

 

 

(8) 경사하강법으로 최적화를 진행합니다.

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
train_op = optimizer.minimize(cost)

 

 

(9) 세션을 초기화시킵니다.

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

 

 

(10) 학습 횟수를 지정해줍니다.

for step in range(200):
    sess.run(train_op, feed_dict={X: x_data, Y: y_data})

    if (step + 1) % 50 == 0:
        print(step + 1, sess.run(cost, feed_dict={X: x_data, Y: y_data}))

여기서는 200번의 학습을 진행하며

50번의 학습마다 손실값을 출력합니다.

 

 

(11) 학습결과를 출력합니다.

predict = tf.argmax(model, axis=1)
actval = tf.argmax(Y, axis=1)
print("예상:", sess.run(predict, feed_dict={X: x_data}))
print("실제:", sess.run(actval, feed_dict={Y: y_data}))

여기서 tf.argmax() 함수는 원 핫 인코딩 형태의 데이터에 최적화된 함수인데,

지정된 배열에서 가장 큰 값의 인덱스를 반환하는 함수입니다.

축(Axis)값에 0을 주면 1차원 배열에 대해 함수를 적용하며

여기서는 1을 주었으므로 2차원 배열에 대해 적용해줍니다.

 

 

(12) 정확도를 출력합니다.

corr = tf.equal(predict, actval)
accu = tf.reduce_mean(tf.cast(corr, tf.float32))
print("Accuracy: %.2f" % sess.run(accu * 100, feed_dict={X: x_data, Y: y_data}))

tf.equal() 함수는 두 값이 동일하면 True, 다르면 False를 반환하는 함수입니다.

tf.cast() 함수는 True/False 형태의 값을 1과 0으로 바꾸어주는 함수입니다.

 

 

5. 결과분석

코드를 실행 시

아래와 같은 결과가 나타납니다.

 

 

 

오늘은 간단한 신경망 예제를 알아보았습니다.

 

반응형