
💡 1분 핵심 요약 (TL;DR)
- ✅ 경사 하강법 실습 — a와 b를 각각 편미분해 2001번 업데이트하면 기울기 2.3, 절편 79에 도착
- ✅ Matplotlib — scatter(산점도), plot(직선), show(화면 표시)로 결과를 그래프로 확인하는 시각화 라이브러리
- ✅ 다중 선형 회귀 — 종속 변수 하나를 독립 변수 두 개 이상으로 예측. y = a1x1 + a2x2 + b, 직선 대신 3D 평면
- ✅ 효과 — 과외 시간(x2)을 더하자 평균 제곱 오차가 8.3 → 약 0.07로 크게 감소
- ✅ 텐서플로 — 구글 브레인팀이 만든 오픈 소스. 계산 구조와 목표 함수만 정의하면 미분을 자동 계산
- ✅ 용어 바꾸기 — 가정하는 식 = 가설 함수 H(x), 기울기 = 가중치, 절편 = 편향, 오차 식 = 손실 함수, 경사 하강법 = 옵티마이저
📚 부산디지털대학교 '파이썬 기반의 AI프로그래밍' 5주차 강의노트와 직접 실습한 코랩 노트를 바탕으로 정리한 학습 노트입니다. (출처는 글 하단 참고)
01 실습 준비 — Matplotlib으로 데이터 보기
1강 · 숫자를 그래프로 바꿔 주는 시각화 라이브러리
4주차에서 개념으로 배운 경사 하강법을 이번 주에는 코드로 직접 돌려 봅니다. 먼저 결과를 눈으로 확인할 수 있도록 Matplotlib(맷플롯립)을 불러옵니다. Matplotlib은 파이썬에서 데이터 시각화에 가장 널리 쓰이는 라이브러리로, 다양한 유형의 그래프와 플롯을 그릴 수 있습니다.
| 함수 | 하는 일 |
| plt.scatter() | 실제 점수를 산점도(점)로 표시 |
| plt.plot() | 예측 점수를 직선으로 표시 |
| plt.title() · xlabel() · ylabel() | 그래프 제목과 x축·y축 이름 설정 |
| plt.legend() | 범례 표시 |
| plt.grid() | 격자(그리드) 추가 |
| plt.show() | 그래프를 화면에 표시 |
데이터를 산점도로 그려 보기
import numpy as np
import matplotlib.pyplot as plt # 시각화 라이브러리
x = np.array([2, 4, 6, 8]) # 공부 시간
y = np.array([81, 93, 91, 97]) # 성적
plt.scatter(x, y) # 점 찍기
plt.show() # 화면에 표시
▶ 실행 결과 (그래프 출력)
(출력 영역에 4개의 점이 찍힌 산점도가 나타남 — 아래 그림 1)

02 경사 하강법 실습 코드 한 줄씩 읽기
4주차 개념이 그대로 코드가 된다
경사 하강법으로 기울기 a와 절편 b 찾기
#초기 변수 설정
a = 0 #기울기
b = 0 #절편
lr = 0.03 #학습률
epochs = 2001 #학습 반복 횟수
n = len(x) #데이터 포인트의 수
for i in range(epochs):
y_pred = a * x + b #예측 값 계산
error = y - y_pred #오차 계산
a_diff = (2/n) * sum(-x * (error)) #기울기의 변화량(a에 대한 편미분 수행)
b_diff = (2/n) * sum(-(error)) #오차의 합을 통한 절편의 변화량(b에 대한 편미분 수행)
a = a - lr * a_diff #학습률 이용하여 기울기 업데이트
b = b - lr * b_diff #학습률 이용하여 절편 업데이트
if i % 100 == 0: #100 에포크마다 출력
print("epoch=%.f, 기울기=%.04f, 절편=%.04f" % (i, a, b))
▶ 실행 결과 (lr = 0.03, epochs = 2001 (중간 일부 생략))
epoch=0, 기울기=27.8400, 절편=5.4300
epoch=100, 기울기=7.0739, 절편=50.5117
epoch=200, 기울기=4.0960, 절편=68.2822
epoch=300, 기울기=2.9757, 절편=74.9678
epoch=400, 기울기=2.5542, 절편=77.4830
epoch=500, 기울기=2.3956, 절편=78.4293
⋮
epoch=1000, 기울기=2.3007, 절편=78.9957
⋮
epoch=1500, 기울기=2.3000, 절편=79.0000
⋮
epoch=2000, 기울기=2.3000, 절편=79.0000

