버전 비교

  • 이 줄이 추가되었습니다.
  • 이 줄이 삭제되었습니다.
  • 서식이 변경되었습니다.

텐서플로우의 예제를 통해서 매우 간단한(질문) 뉴럴 네트워크를 알아 봅시다.

앞서 접해본 [TensorFlow] 001. 맛보기와 내용이 유사한 면이 없지 않습니다. 

둘 다 y = ax + b 일 때, a와 b를 구하는 방법입니다.

하지만 이 예제의 경우, 구해야 하는 a, b를 weights라는 matrix(2x1) 변수로 선언하고, 임의의 표준정규분포 값을 받아서 그 값에서 a와 b를 유추하는 방식으로 진행됩니다.

 

Weight(a)와 bias(b) 구하기

...

y = ax + b

정보
학습 데이터로 x와 y가 주어졌을때, 가중치(weights)로 할당되어 있는 a와 b의 최적의 값을 구해 봅시다.

 

CODE

코드 블럭
languagepy
themeEmacs
titleA simple neural network
linenumberstrue
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
 
num_examples = 50
# -2에서 4까지, -6에서 6까지 50(num_examples)단계로 꾸준히 증가하는 값을 받아서 2개의 배열로 저장 (직선 상태)
X = np.array([np.linspace(-2, 4, num_examples), np.linspace(-6, 6, num_examples)])
# 꾸준히 증가하는 X 배열에 표준정규분포 값을 각각 넣어줌 (데이터 분산 발생)
X += np.random.randn(2, num_examples)
x, y = X
# x 배열 값에 1을 붙여서 x_with_bias 생성 (1을 붙인 이유는 가중치(weights에서 b, a를 사용할 때, b를 그대로 보존하기 위함) y = b*1 + ax = ax + b
x_with_bias = np.array([(1., a) for a in x]).astype(np.float32)
losses = []
training_steps = 50
learning_rate = 0.002
with tf.Session() as sess:
  # 입력은 x_with_bias(50x2) 사용
  input = tf.constant(x_with_bias)
  # 타겟은 y를 전치행렬(1x50 → 50x1) 설정
  target = tf.constant(np.transpose([y]).astype(np.float32))
  # 가중치 출력 텐서의 모양은 (2x1)으로 정규분포의 분산 0, 표준편차 0.1을 가지는 임의의 값을 초기값으로 설정
  weights = tf.Variable(tf.random_normal([2, 1], 0, 0.1))
  
  # 모든 텐서 변수 초기화
  tf.initialize_all_variables().run()
  
  # input(50x2)과 가중치 값(2x1)을 matrix multiple = yhat은 (50x1) 값이 됨, yhat = 학습 진행중인 데이터
  yhat = tf.matmul(input, weights)
 
  # yhat(50x1)에서 target(50x1) 값을 뺀 값을 yerror로 설정
  yerror = tf.sub(yhat, target)
 
  # 학습중인 weights와 실제 target의 차이의 손실값의 평균을 낮추도록 함
  loss = tf.reduce_mean(tf.nn.l2_loss(yerror))
  
  # 경사하강법으로 loss가 최소값이 되도록 학습 설정
  update_weights = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
  
  # 50회 학습
  for _ in range(training_steps):
    # 반복적으로 경사하강법을 통해 텐서플로우 변수들을 업데이트 함
    update_weights.run()
    losses.append(loss.eval())
  # 학습이 종료되면 결과 값을 출력
  betas = weights.eval()
  yhat = yhat.eval()
# 그래프로 표현
# fig는 도표를 그릴 영역을 의미함. 도표가 1x2 형태로 가로로 2개 들어감
fig, (ax1, ax2) = plt.subplots(1, 2)
# 도표간 거리는 0.3
plt.subplots_adjust(wspace=.3)
# 그릴 영역의 사이즈는 가로 10, 세로 4
fig.set_size_inches(10, 4)
# 첫번째 도표(ax1)에 입력에 따른 출력 값을 2차원 평면에 점으로 찍음
ax1.scatter(x, y, alpha=.7)
# 첫번째 도표(ax1)에 최종 가중치(weights)를 적용했을 때, 예상되는 target 값을 기준으로 2차원 평면에 점으로 찍음
ax1.scatter(x, np.transpose(yhat)[0], c="g", alpha=.6)
line_x_range = (-4, 6)

# 첫번째 도표(ax1)에 x 값 -4에서 6사이에서 최종 가중치(weights)에 따른 직선 그래프를 그림 betas[0]은 b를 의미 betas[1]은 a를 의미 (yhat = b + a*input)
ax1.plot(line_x_range, [betas[0] + a * betas[1] for a in line_x_range], "g", alpha=0.6)
# 두 번째 도표(ax2)에 학습 진행에 따른 losses를 도식화)
ax2.plot(range(0, training_steps), losses)
ax2.set_ylabel("Loss")
ax2.set_xlabel("Training steps")
plt.show()


Result

 

요약

y  = ax + b 인 상황에서, 입력값 x(input)와 출력값 y(target)을 알고 있다. 이때 최적의 a와 b를 구해보자.

...