Skip to Content

ML·DL 모델 학습

실습복습
관련 기초 개념

개요

타깃에 맞는 ML 기준선과 신경망을 학습·검증하는 코드를 구성한다.

먼저 전처리와 데이터 분할, 분류·회귀·군집 기준선, 신경망·학습·과적합의 핵심 개념을 확인하세요.

세부 학습 목표

  • 분류·회귀 문제에 맞는 ML 기준선과 비교 모델을 작성한다.
  • 입력 차원·출력 활성함수·라벨·손실을 맞춰 신경망을 구성한다.
  • fit·predict·검증 중단과 독립 시험 평가를 구별한다.

핵심 개요

모델 학습에서는 먼저 간단한 기준선을 만들고 문제에 맞는 분류·회귀 모델을 비교합니다. 신경망은 입력 차원·손실·출력 형태가 타깃과 맞아야 하며 검증 자료로 학습 중단과 설정을 선택합니다.

정해진 환경에서 재현 가능한 작은 실험을 완성한 뒤 복잡도를 늘립니다. 많은 모델을 돌리고 가장 좋은 시험 점수만 고르면 평가 자료에 과적합할 수 있습니다.

필요한 용어

  • 기준선: 단순 규칙이나 모델로 얻은 비교 출발점
  • 하이퍼파라미터: 학습 전에 선택하는 모델·학습 설정

작동 과정

  1. 작업 유형과 평가 지표를 정합니다.
  2. 같은 분할에서 기준선과 후보를 학습합니다.
  3. 검증으로 선택하고 독립 시험에서 마지막 비교를 수행합니다.

타깃이 출력층과 손실을 결정한다

  • ML은 자료에서 규칙을 학습하는 넓은 범주이고 딥러닝은 여러 신경망 층을 사용하는 접근입니다. 우선 같은 분할의 단순 기준선과 비교합니다. 분류는 범주, 회귀는 수치를 예측합니다.
문제출력 예손실 예
0/1 이진 분류Dense(1, sigmoid)binary_crossentropy
상호 배타적 K개 분류·정수 라벨Dense(K, softmax)sparse_categorical_crossentropy
같은 분류·one-hot 라벨Dense(K, softmax)categorical_crossentropy
수치 하나 회귀Dense(1), 선형 출력MSE·MAE 등
  • Dense는 입력과 가중치의 계산에 편향·활성함수를 적용하는 층입니다. 전처리 후 열이 12개라면 입력 차원도 12에 맞춥니다. sigmoid는 0~1 출력, softmax는 범주 확률의 합을 1로 만드는 역할입니다. 회귀값을 sigmoid로 제한하면 타깃의 단위·범위와 맞지 않을 수 있습니다.

  • compile은 손실·최적화·지표를 정하고 fit은 학습, predict는 새 입력의 출력을 만듭니다. 확률 출력과 임계값으로 나눈 최종 범주를 구별합니다. from_logits 설정은 출력이 확률인지 변환 전 점수인지와 맞춰야 합니다.

Keras: Dense layer  · Keras: Probabilistic losses 

검증 자료로 멈출 시점을 선택하기

  • Epoch는 학습 자료를 한 차례 처리하는 단위이고 batch는 한 번의 갱신에 사용하는 묶음입니다. 학습률은 갱신 크기에 영향을 줍니다. 학습을 오래 했다는 사실만으로 새 자료의 성능이 좋아지지는 않습니다.

    EarlyStopping은 val_loss 같은 관측값이 정한 기간 개선되지 않으면 중단합니다. restore_best_weights=True는 관측값이 가장 좋았던 가중치를 복원하게 하는 설정이며, 마지막 epoch와 같다고 가정하지 않습니다.

  • 아래 자체 예제는 가상 표 자료 생성→학습/검증/시험 분할→학습 기준 표준화→로지스틱 기준선·신경망 비교→곡선 저장을 연결합니다. 외부 자료를 내려받지 않습니다. 실행 환경은 시험 환경과 별개이며 실제 시험 문제를 복제하지 않았습니다.