처음에는 기울기가 27.84로 크게 튀지만, 반복할수록 기울기 2.3, 절편 79로 수렴합니다. 3주차 최소 제곱법, 4주차 미리 보기에서 구한 값과 똑같습니다.
| 코드 | 의미 | 4주차 개념 |
| y_pred = a * x + b | 현재 a, b로 예측 | 가설(임의의 직선) |
| error = y - y_pred | 실제 − 예측 | 오차 |
| a_diff = (2/n) * sum(-x * error) | MSE를 a로 편미분한 값 | ∂MSE/∂a |
| b_diff = (2/n) * sum(-error) | MSE를 b로 편미분한 값 | ∂MSE/∂b |
| a = a - lr * a_diff | 기울기 반대 방향으로 학습률만큼 이동 | 경사 하강 |
| epochs = 2001 | 위 과정을 반복할 횟수 | 반복 |
📖 에포크(epoch)란?
가지고 있는 데이터 전체를 한 번 다 사용해 학습하는 것을 1 에포크라고 합니다. epochs = 2001이면 데이터 4개 전체로 a와 b를 2,001번 고친다는 뜻입니다. range(2001)은 0부터 2000까지이므로, i % 100 == 0 조건으로 0, 100, …, 2000번째에 모두 21번 출력됩니다.
❌ 강의노트 코드를 복사할 때 주의 — 긴 대시(–)
강의노트 PDF의 error = y – y_pred에 들어 있는 기호는 키보드의 빼기(-)가 아니라 긴 대시(–, U+2013)입니다. 그대로 복사해 실행하면 SyntaxError: invalid character '–' (U+2013) 오류가 납니다. 코랩에 붙여 넣은 뒤에는 빼기 기호를 키보드로 다시 입력하세요.
❌ 시험 함정 — 경사 하강법은 "편미분"
경사 하강법에서 a와 b를 구할 때는 식 전체를 미분하는 것이 아니라, 필요한 값인 a와 b를 중심으로 각각 미분합니다. 즉 편미분을 수행해 예측선을 만듭니다. 코드의 a_diff와 b_diff가 바로 그 두 편미분 값입니다.
결과를 그래프로 확인하기
최종 예측선 그리기
#최종 예측과 시각화
y_pred = a * x + b
plt.scatter(x, y) # 실제 점수(점) - 산점
plt.plot(x, y_pred, 'r') # 예측선(빨간 직선)
plt.show()
▶ 실행 결과 (그래프 출력)
(점 4개를 가로지르는 빨간 예측선 y = 2.3x + 79가 나타남 — 아래 그림 2)

