@ 멀티 레이어 퍼셉트론 이해하기위해 정리하는 글
※ 파이썬에서는 10e-50보다 작은 수를 0으로 처리함
-> 부동소수점 오차 방지를 위해 10e-5 소수점으로 작업
▼ 부동소수점 : 가수부와 지수부로 나누어서 저장, 2^n이 아니면 약간의 오차 발생,
javascript의 Bigint에서 오차가 발생하는 원인 상기하기
퍼셉트론 함수 만들기 1
단일 퍼셉트론 동작
epsilon = 0.000001 # 부동소수점 오차 방지
def perceptron(x1, x2):
w1, w2, b = 1.0, 1.0, -1.5
sum = x1*w1 + x2*x2 + b
if sum > epsilon :
return 1
else :
return 0
# 출력, AND 최적화
print(perceptron(0,0))
print(perceptron(0,1))
print(perceptron(1,0))
print(perceptron(1,1))
>>
0
0
0
1
멀티 레이어 퍼셉트론 동작 원리
import numpy as np
def perceptron(X1, X2):
X = np.array([X1,X2])
W = np.array
b = -1.5
sum = np.dot(W,X) + b
if sum > epsilon:
return 1
else :
return -0
# step_func 함수, <- 안에 내적으로 계산해서 넣
def step_func(t):
if t > epsilon :
return 1
else :
return 0
step1 ) 임의의 학습 시킬 데이터 지정
# 학습을 시킬려면 학습 데이터 필요
X = np.array([[0,0,1], # 맨 끝의 1은 바이어스를 위한 갓,
[0,1,1],
[1,0,1],
[1,1,1]])
X.shape, len(X[0])
>>
((4, 3), 3)
step 2) 임의의 종속변수 행렬 지정, 구할 가중치 초기화(저장할 행렬 생성)
y = np.array([0, 0, 0, 1]) # 종속변수 행렬
W = np.zeros(len(X[0])) # 가중치를 저장하는 행렬
step 3) 퍼셉트론 학습 알고리즘
원래는 객체지향 코딩을 해야하지만 쉽게 이해하기 위해서 함수로 사용
global로 전역변수 가져오기
# 퍼셉트론 학습 알고리즘
def perceptron_fit(X, y , epochs=10):
global W
eta = 0.2 # 학습률
# 오차 계산 => 학습로직
# 학습 횟수 만큼 반복
for t in range(epochs):
print('epoch = ', t, '='*10)
# 데이타 만큼 반복
for i in range(len(X)):
# 예측 값 구하기
predict = step_func(np.dot(X[i],W))
error = y[i] - predict # 오차 계산
W += eta * error * X[i] # 가중치 없데이트
print('현재 입력=',X[i],'정답=',y[i],'예측=', predict,'변경된 W=', W)
print('='*20)
실행
print(perceptron_fit(X, y, 10))
>>
epoch = 0 ==========
현재 입력= [0 0 1] 정답= 0 예측= 0 변경된 W= [0. 0. 0.]
현재 입력= [0 1 1] 정답= 0 예측= 0 변경된 W= [0. 0. 0.]
현재 입력= [1 0 1] 정답= 0 예측= 0 변경된 W= [0. 0. 0.]
현재 입력= [1 1 1] 정답= 1 예측= 0 변경된 W= [0.2 0.2 0.2]
====================
epoch = 1 ==========
현재 입력= [0 0 1] 정답= 0 예측= 1 변경된 W= [0.2 0.2 0. ]
현재 입력= [0 1 1] 정답= 0 예측= 1 변경된 W= [ 0.2 0. -0.2]
현재 입력= [1 0 1] 정답= 0 예측= 0 변경된 W= [ 0.2 0. -0.2]
현재 입력= [1 1 1] 정답= 1 예측= 0 변경된 W= [0.4 0.2 0. ]
====================
epoch = 2 ==========
현재 입력= [0 0 1] 정답= 0 예측= 0 변경된 W= [0.4 0.2 0. ]
현재 입력= [0 1 1] 정답= 0 예측= 1 변경된 W= [ 0.4 0. -0.2]
현재 입력= [1 0 1] 정답= 0 예측= 1 변경된 W= [ 0.2 0. -0.4]
현재 입력= [1 1 1] 정답= 1 예측= 0 변경된 W= [ 0.4 0.2 -0.2]
====================
epoch = 3 ==========
현재 입력= [0 0 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.2]
현재 입력= [0 1 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.2]
현재 입력= [1 0 1] 정답= 0 예측= 1 변경된 W= [ 0.2 0.2 -0.4]
현재 입력= [1 1 1] 정답= 1 예측= 0 변경된 W= [ 0.4 0.4 -0.2]
====================
epoch = 4 ==========
현재 입력= [0 0 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.4 -0.2]
현재 입력= [0 1 1] 정답= 0 예측= 1 변경된 W= [ 0.4 0.2 -0.4]
현재 입력= [1 0 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.4]
현재 입력= [1 1 1] 정답= 1 예측= 1 변경된 W= [ 0.4 0.2 -0.4]
====================
epoch = 5 ==========
현재 입력= [0 0 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.4]
현재 입력= [0 1 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.4]
현재 입력= [1 0 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.4]
현재 입력= [1 1 1] 정답= 1 예측= 1 변경된 W= [ 0.4 0.2 -0.4]
====================
epoch = 6 ==========
현재 입력= [0 0 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.4]
현재 입력= [0 1 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.4]
현재 입력= [1 0 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.4]
현재 입력= [1 1 1] 정답= 1 예측= 1 변경된 W= [ 0.4 0.2 -0.4]
====================
epoch = 7 ==========
현재 입력= [0 0 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.4]
현재 입력= [0 1 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.4]
현재 입력= [1 0 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.4]
현재 입력= [1 1 1] 정답= 1 예측= 1 변경된 W= [ 0.4 0.2 -0.4]
====================
epoch = 8 ==========
현재 입력= [0 0 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.4]
현재 입력= [0 1 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.4]
현재 입력= [1 0 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.4]
현재 입력= [1 1 1] 정답= 1 예측= 1 변경된 W= [ 0.4 0.2 -0.4]
====================
epoch = 9 ==========
현재 입력= [0 0 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.4]
현재 입력= [0 1 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.4]
현재 입력= [1 0 1] 정답= 0 예측= 0 변경된 W= [ 0.4 0.2 -0.4]
현재 입력= [1 1 1] 정답= 1 예측= 1 변경된 W= [ 0.4 0.2 -0.4]
====================
이때의 W
array([ 0.4, 0.2, -0.4])
※ bool 함수를 int 타입으로 변경 후 return 하면 0, 1로 받을 수 있음 // 아이디어로 사용하기
활성함수(Activation Function) 종류
계단함수 _ 단일 퍼셉트론에서 사용
sigmoid 함수
Hyperbolic Tangent 보다 곡선이 더 급함, 오차 폭이 큼 -> 이상치에 더 영향을 받음
Hyperbolic Tangent 함수 (tanh)
Relu 함수
- rgb 등에서 사용, 0보다 낮게 가는 leaky Relu도 있음
순방향 MLP
미분을 통해서 극값에 이를 때 까지 탐색하게 됨
ex) sigmoid를 이용해 구해보기
step 1) 함수 정의
# 활성화 함수 (시그모이드)
def actf(x):
return 1.0 / (1.0 + np.exp(-x))
# 시그모이드 함수의 미분치
# d/dx(sigmoid(x)) = sigmoid(x)(1-sigmoid(x))
def actf_deriv(x):
return x * (1-x)
step 2) 입력값 주기
# 입력 유닛수, 은닉 유닛수, 출력 유닛수
inputs, hiddens, outputs = 2, 2, 1
learning_rate = 0.2
# 훈련 데이타
X = np.array([[0,0], [0,1], [1,0], [1,1]])
T = np.array([[0],[0],[0],[1]])
# 가중치, 바이어스
W1 = np.array([[0.10, 0.20],[0.30, 0.60]])
W2 = np.array([[0.50],[0.60]])
B1 = np.array([0.1,0.2])
B2 = np.array([0.3])
step 3) 순방향 전파 계산 함수
# 순방향 전파 계산
def predict(x):
layer0 = x #입력 레이어
Z1 = np.dot(layer0, W1) + B1 # 가중치 행렬곱 계산
layer1 = actf(Z1) # 활성화 함수 적용
Z2 = np.dot(layer1, W2) + B2 # 가중치 행렬곱 계산
layer2 = actf(Z2) # 활성화 함수 적용
return layer0, layer1, layer2
step 4) test 함수 만들기
def test():
# print(predict(X))
for x, y in zip(X,T):
# print(x,y)
x = np.reshape(x, (1,-1)) # -1은 알아서 찾아주게끔
layer0, layer1, layer2 = predict(x)
print(x,y,layer2)
실행 결과
test()
[[0 0]] [0] [[0.70938314]]
[[0 1]] [0] [[0.73367104]]
[[1 0]] [0] [[0.71791234]]
[[1 1]] [1] [[0.74074894]]
+ 추가 오차함수 (MSE, RMSE)로 구해보기
# 오차 함수
def MSE(target, y):
return (0.5 * #데이터 사이즈만큼 바뀜 (n개)
np.sum((y-target)**2))
print(MSE(target, y)) # MSE
print(np.sqrt(MSE(target,y))) #RMSE 확인
순간변화율(gradient)
step 1) 임의의 손실함수를 정의
# 그래디언트
x = 10
learning_rate = 0.2 # 학습을 어느정도로 시킬지, 학습 스텝, 경사 비율
# 너무 크면, 점짐적 하강하지 못하고 발산, 너무 작으면 아주 오랜 시간 걸림
predision = 0.00001 # 최소 크기
max_iterations = 100 # 반복 횟수
# 손실함수를 람다식으로 정의
loss_func = lambda x: (x-3)**2 + 10 #예시
step 2) step 1의 gradient 정의
# 그래디언트를 람다식으로 정의,
# 손실함수의 1차 미분값
gradient = lambda x: 2*x - 6
위의 과정을 이용해 GD(경사하강법) 을 구해보기
# 그래디언트 강하법
for i in range(max_iterations):
x = x - learning_rate * gradient(x)
print('손실함수 =(',x,')',loss_func(x))
list에 담아서 그래프로 표현
list1 = []
list2 = []
for i in range(max_iterations):
x = x - learning_rate * gradient(x)
list1.append(x)
list2.append(loss_func(x))
print('손실함수 : (', list1[i], ')', list2[i])
역방향(역전파, Backpropagation)
predict(x)를 순방향 전파 함수로 정의 (위 쪽에 작성)
max_iterations, learning_rate는 직접 찾아가면서 해야함(뭐가 알맞는지 잘 알 수 없음, 직접 하면서 찾기)
# 역방향 전파 계산
max_iterations = 90000 #임의로 주는 횟수
def fit():
global W1, W2, B1, B2
for i in range(max_iterations): # 학습 횟수 만큼 반복
for x, y in zip(X,T) : # 학습 샘플을 하나씩
x = np.reshape(x, (1, -1)) # 2차원 행렬로 변환
y = np.reshape(y, (1, -1)) # 2차원 행렬로 변환
layer0, layer1, layer2 = predict(x) # 순방형 계산
layer2_error = layer2 - y # 오차 계산 , y는 여기서는 임의로 오차를 적어줌
layer2_delta = layer2_error * actf_deriv(layer2) # 출력층 델타
layer1_error = np.dot(layer2_delta, W2.T) # 은닉층 오차 계산, .T는 뒤집음
layer1_delta = layer1_error * actf_deriv(layer1) # 은닉층 델타
W2 += -learning_rate * np.dot(layer1.T, layer2_delta)
W1 += -learning_rate * np.dot(layer0.T, layer1_delta)
B2 += -learning_rate * np.sum(layer2_delta, axis = 0)
B1 += -learning_rate * np.sum(layer1_delta, axis = 0)
학습 최적화 - 1. 미니 배치 경사 하강법
풀 배치 경사 하강법 시 전체를 보고 작업하기에 비효율 적임, 이를 해결하기 위해 나눠서 사용
※ SGD(확률적 경사 하강법) <- 복잡한 데이터 3차원 굴곡 상황에서 최적화 안되는 문제 해결하기 위해서 사용 (GD 업그레이드 버전)
step 1 ) 데이터 학습데이터와 테스트 데이터 나누기
# 미니배치
import tensorflow as tf
import numpy as np
# 데이터를 학습 데이터와 테스트 데이터 나누기
(x_train, y_train), (x_test, y_test) = \
tf.keras.datasets.mnist.load_data()
step 2) batch_size 지정
batch_size = 12 # 배치 크기
step 3) 학습
selected = np.random.choice(data_size, batch_size)
x_batch = x_train[selected]
y_batch = y_train[selected]
optimizer 종류
학습률 : 너무 크면 발산, 너무 적으면 너무 느리게 작동 ~> 얼마나 적게 계산해서 백미분 시키냐 정함
모멘텀 : 가속도 개념, 어느 정도 가중치를 줘서 다시 언덕을 올라가서 떨어지게끔?
adagrad : 학습을 하면서 점점 학습률이 줄어들게 해주는 것
RMSprop : adagrad 수정판, 요즘 간간히 사용, 가중을 하는데 이동 평균을 구해서 가중 (평균치를 이용한 가중치)
Adam : 요즘 많이 사용, RMSprop + 모멘텀, 좋은 것만 뽑아서 사용, 연산이 많음
tenserflow 설치 방법
-by window
tenserflow 설치
1. 새 가상환경 만들기
conda create -n tf29py38 python=3.8
2. 가상환경 실행
tf29py38
tensorflow 2.9가 python 3.8에서 제일 안정적임
3. tensorflow numpy pandas jupyter notebook lab seaborn matplotlib tqdm 설치
conda install 설치할 것들
4. 주피터 노트북 내에 가상환경이 인식이 안 될 경우
conda install ipykernel
python -m ipykernel install --user --name tf29py38 --display-name tf20py38
5. 커널 선택
※ gpu 사용하려면 좋은 컴퓨터 쓰던가, 없으면 colab 이용하기 _
'복습용 기술공부' 카테고리의 다른 글
230315 CNN과 tensorflow 기본 (0) | 2023.03.15 |
---|---|
230314 DNN 기본 (0) | 2023.03.14 |
230310 딥러닝 개념 (1) | 2023.03.10 |
230309 머신 러닝 _ 업무처럼 연습해보기 (0) | 2023.03.09 |
230308 데이터 분석 연습, 클러스트 군집 (0) | 2023.03.08 |