[딥러닝]2. 딥러닝 원리
1. 선형회귀(linear regression)
= 가장 훌륭한 예측선 긋기
1) 선형회귀의 정의
- 독립변수 x를 사용해 종속변수 y의 움직임을 예측하고 설명하는 작업
- 독립변수 : 독립적으로 변할 수 있는 값
- 종속변수 : 독립변수에 의해 종속적으로 변하는 값
- 종류
1️⃣ 단순선형회귀(simple linear regression) : 독립변수 1개
2️⃣ 다중선형회귀(multiple linear regression) : 독립변수 여러개
1-1. 가장 훌륭한 예측선
- 직선의 기울기와 y 절편값을 정확하게 예측 ➡️ 최적의 a, b값 찾아내기
- ex) y = ax 구하기
X = { 2, 4, 6, 8 }
Y = { 81, 93, 91, 97 }
1-2. 최소 제곱법(method of least squares)
- 각 점의 좌표값과 함수값의 오차의 제곱의 합이 최소가 되는 경우의 선
1️⃣ 기울기 a 구하기
- 편차 : 각 값과 평균과의 차이
- 즉, a = (x,y 편차의 곱의 합) / (x 편차 제곱의 합)
• x 평균: (2 + 4 + 6 + 8) ÷ 4 = 5
• y 평균: (81+ 93 + 91 + 97) ÷ 4 = 90.5
➡️ a = 2.3
2️⃣ y절편 b 구하기
- 즉, y 평균에서 x평균에 기울기를 곱한 값을 빼면 됨
➡️ b = 90.5-(2.3 x 5) = 79
= 가장 훌륭한 예측선 긋기
- 독립변수 x를 사용해 종속변수 y의 움직임을 예측하고 설명하는 작업
- 독립변수 : 독립적으로 변할 수 있는 값
- 종속변수 : 독립변수에 의해 종속적으로 변하는 값
- 종류
1️⃣ 단순선형회귀(simple linear regression) : 독립변수 1개
2️⃣ 다중선형회귀(multiple linear regression) : 독립변수 여러개
- 직선의 기울기와 y 절편값을 정확하게 예측 ➡️ 최적의 a, b값 찾아내기
- ex) y = ax 구하기
X = { 2, 4, 6, 8 }
Y = { 81, 93, 91, 97 }
- ex) y = ax 구하기
- 각 점의 좌표값과 함수값의 오차의 제곱의 합이 최소가 되는 경우의 선
1️⃣ 기울기 a 구하기
- 편차 : 각 값과 평균과의 차이
- 즉, a = (x,y 편차의 곱의 합) / (x 편차 제곱의 합)• x 평균: (2 + 4 + 6 + 8) ÷ 4 = 5
• y 평균: (81+ 93 + 91 + 97) ÷ 4 = 90.5
➡️ a = 2.3
2️⃣ y절편 b 구하기
- 즉, y 평균에서 x평균에 기울기를 곱한 값을 빼면 됨
➡️ b = 90.5-(2.3 x 5) = 79
➡️ y = 2.3x + 79
1. 단순 반복문 이용
import numpy as np
x = [2,4,6,8]
y = [81, 93, 91, 97]
mx = np.mean(x)
my = np.mean(y)
divisor = sum([(i - mx)**2 for i in x])
# 분모
def top(x, mx, y, my):
d = 0
for i in range(len(x)):
d += (x[i] - mx)*(y[i] - my)
return d
dividend = top(x, mx, y, my)
# 분자
a = dividend/divsor
b = my - (mx * a)
print("분모:", divisor)
print("분자:", dividend)
print("기울기 a =", a)
print("y 절편 b =", b)
- divisor = (x[0] - mx)^2 + ... + (x[3] - mx)^2
- dividend = (x[0] - mx)(y[0]-my) + ... + (x[3] - mx)(y[3]-my)
2. ✅넘파이 배열 이용 시
x = np.array(x)
y = np.array(y)
divisor = ((x - x.mean()) ** 2).sum()
dividend = ((x - x.mean()) * (y - y.mean())).sum()
a = dividend/divisor
b = y.mean() - x.mean()*a
print("분모:", divisor)
print("분자:", dividend)
print("기울기 a =", a)
print("y 절편 b =", b)
y_pred = a*x + b
print("예측값 : ", y_pred)
import matplotlib.pyplot as plt
plt.rc('font', family='AppleGothic')
plt.scatter(x, y, label='실제값')
plt.scatter(x, y_pred, label='예측값')
plt.plot(x, y_pred, c='y')
plt.legend()
plt.show()
2) 평균 제곱 오차 (mean square error, MSE)
- 1️⃣ 최소 제곱 오차 : 입력이 하나일 때 가장 훌륭한 예측선 찾기
- 2️⃣ 평균 제곱 오차 : 입력이 여러 개일 때 가장 훌륭한 예측선을 찾아내기 위한 오차 평가 알고리즘
- ✔️ 오차 = 실제값 - 예측값
- 오차 합 = 각 오차값을 제곱하여 부호를 없앰
- i : x가 나오는 순서
- n : x의 총개수
- x에 대응하는 실제 값에서 예측값을 빼줌
- 여기서 평균값으로 나눠주면 평균제곱 오차임
- ❗️선형 회귀 : 임의의 직선을 그어 평균 제곱 오차를 구하고 이 값을 최소화해주는 a, b값을 찾아감
2-1. 잘못 그은 선 바로잡기
- 원리 : 임의의 직선을 그은 후 실측값과의 오차 구한 뒤(평균제곱오차법) 이전 임의의 직선과 비교하여 차츰 개선해 나감
ex) 1️⃣ 임의의 직선 : y = 3x + 76
2️⃣ 기울기를 너무 크게 잡았을 경우
3️⃣ 기울기를 너무 작게 잡은 경우
1. 반복문 이용
fake = [3, 76] # 임의의 기울기와 y절편값
data = [[2, 81], [4, 93], [6, 91], [8, 97]]
x = [i[0] for i in data]
y = [i[1] for i in data]
def predict(x): # y = ax + b
return x*fake[0] + fake[1]
def mse(y_hat, y): #mse 함수
return ((y_hat-y)**2).mean()
def mse_val(predict_result, y):#예측값과 실제값을 mse 함수에 대입
return mse(np.array(predict_result), np.array(y))
pr= []
for i in range(len(x)):#모든 값에 대하여
pr.append(predict(x[i])) #결과값에 실제 데이터에 대한 예측값 삽입
print("공부시간 = %.f, 실제 점수 = %.f, 예측 점수 = %.f" % (x[i], y[i], predict(x[i])))
print("mse 최종값: " + str(mse_val(pr, y)))
- 오차가 11임.
2. ✅넘파이 배열 이용 시
x = [2,4,6,8]
y = [81, 93, 91, 97]
X = np.array(x)
Y = np.array(y)
a, b = 3, 76
Y_pred = a*X + b
err = Y - Y_pred
MSE = (err**2).sum()/len(X)
plt.scatter(X,Y)
plt.scatter(X, Y_pred)
plt.plot(X, Y_pred)
plt.show()
2. 경사 하강법(gradient descent) : 오차수정
- 오차를 비교하여 가장 작은 방향으로 이동
- 기울기 a를 이동시켜 최솟값 m을 찾는 방법
- 순간 기울기가 0인 점이 곧 최솟값 m이 됨
- ➡️ 미분값이 0인 지점 찾기
- 1️⃣ a1에서의 미분을 구한다
- 2️⃣ 구해진 기울기의 반대 방향으로 얼마간 이동시킨 a2에서 미분
- 3️⃣ 0이 될때까지 반복
- 4️⃣ 값들은 점점 0으로 수렴하게 됨
- 절편 b
- 너무 크면 오차가 커짐
- 너무 작아도 오차가 커짐
- 최솟값을 구하려면 이차함수에서 미분해야함 ➡️ 평균제곱오차에서 나옴
- MSE에 y = ax + b 대입
- a에 대한 편미분
- b에 대한 편미분
- 연쇄법칙 : y = f(g(x)) ➡️ y' = f'(g(x))*g'(x)
- a,b에 대해 편미분이므로 이를 제외한 값은 모두 상수취급하여 미분 시 사라짐
- 시그마 편미분 = 편미분의 합
import pandas as pd
data = [[2, 81], [4, 93], [6, 91], [8, 97]]
x = [i[0] for i in data]
y = [i[1] for i in data]
plt.figure(figsize=(8,5))
plt.scatter(x,y)
plt.show()
X = np.array(x)
Y = np.array(y)
a, b = 0, 0 #기울기, y절편 초기화
lr = 0.01 # 학습률
ep = 2001 #에포크
for i in range(ep):
y_pred = a * X + b
err = Y - y_pred
a_diff = -(2/len(X))*sum(X * err)
b_diff = -(2/len(X))*sum(err)
a = a - lr*a_diff
b = b - lr*b_diff
if i % 100 == 0:
print("epoch=%.f, 기울기=%.04f, 절편=%.04f" % (i, a, b))
y_pred = a * X + b
plt.scatter(x,y)
plt.plot([min(X), max(X)],[min(Y), max(Y)])
plt.show()
- 오차를 비교하여 가장 작은 방향으로 이동
- 기울기 a를 이동시켜 최솟값 m을 찾는 방법
- 순간 기울기가 0인 점이 곧 최솟값 m이 됨
- ➡️ 미분값이 0인 지점 찾기
- 1️⃣ a1에서의 미분을 구한다
- 2️⃣ 구해진 기울기의 반대 방향으로 얼마간 이동시킨 a2에서 미분
- 3️⃣ 0이 될때까지 반복
- 4️⃣ 값들은 점점 0으로 수렴하게 됨
- 절편 b
- 너무 크면 오차가 커짐
- 너무 작아도 오차가 커짐
- 최솟값을 구하려면 이차함수에서 미분해야함 ➡️ 평균제곱오차에서 나옴
- MSE에 y = ax + b 대입
- a에 대한 편미분
- b에 대한 편미분
- 연쇄법칙 : y = f(g(x)) ➡️ y' = f'(g(x))*g'(x)
- a,b에 대해 편미분이므로 이를 제외한 값은 모두 상수취급하여 미분 시 사라짐
- 시그마 편미분 = 편미분의 합
import pandas as pd
data = [[2, 81], [4, 93], [6, 91], [8, 97]]
x = [i[0] for i in data]
y = [i[1] for i in data]
plt.figure(figsize=(8,5))
plt.scatter(x,y)
plt.show()
X = np.array(x)
Y = np.array(y)
a, b = 0, 0 #기울기, y절편 초기화
lr = 0.01 # 학습률
ep = 2001 #에포크
for i in range(ep):
y_pred = a * X + b
err = Y - y_pred
a_diff = -(2/len(X))*sum(X * err)
b_diff = -(2/len(X))*sum(err)
a = a - lr*a_diff
b = b - lr*b_diff
if i % 100 == 0:
print("epoch=%.f, 기울기=%.04f, 절편=%.04f" % (i, a, b))
y_pred = a * X + b
plt.scatter(x,y)
plt.plot([min(X), max(X)],[min(Y), max(Y)])
plt.show()
✅넘파이 이용
X = np.array([2,4,6,8])
Y = np.array([81,93,91,97])
a, b = 0, 0 #기울기, y절편 초기화
lr = 0.01 # 학습률
ep = 2001 #에포크
for i in range(ep):
y_pred = a * X + b
err = Y - y_pred
n = len(X)
a_diff = -(2/n) * (X * err).sum()
b_diff = -(2/n) * (err).sum()
a -= lr*a_diff
b -= lr*b_diff
if i % 100 == 0:
print("epoch=%.f, 기울기=%.04f, 절편=%.04f" % (i, a, b))
y_pred = a * X + b
plt.scatter(x,y)
plt.plot(X, y_pred)
plt.show()
1) 학습률(learning rate)
- 어느만큼 이동시킬지 나타내는 이동거리
- 학습률을 너무 크게 잡으면 한 점으로 수렴하지 않고 발산함.
- 인공지능에서 변화량(학습률) 결정하는 것은 중요함
2) 다중 선형 회귀
- 독립변수의 수를 여러개 사용하여 선형 회귀 수행 ➡️ 더 정확한 예측을 위함.
data = [[2, 0, 81], [4, 4, 93], [6, 2, 91], [8, 3, 97]]
x1 = [i[0] for i in data]
x2 = [i[1] for i in data]
y = [i[2] for i in data]
from mpl_toolkits import mplot3d #3D 그래프
ax = plt.axes(projection='3d')
ax.set_xlabel('study_hours')
ax.set_ylabel('private_class')
ax.set_zlabel('Score')
ax.dist = 11
ax.scatter(x1, x2, y)
plt.show()
x1 = np.array(x1)
x2 = np.array(x2)
y = np.array(y)
a1, a2, b = 0,0,0
lr = 0.003
ep = 2001
for i in range(ep):
y_pred = a1 * x1 + a2 * x2 + b
err = y - y_pred
a1_diff = -(2/len(x1))*sum(x1*err)
a2_diff = -(2/len(x2))*sum(x2*err)
b_diff = -(2/len(x1))*sum(err)
a1 -= lr*a1_diff
a2 -= lr*a2_diff
b -= lr*b_diff
# 학습률 만큼 빼주면서 학습 반복
if i % 100 == 0: # 100번 반복될 때마다 현재의 a1, a2, b 값 출력
print("epoch=%.f, 기울기1=%.04f, 기울기2=%.04f, 절편=%.04f" % (i, a1, a2, b))
✅넘파이 이용
x1 = np.array([2,4,6,8])
x2 = np.array([0,4,2,3])
y = np.array([81,93,91,97])
a1, a2, b = 0,0,0
lr = 0.003
ep = 2001
for i in range(ep):
y_pred = a1 * x1 + a2 * x2 + b
err = y - y_pred
a1_diff = -(2/len(x1))*(x1*err).sum()
a2_diff = -(2/len(x2))*(x2*err).sum()
b_diff = -(2/len(x1))*err.sum()
a1 -= lr*a1_diff
a2 -= lr*a2_diff
b -= lr*b_diff
if i % 100 == 0: # 100번 반복될 때마다 현재의 a1, a2, b 값 출력
print("epoch=%.f, 기울기1=%.04f, 기울기2=%.04f, 절편=%.04f" % (i, a1, a2, b))
y_pred = a1 * x1 + a2 * x2 + b
print('a1 : {}, a2 : {}, b : {}'.format(a1,a2,b))
print('y:', y)
print('y_pred : ', y_pred)
print('error : ', err)
3. 로지스틱 회귀(logistic regression)
- 독립변수와 종속변수의 관계를 사용하여 참 거짓 예측하는 방법
- 선형 회귀와 마찬가지로 적절한 선(S선)을 그려가는 과정
1) 시그모이드 함수
- 독립변수와 종속변수의 관계를 사용하여 참 거짓 예측하는 방법
- 선형 회귀와 마찬가지로 적절한 선(S선)을 그려가는 과정
- 결국 a, b를 구해야 함
1️⃣ a : 기울기의 경사도
✔️a값이 크면 경사도가 가팔라지고 작으면 경사도가 완만
➡️ 기울기 a와 오차의 관계 : a가 작아질수록 오차는 무한대로 커지나 a가 커질 수록 오차는 줄어든다(오차가 없어지는 건 아님)
2️⃣ b : 그래프의 좌우이동
➡️ b와 오차의 관계 : b값이 너무 작아지거나 커지면 오차도 급증* 오차공식
경사하강법 이용
- 시그모이드 함수 : y값이 0과 1 사이의 값 ➡️ 실제값이 1일 때 예측값이 0에 가까워질 수록 오차가 커짐.(역도 마찬가지)
- ➡️ 로그함수 이용
- 실제값이 1일 때, 0으로 갈수록 오차값이 커짐(-log h)
- 실제값이 0일 때, 1로 갈수록 오차값이 커짐(-log (1-h))
- 실제값 : y_data
- 실제값 1이면 B 없어짐.
코드
data = [[2, 0], [4, 0], [6, 0], [8, 1], [10, 1], [12, 1], [14, 1]]
x = [i[0] for i in data]
y = [i[1] for i in data]
plt.scatter(x, y)
plt.xlim(0, 15)
plt.ylim(-.1, 1.1)
a,b = 0,0
lr = 0.003
def sigmoid(x): # 시그모이드 함수
return 1/(1+np.e**(-x))
for i in range(2001):
for x, y in data:
a_diff = x * (sigmoid(a*x + b) - y)
b_diff = sigmoid(a*x + b) - y
a = a - lr*a_diff
b = b - lr*b_diff
if i%1000 == 0:
print("epoch=%.f, 기울기=%.04f, 절편=%.04f" % (i, a, b))
plt.scatter(x, y)
plt.xlim(0, 15)
plt.ylim(-.1, 1.1)
x_range = (np.arange(0, 15, 0.1)) # 그래프로 나타낼 x 값의 범위 정하기
plt.plot(np.arange(0, 15, 0.1), np.array([sigmoid(a * x + b) for x in x_range]))
plt.show()
퍼셉트론에 이용
- 입력값 : x1, x2
- 가중치 : a1, a2
- 출력값 y : 0 or 1
Author And Source
이 문제에 관하여([딥러닝]2. 딥러닝 원리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jjaa9292/딥러닝2.-딥러닝-원리저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)