✓ plot의 'r'은?
plt.plot()의 세 번째 인자는 선의 색과 모양을 정하는 형식 문자열입니다. 'r'은 red(빨간색) 실선, 'b'는 파란색, 'g--'는 초록 점선입니다.
03 다중 선형 회귀란?
2강 · 성적은 공부 시간만으로 정해지지 않는다
지금까지는 공부한 시간 하나로 성적을 예측했습니다. 하지만 실제 성적에는 공부 시간 말고도 다른 요소가 영향을 줍니다. 그래서 등장하는 것이 다중 선형 회귀입니다.
📖 다중 선형 회귀 (Multiple Linear Regression)
하나의 종속 변수와 두 개 이상의 독립 변수 간의 관계를 모델링하는 통계 기법
· 종속 변수(Dependent Variable) : 예측하고자 하는 변수, 보통 Y로 표기
· 독립 변수(Independent Variables) : 종속 변수에 영향을 미치는 변수
공부한 시간(x1)에 과외 수업 시간(x2)이라는 독립 변수를 하나 더 추가한 새 데이터입니다.
| 공부한 시간 x1 | 2 | 4 | 6 | 8 |
| 과외 수업 시간 x2 | 0 | 4 | 2 | 3 |
| 성적 y | 81 | 93 | 91 | 97 |
y = a1x1 + a2x2 + b
a1 : 공부 시간의 기울기 | a2 : 과외 시간의 기울기 | b : 절편
| 단순 선형 회귀 · 독립 변수 1개 (x) · 2차원 좌표 위의 직선 · y = ax + b |
다중 선형 회귀 · 독립 변수 2개 이상 (x1, x2 …) · 축이 하나 늘어난 3D 공간의 평면 · y = a1x1 + a2x2 + b |

| 다중 선형 회귀의 특징 | 내용 |
| 현실 반영 | 현실 데이터는 여러 요인이 복합적으로 영향 → 단일 선형 회귀로는 부족 |
| 정확도 향상 | 여러 독립 변수를 활용해 종속 변수를 더 정확하게 예측 |
| 상호작용 분석 | 독립 변수 간 상호작용을 분석해 복잡한 관계 이해 |
| 변수별 영향 평가 | 여러 변수의 영향을 동시에 평가해 각 변수의 중요성과 역할 파악 |
❌ 시험 함정 — 다중 선형 회귀는 "변수 개수를 늘리는" 방식
일반 선형 회귀가 하나의 변수를 기준으로 예측한다면, 다중 선형 회귀는 정보를 가진 변수의 개수를 늘려 예측 정확도를 높이는 방식입니다. 그래서 2차원의 예측 직선이 아니라 다차원의 예측 평면을 조절하게 됩니다.
04 다중 선형 회귀 실습
기울기가 두 개, 편미분도 세 번
3D 산점도로 데이터 분포 보기
import numpy as np
import matplotlib.pyplot as plt
#공부 시간 x1과 과외 시간 x2, 성적 y의 넘파이 배열
x1 = np.array([2, 4, 6, 8])
x2 = np.array([0, 4, 2, 3])
y = np.array([81, 93, 91, 97])
#시각적 데이터 분포(3D) 확인
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d') # 3D 좌표축 만들기
ax.scatter3D(x1, x2, y) # ax.scatter(x1, x2, y)로 써도 똑같이 동작
plt.show()
▶ 실행 결과 (그래프 출력)
(x1·x2·y 세 축으로 된 3D 공간에 점 4개가 나타남 — 아래 그림 3)

