본문 바로가기

유니티 ML Agents/머신러닝과 강화학습 코딩

7. 텐서플로우 심층 신경망

네트워크 구성 및 손실 함수 정의


단일 신경망은 성능이 좋지 않기 때문에 사용되지 않는다. 레이어가 여러 개 있는 신경망을 심층 신경망이라 하며 심층 신경망부터 딥러닝이라 한다.


단일 신경망 코드를 심층 신경망으로 만들기 위해서는 다른 부분은 모두 동일하고 레이어 여러 개 추가하는 몇 줄의 코드만 입력하면 된다. 테스트를 위해 하나의 레이어만 추가하도록 하겠다.


지금 만들고자 하는 심층 신경망은 2개의 레이어에 각각 10개의 노드를 가지고 있는 신경망이다.


(1) 레이어가 두 개 이기 때문에 가중치와 편향을 2개씩 생성했다. 심층 신경망은 단일 신경망 보다는 성능이 좋기 때문에 초기 설정 값에 영향을 덜 받으므로 random_uniform 함수를 사용해 변수를 초기화 했다.


(2) 이제 레이저를 선언할 차례이다. 첫번째 레이어는 두번째 레이어의 입력 값이 된다. 따라서 L2를 선언할 때 L1을 입력 값으로 사용한다.


(3) 마지막으로 L2 함수의 결과값을 softmax로 변환해서 출력하는 모델을 생성한다.


학습결과


모델을 학습시키고 예측 값과 결과 값을 비교해보자. 심층 신경망 모델의 정확도는 66% 정도 나왔다. 단순히 레이어와 노드만 추가해서 단일 신경망 모델에 10% 정도의 성능 향상을 가져왔다.


지금 살펴본 심층 신경망의 경우 레이어와 노드의 숫자가 비교적 적지만 데이터가 충분히 있는 상황에서는 컴퓨팅 파워가 지원하는 범위에서 레이어와 노드의 개수를 늘려 성능향상을 도모할 수 있다.


이제 심층 신경망을 강화학습에 적용한 DQN(Deep Q Network) 코드를 만들어보자.



import tensorflow as tf
import pandas as pd
from sklearn.datasets import make_classification
X, y = make_classification(n_features=2, n_informative=2, n_redundant=0, n_clusters_per_class=1, random_state=2)
df = pd.DataFrame(dict(x1=X[:,0], x2=X[:,1], y=y))
df.plot.scatter(x='x1', y='x2', c=y, s=100, edgecolor="k", linewidth=2)
x_array = df[['x1','x2']].values
y_array = df[['y']].values
X = tf.placeholder(tf.float32, name="X")
Y = tf.placeholder(tf.float32, name="Y")
w1 = tf.Variable(tf.random_uniform([2,10], -1.0, 1.0))
a1 = tf.Variable(tf.random_uniform([10], -1.0, 1.0), name='a1')
w2 = tf.Variable(tf.random_uniform([10,2], -1.0, 1.0))
a2 = tf.Variable(tf.random_uniform([2], -1.0, 1.0), name='a2')
L1 = tf.add(tf.matmul(X, w1), a1)
L1 = tf.nn.relu(L1)
L2 = tf.add(tf.matmul(L1, w2), a2)
L2 = tf.nn.relu(L2 )
model = tf.nn.softmax(L2)
cost = tf.reduce_mean(-tf.reduce_sum(Y*tf.log(model), axis=1))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.00001)
trainnig = optimizer.minimize(cost)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
for step in range(80000):
sess.run(trainnig, feed_dict={X: x_array, Y: y_array})
none, cost_val = sess.run([trainnig, cost], feed_dict={X: x_array, Y: y_array})
if(step % 5000 == 0):
print(step, cost_val)
prediction = tf.argmax(model, axis=1)
result = sess.run(prediction, feed_dict={X: x_array})
print("예측값:", result)
sess.close()