지노랩 /JinoLab
13. 브루트 포스 학습(Brute‑Force Learning) 본문
아래는 “브루트 포스 학습(Brute‑Force Learning)”이라 부르는, 가중치를 한 스텝씩 올려보거나 내려보면서 오차가 줄어드는 방향으로 학습하는 단일 퍼셉트론 C 예제입니다. 이해를 돕기 위해 상세 주석과 함께, 반복(iterations)마다 가중치·예측값·오차가 어떻게 변하는지 출력합니다.
#include <stdio.h>
#include <math.h>
/**
* @brief 제곱 오차 계산: (y_pred - y_true)^2
*/
double squared_error(double y_pred, double y_true) {
double diff = y_pred - y_true;
return diff * diff;
}
/**
* @brief 브루트 포스 학습 시뮬레이션
* @param x 입력값
* @param w 초기 가중치 (참조로 전달하여 업데이트)
* @param y_true 실제값(정답)
* @param step 가중치 증감 스텝(학습률 α 역할)
* @param iterations 반복 횟수(에포크 수)
*/
void brute_force_learn(double x, double *w, double y_true,
double step, int iterations) {
printf("=== Brute‑Force Learning Start ===\n");
printf("Init weight = %.6f, input x = %.6f, target y = %.6f\n\n",
*w, x, y_true);
for (int i = 1; i <= iterations; i++) {
// 1) 현재 가중치로 예측값과 오차 계산
double y_pred = x * (*w);
double err_current = squared_error(y_pred, y_true);
// 2) 가중치를 올렸을 때의 오차
double w_up = *w + step;
double y_pred_up = x * w_up;
double err_up = squared_error(y_pred_up, y_true);
// 3) 가중치를 내렸을 때의 오차
double w_down = *w - step;
double y_pred_down = x * w_down;
double err_down = squared_error(y_pred_down, y_true);
// 4) 오차가 더 작아지는 방향으로 가중치 업데이트
if (err_up < err_down && err_up < err_current) {
*w = w_up; // 증가시켰을 때 오차가 최소
} else if (err_down < err_up && err_down < err_current) {
*w = w_down; // 감소시켰을 때 오차가 최소
}
// 아니면 변경하지 않음 (local minimum 또는 plateau)
// 5) 업데이트 후 예측값과 오차 재계산
double y_pred_new = x * (*w);
double err_new = squared_error(y_pred_new, y_true);
// 6) 진행 상황 출력
printf("Iter %3d: w = %.6f, y_pred = %.6f, error = %.6f\n",
i, *w, y_pred_new, err_new);
}
printf("=== Learning Finished: final w = %.6f ===\n", *w);
}
int main(void) {
// 학습 설정
double input = 0.5; // 입력값 x
double weight = 0.5; // 초기 가중치 w
double target = 0.8; // 목표값 y_true
double step_size = 0.001; // 가중치 증감 스텝 (learning rate)
int epochs = 800; // 반복 횟수
// 학습 시뮬레이션 호출
brute_force_learn(input, &weight, target, step_size, epochs);
return 0;
}
코드 설명
- squared_error
- 예측값과 실제값의 차이를 제곱해 항상 양수인 오차를 반환합니다.
- brute_force_learn 함수 인자
- x : 모델 입력
- *w: 학습 중 업데이트될 가중치 (포인터로 전달)
- y_true: 목표값(레이블)
- step: 가중치 한 스텝의 크기 (일종의 학습률 α)
- iterations: 전체 반복 횟수(에포크 수)
- 학습 루프 (for):
- 현재 오차(err_current) 계산
- 가중치 +step 일 때 오차(err_up) 계산
- 가중치 –step 일 때 오차(err_down) 계산
- 가장 오차가 작아지는 방향으로만 가중치를 업데이트
- 업데이트 후 새 오차를 계산하고, 진행 상황을 출력
- 메인 함수
- 학습 파라미터(input, weight, target, step_size, epochs)를 정의
- brute_force_learn 호출로 시뮬레이션 실행
실행 예시
gcc -o brute_learn brute_learn.c -lm
./brute_learn
=== Brute‑Force Learning Start ===
Init weight = 0.500000, input x = 0.500000, target y = 0.800000
Iter 1: w = 0.501000, y_pred = 0.250500, error = 0.302150
Iter 2: w = 0.502000, y_pred = 0.251000, error = 0.301373
...
Iter 799: w = 1.598000, y_pred = 0.799000, error = 0.000001
Iter 800: w = 1.599000, y_pred = 0.799500, error = 0.000000
=== Learning Finished: final w = 1.599000 ===
- 초기 예측값은 0.5×0.5=0.25, 오차는 (0.25−0.8)²=0.3025….
- 반복할수록 가중치가 ≈1.6으로 이동하며, 예측값 x·w가 0.8에 근접하고 오차가 0에 가깝게 감소합니다.
주의: 이 방식은 매우 비효율적이지만(모든 방향을 브루트 포스로 탐색),
“학습 = 오차를 줄이는 과정” 이라는 개념을 가장 직관적으로 보여 줍니다.
다음 단계로는 경사하강법(Gradient Descent) 을 통해 보다 효율적으로 가중치를 업데이트하는 방법을 살펴보겠습니다!
'프로그래밍 > C언어를 이용한 Deep Learning' 카테고리의 다른 글
| 15. 생물학적 뉴런의 기능과 인공 뉴런 비교 (2) | 2025.08.10 |
|---|---|
| 14. 경사하강법(Gradient Descent) (3) | 2025.08.09 |
| 12. 학습(Learn) / 단일 입력·단일 출력 퍼셉트론에서 오차를 줄이기 위해 가중치 (3) | 2025.08.07 |
| 11. 텐서(Tensor) 기본 개념 (2) | 2025.08.06 |
| 10. 비교(compare) / 오차(error) 계산 (1) | 2025.08.05 |