✓ scatter3D와 scatter
projection='3d'로 만든 3D 좌표축(Axes3D)에서는 2D 그래프에서 쓰던 ax.scatter(x1, x2, y)를 그대로 써도 3D 산점도가 그려집니다. 강의노트의 scatter3D도 그대로 유효하므로 둘 중 편한 쪽을 쓰면 됩니다.
경사 하강법으로 a1, a2, b 찾기
#기울기와 절편 값 초기화
a1 = 0
a2 = 0
b = 0
lr = 0.01 #학습률
epochs = 2001
n = len(x1)
for i in range(epochs):
y_pred = a1 * x1 + a2 * x2 + b #예측 값 계산
error = y - y_pred #실제 값과 비교한 오차
a1_diff = (2/n) * sum(-x1 * (error)) #오차함수를 a1으로 편미분
a2_diff = (2/n) * sum(-x2 * (error)) #오차함수를 a2로 편미분
b_diff = (2/n) * sum(-(error)) #오차함수를 b로 편미분
a1 = a1 - lr * a1_diff #학습률을 이용하여 기존 값 업데이트
a2 = a2 - lr * a2_diff
b = b - lr * b_diff
if i % 100 == 0:
print("epoch=%.f, 기울기1=%.04f, 기울기2=%.04f, 절편=%.04f" % (i, a1, a2, b))
print("실제 점수:", y)
print("예측 점수:", y_pred)
▶ 실행 결과 (lr = 0.01, epochs = 2001 (중간 일부 생략))
epoch=0, 기울기1=9.2800, 기울기2=4.2250, 절편=1.8100
epoch=100, 기울기1=9.5110, 기울기2=5.0270, 절편=22.9205
epoch=500, 기울기1=3.7447, 기울기2=3.0608, 절편=62.4448
⋮
epoch=1000, 기울기1=1.9583, 기울기2=2.4440, 절편=74.7103
⋮
epoch=1500, 기울기1=1.5936, 기울기2=2.3180, 절편=77.2146
⋮
epoch=2000, 기울기1=1.5191, 기울기2=2.2923, 절편=77.7260
실제 점수: [81 93 91 97]
예측 점수: [80.76387645 92.97153922 91.42520875 96.7558749 ]
예측 점수가 실제 점수 81, 93, 91, 97에 거의 붙었습니다. 독립 변수가 하나 늘었을 뿐인데 예측이 훨씬 정확해졌습니다.
| 모델 | 예측식 | 평균 제곱 오차 |
| 단순 선형 회귀 (3·4주차) | y = 2.3x + 79 | 8.30 |
| 다중 선형 회귀 (5주차) | y ≈ 1.52x1 + 2.29x2 + 77.73 | 약 0.07 |
📖 심화 — 2001번으로는 아직 끝까지 내려가지 않았다
같은 데이터를 최소 제곱법으로 정확히 풀면 a1 = 1.5, a2 ≈ 2.2857, b ≈ 77.8571입니다. 실습 결과(1.5191, 2.2923, 77.7260)는 그 근처까지 왔지만 아직 계속 움직이는 중입니다. 변수가 늘어나고 학습률이 0.01로 작아져 수렴이 느려졌기 때문입니다. epochs를 더 늘리면 이 값에 더 가까워집니다(7장 텐서플로 실습에서 5,000번 학습하면 1.5002, 2.2858, 77.856). 4주차에서 배운 "학습률이 작으면 수렴이 느리다"를 실제로 확인할 수 있는 부분입니다.
✓ 예측 점수 출력에 대해 한 가지 더
마지막 print("예측 점수:", y_pred)의 y_pred는 반복문 마지막 회차의 업데이트 직전 a1, a2, b로 계산한 값입니다. 업데이트가 아주 작게 일어나는 단계라 결과 차이는 소수점 셋째 자리 수준이지만, 최종 값으로 예측하려면 반복문이 끝난 뒤 y_pred = a1 * x1 + a2 * x2 + b를 한 번 더 계산하면 됩니다.
05 텐서플로(TensorFlow)란?
3강 · 구글 브레인팀이 만든 딥러닝 오픈 소스
| 특징 | 내용 |
| 개발 | 구글 브레인(Google Brain)팀이 개발한 오픈 소스 라이브러리 |
| 표현력 | 데이터 플로 그래프(데이터가 흐르는 계산 그래프)를 통한 풍부한 표현력 |
| 활용 범위 | 아이디어 테스트 단계부터 실제 서비스 단계까지 이용 가능 |
| 자동 미분 | 계산 구조와 목표 함수만 정의하면 미분을 자동으로 계산 |
| 지원 언어 | Python, C++, Go, Java, R 등 (강의노트 표기) |
✓ "자동 미분"이 왜 중요할까?
1·2강에서는 a_diff, b_diff처럼 편미분 식을 사람이 직접 코드로 썼습니다. 변수가 수백만 개인 딥러닝에서는 이걸 손으로 쓸 수 없습니다. 텐서플로는 모델과 손실 함수만 정하면 편미분을 알아서 계산해 줍니다. 7장 코드에 미분 식이 한 줄도 없는 이유입니다.
📖 보충 — 지원 언어와 데이터 플로 그래프의 현재
· 강의노트의 "R[2]"에서 [2]는 원문 자료의 각주 번호가 남은 것으로 보입니다.
· 텐서플로 공식 API 문서 기준으로 API 안정성(하위 호환)이 보장되는 것은 Python뿐입니다. JavaScript·C++·Java는 공식 지원하지만 안정성 보장 대상이 아니고, R은 커뮤니티가 지원하며, Go는 보관(archived) 상태입니다.
· SWIG를 통한 언어 연결과 "데이터 플로 그래프를 먼저 만들고 실행"하는 방식은 주로 텐서플로 1.x 시절의 특징입니다. 텐서플로 2.x부터는 코드를 바로 실행하는 즉시 실행(eager execution)이 기본이고, 그래프는 필요할 때 tf.function으로 만듭니다.
(근거: TensorFlow 공식 문서 「API Documentation」)
06 머신러닝 용어 vs 딥러닝 용어
같은 개념, 다른 이름
텐서플로 같은 딥러닝 도구를 쓰기 시작하면 지금까지 쓰던 말이 다른 이름으로 바뀝니다. 개념은 그대로이니 짝을 지어 기억하세요.
| 지금까지 쓴 말 | 딥러닝에서 부르는 이름 | 의미 |
| 가정하는 식 y = ax + b | 가설 함수 (hypothesis), H(x) | 입력으로 예측값을 내는 식 |
| 기울기 a | 가중치 (weight), w | x에 어느 정도의 가중치를 곱할지 결정 |
| 절편 b | 편향 (bias), b | 데이터의 특성에 따라 따로 부여되는 값 |
| 오차를 구하는 식 (MSE 등) | 손실 함수 (loss function) | 실제 값과 예측 값 사이의 오차에 대한 식 |
| 경사 하강법 | 옵티마이저 (optimizer) | 손실을 줄이도록 가중치·편향을 고치는 방법 |

