다중 선형회귀(Multi-variable Linear Regression)

Matrix

⇒ $H(x_1, x_2, x_3, ..., x_n) = w_1 x_1 + w_2 x_2 + w_3 x_3 + ... \ +w_n x_n$

$\rightarrow \begin{pmatrix} x_1, x_2, x_3 \end{pmatrix} \times \begin{pmatrix} w_1 \\ w_2 \\ w_3 \end{pmatrix} = (x_1 w_1 + x_2 w_2 + x_3 w_3)$

$\therefore H(x) = XW$

앞에 오는 Matrix의 행과 뒤쪽에 오는 Matrix의 열을 함께 연산을 하기 때문에 X가 앞에 오고 W가 뒤에 오는 형태

일반

import tensorflow as tf

# data input
x1 = [ 73.,  93.,  89.,  96.,  73.]
x2 = [ 80.,  88.,  91.,  98.,  66.]
x3 = [ 75.,  93.,  90., 100.,  70.]
Y  = [152., 185., 180., 196., 142.]

# weights
w1 = tf.Variable(tf.random.normal([1]))
w2 = tf.Variable(tf.random.normal([1]))
w3 = tf.Variable(tf.random.normal([1]))
b = tf.Variable(tf.random.normal([1]))

learning_rate = 0.000001

for i in range(1000 + 1):
    # 비용 함수의 gradient를 기록하기 위해
    with tf.GradientTape() as tape:
        hypothesis = w1 * x1 + w2 * x2 + w3 * x3 + b
        cost = tf.reduce_mean(tf.square(hypothesis - Y))
    
    # 비용 함수의 gradient를 계산
    w1_grad, w2_grad, w3_grad, b_grad = tape.gradient(cost, [w1, w2, w3, b])
    
    # 기존의 값에서 learning_rate * w1_grad를 빼서 업데이트
    w1.assign_sub(learning_rate * w1_grad)
    w2.assign_sub(learning_rate * w2_grad)
    w3.assign_sub(learning_rate * w3_grad)
    b.assign_sub(learning_rate * b_grad)
    
    if i % 50 == 0:
        print("{:5} | {:12.4f}".format(i, cost.numpy()))

Matrix 사용

import tensorflow as tf
import numpy as np
data = np.array([
    # X1,   X2,    X3,   y
    [ 73.,  80.,  75., 152. ],
    [ 93.,  88.,  93., 185. ],
    [ 89.,  91.,  90., 180. ],
    [ 96.,  98., 100., 196. ],
    [ 73.,  66.,  70., 142. ]
], dtype=np.float32)    # 5 X 3 행렬

# slice data
X = data[:, :-1] # [행 , 열] 슬라이싱
y = data[:, [-1]]

W = tf.Variable(tf.random.normal((3, 1))) # weight 는 3 X 1 행렬
b = tf.Variable(tf.random.normal((1,)))

learning_rate = 0.000001

# 가설함수
def predict(X):
    return tf.matmul(X, W) + b

print("epoch | cost")

n_epochs = 2000
for i in range(n_epochs+1):
    with tf.GradientTape() as tape:
        cost = tf.reduce_mean((tf.square(predict(X) - y)))

    W_grad, b_grad = tape.gradient(cost, [W, b])

    W.assign_sub(learning_rate * W_grad)
    b.assign_sub(learning_rate * b_grad)
    
    if i % 100 == 0:
        print("{:5} | {:10.4f}".format(i, cost.numpy()))