Keras: EarlyStopping  · TensorFlow: Overfit and underfit 

풀이 예제

아래 입력과 기록은 직접 만든 교육용 가상 자료입니다.

입력·조건

분류 후보 20개를 시험셋에서 계속 비교하고 가장 높은 모델을 선택했습니다.

판단·결과

시험셋이 선택에 사용됐으므로 독립 평가의 의미가 약해졌습니다.

이렇게 판단한 이유

모델을 고르는 데 쓴 자료와 성능을 마지막으로 확인할 자료를 분리해야 합니다.

로컬 실행 예제

실행 파일 받기

Python 3.10 이상과 numpy·scikit-learn·TensorFlow·matplotlib가 필요합니다. 학습용 별도 환경에서 패키지를 준비하고 사용 버전을 기록합니다. 실행하면 현재 폴더에 aice-practice-output 폴더와 연습 산출물을 만듭니다. 기존 폴더가 있으면 덮어쓰지 않고 멈춥니다.

python -m pip install numpy scikit-learn tensorflow matplotlib python aice_neural_workflow.py
"""Authored synthetic tabular exercise; not an official AICE question or score. Requires Python 3.10+, numpy, scikit-learn, tensorflow and matplotlib. Creates a new aice-practice-output directory in the current working directory. An existing output directory is never overwritten. """ from pathlib import Path import csv import json import platform import numpy as np import sklearn from sklearn.linear_model import LogisticRegression from sklearn.metrics import confusion_matrix, precision_recall_fscore_support from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler import tensorflow as tf import matplotlib matplotlib.use("Agg") from matplotlib import pyplot as plt def main(): output = Path("aice-practice-output") if output.exists(): raise FileExistsError("aice-practice-output already exists; choose a fresh working folder") tf.keras.utils.set_random_seed(17) rng = np.random.default_rng(17) x = rng.normal(size=(300, 4)).astype("float32") y = (x[:, 0] + 0.5 * x[:, 1] > 0).astype("int32") ids = np.arange(len(y)) train_val, test = train_test_split(ids, test_size=0.2, random_state=17, stratify=y) train, validation = train_test_split( train_val, test_size=0.25, random_state=17, stratify=y[train_val] ) assert (len(train), len(validation), len(test)) == (180, 60, 60) assert not (set(train) & set(validation) or set(train_val) & set(test)) scaler = StandardScaler().fit(x[train]) x_train = scaler.transform(x[train]).astype("float32") x_val = scaler.transform(x[validation]).astype("float32") baseline = LogisticRegression(random_state=17).fit(x_train, y[train]) model = tf.keras.Sequential([ tf.keras.Input(shape=(x_train.shape[1],)), tf.keras.layers.Dense(8, activation="relu"), tf.keras.layers.Dense(1, activation="sigmoid"), ]) model.compile(optimizer="adam", loss="binary_crossentropy", metrics=["accuracy"]) stop = tf.keras.callbacks.EarlyStopping( monitor="val_loss", patience=4, restore_best_weights=True ) history = model.fit( x_train, y[train], validation_data=(x_val, y[validation]), epochs=30, batch_size=16, callbacks=[stop], verbose=0, ) assert np.isfinite(history.history["val_loss"]).all() # Test data is evaluated only after fitting and stopping are finished. x_test = scaler.transform(x[test]).astype("float32") probabilities = model.predict(x_test, verbose=0) assert probabilities.shape == (60, 1) assert np.isfinite(probabilities).all() assert ((probabilities >= 0) & (probabilities <= 1)).all() predictions = (probabilities[:, 0] >= 0.5).astype("int32") baseline_predictions = baseline.predict(x_test) scores = {} for name, values in [("baseline", baseline_predictions), ("neural", predictions)]: p, r, f1, _ = precision_recall_fscore_support( y[test], values, average="binary", zero_division=0 ) matrix = confusion_matrix(y[test], values, labels=[0, 1]) assert matrix.sum() == len(test) scores[name] = {"precision": float(p), "recall": float(r), "f1": float(f1)} # mkdir(exist_ok=False) also protects against a concurrent creator. output.mkdir(exist_ok=False) with (output / "predictions.csv").open("w", newline="", encoding="utf-8") as stream: writer = csv.writer(stream) writer.writerow(["id", "probability", "prediction"]) writer.writerows(zip(test.tolist(), probabilities[:, 0].tolist(), predictions.tolist())) with (output / "predictions.csv").open(newline="", encoding="utf-8") as stream: rows = list(csv.DictReader(stream)) assert [int(row["id"]) for row in rows] == test.tolist() assert len(rows) == len(test) and len({row["id"] for row in rows}) == len(test) fig, ax = plt.subplots() ax.plot(history.history["loss"], label="train") ax.plot(history.history["val_loss"], label="validation") ax.set(xlabel="Epoch (zero-based index)", ylabel="Binary crossentropy") ax.legend() fig.savefig(output / "learning-curve.png", bbox_inches="tight") plt.close(fig) model.save(output / "neural.keras") # Preserve the fitted preprocessing contract alongside the neural model. np.savez(output / "scaler.npz", mean=scaler.mean_, scale=scaler.scale_) versions = {"python": platform.python_version(), "numpy": np.__version__, "sklearn": sklearn.__version__, "tensorflow": tf.__version__, "matplotlib": matplotlib.__version__} report = {"versions": versions, "scores": scores, "splits": {"train": train.tolist(), "validation": validation.tolist(), "test": test.tolist()}, "history": history.history, "note": "synthetic data; not a real-world or official exam score"} (output / "report.json").write_text(json.dumps(report, indent=2), encoding="utf-8") print("PASS: split 180/60/60, probability shape (60, 1), finite outputs, CSV IDs") print(json.dumps({"versions": versions, "scores": scores}, indent=2)) print("Synthetic data only; no production or certification readiness claim.") if __name__ == "__main__": main()