H(x) = wx + b
2주차 뉴런 y = f(wx + b)에서 활성화 함수 f를 뺀 모양과 같음
왜 용어가 달라졌을까?
| 차이 | 내용 |
| 기술적 차이 (모델 구조) |
머신러닝은 선형 회귀·결정 트리·SVM 등 다양한 알고리즘을 사용. 딥러닝은 인공 신경망을 기반으로 여러 층을 쌓아 학습 → 층(layer), 뉴런(neuron), 활성화 함수 같은 용어 등장 |
| 복잡성의 차이 (데이터 처리 수준) |
머신러닝은 주로 구조화된 데이터, 딥러닝은 이미지·텍스트 같은 비구조화 데이터에 강함 → 데이터 증강, 전이 학습 같은 용어 추가 |
| 학습 방식의 차이 | 지도·비지도·준지도 학습 개념은 공통이지만, 딥러닝에서는 이를 설명하는 용어가 더 구체적이고 전문적 |
| 응용 분야의 차이 | 이미지 인식·자연어 처리·음성 인식 등 특정 분야에 특화 → CNN, RNN 같은 용어 존재 |
❌ 시험 함정 — 기울기 a는 "가설 함수"가 아니라 "가중치"
기울기 a는 변수 x에 어느 정도의 가중치를 곱할지 결정하므로 가중치(weight)라고 부릅니다. 가설 함수는 가정하는 식 전체를 가리키는 말로 H(x)로 표기합니다. 나머지 짝(오차 식 = 손실 함수, 절편 b = 편향, 경사 하강법 = 옵티마이저)도 함께 외워 두세요. 강의노트는 가중치를 ω(오메가)로 표시하지만, 교재와 코드에서는 보통 알파벳 w를 씁니다.
07 텐서플로로 선형 회귀 · 다중 선형 회귀
내 코랩 실습 + 다중 선형 회귀 보충 (편미분 식 없이 학습)
3강 실습 코드를 코랩에서 셀 단위로 나눠 직접 실행했습니다. ①~④의 코드와 실행 결과는 제 코랩 노트(5주 3강.ipynb)에 있는 그대로입니다. 2주차에서 본 Sequential과 Dense를 그대로 씁니다.
① 준비 · 모델 만들기
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
x = np.array([2,4,6,8,])
y = np.array([81,93,91,97])
model = Sequential()
model.add(Dense(1,input_dim=1, activation = 'linear'))
▶ 실행 결과 (코랩 실행 — 경고 메시지)
/usr/local/lib/python3.13/dist-packages/keras/src/layers/core/dense.py:106: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.
super().__init__(activity_regularizer=activity_regularizer, **kwargs)
⚠️ UserWarning는 오류가 아니다
빨간 글씨로 나와서 놀랄 수 있지만 경고(Warning)일 뿐이고 모델은 정상으로 만들어집니다. Dense(1, input_dim=1)처럼 첫 층에 입력 크기를 함께 적는 방식은 예전 케라스 문법이라, 최신 Keras 3가 "첫 층으로 Input(shape) 객체를 쓰라"고 권하는 것입니다(2주차 9장 팁과 같은 내용). 경고 없이 쓰려면 Sequential([Input(shape=(1,)), Dense(1, activation='linear')])처럼 Input을 맨 앞에 두면 됩니다. x 배열의 [2,4,6,8,]처럼 마지막에 붙은 쉼표는 파이썬에서 허용되는 문법이라 결과에 영향이 없습니다.
② 컴파일 · 학습
model.compile(optimizer='sgd', loss = 'mse') # 옵티마이저: 경사 하강법(SGD), 손실 함수: 평균 제곱 오차
model.fit(x, y, epochs=2000) # 2000 에포크 학습
▶ 실행 결과 (코랩 실행 (2000줄 중 일부))
Epoch 1/2000
1/1 ━━━━━━━━━━━━━━━━━━━━ 1s 1s/step - loss: 9332.1045
Epoch 2/2000
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 48ms/step - loss: 2198.9106
Epoch 3/2000
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 47ms/step - loss: 1145.9053
⋮
Epoch 500/2000
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 57ms/step - loss: 46.2271
⋮
Epoch 1000/2000
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 57ms/step - loss: 9.7735
⋮
Epoch 2000/2000
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 141ms/step - loss: 8.3022
loss(손실)는 매 에포크의 평균 제곱 오차입니다. 처음 9,332에서 시작해 마지막에는 8.3022까지 내려갔습니다. 3·4주차에서 구한 가장 좋은 직선 y = 2.3x + 79의 평균 제곱 오차가 8.30이므로, 텐서플로도 거의 같은 직선을 찾아냈다는 뜻입니다.
✓ 코드 읽기 포인트
· optimizer='sgd' : 확률적 경사 하강법(Stochastic Gradient Descent). 문자열로만 적으면 기본 학습률 0.01이 쓰입니다. 학습률을 직접 정하려면 tf.keras.optimizers.SGD(learning_rate=0.03)처럼 씁니다.
· loss='mse' : 손실 함수로 평균 제곱 오차 사용
· fit()의 출력 : verbose를 따로 정하지 않으면 에포크마다 진행 막대와 loss가 한 줄씩 찍힙니다. 출력을 숨기려면 verbose=0을 넣습니다.
③ 예측선 그래프 그리기
plt.scatter(x, y)
plt.plot(x, model.predict(x), 'r') # 학습된 모델의 예측값을 빨간 선으로
plt.show()
▶ 실행 결과 (코랩 실행)
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 106ms/step
(점 4개와 빨간 예측선이 나타남 — 아래 그림 4)

