Tensorflow 2.0 Tutorial ch3.3.3 - 첫번째 신경망 네트워크, AND
공지
- 본 Tutorial은 교재
시작하세요 텐서플로 2.0 프로그래밍
의 강사에게 국비교육 강의를 듣는 사람들에게 자료 제공을 목적으로 제작하였습니다. - 강사의 주관적인 판단으로 압축해서 자료를 정리하였기 때문에, 자세하게 공부를 하고 싶은 반드시 교재를 구매하실 것을 권해드립니다.
- 본 교재 외에 강사가 추가한 내용에 대한 Reference를 확인하셔서, 추가적으로 학습하시는 것을 권유드립니다.
Tutorial
이전 강의가 궁금하신 분들은 아래에서 선택하여 추가 학습 하시기를 바랍니다.
- Google Colab Tensorflow 2.0 Installation
- Tensorflow 2.0 Tutorial ch3.3.1 - 난수 생성 및 시그모이드 함수
- Tensorflow 2.0 Tutorial ch3.3.2 - 난수 생성 및 시그모이드 함수 편향성
I. AND 연산의 기본 개념
AND 연산의 기본개념은 아래와 같습니다. 다른 프로그래밍과 다르지 않습니다.
입력1 |
입력2 |
AND 연산 |
---|---|---|
참 | 참 | 참 |
참 | 거짓 | 거짓 |
거짓 | 참 | 거짓 |
거짓 | 거짓 | 거짓 |
파이썬에서는 참, 거짓을 나타내는 값은 True
, False
입니다. 그런데, 딥러닝의 주요 입력값은 정수(Integer)나 실수(float)입니다. 참과 거짓의 값을 출력하여 확인해봅니다.
print(int(True))
print(int(False))
1
0
참은 1로 출력하고 거짓은 0으로 출력한 것을 확인하였습니다. 다시 AND 연산 기본개념에 적용하면 아래와 같습니다.
입력1 |
입력2 |
AND 연산 |
---|---|---|
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
이제 숫자로 된 네개의 입력과 출력(AND 연산)의 쌍이 생겼습니다. 이제 AND 연산을 할 수 있는 신경망 네트워크를 만들어봅니다.
# 본 예제
import tensorflow as tf
import numpy as np
import math
# 시그모이드 함수 정의
def sigmoid(x):
return 1 / (1 + math.exp(-x))
x = np.array([[1, 1], [1, 0], [0, 1], [0, 0]])
y = np.array([[1], [0], [0], [0]])
w = tf.random.normal([2], 0, 1)
b = tf.random.normal([1], 0, 1)
b_x = 1
for i in range(2000):
error_sum = 0
for j in range(4):
output = sigmoid(np.sum(x[j] * w) + b_x * b)
error = y[j][0] - output
w = w + x[j] * 0.1 * error
b = b + b_x * 0.1 * error
error_sum += error
if i % 200 == 199:
print(i, error_sum)
199 -0.10664604227192419
399 -0.0643946715061894
599 -0.04600188172236917
799 -0.03567996639075575
999 -0.029089461092594807
1199 -0.024526551513673306
1399 -0.0211850336803021
1599 -0.018634950907257527
1799 -0.016626949381179347
1999 -0.01500491979044496
NumPy
에 관한 내용은 여기에서는 생략합니다.
위에 가중치(w
)에 적용된 수식은 다음과 같습니다. $$w = w + x[j] \times 0.1 \times error$$
여기서는 $x[j]\times0.1$ 부분의 계산을 빨리 하기 위해 NumPy Array
를 활용했습니다.
II. NumPy VS List
여기에서 NumPy와 List를 혼동할 때가 많습니다. 메모리 연산 등에 비교하는 문서가 필요하면 Python Lists VS Numpy Arrays에서 확인 후 직접 코드 실행을 해서 익히기를 바랍니다.
딥러닝에서 확인하고 싶은 것은 왜 List 대신에 NumPy가 사용되는 것인지에 대한 내용입니다.
수식을 보면, 오차(error
)가 먼저 계산되고 난 뒤, 가중치를 업데이트 하게 됩니다. 이 때 만약 리스트로 값이 이루어진다면, 오차가 0
이거나 또는 음수
일 때는 Empty(빈)리스트가 반환될 것입니다.
print([1, 2, 3] * 2)
print([1, 2, 3] * 0)
print([1, 2, 3] * -1)
[1, 2, 3, 1, 2, 3]
[]
[]
또한 0.01과 같은 실수를 곱하면 다음과 같은 에러가 발생합니다.
print([1,2,3] * 0.01)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-4-31e359ec4ae9> in <module>()
----> 1 print([1,2,3] * 0.01)
TypeError: can't multiply sequence by non-int of type 'float'
반대로, NumPy array에 실수를 곱하면 어떨까요?
import numpy as np
print(np.array([1,2,3]) * 2)
print(np.array([1,2,3]) * 0)
print(np.array([1,2,3]) * -1)
print(np.array([1,2,3]) * 0.01)
[2 4 6]
[0 0 0]
[-1 -2 -3]
[0.01 0.02 0.03]
위에서 확인하는 것처럼 모두 출력되는 것을 확인할 수 있습니다. AND 연산의 수가 4배로 많아졌기 때문에 네트워크가 경사하강법으로 수렴하는데에는 더 많은 연산이 필요합니다. error_sum
을 통해서 점점 줄어드는 것을 확인할 수 있습니다.
III. AND 네트워크의 평가
이렇게 학습시킨 네트워크가 정상적으로 작동하는지 평가해본다. 네트워크에 x의 각 값을 넣었을 때, 실제 출력이 기대출력인 y값에 얼마나 가까운지 다음 코드를 통해 확인한다.
for i in range(4):
print('X:', x[i], 'Y:', y[i], 'Output:', sigmoid(np.sum(x[i]*w)+b))
X: [1 1] Y: [1] Output: 0.9649695824038163
X: [1 0] Y: [0] Output: 0.024824442411186316
X: [0 1] Y: [0] Output: 0.024900221652718595
X: [0 0] Y: [0] Output: 2.359785345402601e-05
마지막 Output
이 2.359785345402601e-05
나오는 것은 일종의 과학적 표기법으로 실수를 가수와 지수로 표현하는 방법이다.
다음을 통해서 확인해본다.
print("{:.16f}".format(float("2.359785345402601e-05")))
0.0000235978534540
IV. 연습 파일
V. Reference
김환희. (2020). 시작하세요! 텐서플로 2.0 프로그래밍: 기초 이론부터 실전 예제까지 한번에 끝내는 머신러닝, 딥러닝 핵심 가이드. 서울: 위키북스.