예시를 보고 스스로 고치는 인공지능 만들기
예시 데이터를 보고, 예측이 틀릴 때마다 스스로 계산에 쓰는 숫자를 고치는 프로그램을 만들어 봅니다. Python 파일 하나로 만들 수 있고, 추가 라이브러리나 유료 AI 서비스는 필요 없습니다. 이 화면에서 바로 실행해 볼 수도 있습니다.
배울 데이터
이번 모델이 배울 데이터는 다음과 같습니다.
| 입력 | 정답 |
|---|---|
| 1 | 2 |
| 2 | 4 |
| 3 | 6 |
| 4 | 8 |
우리 눈에는 "입력의 두 배"라는 규칙이 보입니다. 프로그램도 이 데이터를 이용해서 그 관계를 배우게 하겠습니다. 이 끝나면 학습에 사용하지 않은 5와 7을 넣어 예측을 확인합니다.
계산의 틀 — 모델
먼저 프로그램에 다음과 같은 계산의 틀, 즉 을 정해 줍니다.
예측값 = 입력 × w
w 는 프로그램이 학습하면서 바꿀 숫자입니다. 이런 값을 매개변수, 또는 이 경우에는 라고 부릅니다.
처음에는 w = 0 으로 시작합니다.
입력 3 → 예측 0 → 정답은 6 → 차이가 크다!
학습을 반복하면서 w 가 2에 가까워지면 다음처럼 됩니다.
입력 3 → 예측 약 6 → 정답과 거의 같다!
사람은 계산의 틀과 예시 데이터를 준비하고, 프로그램은 데이터에 맞는 w 를 찾습니다.
코드 — mini_ai.py
아래 코드를 mini_ai.py 라는 이름으로 저장하세요. 이 화면에서는 [실행]을 누르면 브라우저 안의 파이썬이 바로 돌립니다. 코드를 고쳐서 다시 실행해도 됩니다.
[실행]을 누르면 브라우저 파이썬을 준비합니다. 처음 한 번은 약 12MB 를 받습니다.
# 1. 학습 데이터: (입력, 정답)
data = [(1, 2), (2, 4), (3, 6), (4, 8)]
# 2. 처음에는 규칙을 모르는 상태로 시작합니다.
weight = 0.0
learning_rate = 0.01
# 3. 전체 데이터를 보며 100번 학습합니다.
for step in range(100):
gradient = 0.0
for x, answer in data:
prediction = weight * x # 현재 가중치로 예측
error = prediction - answer # 정답과 얼마나 다른지 계산
gradient += 2 * error * x # 수정할 방향과 크기 계산
# 모든 데이터의 결과를 모아 가중치를 조금 수정합니다.
weight -= learning_rate * gradient / len(data)
if step + 1 in [1, 10, 50, 100]:
print(f"{step + 1}회 학습: w = {weight:.4f}")
# 4. 학습에 사용하지 않은 입력으로 예측합니다.
print(f"입력 5의 예측: {weight * 5:.4f}")
print(f"입력 7의 예측: {weight * 7:.4f}")
실행 결과
[실행]을 누르면 여기에 결과가 나타나요.
내 컴퓨터에서 실행하기
파일을 저장한 폴더에서 다음 명령으로 실행합니다.
python3 mini_ai.py
실행 결과
실제로 실행해 확인한 결과입니다. 숫자는 소수점 넷째 자리까지 표시했습니다.
1회 학습: w = 0.3000 10회 학습: w = 1.6063 50회 학습: w = 1.9994 100회 학습: w = 2.0000 입력 5의 예측: 10.0000 입력 7의 예측: 14.0000
처음에는 0이었던 가 을 거쳐 약 2가 되었습니다. 이 가중치를 이용해 새로운 입력의 답을 계산하는 것이 예측, 또는 추론입니다.
코드에서 이해할 핵심 세 가지
error얼마나 틀렸는가- 예측값에서 정답을 뺀 값입니다. 에서는 이 오차를 제곱한 값들의 평균이 작아지도록 를 조정합니다.
gradient가중치를 어떻게 바꿔야 하는가- 오차를 줄이는 데 필요한 수정 방향과 크기를 계산합니다. 이 방법을 경사하강법이라고 합니다. 2 * error * x 는 이 의 제곱 오차를 미분해서 얻은 식입니다. 처음에는 미분을 완전히 이해하지 않아도 실험할 수 있습니다.
learning_rate한 번에 얼마나 바꿀 것인가- 여기서는 0.01 입니다. 너무 작으면 이 느려지고, 너무 크면 가 크게 흔들리거나 학습에 실패할 수 있습니다.
직접 실험해 보기
한 가지씩 바꾸고 다시 실행해 보세요. [불러와 실행]을 누르면 바꾼 코드가 위의 편집기에 들어가고 바로 실행됩니다.
-
데이터를 세 배 관계로 바꾸기
data = [(1, 3), (2, 6), (3, 9), (4, 12)]나머지 코드를 그대로 두고 실행하세요. 이번에는 가중치가 약 3으로 학습되는지 확인합니다.
확인한 결과 보기
1회 학습: w = 0.4500 10회 학습: w = 2.4094 50회 학습: w = 2.9991 100회 학습: w = 3.0000 입력 5의 예측: 15.0000 입력 7의 예측: 21.0000
-
학습 횟수를 줄이기
for step in range(10):100번 학습했을 때보다 예측이 얼마나 부정확해지는지 비교합니다.
확인한 결과 보기
1회 학습: w = 0.3000 10회 학습: w = 1.6063 입력 5의 예측: 8.0313 입력 7의 예측: 11.2438
-
예시에서 완벽한 규칙을 없애 보기
data = [(1, 2.1), (2, 3.9), (3, 6.2), (4, 7.8)]데이터가 조금씩 어긋나도, 전체적으로 잘 맞는 가중치를 찾는지 살펴봅니다.
확인한 결과 보기
1회 학습: w = 0.2985 10회 학습: w = 1.5982 50회 학습: w = 1.9894 100회 학습: w = 1.9900 입력 5의 예측: 9.9500 입력 7의 예측: 13.9300
다음 과제 — 입력 × w + b
이 이 표현할 수 있는 관계는 입력 × w 형태의 비례 관계입니다. 예를 들어 입력 × 2 + 3 을 배우려면 모델을 입력 × w + b 로 확장하고, w 와 b 두 숫자를 학습해야 합니다. b 는 편향이라고 부릅니다.
위 실험을 이해했다면 먼저 스스로 코드를 고쳐 보고, 막히면 아래 풀이를 열어 보세요.
풀이 코드 보기
학습 데이터는 입력 × 2 + 3 으로 만든 (1, 5), (2, 7), (3, 9), (4, 11) 입니다. 숫자를 두 개 배우므로 학습률을 0.05 로 올리고 1000번 학습합니다.
# 1. 학습 데이터: 입력 × 2 + 3 으로 만든 (입력, 정답)
data = [(1, 5), (2, 7), (3, 9), (4, 11)]
# 2. 가중치 w 와 편향 b 를 모두 0 에서 시작합니다.
weight = 0.0
bias = 0.0
learning_rate = 0.05
# 3. 전체 데이터를 보며 1000번 학습합니다.
for step in range(1000):
grad_w = 0.0
grad_b = 0.0
for x, answer in data:
prediction = weight * x + bias # 현재 w 와 b 로 예측
error = prediction - answer # 정답과 얼마나 다른지 계산
grad_w += 2 * error * x # w 를 바꿀 방향과 크기
grad_b += 2 * error # b 를 바꿀 방향과 크기
# w 와 b 를 함께 조금씩 수정합니다.
weight -= learning_rate * grad_w / len(data)
bias -= learning_rate * grad_b / len(data)
if step + 1 in [1, 10, 100, 500, 1000]:
print(f"{step + 1}회 학습: w = {weight:.4f}, b = {bias:.4f}")
# 4. 학습에 사용하지 않은 입력으로 예측합니다.
print(f"입력 5의 예측: {weight * 5 + bias:.4f}")
print(f"입력 7의 예측: {weight * 7 + bias:.4f}")
1회 학습: w = 2.2500, b = 0.8000 10회 학습: w = 2.6082, b = 1.2119 100회 학습: w = 2.1565, b = 2.5399 500회 학습: w = 2.0004, b = 2.9989 1000회 학습: w = 2.0000, b = 3.0000 입력 5의 예측: 13.0000 입력 7의 예측: 17.0000
w 는 처음에 2를 넘었다가 b 가 커지면서 2로 돌아오고, 끝에는 w = 2, b = 3 이 됩니다.