기대 결과: 학습/검증/시험 180/60/60행, 신경망 출력 (60, 1), 점수와 실제 사용 버전, 학습 곡선·예측 CSV·모델 파일 생성. 점수는 환경에 따라 달라집니다.

공식 Keras 계약과 Python 구문을 확인했습니다. 이 환경에는 TensorFlow가 없어 신경망 학습·그래프 생성은 실행 검증하지 못했습니다. 실행 시 출력 형태·유한 확률·ID 순서·산출물 검사가 모두 통과하는지 확인하세요.

실습 자료

흔한 실패와 복구

복잡한 모델의 학습 완료를 높은 품질로 해석하지 않습니다. 기준선·검증·업무 오류를 비교합니다.

확인 문제

시험셋을 반복해서 모델 선택에 쓰면?

  1. 항상 일반화가 좋아진다
  2. 선택에 맞춰져 독립 평가가 약해진다
  3. 자료 누출 위험이 없어진다

풀이 기록 기능을 불러오는 중…

해설 보기

정답: B. 선택에 맞춰져 독립 평가가 약해진다

선택에 맞춰져 독립 평가가 약해진다 복잡한 모델의 학습 완료를 높은 품질로 해석하지 않습니다. 기준선·검증·업무 오류를 비교합니다.

타깃이 3개 범주의 정수 라벨이면 적절한 조합은?

  1. 1개 sigmoid 출력과 회귀 MAE만
  2. 3개 softmax 출력인데 binary loss만 항상 사용
  3. 3개 softmax 출력과 sparse categorical crossentropy

풀이 기록 기능을 불러오는 중…

해설 보기

정답: C. 3개 softmax 출력과 sparse categorical crossentropy

상호 배타적 범주의 개수와 라벨 표현에 출력·손실을 맞춰야 합니다.

