반응형


+ Tensorflow로 XOR  학습을 구현하기


XOR 학습을 수동으로 계산하지 않고, tensorflow의 api를 사용하면 심플해진다.

복잡한 네트웍도 쉽게 구현이 가능하다.


노드의 개수 및 레이어를 2-4-1 로 구성.

입력층에 노드 2개(feature 개수. x1, x2)

은닉층에는 4개 

출력층은 1개의 노드. (Y)

back-propagation을 위한 골치 아픈 작업(미분)들을 할 필요없이 api 하나로 학습 가능! activation function도 원하는대로 쉽게 변경하고, 학습 알고리즘은 쉽게 바꿀 수 있다.


#!/usr/bin/env python3

# -*- coding: utf-8 -*-

"""

Created on Tue May 23 14:56:53 2017


@author: crazyj

"""



import numpy as np

import tensorflow as tf


# trainint set

X_train = np.array( [[0,0], [0,1], [1,0], [1,1]])

T_train = np.array( [[0], [1], [1], [0]] )



# placeholder

X = tf.placeholder(tf.float32, [None, 2])

T = tf.placeholder(tf.float32, [None, 1])


# variable

W1 = tf.Variable(tf.truncated_normal([2,4]))

b1 = tf.Variable(tf.zeros([4]))

W2 = tf.Variable(tf.truncated_normal([4,1]))

b2 = tf.Variable(tf.zeros([1]), dtype=tf.float32)


# model

A1 = tf.matmul(X, W1)+b1

Z1 = tf.sigmoid(A1)

A2 = tf.matmul(Z1, W2)+b2

Z2 = tf.sigmoid(A2)


learn_rate = 0.1

Cost = tf.reduce_mean(tf.reduce_sum(tf.square(Z2-T), 1))

train = tf.train.GradientDescentOptimizer(learn_rate).minimize(Cost)


predict = Z2


sess = tf.Session()

sess.run(tf.global_variables_initializer())

for i in range(5000):

    _train, _Cost = sess.run([train, Cost], feed_dict={X:X_train, T:T_train})

    print( "cost=", _Cost)

    

_predict = sess.run([predict], feed_dict={X:X_train})

print("predict=", _predict)

print("result=", np.array(np.array(_predict)>=0.5, np.int))




결과

cost= 0.021748

cost= 0.0217359

cost= 0.0217239

predict= [array([[ 0.10571096],

       [ 0.86153752],

       [ 0.84178925],

       [ 0.17739831]], dtype=float32)]

result= [[[0]

  [1]

  [1]

  [0]]]


+ 코드 설명

# trainint set

X_train = np.array( [[0,0], [0,1], [1,0], [1,1]])

T_train = np.array( [[0], [1], [1], [0]] )

훈련 데이터는 당연히 xor의 입력 조합에 따른 결과를 훈련시킨다. (0,0) -> 0 , (0,1) -> 1 , (1,0) -> 1 , (1,1)->1


# placeholder

X = tf.placeholder(tf.float32, [None, 2])

T = tf.placeholder(tf.float32, [None, 1])

플레이스 홀더는 텐서플로우내에서 돌아갈 입출력 변수들이라고 보면 된다. 노드에서 변수가 되는 것을 X 입력층은 (?,2) 매트릭스 크기(로우는 임의의 개수, 컬럼은 2개(x1,x2)), 출력층 T는 (n,1) 매트릭스 형태로 선언한다.


# variable

W1 = tf.Variable(tf.truncated_normal([2,4]))

b1 = tf.Variable(tf.zeros([4]))

W2 = tf.Variable(tf.truncated_normal([4,1]))

b2 = tf.Variable(tf.zeros([1]), dtype=tf.float32)

텐서 플로우 변수들을 정의한다. 이것은 그래프에 구성될 노드들의 변수의 형태를 정의한다.

네트웍을 2-4-1로 구성할 것이므로 여기에 따른 weight를 담을 변수와 bias 변수의 형태는 다음과 같다.

2개 노드는 placeholder로 X이고, 2-4연결되는 W(웨이트)는 2행(입력노드개수) 4열(출력노드개수) 매트릭스이다. bias는 4개(출력노드개수)이다.

4-1로 연결되는 파트의 W는 4x1 이렇게 b는 1개 이렇게 구성한다. 초기값들은 랜덤하게 채워준다. bias는 0으로 초기화해준다.


# model

A1 = tf.matmul(X, W1)+b1

Z1 = tf.sigmoid(A1)

A2 = tf.matmul(Z1, W2)+b2

Z2 = tf.sigmoid(A2)

이제 빠진 히든 노드들과 출력층 노드들을 구성한다.

2-4-1네트웍에서 2개는 X, 4개는 A1으로 정하고,

A1 = X x W1 + b1 으로 정의한다.

Z1=은 A1에 활성화함수 sigmoid를 적용한다.


A2=Z1 x W2 + b2로 정의한다. 앞 노드의 출력 결과에 weighted sum이다.

Z2 = A2에 sigmoid를 적용한 것으로 최종 output이다.


learn_rate = 0.1

Cost = tf.reduce_mean(tf.reduce_sum(tf.square(Z2-T), 1))

train = tf.train.GradientDescentOptimizer(learn_rate).minimize(Cost)

predict = Z2

이제 학습방식을 정한다.
cost function은 오차 제곱법을 쓰고, 학습방식은 gradient descent를 사용하여 훈련 그래프를 만든다.
예측값은 최종 노드 출력인 Z2가 된다.


sess = tf.Session()

sess.run(tf.global_variables_initializer())

for i in range(5000):

    _train, _Cost = sess.run([train, Cost], feed_dict={X:X_train, T:T_train})

    print( "cost=", _Cost)

텐서플로우로 학습을 돌린다. 세션을 만들고, 초기화하여 5000번 학습한다. 그래프의 꼭지인 train을 집어 넣고, feed_dict로 플레이스 홀더 X, T에 훈련 데이터를 넣는다.  학습1회마다 cost값을 출력해 본다. 


_predict = sess.run([predict], feed_dict={X:X_train})
학습 완료후, 학습이 잘 되었는지  입력값 X_train을 넣고 출력값을 생성한다.

print("result=", np.array(np.array(_predict)>=0.5, np.int))

최종 결과로 시그모이드 함수에서 0.5이상이면 1로 미만이면 0으로 출력하여 binary 분류를 한다.





+ Recent posts