1. Tensorflow 설치
1.1 Pip Upgrade
- pip install –upgrade pip
- Tensorflow 설치를 위해선 pip 버전이 19.X 이상이어야함
1.2 Tensorflow 설치
- pip install tensorflow
2. Tensorflow
2.1 Tensorflow란?
- 머신러닝을 위한 오픈소스 플랫폼 - 딥러닝 프레임 워크
- 구글이 주도적으로 개발하였고, 구글코랩에는 기본으로 설치되어 있음
- 최근 2.x 버전이 발표되었음
- Keras와 병합되었음
- Tensor : 벡터나 행렬을 의미
- Graph : 텐서가 흐르는 경로 or 공간
- Tensor Flow : Tensor가 Graph를 통해 흐름
3. 딥러닝 기초
3.1 Neural Net
- Neural Net은 신경망에서 아이디어를 얻어서 시작됨
3.2 뉴런
- 뉴런은 입력, 가중치, 활성화함수, 출력으로 구성되어 있음
- 뉴런에서 학습할때 변하는 것은 가중치, 처음에는 초기화를 통해 랜덤값을 넣고, 학습과정에서 일정한 값으로 수렴됨
3.3 레이어와 망
- 뉴런이 모여서 Layer를 구성하고, 망(net)이 됨
3.4 딥러닝
- 이러한 신경망이 많아지면 Deep Learning이 됨
4. 실습 1
4.1 Blood Fat
1
2
import tensorflow as tf
tf.__version__
1
'2.3.1'
- Tensorflow 버전 확인
1
2
3
4
import numpy as np
raw_data = np.genfromtxt('https://raw.githubusercontent.com/hmkim312/datas/main/blood%20fat/x09.txt', skip_header=36)
raw_data
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
array([[ 1., 1., 84., 46., 354.],
[ 2., 1., 73., 20., 190.],
[ 3., 1., 65., 52., 405.],
[ 4., 1., 70., 30., 263.],
[ 5., 1., 76., 57., 451.],
[ 6., 1., 69., 25., 302.],
[ 7., 1., 63., 28., 288.],
[ 8., 1., 72., 36., 385.],
[ 9., 1., 79., 57., 402.],
[ 10., 1., 75., 44., 365.],
[ 11., 1., 27., 24., 209.],
[ 12., 1., 89., 31., 290.],
[ 13., 1., 65., 52., 346.],
[ 14., 1., 57., 23., 254.],
[ 15., 1., 59., 60., 395.],
[ 16., 1., 69., 48., 434.],
[ 17., 1., 60., 34., 220.],
[ 18., 1., 79., 51., 374.],
[ 19., 1., 75., 50., 308.],
[ 20., 1., 82., 34., 220.],
[ 21., 1., 59., 46., 311.],
[ 22., 1., 67., 23., 181.],
[ 23., 1., 85., 37., 274.],
[ 24., 1., 55., 40., 303.],
[ 25., 1., 63., 30., 244.]])
- 해당 데이터는 고혈압(혈중 지질)을 나타낸 데이터
- 3번째는 몸무게, 4번째는 나이, 마지막이 타겟인 혈중지질임
4.2 그래프로 보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
%matplotlib inline
xs = np.array(raw_data[:,2], dtype = np.float32)
ys = np.array(raw_data[:,3], dtype = np.float32)
zs = np.array(raw_data[:,4], dtype = np.float32)
fig = plt.figure(figsize=(12, 12))
ax = fig.add_subplot(111, projection = '3d')
ax.scatter(xs, ys, zs)
ax.set_xlabel('Weight')
ax.set_ylabel('Age')
ax.set_zlabel('Blood Fat')
ax.view_init(15, 15)
plt.show()
- 나이와 몸무게를 알려주면 주어진 데이터 기준의 Blood Fat을 얻는것
- 즉, 46살 84키로인 사람의 데이터 기준 Blood Fat을 물으면 답이 나와야하는것
- Linear Regression으로 풀자
4.3 Linear Regression
- 직선 모델을 얻는것으로 하면, 주어진 입출력 데이터로 W와 b 즉, 모델을 얻어야 함
4.4 예측
- 모델 (W,b)를 이용해서, 예측을 한다. 즉 age 40, weight 80인 사람의 y(blood fat)은 얼마인가?
4.5 목표
- 목적은 x1, x2를 입력해서 y가 나오게 하는 W와 b를 구하는것
4.6 데이터 정리
1
2
3
x_data = np.array(raw_data[:, 2:4], dtype=np.float32)
y_data = np.array(raw_data[:, 4], dtype=np.float32)
y_data = y_data.reshape((25, 1))
- 원래 데이터에서 x와 y를 정리하고, y를 reshape해준다
4.7 모델 생성
1
2
3
4
5
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(1, input_shape=(2,)),
])
model.compile(optimizer='rmsprop', loss='mse')
4.7.1 Loss
- 학습을 위해서는 loss(cost) 함수를 정해야함
- 정답까지 얼마나 멀리 있는지 측정하는 함수
- mse : 오차 제곱의 평균
- 그외 선택 가능한 loss https://keras.io/api/losses/
4.7.2 Optimizer
- Optimizer를 선정함, loss를 어떻게 줄일것인지를 결정하는 것
- loss함수를 최소화하는 가중치를 찾아가는 과정에 대한 알고리즘
- 그외 선택 가능한 Optimizer https://keras.io/api/optimizers/
4.8 Summary
1
model.summary()
1
2
3
4
5
6
7
8
9
10
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 1) 3
=================================================================
Total params: 3
Trainable params: 3
Non-trainable params: 0
_________________________________________________________________
- 모델 구성에 대한 요약을 볼수 있다.
- 현재는 모델 구성만 한것이고, 학습을 시도한것은 아니다.
- 나이와 몸무게를 받아서 Blood Fat을 추정하는 모델을 학습을 통해 얻으려고 함
- 모델(네트워크)를 구성하였고, 모델의 loss function을 선정, loss의 감소를 위한 optimizer도 선정함
4.9 모델 학습
1
hist = model.fit(x_data, y_data, epochs=5000)
1
2
3
4
5
6
7
8
9
10
11
Epoch 1/5000
1/1 [==============================] - 0s 647us/step - loss: 112005.7578
Epoch 2/5000
1/1 [==============================] - 0s 469us/step - loss: 111776.2500
Epoch 3/5000
1/1 [==============================] - 0s 544us/step - loss: 111609.9688
...
Epoch 4999/5000
1/1 [==============================] - 0s 386us/step - loss: 2318.3562
Epoch 5000/5000
1/1 [==============================] - 0s 486us/step - loss: 2317.8252
- epochs = 1은 전체 데이터 셋에 대해 한 번 학습을 완료한 상태
- epochs = 40이라면 전체 데이터를 40번 사용해서 학습을 거치는 것
4.10 Loss 확인
1
2
3
4
5
plt.plot(hist.history['loss'])
plt.title('Model Loss')
plt.ylabel('Loss')
plt.xlabel('Epochs')
plt.show()
- Epochs를 진행할수록 Loss가 떨어짐을 알수있다.
- 처음에는 140,000 였다가 마지막에 2000대로 떨어졌다.
4.11 예측
1
model.predict(np.array([100,44]).reshape(1,2))
1
array([[395.40054]], dtype=float32)
- 몸무게 100에 44살인 사람의 Blood Fat을 예측하니 387.94가 나왔음
1
model.predict(np.array([60,25]).reshape(1,2))
1
array([[233.83997]], dtype=float32)
- 몸무게 60에 25살 사람의 Blood Fat은 228.48이 나옴
4.12 W(가중치)와 bias는?
1
2
3
W_, b_ = model.get_weights()
print(f'가중치(Weight) is : {W_})')
print(f'Bias is : {b_})')
1
2
3
가중치(Weight) is : [[2.211234]
[3.847958]])
Bias is : [4.9669867])
- 가중치와 bias는 get_weights를 통해서 알수 있음
4.13 모델 확인 및 그리기
1
2
3
4
5
x1 = np.linspace(20, 100, 50).reshape(50, 1)
x2 = np.linspace(10, 70, 50).reshape(50, 1)
X = np.concatenate((x1, x2), axis=1)
y = np.matmul(X, W_) + b_
- x1은 몸무게, x2는 나이, y는 모델의 값을 적용하여 만들어낸 Blood Fat, 총 50개의 데이터
1
2
3
4
5
6
7
8
9
fig = plt.figure(figsize=(12, 12))
ax = fig.add_subplot(111, projection = '3d')
ax.scatter(xs, ys, zs) # 기존 데이터
ax.scatter(x1, x2, y) # 새로 만든 데이터
ax.set_xlabel('Weight')
ax.set_ylabel('Age')
ax.set_zlabel('Blood Fat')
ax.view_init(15,15)
plt.show()
- 주황색이 새로 만든 데이터로 그린 스캐터플롯임
- 일직선이 나오는걸로 봐서 생각보다 모델이 잘 만들어진듯 하다
5. XOR 문제
5.1 XOR 문제
- 입력이 같으면
0
, 다르면1
의 출력이 나오는 소자 - 즉, 입력 중 어느 하나 만
1
일 경우에 만 출력이1
이 되는 소자
5.2 선형 모델의 XOR
- 선형 모델로는 XOR 문제를 풀수 없음
5.3 데이터 준비
1
2
3
4
5
6
7
import numpy as np
X = np.array([[0, 0],
[1, 0],
[0, 1],
[1, 1]])
y = np.array([[0], [1], [1], [0]])
- XOR의 진리표에 따라 A, B가 같지 않으면 1, 같으면 0을 출력
5.4 모델 생성
1
2
3
4
model = tf.keras.Sequential([
tf.keras.layers.Dense(2, activation = 'sigmoid', input_shape = (2,)),
tf.keras.layers.Dense(1, activation = 'sigmoid')
])
- 위 모델의 생김새는 그림과 같다
5.5 Model의 Compile
1
model.compile(optimizer=tf.keras.optimizers.SGD(lr = 0.1), loss = 'mse')
- 옵티마이저를 선정하고 학습률을 선정함
- Loss는 mse로
- SGD : 그래디언트 벡터
- lr : 아래로 내려가는 정도
5.6 Model Summary
1
model.summary()
1
2
3
4
5
6
7
8
9
10
11
12
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_1 (Dense) (None, 2) 6
_________________________________________________________________
dense_2 (Dense) (None, 1) 3
=================================================================
Total params: 9
Trainable params: 9
Non-trainable params: 0
_________________________________________________________________
5.7 학습
1
hist = model.fit(X, y, epochs=5000, batch_size = 1)
1
2
3
4
5
6
7
8
9
10
11
12
13
Epoch 1/5000
4/4 [==============================] - 0s 611us/step - loss: 0.2555
Epoch 2/5000
4/4 [==============================] - 0s 568us/step - loss: 0.2555
Epoch 3/5000
4/4 [==============================] - 0s 535us/step - loss: 0.2555
...
Epoch 4918/5000
4/4 [==============================] - 0s 601us/step - loss: 0.0032
Epoch 4919/5000
4/4 [==============================] - 0s 528us/step - loss: 0.0032
Epoch 4920/5000
4/4 [==============================] - 0s 526us/step - loss: 0.0032
- Epochs : 지정된 횟수만큼 학습 하는것
- Batch_size : 한번의 학습에 사용될 데이터의 수
- fit을 여러번 진행하면 처음부터 진행하는것이 아닌, 기존에 업데이트된 loss에서부터 계속 연속으로 지정됨
5.8 학습결과
1
model.predict(X)
1
2
3
4
array([[0.05735993],
[0.94680035],
[0.9466035 ],
[0.05780149]], dtype=float32)
- 0은 아니지만 0과 근접한 수치, 1은 아니지만 1과 근접한 수치가 나옴
5.9 Loss Graph
1
2
3
4
5
6
7
8
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 12))
plt.plot(hist.history['loss'])
plt.title('Model Loss')
plt.ylabel('Loss')
plt.xlabel('Epochs')
plt.show()
- Epochs가 진행되면서 loss가 쭉 떨어지다가 다시 변화가 없음
5.10 가중치 확인
1
2
3
4
for w in model.weights:
print('----')
print(w)
print()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
----
<tf.Variable 'dense_1/kernel:0' shape=(2, 2) dtype=float32, numpy=
array([[5.907916 , 3.734393 ],
[5.844629 , 3.7225044]], dtype=float32)>
----
<tf.Variable 'dense_1/bias:0' shape=(2,) dtype=float32, numpy=array([-2.4336848, -5.7000146], dtype=float32)>
----
<tf.Variable 'dense_2/kernel:0' shape=(2, 1) dtype=float32, numpy=
array([[ 7.470416],
[-8.074545]], dtype=float32)>
----
<tf.Variable 'dense_2/bias:0' shape=(1,) dtype=float32, numpy=array([-3.3748236], dtype=float32)>
6. 분류 실습
6.1 Iris 데이터
1
2
3
4
5
6
from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data
y = iris.target
- Iris 데이터를 불러오고 X,y로 나누어줌
- 다만 y가 0,1,2로 나누어져 있어서 원핫인코딩이 필요하다
6.2 원핫인코딩
- 타켓을 1,2,3을 각 컬럼으로 만들어 0과 1로 만드는 행위
6.3 Sklearn의 One Hot Encoder
1
2
3
4
from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder(sparse=False, handle_unknown='ignore')
enc.fit(y.reshape(len(y), 1))
1
OneHotEncoder(handle_unknown='ignore', sparse=False)
- Sklearn의 One Hot Encoder를 사용하여 재정리를 해줌
1
enc.categories_
1
[array([0, 1, 2])]
- Target의 컬럼
1
2
y_onehot = enc.transform(y.reshape(len(y), 1))
y_onehot[:3]
1
2
3
array([[1., 0., 0.],
[1., 0., 0.],
[1., 0., 0.]])
- fit한것을 Transform 함
6.4 데이터 정리
1
2
3
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y_onehot, test_size = 0.2, random_state = 13)
- 데이터를 학습과 테스트데이터로 나눔
6.5 신경망 구조도
- Iris 데이터의 구조도
6.6 코드로 작성
1
2
3
4
5
6
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(32, input_shape=(4,), activation = 'relu'),
tf.keras.layers.Dense(32, activation = 'relu'),
tf.keras.layers.Dense(32, activation = 'relu'),
tf.keras.layers.Dense(3, activation = 'softmax'),
])
6.7 Activation이란
- 하나의 뉴런 끝단에 Activation이라는 함수가 있음
6.9 역전파(Back-Propagation)
6.10 역전파에는 sigmoid문제가 있음
6.11 Vanishing Gradient 현상
6.12 Relu
6.13 Softmax?
6.14 완성된 모델
6.15 Model Summary
1
2
model.compile(optimizer='adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])
model.summary()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Model: "sequential_2"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_3 (Dense) (None, 32) 160
_________________________________________________________________
dense_4 (Dense) (None, 32) 1056
_________________________________________________________________
dense_5 (Dense) (None, 32) 1056
_________________________________________________________________
dense_6 (Dense) (None, 3) 99
=================================================================
Total params: 2,371
Trainable params: 2,371
Non-trainable params: 0
_________________________________________________________________
6.16 Gradient Decent
- Grdient Decent : 기준 뉴럴넷이 가중치 Parameter들을 최적화(Optimize)하는 방법
- Loss Function의 현 가중치에서 기울기(Gradient)를 구해서 Loss를 줄이는 방향으로 업데이트
6.17 Loss Function
- 뉴럴넷은 Loss(or Cost) Function을 가지고 있음. = 틀린 정도
- 현재 가진 Weight 세팅에서 내가 가진 데이터를 다 넣으면 전체 에러가 계산됨
- 거기서 미분을 하면 에러를 줄이는 방향을 알수 있음 (내자리의 기울기 * 반대 방향)
- 그 방향으로 정해진 스텝량(Learning Rate)을 곱해서 weight를 이동
- 위의 내용을 반복
- Weight의 업데이트 = 에러 낮추는 방향(Decent) * 한발자국 크기(Learning Rate) * 현 지점의 기울기 (Gradient)
6.18 SGD (Stochastic Gradient Decent)
- Gradient Decent : Full Batch로 학습데이터를 모두 다 읽고 최적의 1스텝을 감
- SGD (Stochastic Gradient Decent) : 학습 데이터를 토막(Mini Batch)내서 토막낸 학습데이터로 1스탭씩 가는것
6.19 GD vs SGD
- Gradient Decent : 모든걸 계산 후 최적의 1 스탭을 감. 최적인데 너무 느림!
- Stochastic Gradient Descent : 일부만 검토 후 1 스탭을 감. 최적은 아니지만 매우 빠름
6.20 Optimizer의 선택
- 산을 잘타고 내려오는것은 어느 방향으로 발을 디딜지, 얼마의 보폭으로 발을 디딜지 두 가지를 잘 잡아야 빠르게 타고 내려옴
- SGD를 개선한 Opmimizer들고 있음
6.21 Optimizer의 발달 계보
- 일단 데이터가 복잡하다면 Adam을 쓴다.
6.22 학습
1
hist = model.fit(X_train, y_train, epochs=100)
1
2
3
4
5
6
7
8
9
Epoch 1/100
4/4 [==============================] - 0s 777us/step - loss: 0.9711 - accuracy: 0.4583
Epoch 2/100
4/4 [==============================] - 0s 635us/step - loss: 0.8974 - accuracy: 0.7417
Epoch 3/100
4/4 [==============================] - 0s 584us/step - loss: 0.8529 - accuracy: 0.6583
...
Epoch 100/100
4/4 [==============================] - 0s 589us/step - loss: 0.0624 - accuracy: 0.9833
- 100번의 Epochs를 했고 Accuracy가 높게 잘 나온다.
6.23 Test 데이터의 Accuracy
1
model.evaluate(X_test, y_test, verbose=2)
1
2
1/1 - 0s - loss: 0.0932 - accuracy: 0.9667
[0.09320703893899918, 0.9666666388511658]
6.24 Loss와 Acc의 변화
1
2
3
4
5
6
7
plt.figure(figsize=(12,6))
plt.plot(hist.history['loss'])
plt.plot(hist.history['accuracy'])
plt.title('Model Loss')
plt.ylabel('Loss')
plt.xlabel('Epochs')
plt.show()
- Epochs가 늘어나며 Loss는 떨어지고, Accuracy는 일정 구간까지 올라가는 모습을 보인다.
7. 요약
7.1 요약
- 딥러닝의 기초를 살짝 다루었다.
- Optimizer와 Loss Function, Activation Function 등 생소한 표헌과 잘 이해가지 않는 함수들이 대거 출연하여 어려운 내용이었다.
- 하용호님의 자료 https://www.slideshare.net/yongho/ss-79607172를 참조 하였다.
- 좀더 공부를 해야겠다.