지노랩 /JinoLab
16. 헬스장 데이터(운동 시간·휴식 시간 → 근육량 증가) Forward Propagation 본문
프로그래밍/C언어를 이용한 Deep Learning
16. 헬스장 데이터(운동 시간·휴식 시간 → 근육량 증가) Forward Propagation
지노랩/JinoLab 2025. 8. 11. 09:51아래는 “헬스장 데이터”(운동 시간·휴식 시간 → 근육량 증가) 예제를 C 언어로 구현한 앞으로 전파(Forward Propagation) 코드입니다.
- 데이터 전처리: 원본 데이터를 최대값으로 나눠 [0,1] 구간으로 정규화
- 네트워크 구조:
- 입력층: 2개 특성(운동 시간, 휴식 시간)
- 은닉층: 3개 유닛 (ReLU 활성화)
- 출력층: 1개 유닛 (항등 활성화)
#include <stdio.h>
// --- 활성화 함수들 ---
double relu(double x) {
return x > 0 ? x : 0;
}
// --- 행렬·벡터 곱: z = X (m×n) · W (n×p) -->
// result is Z (m×p)
void matmul(const double *X, int m, int n,
const double *W, int p,
double *Z) {
// X row-major: X[i*n + k]
// W row-major: W[k*p + j]
for (int i = 0; i < m; i++) {
for (int j = 0; j < p; j++) {
double sum = 0.0;
for (int k = 0; k < n; k++) {
sum += X[i*n + k] * W[k*p + j];
}
Z[i*p + j] = sum;
}
}
}
int main(void) {
// --- 1) 원본 데이터 (3번의 세션) ---
// 운동 시간(hours), 휴식 시간(hours), 근육 증가량(grams)
double raw_X[3][2] = {
{1.0, 2.0}, // 예: 1시간 운동, 2시간 휴식 → 300g 증가
{2.0, 1.0}, // 2시간 운동, 1시간 휴식 → 500g 증가
{3.0, 1.5} // 3시간 운동, 1.5시간 휴식 → 650g 증가
};
double raw_y[3] = {300.0, 500.0, 650.0};
// --- 2) 정규화 --- (각 컬럼의 최대값으로 나누기)
double max_x0 = 3.0, max_x1 = 2.0, max_y = 650.0;
double X[3][2], y[3];
for (int i = 0; i < 3; i++) {
X[i][0] = raw_X[i][0] / max_x0;
X[i][1] = raw_X[i][1] / max_x1;
y[i] = raw_y[i] / max_y; // (0~1로 스케일링)
}
// --- 3) 네트워크 가중치 초기값 ---
// W1: 입력(2) → 은닉(3)
double W1[2][3] = {
{ 0.5, -0.3, 0.8},
{ 0.2, 0.4, -0.5}
};
// W2: 은닉(3) → 출력(1)
double W2[3][1] = {
{ 1.0},
{-1.2},
{ 0.5}
};
// --- 4) Forward Propagation ---
// 4-1. Z2 = X · W1 (3×2)·(2×3) = (3×3)
double Z2[3][3];
matmul(&X[0][0], 3, 2, &W1[0][0], 3, &Z2[0][0]);
// 4-2. A2 = ReLU(Z2) (3×3)
double A2[3][3];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
A2[i][j] = relu(Z2[i][j]);
// 4-3. Z3 = A2 · W2 (3×3)·(3×1) = (3×1)
double Z3[3][1];
matmul(&A2[0][0], 3, 3, &W2[0][0], 1, &Z3[0][0]);
// 4-4. y_hat = Z3 (항등 활성화)
double y_hat[3];
for (int i = 0; i < 3; i++) {
y_hat[i] = Z3[i][0];
}
// --- 5) 결과 출력 (역정규화 포함) ---
printf("예측근육증가량(grams) vs 실제(grams):\n");
for (int i = 0; i < 3; i++) {
double pred_g = y_hat[i] * max_y; // 역정규화
printf(" 입력(%.1fh, %.1fh) → 예측: %6.1fg, 실제: %6.1fg\n",
raw_X[i][0], raw_X[i][1],
pred_g, raw_y[i]);
}
return 0;
}
코드 설명
- 데이터 정규화
- 입력 X[i][j] = raw_X[i][j] / max(raw_X[:,j])
- 출력 y[i] = raw_y[i] / max(raw_y)
→ 모든 값이 [0,1] 구간에 있도록 스케일링
- 행렬 곱 함수(matmul)
- 일반적인 Z=XW 연산을 수행하기 위한 3중 for‑loop 구현
- X는 m×n, W는 n×p, 결과 Z는 m×p
- 순전파(Forward Propagation)
- Z₂ = X·W₁ → 은닉층 선형결합
- A₂ = ReLU(Z₂) → 은닉층 비선형 활성화
- Z₃ = A₂·W₂ → 출력층 선형결합
- ŷ = Z₃ → 항등(Identity) 활성화
- 역정규화 후 출력 비교
- 모델이 예측한 y^를 다시 원단위(grams)로 변환하여(ŷ * max_y) 실제값과 비교
이 예제는 모델 학습 없이, 임의의 가중치로 “순전파”만 시연합니다. 이후 경사하강법(Gradient Descent) 및 역전파(Backpropagation) 과정을 통해 W1, W2를 학습시키면, 주어진 운동·휴식 시간에 따른 근육량 예측 성능을 개선할 수 있습니다.
'프로그래밍 > C언어를 이용한 Deep Learning' 카테고리의 다른 글
| 18. 은닉층·출력층 가중치 행렬 (2) | 2025.08.13 |
|---|---|
| 17. 데이터 정규화(Normalization) 과정 (0) | 2025.08.12 |
| 15. 생물학적 뉴런의 기능과 인공 뉴런 비교 (2) | 2025.08.10 |
| 14. 경사하강법(Gradient Descent) (3) | 2025.08.09 |
| 13. 브루트 포스 학습(Brute‑Force Learning) (1) | 2025.08.08 |