Adventure Time - Finn 3
본문 바로가기
AI/ML

Multi-variable Linear Regression 코드로 구현해보기 (TensorFlow)

by hyun9_9 2026. 3. 7.

지난 포스트에서 여러 변수를 사용하는 Multi-variable 선형 회귀와 Matrix를 이용한 표현 방법을 알아봤습니다.
이번엔 실제 코드로 두 가지 방법으로 구현해보겠습니다.


방법 1 : 변수를 하나하나 따로 기술하기

import tensorflow as tf

# data and label
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):
    with tf.GradientTape() as tape:
        hypothesis = w1*x1 + w2*x2 + w3*x3 + b
        cost = tf.reduce_mean(tf.square(hypothesis - Y))
    w1_grad, w2_grad, w3_grad, b_grad = tape.gradient(cost, [w1, w2, w3, b])

    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()))

방법 2 : Matrix로 간결하게 표현하기

import tensorflow as tf
import numpy as np

# data and label
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)

# slice data
X = data[:, :-1]   # 마지막 열 제외 → 입력 데이터 [5, 3]
Y = data[:, [-1]]  # 마지막 열만    → 정답 데이터 [5, 1]

# weights
W = tf.Variable(tf.random.normal([3, 1]))  # [입력 변수 수, 출력 수]
b = tf.Variable(tf.random.normal([1]))

learning_rate = 0.000001

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

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 % 50 == 0:
        print("{:5} | {:12.4f}".format(i, cost.numpy()))

방법 1 코드 살펴보기

데이터와 가중치 선언

x1 = [73., 93., 89., 96., 73.]
x2 = [80., 88., 91., 98., 66.]
x3 = [75., 93., 90., 100., 70.]

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

지난 포스트에서 배운 가설 H(x1,x2,x3) = w1*x1 + w2*x2 + w3*x3 + b 를 그대로 코드로 옮긴 것입니다.
변수가 3개이므로 가중치도 w1, w2, w3 으로 3개를 선언합니다.

가설 계산 및 W 업데이트

hypothesis = w1*x1 + w2*x2 + w3*x3 + b
cost = tf.reduce_mean(tf.square(hypothesis - Y))

w1_grad, w2_grad, w3_grad, b_grad = tape.gradient(cost, [w1, w2, w3, b])

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)

변수가 3개이므로 gradient도 3개, assign_sub도 3번 따로따로 해줘야 합니다.
변수가 수백 개라면 이 방식으로는 감당이 안 되겠죠.


방법 2 코드 살펴보기

데이터를 Matrix로 묶기

data = np.array([
    [73., 80., 75., 152.],
    ...
], dtype=np.float32)

X = data[:, :-1]   # 마지막 열 제외 → 입력 [5, 3]
Y = data[:, [-1]]  # 마지막 열만    → 정답 [5, 1]

흩어져 있던 x1, x2, x3, Y 를 하나의 행렬로 묶고, 슬라이싱으로 입력과 정답을 분리합니다.

W의 Shape

W = tf.Variable(tf.random.normal([3, 1]))

지난 포스트에서 배운 내용 그대로입니다.

[n, 3]  *  [3, 1]  =  [n, 1]
  X     *    W    =    결과

입력 컬럼이 3개, 출력이 1개이므로 W의 shape는 [3, 1] 입니다.

tf.matmul 로 Dot Product

def predict(X):
    return tf.matmul(X, W) + b

tf.matmul 은 행렬의 Dot Product(점곱) 를 수행하는 함수입니다.
지난 포스트에서 배운 H(X) = XW 를 그대로 한 줄로 표현한 것입니다.

W 업데이트도 한 번에

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

방법 1에서는 w1, w2, w3 을 따로따로 업데이트했지만,
행렬을 사용하면 변수가 몇 개든 W 하나만 업데이트하면 됩니다.


두 방법 비교

방법 1 (변수 따로) 방법 2 (Matrix)

가설 w1*x1 + w2*x2 + w3*x3 + b tf.matmul(X, W) + b
W 선언 w1, w2, w3 따로 선언 W = tf.Variable([3, 1])
gradient w1_grad, w2_grad, w3_grad W_grad 하나
변수 100개라면 100줄 작성 동일하게 한 줄

결론

행렬(Matrix)을 사용하지 않으면 변수의 개수만큼 따로따로 기술해야 하지만,
행렬을 사용하면 변수가 몇 개든 H(X) = XW + b 한 줄로 표현이 가능합니다. 🚀