기본적으로 코드들은 코랩에서 실행한다.
텐서플로 2.x 버전 가져오기
try:
%tensorflow_version 2.x
except Exception:
pass
import tensorflow as tf
print(tf.__version__) # 2.4.1
난수 생성
같은 확률로 난수 생성
rand = tf.random.uniform([1], 0, 1) # tf.random.uniform(shape, 최소값, 최대값)
print(rand) # tf.Tensor([0.6305238], shape=(1,), dtype=float32)
정규분포로 난수 생성
# 정규분포로 난수를 뽑음
rand = tf.random.normal([4], 0, 1) # tf.random.noraml(shape, 평균, 표준편차)
print(rand)
# tf.Tensor([-1.389584 -0.10909464 -0.3136603 -0.4502219 ], shape=(4,), dtype=float32)
퍼셉트론 생성
# 활성화함수 sigmoid
import math
def sigmoid(x):
return 1 / (1 + math.exp(-x))
x = 1
y = 0
w = tf.random.normal([1], 0, 1) # 난수생성
output = sigmoid(x * w) # 활성화 함수 적용
경사 하강법
output을 최대한 정답에 가깝게 맞추도록 가중치를 갱신하는 방법이다. 반복될수록 error는 점점 줄어들고, output은 정답인 0에 가까워지는 것을 볼 수 있다.
for i in range(1000):
output = sigmoid(x * w)
error = y - output
w = w + x * 0.1 * error # 학습률은 0.1로 설정
if i % 100 == 99:
print(i, error, output)
#---------------------출력---------------------#
# 99 -0.11310331711500524 0.11310331711500524
# 199 -0.05525516691999154 0.05525516691999154
# 299 -0.036134545309195125 0.036134545309195125
# 399 -0.02675293191878269 0.02675293191878269
# 499 -0.02120766920554343 0.02120766920554343
# 599 -0.01755329196981286 0.01755329196981286
# 699 -0.014966658229093838 0.014966658229093838
# 799 -0.013040807186870356 0.013040807186870356
# 899 -0.011551897156336102 0.011551897156336102
# 999 -0.010366791686728452 0.010366791686728452
만약 x=0인 경우에는 어떻게 될까?
에러도 0.5에서 더 줄어들지 않고, output도 0.5에서 변하지 않는다. x=0이기 때문에 학습이 되지 않는다. 이런 경우를 위해 bias(b)가 필요하다.
x = 0
y = 1
w = tf.random.normal([1], 0, 1)
output = sigmoid(x * w)
print(output) # 0.5
for i in range(1000):
output = sigmoid(x * w)
error = y - output
w = w + x * 0.1 * error
if i % 100 == 99:
print(i, error, output)
#---------------------출력---------------------#
# 99 0.5 0.5
# 199 0.5 0.5
# 299 0.5 0.5
# 399 0.5 0.5
# 499 0.5 0.5
# 599 0.5 0.5
# 699 0.5 0.5
# 799 0.5 0.5
# 899 0.5 0.5
# 999 0.5 0.5
bias를 추가한 경우
error가 줄어들고, output도 정답인 1에 거의 근접했다.
x = 0
y = 1
w = tf.random.normal([1], 0, 1)
b = tf.random.normal([1], 0, 1)
for i in range(1000):
output = sigmoid(x * w + 1 * b)
error = y - output
w = w + x * 0.1 * error
b = b + 1 * 0.1 * error
if i % 100 == 99:
print(i, error, output)
#---------------------출력---------------------#
# 99 0.11046792076952594 0.8895320792304741
# 199 0.05457995828296547 0.9454200417170345
# 299 0.03583897739278796 0.964161022607212
# 399 0.026589096309596272 0.9734109036904037
# 499 0.021104036753882838 0.9788959632461172
# 599 0.017481991938524843 0.9825180080614752
# 699 0.014914663244828152 0.9850853367551718
# 799 0.013001207731670572 0.9869987922683294
# 899 0.01152079468956213 0.9884792053104379
# 999 0.010341715869476853 0.9896582841305231
신경망 네트워크
And 게이트
And 게이트는 입력이 모두 1일때만 1을 출력한다.
import numpy as np
x = np.array([[0,0], [1,0], [0,1], [1,1]])
y = np.array([[0], [0], [0], [1]])
w = tf.random.normal([2],0,1)
b = tf.random.normal([1],0,1)
b_x = 1
for i in range(2001):
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 % 400 == 0:
print(i, error_sum)
#---------------------출력---------------------#
0 -1.5467700244922273
400 -0.06479694274470607
800 -0.03580663398071523
1200 -0.02458656329598055
1600 -0.01867050284398148
2000 -0.015027795258891878
학습된 가중치가 실제로 맞는 값을 가르키는지 살펴보자.
for i in range(4):
print('input:', x[i], ' output:', sigmoid(np.sum(x[i]*w)+b_x*b))
#---------------------출력---------------------#
input: [1 1] output: 0.9650488962798548
input: [1 0] output: 0.024768898672699782
input: [0 1] output: 0.024844223870939347
input: [0 0] output: 2.3434300193304377e-05
OR 게이트
OR 게이트는 입력 중 하나만 1이어도 1을 출력한다.
= np.array([[0, 0], [1, 0], [0, 1], [1, 1]])
y = np.array([[0], [1], [1], [1]])
w = tf.random.uniform([2],0,1)
b = tf.random.uniform([1],0,1)
b_x = 1
for i in range(2001):
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 % 400 == 0:
print(i, error_sum)
#---------------------출력---------------------#
0 0.5169845174011798
400 -0.025759148021826647
800 -0.013033428543949538
1200 -0.00866607518100053
1600 -0.006475455255724974
2000 -0.005162616073124557
학습된 가중치가 실제로 맞는 값을 가르키는지 살펴보자.
for i in range(4):
print('input:', x[i], ' output:', sigmoid(np.sum(x[i]*w)+b_x*b))
#---------------------출력---------------------#
input: [0 0] output: 0.025601225400094334
input: [1 0] output: 0.9898147401582366
input: [0 1] output: 0.9897890663503223
input: [1 1] output: 0.9999972109037591
XOR 게이트
XOR게이트는 입력의 값이 서로 다를때만 1을 출력한다.
x = np.array([[0, 0], [1, 0], [0, 1], [1, 1]])
y = np.array([[0], [1], [1], [0]])
w = tf.random.uniform([2],0,1)
b = tf.random.uniform([1],0,1)
b_x = 1
for i in range(2001):
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 % 400 == 0:
print(i, error_sum)
#---------------------출력---------------------#
0 -0.5038278035452097
400 0.00010551105352096801
800 1.6659719226375103e-07
1200 4.746623760709667e-08
1600 4.746623760709667e-08
2000 4.746623760709667e-08
학습된 가중치가 실제로 맞는 값을 가르키는지 살펴보자.
for i in range(4):
print('input:', x[i], ' output:', sigmoid(np.sum(x[i]*w)+b_x*b))
#---------------------출력---------------------#
input: [0 0] output: 0.5128175691057347
input: [1 0] output: 0.49999997485429043
input: [0 1] output: 0.4871823676059484
input: [1 1] output: 0.47438160794816525
잘 학습이 되지 않았다. 한 층의 퍼셉트론으로는 XOR 게이트를 구현할 수 없다. 여러개의 퍼셉트론을 사용해야한다. tf.Keras를 통해 구현해본다.
2개의 층으로 XOR구현
x = np.array([[0, 0], [1, 0], [0, 1], [1, 1]])
y = np.array([[0], [1], [1], [0]])
model = tf.keras.Sequential([
tf.keras.layers.Dense(units=2, activation='sigmoid', input_shape=(2,)),
tf.keras.layers.Dense(units=1, activation='sigmoid')
])
model.compile(optimizer=tf.keras.optimizers.SGD(lr=0.1), loss='mse')
model.summary()
#---------------------출력---------------------#
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 2) 6
_________________________________________________________________
dense_1 (Dense) (None, 1) 3
=================================================================
Total params: 9
Trainable params: 9
Non-trainable params: 0
_________________________________________________________________
학습
history = model.fit(x, y, epochs=2000, batch_size=1)
확인
x를 넣어서 학습이 잘 되었는지 확인해본다. 조금은 아쉽지만 학습이 되는것은 확인할 수 있다.
model.predict(x)
#---------------------출력---------------------#
array([[0.23168063],
[0.7207968 ],
[0.78110605],
[0.20379293]], dtype=float32)
가중치 확인
for weight in model.weights:
print(weight)
#---------------------출력---------------------#
<tf.Variable 'dense/kernel:0' shape=(2, 2) dtype=float32, numpy=
array([[-3.1059098, 5.11057 ],
[ 3.3211062, -4.8253274]], dtype=float32)>
<tf.Variable 'dense/bias:0' shape=(2,) dtype=float32, numpy=array([1.5160486, 2.7006598], dtype=float32)>
<tf.Variable 'dense_1/kernel:0' shape=(2, 1) dtype=float32, numpy=
array([[-3.6596467],
[-3.734692 ]], dtype=float32)>
<tf.Variable 'dense_1/bias:0' shape=(1,) dtype=float32, numpy=array([5.301554], dtype=float32)>
시각화 기초
matplotlib.pyplot을 이용한 그래프 그리기
꺽은선 그래프
import matplotlib.pyplot as plt
x = range(20)
y = tf.random.normal([20],0,1)
plt.plot(x,y)
plt.show()
분산형 그래프
x = range(20)
y = tf.random.normal([20],0,1)
plt.plot(x,y,'bo')
plt.show()
히스토그램
random_normal = tf.random.normal([100000],0,1)
plt.hist(random_normal, bins=100)
plt.show()
XOR 2층의 퍼셉트론 loss 그래프
위에서 만들었던 XOR 2층 퍼셉트론의 학습하면서 기록된 loss그래프를 그려보자.
loss가 감소하는것을 보면 학습이 된다는 것을 알 수 있다.
'책리뷰' 카테고리의 다른 글
(시작하세요! 텐서플로 2.0 프로그래밍) 5장. 분류(Classification) (0) | 2022.07.12 |
---|---|
(시작하세요! 텐서플로 2.0 프로그래밍) 4장. 회귀(Regression) (0) | 2022.07.12 |
(밑바닥부터 시작하는 딥러닝) 8장. 딥러닝 (0) | 2022.07.12 |
(밑바닥부터 시작하는 딥러닝) 7장. 합성곱 신경망(CNN) (0) | 2022.06.23 |
(밑바닥부터 시작하는 딥러닝) 6장. 학습 관련 기술들 (0) | 2022.06.23 |