④ 7시간 공부했을 때 점수 예측
hour = 7
prediction = model.predict(np.array([[hour]], dtype=float))
print("%.f시간 공부할 경우 예상점수는 %.02f점이다." % (hour, prediction))
▶ 실행 결과 (코랩 실행)
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 98ms/step
7시간 공부할 경우 예상점수는 95.12점이다.
/tmp/ipykernel_3173/1329501818.py:3: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)
print("%.f시간 공부할 경우 예상점수는 %.02f점이다." % (hour, prediction))
예측 점수 95.12점은 y = 2.3x + 79에 x = 7을 넣은 값(95.1점)과 거의 같습니다.
⚠️ 실습하며 발견한 점 — DeprecationWarning
model.predict()는 숫자 하나가 아니라 모양이 (1, 1)인 2차원 배열 [[95.12…]]를 돌려줍니다. 이 배열을 그대로 "%.02f"에 넣으면 지금은 NumPy가 숫자로 바꿔 주지만, "앞으로는 오류가 될 것"이라는 경고가 나옵니다. 배열에서 값 하나를 꺼내 prediction[0][0] 또는 prediction.item()으로 넘기면 경고 없이 같은 결과가 나옵니다.
예) print("%.f시간 공부할 경우 예상점수는 %.02f점이다." % (hour, prediction[0][0]))
다중 선형 회귀도 텐서플로로
다중 선형 회귀는 텐서플로로 실습하지 않아서, 같은 방식으로 코드를 직접 작성해 실행했습니다. 경고가 나오지 않도록 Input을 맨 앞에 두었고, 실행할 때마다 같은 결과가 나오도록 시작값을 고정했습니다.
⑤ 텐서플로로 다중 선형 회귀 (보충 코드)
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Input, Dense
tf.keras.utils.set_random_seed(42)
x = np.array([[2, 0], [4, 4], [6, 2], [8, 3]]) # [공부 시간, 과외 시간] 4명분 → 모양 (4, 2)인 2차원 행렬
y = np.array([81, 93, 91, 97])
model = Sequential([Input(shape=(2,)), Dense(1, activation='linear')]) # H(x) = w1x1 + w2x2 + b
model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=0.01), loss='mse')
model.fit(x, y, epochs=5000, verbose=0)
w, b = model.get_weights()
print("가중치 w1 =", round(float(w[0][0]), 4), " w2 =", round(float(w[1][0]), 4))
print("편향 b =", round(float(b[0]), 4))
print("예측 점수:", model.predict(x, verbose=0).flatten().round(2))
▶ 실행 결과 (TensorFlow 2.21 / CPU)
가중치 w1 = 1.5002 w2 = 2.2858
편향 b = 77.856
예측 점수: [80.86 93. 91.43 96.71]
📖 x1, x2를 따로 넘기던 것을 하나의 행렬로
4장에서 직접 구현할 때는 x1(공부 시간)과 x2(과외 시간)를 1차원 배열 두 개로 따로 다뤘습니다. 텐서플로 모델에 넣을 때는 이를 2차원 행렬 하나로 묶습니다. 한 행이 학생 한 명, 한 열이 특성(독립 변수) 하나라서 모양이 (4, 2)가 되고, 그래서 Input(shape=(2,))로 특성 2개를 받습니다. 이미 x1, x2가 있다면 x = np.column_stack((x1, x2))로 같은 행렬을 만들 수 있습니다.
| 코드 | 6장 용어 | 1·2강 직접 구현에서는 |
| Dense(1, activation='linear') | 가설 함수 H(x) = wx + b | y_pred = a * x + b |
| 학습된 Dense 층의 가중치 | 가중치 | 기울기 a (a1, a2) |
| 학습된 Dense 층의 편향 | 편향 | 절편 b |
| loss='mse' | 손실 함수 | mse() 함수 / 오차 제곱 평균 |
| optimizer='sgd' | 옵티마이저 | a = a - lr * a_diff (직접 쓴 편미분) |
| epochs | 반복 횟수 | for i in range(epochs) |
⚠️ 실행할 때마다 끝자리가 조금씩 다를 수 있다
텐서플로는 가중치를 무작위 값에서 시작합니다. 그래서 같은 코드를 다시 실행하면 loss나 예측 점수의 소수점 끝자리가 조금씩 달라질 수 있습니다(내 실습 ①~④는 시작값을 고정하지 않은 결과입니다). 매번 같은 결과를 원하면 ⑤처럼 tf.keras.utils.set_random_seed(42)로 고정하면 됩니다. ⑤의 결과는 TensorFlow 2.21(CPU)에서 실행한 값이며, 환경에 따라 끝자리는 조금 다를 수 있습니다. 어떤 경우든 단순 회귀는 2.3과 79, 다중 회귀는 1.5·2.29·77.86 근처로 모입니다.
✓ 직접 구현 vs 텐서플로
1·2강 코드는 a_diff, b_diff 같은 편미분 식을 사람이 직접 썼고, 텐서플로 코드에는 미분 식이 없습니다. compile()에서 손실 함수와 옵티마이저만 정해 주면 텐서플로가 자동 미분으로 기울기를 계산해 가중치와 편향을 고칩니다. 결과는 두 방법 모두 같은 답으로 모입니다.

