신경망 구조
## Multi Layer Neural Networks
Back Propagation에 필요한 수식
Tensorflow
텐서의 흐름 => 벡터 데이터의 흐름
Tensorflow는 벡터 데이터가 흘러 그 데이터를 처리하고 인간의 뇌처럼 작동하는 AI기술인 Deep Learning의 Framework이다.
Tensorflow 작동 방식
텐서플로우는 기본적으로 그래프 기반으로 작동되는 프레임워크 이다.
출처: tensorflow
1 2 3 4 5 6 7 8 9 10 11
| 1. 그래프 생성 2. 그래프 실행
그래프 생성 단계에서는 연산 과정을 그래프 형태로 표현한다. 밑에 그림에서 볼 수 있듯이 Computational Graph는 Node와 Edge로 이루어진 자료 구조이다.
Node에는 Operator, Variable, Constant등을 정의하고, node간의 연결인 edge를 통해 tensor data를 주고받으면서 계산을 할 수 있도록 프로그래밍 한다.
그래프 생성이 끝나면 Session 객체를 통해 생성한 그래프를 실행 할 수 있다.
|
출처: gitbooks
Tensorflow로 구현하기
Tensorflow import
Tensorflow를 import하면 그 시점에 비어 있는 기본 graph가 만들어지며,
앞으로 작성될 node들은 이 기본 graph에 자동으로 연결된다
Data set
x는 입력 데이터, y는 결과 데이터
총 데이터 갯수 4개
input 값 1개, output 값 1개
1 2
| x_data = [1,2,3,4] y_data = [5,8,11,14]
|
Tensor for Data set
placeholder는 데이터를 입력받는 비어있는 변수
그래프를 구성하고 그래프가 실행되는 시점에 입력 데이터를 넣어주는데 활용된다
그리고 placeholder는 shape인수를 유동적으로 지정할 수 있다
1 2 3 4 5
| x = tf.placeholder(tf.float32) y = tf.placeholder(tf.float32)
type(x) : tensorflow.python.framework.ops.Tensor
|
Weight & Bias
학습 과정에서 모델의 매개변수로 가중치, 편향치가 입력되는데
이 가중치, 편향치가 최적화되기 위해 Variable이라는 객체를 사용한다
가중치가 최적화되는 반복 과정에서 현재의 변수가 다음 반복 과정에 영향을 줄 수
있어야 하기 때문에 Variable 객체를 사용한다
1 2
| W = tf.Variable([1], dtype=tf.float32) b = tf.Variable([1], dtype=tf.float32)
|
Variable은 학습을 통해 변화하는 배열 값을 저장하기 위한 operation.
출처: https://webofthink.tistory.com/68 [Web of Think]**
Placeholder vs Variable
둘다 변수이긴 변수 인데 variable은 연산이 수행되면서 값이 변하고
다음 연산에 그 값을 유지하고 있어야 하기 때문에 정말 ‘변하는 수’ 같은 느낌이고
placeholder는 데이터를 담을 공간을 의미하는 변수인거 같다 (확실하지 않음..)
1
1 2 3 4 5 6 7 8 9 10 11 12 13
| set(dir(W)) & set(dir(x))
: {'device', 'dtype', 'eval', 'get_shape', 'graph', 'name', 'op', 'set_shape', 'shape'}
|
2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| set(dir(W)) - set(dir(x))
: {'SaveSliceInfo', 'assign', 'assign_add', 'assign_sub', 'batch_scatter_update', 'constraint', 'count_up_to', 'from_proto', 'initial_value', 'initialized_value', 'initializer', 'load', 'read_value', 'scatter_add', 'scatter_nd_add', 'scatter_nd_sub', 'scatter_nd_update', 'scatter_sub', 'scatter_update', 'to_proto', 'trainable', 'value'}
|
3
1 2 3 4 5
| set(dir(x)) - set(dir(W))
: {'OVERLOADABLE_OPERATORS', 'consumers', 'value_index'}
|
hypothesis
가설값(추측값) = 가중치 X 입력값 + 편향치
가중치를 찾기 위한 함수 혹은 모델
cost function
(추측값 - 정답)의 제곱의 평균, 즉 내가 추측한 값과 정답 사이의 상관관계를 보기위한 함수
이 비용 함수의 목표는 추측값과 정답의 오차를 줄이는 데에 있다
앞으로 이 비용 함수의 편미분 값은 가중치 조정 알고리즘에 사용된다
1
| cost = tf.reduce_mean(tf.square(hypothesis-y))
|
optimizer
경사하강법을 사용하기 위한 알고리즘
이 경사하강법은 비용 함수에서 오차를 최소로 만들기 위해 사용하는 편미분 알고리즘
1 2 3
| optimizer = tf.train.GradientDescentOptimizer(learning_rate = 0.1)
|
가중치 조절 알고리즘
cost function이 인자로 전달되고 optimizer의 minimize함수를 통해 구현된다
이 알고리즘의 목표는 오차가 최소가 되는 지점의 weight와 bias를 구하는 것이다
조정된 가중치 = 가중치 - 학습률 * cost fucntion의 편미분값
1
| train_op = optimizer.minimize(cost)
|
session
그래프를 구성한 후 실제 수행을 할때 다양한 실행환경(CPU, GPU, 분산처리)하에서 처리하기 위해
Client에서 session을 만들어 전달하는 역할을 한다
1 2 3
| sess = tf.Session() sess.run(tf.global_variables_initializer())
|
Epoch 100으로 학습시키기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| for step in range(100): _, cost_val = sess.run([train_op, cost], feed_dict={x: x_data, y: y_data}) print("Epoch: ",step, "loss: ",cost_val," weight: ", sess.run(W)," bias: ", sess.run(b))
: Epoch: 0 loss: 41.0 weight: [4.5] bias: [2.2] Epoch: 1 loss: 18.415 weight: [2.1499999] bias: [1.4100001] Epoch: 2 loss: 8.274352 weight: [3.72] bias: [1.9530001] Epoch: 3 loss: 3.721009 weight: [2.6634998] bias: [1.6024001] Epoch: 4 loss: 1.6762912 weight: [3.3670502] bias: [1.8501701] Epoch: 5 loss: 0.7579173 weight: [2.8913898] bias: [1.696611] Epoch: 6 loss: 0.34527153 weight: [3.2059994] bias: [1.8115939] Epoch: 7 loss: 0.15970731 weight: [2.9912033] bias: [1.7462754] Epoch: 8 loss: 0.076116346 weight: [3.1312609] bias: [1.8014188] Epoch: 9 loss: 0.038325354 weight: [3.0336602] bias: [1.7755046] Epoch: 10 loss: 0.021112926 weight: [3.0954175] bias: [1.8035736] .... .... .... .... Epoch: 97 loss: 3.7696707e-05 weight: [3.004957] bias: [1.985426] Epoch: 98 loss: 3.5472734e-05 weight: [3.0048087] bias: [1.9858623] Epoch: 99 loss: 3.3379514e-05 weight: [3.0046647] bias: [1.9862854]
|
loss가 0에 가깝긴 하지만 가중치, 편향치가 3.0046647, 1.9862854인걸로 보아 학습이 살짝 모자라다
학습된 모델로 결과 예측하기 (Epoch 100)
1 2 3 4 5
| sess.run(hypothesis, feed_dict={x:5}) sess.run(hypothesis, feed_dict={x:6})
: array([17.00961], dtype=float32) array([20.014275], dtype=float32)
|
Epoch 1000으로 학습시키기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| sess2 = tf.Session() sess2.run(tf.global_variables_initializer())
: Epoch: 0 loss: 41.0 weight: [4.5] bias: [2.2] Epoch: 1 loss: 18.415 weight: [2.1499999] bias: [1.4100001] Epoch: 2 loss: 8.274352 weight: [3.72] bias: [1.9530001] Epoch: 3 loss: 3.721009 weight: [2.6634998] bias: [1.6024001] Epoch: 4 loss: 1.6762912 weight: [3.3670502] bias: [1.8501701] Epoch: 5 loss: 0.7579173 weight: [2.8913898] bias: [1.696611] Epoch: 6 loss: 0.34527153 weight: [3.2059994] bias: [1.8115939] Epoch: 7 loss: 0.15970731 weight: [2.9912033] bias: [1.7462754] Epoch: 8 loss: 0.076116346 weight: [3.1312609] bias: [1.8014188] Epoch: 9 loss: 0.038325354 weight: [3.0336602] bias: [1.7755046] Epoch: 10 loss: 0.021112926 weight: [3.0954175] bias: [1.8035736] .... .... .... Epoch: 995 loss: 7.9580786e-13 weight: [3.000001] bias: [1.9999975] Epoch: 996 loss: 7.9580786e-13 weight: [3.000001] bias: [1.9999975] Epoch: 997 loss: 7.9580786e-13 weight: [3.000001] bias: [1.9999975] Epoch: 998 loss: 7.9580786e-13 weight: [3.000001] bias: [1.9999975] Epoch: 999 loss: 7.9580786e-13 weight: [3.000001] bias: [1.9999975]
|
학습된 모델로 결과 예측하기 (Epoch 1000)
1 2 3 4 5
| sess2.run(hypothesis, feed_dict={x:5}) sess2.run(hypothesis, feed_dict={x:6})
: array([17.000002], dtype=float32) array([20.000004], dtype=float32)
|