검증 손실 최저 epoch가 5, 마지막 epoch가 8이라면?

  1. 최선 가중치 복원 설정을 확인하고 독립 시험은 선택 뒤 평가한다
  2. 항상 epoch 8이 최선이다
  3. 시험 손실이 최소가 될 때까지 학습한다

풀이 기록 기능을 불러오는 중…

해설 보기

정답: A. 최선 가중치 복원 설정을 확인하고 독립 시험은 선택 뒤 평가한다

중단 시점과 최선 가중치는 다를 수 있습니다. 시험은 중단·설정 선택에 사용하지 않습니다.

참고 자료

  1. AICE Associate official overview  — 공식 렌더링 화면에서 데이터 분석·전처리·AI 모델링의 세부 범위 및 30·30·40점 확인. 패키지 버전·개별 알고리즘의 필수 출제 여부는 확정하지 않음.
  2. Google ML Crash Course  — 학습 방식·회귀·분류·손실·평가의 기초.
  3. scikit-learn: Common pitfalls  — 분할 전후 전처리와 데이터 누출.
  4. Keras: Dense layer  — 입력·가중치·활성함수·출력 형태.
  5. Keras: Probabilistic losses  — 이진·다중 분류 손실과 라벨·출력 계약.
  6. Keras: EarlyStopping  — 관측 지표·대기·최선 가중치 복원.
  7. TensorFlow: Overfit and underfit  — 학습·검증 곡선과 과적합 완화.

자료 확인: 2026-10-25. 사례·문항·실습은 자체 제작했습니다. 외부 서비스 호출과 실제 모델 품질 측정은 학습자가 별도 환경에서 수행합니다.

직접 적용하기

교육용 가상 상황

전처리 뒤 입력은 12열, 타깃은 서로 배타적인 3개 범주의 정수 0·1·2입니다. 입력·출력·손실을 정하고, val_loss가 최저인 epoch와 마지막 epoch가 다를 때 선택·평가 절차를 쓰세요.

선택·계산·진단의 근거를 조건과 연결하고, 확인할 결과를 적으세요.

답안 저장 기능을 불러오는 중…

검증 기준과 해설 보기
  1. 입력 12·출력 3 softmax와 정수 라벨 손실을 맞춘다
  2. 검증 관측·중단·최선 가중치 복원을 설명한다
  3. 고정 분할의 기준선과 선택 후 독립 시험을 비교한다

Input(12), Dense(3, softmax), sparse_categorical_crossentropy를 사용할 수 있습니다. 검증 val_loss를 관측해 EarlyStopping과 최선 가중치 복원을 설정합니다. 검증에서 모델·설정을 선택한 뒤 시험을 최종 평가합니다. 같은 전처리·분할의 단순 기준선과 비교하고 시험으로 epoch를 고르지 않습니다.

복습하기

  1. ML·DL 비교에서 고정할 것은?
  2. 신경망에서 맞출 것은?
  3. 과적합은 무엇으로 보나요?
  4. 타깃이 3개 범주의 정수 라벨이면 적절한 조합은?
  5. 검증 손실 최저 epoch가 5, 마지막 epoch가 8이라면?
답변 확인 기준
  1. ML·DL 비교에서 고정할 것은?

    입력·분할·전처리·평가 기준입니다.

  2. 신경망에서 맞출 것은?

    타깃에 맞는 입력 차원·출력·손실입니다.

  3. 과적합은 무엇으로 보나요?

    학습과 검증 성능의 차이·추세와 새 자료 성능을 봅니다.

  4. 타깃이 3개 범주의 정수 라벨이면 적절한 조합은?

    3개 softmax 출력과 sparse categorical crossentropy. 상호 배타적 범주의 개수와 라벨 표현에 출력·손실을 맞춰야 합니다.

  5. 검증 손실 최저 epoch가 5, 마지막 epoch가 8이라면?

    최선 가중치 복원 설정을 확인하고 독립 시험은 선택 뒤 평가한다. 중단 시점과 최선 가중치는 다를 수 있습니다. 시험은 중단·설정 선택에 사용하지 않습니다.