본문 바로가기
python/deep learning

python 경사 하강법

by Falto 2021. 8. 6.

ref: https://github.com/gilbutITbook/006958/tree/master/deeplearning/deep_class

단순 선형 회귀

import random

def sqrt(x):
   return x ** 0.5

# x, y의 데이터 값
data = [[2, 81], [4, 93], [6, 91], [8, 97]]
x_data = [x_row[0] for x_row in data]
y_data = [y_row[1] for y_row in data]

# 기울기 a와 y 절편 b의 값을 임의로 정한다.
# 단, 기울기의 범위는 0 ~ 10 사이이며 y 절편은 0 ~ 100 사이에서 변하게 한다.
a = random.random() * 10
b = random.random() * 100

# y에 대한 일차 방정식 ax+b의 식을 세운다.
def predict(a, b, x):
    y = a * x + b
    return y

# RMSE 함수
def getrmse(y_predict, y_data):
   a2 = []
   for a0, a1 in zip(y_predict, y_data):
      a3 = (a0 - a1) ** 2
      a2.append(a3)
   a4 = sum(a2) / len(a2)
   a5 = sqrt(a4)
   return a5

def ab2rmse(a, b):
    y_predict = []
    for x in x_data:
        y_predict.append(predict(a, b, x))
    rmse = getrmse(y_predict, y_data)
    return rmse

k = 0.1

for i in range(2001):
    rmse0 = ab2rmse(a, b)
    rmse1 = ab2rmse(a+1e-9, b)
    d = (rmse1 - rmse0) / 1e-9
    a1 = a - k * d
    if abs(a1 - a) > 1e-9:
        a = a1
    rmse0 = ab2rmse(a, b)
    rmse1 = ab2rmse(a, b+1e-9)
    d = (rmse1 - rmse0) / 1e-9
    b1 = b - k * d
    if abs(b1 - b) > 1e-9:
        b = b1
    if i % 100 == 0:
        print('%.4f'%rmse0, '%.4f'%a, '%.4f'%b)

print('최종:', '%.4f'%rmse0, '%.4f'%a, '%.4f'%b)
결과 tensorflow pure python
RMSE 2.8810 2.8810
a 2.3000 2.3019
b 79.0000 78.9888

다중 선형 회귀

import random

mmmm = 1e-9

def sqrt(x):
   return x ** 0.5

# x1, x2, y의 데이터 값

data = [[2, 0, 81], [4, 4, 93], [6, 2, 91], [8, 3, 97]]
x1_data = [x_row1[0] for x_row1 in data]
x2_data = [x_row2[1] for x_row2 in data] # 새로 추가되는 값
y_data = [y_row[2] for y_row in data]

# 기울기 a와 y 절편 b의 값을 임의로 정한다.
# 단, 기울기의 범위는 0 ~ 10 사이이며 y 절편은 0 ~ 100 사이에서 변하게 한다.
a1 = random.random() * 10
a2 = random.random() * 10
b = random.random() * 100

# y에 대한 일차 방정식 ax+b의 식을 세운다.
def predict(a1, x1, a2, x2, b):
    y = a1 * x1 + a2 * x2 + b
    return y

# RMSE 함수
def getrmse(y_predict, y_data):
   a2 = []
   for a0, a1 in zip(y_predict, y_data):
      a3 = (a0 - a1) ** 2
      a2.append(a3)
   a4 = sum(a2) / len(a2)
   a5 = sqrt(a4)
   return a5

def ab2rmse(a1, a2, b):
    y_predict = []
    for i in range(len(x1_data)):
        y_predict.append(predict(a1, x1_data[i], a2, x2_data[i], b))
    rmse = getrmse(y_predict, y_data)
    return rmse

k = 0.1

for i in range(2001):
    rmse0 = ab2rmse(a1, a2, b)
    rmse1 = ab2rmse(a1+mmmm, a2, b)
    d = (rmse1 - rmse0) / mmmm
    a1_temp = a1 - k * d
    if abs(a1_temp - a1) > mmmm:
        a1 = a1_temp

    rmse0 = ab2rmse(a1, a2, b)
    rmse1 = ab2rmse(a1, a2+mmmm, b)
    d = (rmse1 - rmse0) / mmmm
    a2_temp = a2 - k * d
    if abs(a2_temp - a2) > mmmm:
        a2 = a2_temp

    rmse0 = ab2rmse(a1, a2, b)
    rmse1 = ab2rmse(a1, a2, b+mmmm)
    d = (rmse1 - rmse0) / mmmm
    b_temp = b - k * d
    if abs(b_temp - b) > mmmm:
        b = b_temp

    if i % 100 == 0:
        print('%.4f'%rmse0, '%.4f'%a1, '%.4f'%a2, '%.4f'%b)

print('최종:', '%.4f'%rmse0, '%.4f'%a1, '%.4f'%a2, '%.4f'%b)
결과 tensorflow pure python
RMSE 1.8370 1.2333
a1 1.2301 1.7637
a2 2.1633 2.1632
b 77.8117 77.8131