08 핵심 정리
시험 직전에 이것만은 꼭
📌 핵심 정리
· 경사 하강법 실습 : a와 b를 중심으로 각각 미분 = 편미분 (식 전체 미분 X). a_diff = (2/n)Σ(−x·error), b_diff = (2/n)Σ(−error)
· 업데이트 : a = a − lr × a_diff, b = b − lr × b_diff를 epochs만큼 반복 → 기울기 2.3, 절편 79
· Matplotlib : 그래프로 시각적 확인. scatter(산점도), plot(직선), show(표시), title·xlabel·ylabel, legend, grid
· 다중 선형 회귀 : 하나의 종속 변수와 두 개 이상의 독립 변수 관계 모델링. y = a1x1 + a2x2 + b
· 다중 선형 회귀의 장점 : 현실 반영, 정확도 향상(MSE 8.3 → 약 0.07), 변수 간 상호작용 분석, 변수별 영향 평가. 직선이 아닌 3D 평면
· 텐서플로 : 구글 브레인팀 개발 오픈 소스. 데이터 플로 그래프, 테스트~서비스 단계 활용, 자동 미분
· 용어 짝 : 가정하는 식 = 가설 함수 H(x) / 기울기 a = 가중치(weight) / 절편 b = 편향(bias) / 오차 식 = 손실 함수 / 경사 하강법 = 옵티마이저
· 용어가 다른 이유 : 기술적 차이(모델 구조) · 복잡성 차이(데이터 처리 수준) · 학습 방식 차이 · 응용 분야 차이
태그 : 경사 하강법 파이썬 코드편미분 경사 하강법matplotlib scatter plot다중 선형 회귀란단순 선형회귀 다중 선형회귀 차이다중 선형 회귀 파이썬텐서플로란가중치 편향 손실함수 옵티마이저텐서플로 선형 회귀 예제케라스 Dense 선형 회귀
출처 : 이 글은 부산디지털대학교(BDU)의 '파이썬 기반의 AI프로그래밍' 과목 2026년도 강의노트를 참고하여 학습용으로 작성한 글입니다.
'학과 수업 노트 > 파이썬 기반의 AI 프로그래밍' 카테고리의 다른 글
| 4. 예측선 - 평균 제곱 오차, 실습 코드 분석, 오차를 줄이는 방법 (0) | 2026.10.02 |
|---|---|
| 3. 훌륭한 예측선 - 예측선과 선형회귀, 최소제곱법, 실습 코드 분 (1) | 2026.10.02 |
| 2. 실습 환경 구축 및 분석 - Colab 활용, Git, 딥러닝 계층 구조 (0) | 2026.10.02 |
| 1. 인공지능 - 인공지능 개념, 머신러닝, 딥러닝, 기초 수 (0) | 2026.10.02 |
