단순 로지스틱 회귀

#-*- coding: utf-8 -*-
import math
import random

mmmm = 1e-9

# x,y의 데이터 값
data = [[2, 0], [4, 0], [6, 0], [8, 1], [10, 1], [12, 1], [14, 1]]
x_data = [x_row[0] for x_row in data]
y_data = [y_row[1] for y_row in data]

# a와 b의 값을 임의로 정함
a = random.random()
b = random.random()

# y 시그모이드 함수의 방정식을 세움
def sigmoid(a, b, x):
    y = 1/(1 + math.e**(-a * x + b))
    return y

# loss를 구하는 함수
def getloss(arry):
    a0 = []
    for i in range(len(arry)):
        if y_data[i] == 0:
            a1 = - math.log(1 - arry[i])
        else:
            a1 = - math.log(arry[i])
        a0.append(a1)
    a2 = sum(a0) / len(a0)
    return a2

def var2loss(a, b):
    arry = []
    for i in range(len(x_data)):
        arry.append(sigmoid(a, b, x_data[i]))
    try:
        loss = getloss(arry)
    except ValueError as e:
        print(arry)
        raise e
    return loss

# 학습률 값
learning_rate = 0.5

# loss를 최소로 하는 값 찾기

# 학습
for i in range(60001):
    loss0 = var2loss(a, b)
    loss1 = var2loss(a+mmmm, b)
    dy_da = (loss1 - loss0) / mmmm
    new_a = a - learning_rate * dy_da
    old_a = a
    a = new_a
    
    loss0 = var2loss(a, b)
    loss1 = var2loss(a, b+mmmm)
    dy_db = (loss1 - loss0) / mmmm
    new_b = b - learning_rate * dy_db
    old_b = b
    b = new_b

    if i % 6000 == 0:
        print("Epoch: %i, loss = %.4f, 기울기 a = %.4f, 바이어스 b = %.4f" % (i, loss0, a, b))
결과 tensorflow pure python
loss 0.0017 0.0017
a 5.1489 5.1520
b 35.9003 35.9224

다중 로지스틱 회귀

#-*- coding: utf-8 -*-
import random
import math

mmmm = 1e-4

# x,y의 데이터 값
x_data = [[2, 3],[4, 3],[6, 4],[8, 6],[10, 7],[12, 8],[14, 9]]
y_data = [0, 0, 0, 1, 1, 1, 1]

# 기울기 a와 bias b의 값을 임의로 정함.
a1 = random.random()
a2 = random.random()
b = random.random()

# y 시그모이드 함수의 방정식을 세움
def sigmoid(a1, x1, a2, x2, b):
    y = 1/(1 + math.e**(- a1 * x1 - a2 * x2 - b))
    return y

# 오차를 구하는 함수
def getloss(arry):
    a0 = []
    for i in range(len(arry)):
        if y_data[i] == 0:
            a1 = - math.log(1 - arry[i])
        else:
            a1 = - math.log(arry[i])
        a0.append(a1)
    a2 = sum(a0) / len(a0)
    return a2

def var2loss(a1, a2, b):
    arry = []
    for i in range(len(x_data)):
        arry.append(sigmoid(a1, x_data[i][0], a2, x_data[i][1], b))
    try:
        loss = getloss(arry)
    except ValueError as e:
        print(arry)
        raise e
    return loss

# 학습률 값
learning_rate=0.1

# 오차를 최소로 하는 값 찾기

# 학습
for i in range(3001):
    loss0 = var2loss(a1, a2, b)
    loss1 = var2loss(a1+mmmm, a2, b)
    d = (loss1 - loss0) / mmmm
    a1 = a1 - learning_rate * d

    loss0 = var2loss(a1, a2, b)
    loss1 = var2loss(a1, a2+mmmm, b)
    d = (loss1 - loss0) / mmmm
    a2 = a2 - learning_rate * d

    loss0 = var2loss(a1, a2, b)
    loss1 = var2loss(a1, a2, b+mmmm)
    d = (loss1 - loss0) / mmmm
    b = b - learning_rate * d

    if (i + 1) % 300 == 0:
        print("step=%d, a1=%.4f, a2=%.4f, b=%.4f, loss=%.4f" % (i + 1, a1, a2, b, loss0))


# 어떻게 활용하는가
new_x = [7, 6.]  #[7, 6]은 각각 공부 시간과 과외 수업수.
new_y = sigmoid(a1, new_x[0], a2, new_x[1], b)

print("공부 시간: %d, 개인 과외 수: %d" % (new_x[0], new_x[1]))
print("합격 가능성: %6.2f %%" % (new_y*100))
결과 tensorflow pure python
a1 0.1779 0.1584
a2 1.5675 1.5958
b -8.8635 -8.8690
loss 0.0579 0.0576
입력값 (7, 6)일 때의 출력값 0.8566 0.8600

'python > deep learning' 카테고리의 다른 글

softmax 함수의 장점  (0) 2021.08.10
NAND NOR  (0) 2021.08.09

댓글