인지야공

인지야공/인공 지능 공부 치트 시트 정리/12번째 글

Keras 치트시트를 다시 쓴다 — 조용히 학습이 안 되는 자리들

Keras 치트시트는 순서가 잘 잡혀 있다. 정의 → 컴파일 → 학습 → 평가 → 예측. 문제는 그 줄들 중 지금 그대로 치면 에러가 나는 것이 여럿이고, 더 나쁘게는 에러도 없이 학습이 안 되는 자리가 있다는 것이다.

확인 환경은 TensorFlow 2.21.0 · Keras 3.15.1 이다. ADP 시험장은 TensorFlow 1.13.1 · Keras 2.2.4 라 이 시리즈에서 격차가 가장 큰 글이 되었다. 그 대비는 마지막 절에 모았다.

뼈대는 다섯 줄이다

model = Sequential([...])                      # 1. 정의
model.compile(optimizer=..., loss=..., metrics=[...])  # 2. 컴파일
model.fit(x, y, epochs=..., batch_size=...)    # 3. 학습
model.evaluate(x_test, y_test)                 # 4. 평가
model.predict(x_test)                          # 5. 예측

나머지는 전부 이 다섯 줄의 인자를 채우는 이야기다.

정의 — 첫 층에 input_dim 을 주지 않는다

# 치트시트 방식 — 돌지만 경고가 뜬다
model.add(Dense(32, activation="relu", input_dim=100))
# UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer.

# 지금 방식 — 입력을 층으로 명시한다
model = Sequential([
    Input(shape=(100,)),
    Dense(32, activation="relu"),
    Dense(1, activation="sigmoid"),
])

Input 을 앞에 두면 모델이 바로 만들어져서 model.summary() 에 출력 모양과 파라미터 수가 제대로 뜬다. 층을 쌓다 크기가 안 맞을 때 가장 먼저 보는 것이 이 표라, 습관을 들여 두면 좋다.

컴파일 — 여기서 조용히 틀린다

문제마지막 층손실 함수
이진 분류Dense(1, activation="sigmoid")binary_crossentropy
다중 분류 (원핫 라벨)Dense(K, activation="softmax")categorical_crossentropy
다중 분류 (정수 라벨)Dense(K, activation="softmax")sparse_categorical_crossentropy
회귀Dense(1) — 활성화 없음mse (지표는 mae)

이 표를 어기면 에러가 아니라 이상한 학습이 된다. 출력이 1개인 이진 분류 모델에 categorical_crossentropy 를 물려 학습시켜 봤다.

손실값: [0.0, 0.0]     ← 두 에포크 내내 정확히 0 이다

경고 한 줄이 뜨긴 하지만 학습은 “성공”한 것처럼 끝난다. 손실이 0 이면 기울기도 0 이라 가중치가 한 번도 갱신되지 않는다. 정확도가 이상하게 낮은데 손실이 예쁘면 이걸 의심한다.

라벨 모양도 같은 자리다. 정수 라벨([0, 1, 2])에는 sparse_ 붙은 쪽을, 원핫(to_categorical 을 거친 것)에는 안 붙은 쪽을 쓴다.

학습 — History 의 키 이름

history = model.fit(x, y,
                    epochs=15, batch_size=32, verbose=1,
                    validation_split=0.2)          # 또는 validation_data=(x_val, y_val)
history.history.keys()
# ['accuracy', 'loss', 'val_accuracy', 'val_loss']

validation_split 은 데이터의 뒤쪽에서 잘라 간다. 정렬된 데이터를 그대로 넣으면 검증 세트에 특정 부류만 들어갈 수 있으니, 미리 섞어 두거나 validation_data 로 직접 준다.

키 이름이 accuracy 인 것도 기억해 둔다. 옛 Keras(2.2.x)에서는 acc, val_acc 였다. 학습 곡선을 그리는 코드가 KeyError 로 죽는 이유의 대부분이 이것이다.

콜백 — EarlyStopping 은 되돌리지 않는다

es = EarlyStopping(monitor="val_loss", patience=2)
es.restore_best_weights      # False  ← 기본값이다

이름만 보면 “제일 좋았을 때로 되돌려 준다”고 오해하기 쉬운데, 기본값에서는 멈춘 시점의 가중치를 그대로 둔다. 즉 과적합이 두 에포크 진행된 상태로 끝난다. 되돌리려면 명시해야 한다.

EarlyStopping(monitor="val_loss", patience=3, restore_best_weights=True)
ModelCheckpoint("best.keras", monitor="val_loss", save_best_only=True)

평가와 예측

model.evaluate(x_test, y_test)   # [0.7133, 0.45] ← 리스트다. 첫 값이 loss, 뒤는 metrics 순서
model.predict(x_test)            # 확률(또는 회귀값) 배열

부류 번호가 필요하면 직접 뽑는다. 치트시트의 predict_classes 는 사라졌다.

model.predict_classes(x)              # AttributeError
np.argmax(model.predict(x), axis=-1)  # 다중 분류
(model.predict(x) > 0.5).astype(int)  # 이진 분류

드롭아웃이 있는 모델은 학습 때와 추론 때가 다르게 동작한다. predict 는 알아서 추론 모드로 돈다.

predict 두 번      : [0.553347, 0.594437, 0.592502] / [0.553347, 0.594437, 0.592502]  → 같다
training=True 두 번: [0.5163, 0.4992, 0.6221] / [0.6520, 0.6284, 0.6645]              → 다르다

예측이 부를 때마다 달라진다면 추론 모드로 부르지 않은 것이다.

저장

model.save("model_file.keras")                  # 지금 권장 형식
model.save("model_file.h5")                     # 아직 되지만 옛 형식이다
keras.models.load_model("model_file.keras")

치트시트는 model_file.h5 로 저장해 놓고 my_model.h5 를 불러온다. 그대로 따라 하면 ValueError: File not found 다. 사소해 보여도 저장 이름과 불러오는 이름을 눈으로 맞추는 것이 실기에서 시간을 아낀다.

치트시트가 낡은 부분

TF 2.21 / Keras 3.15 에서 한 줄씩 쳐 보고 정리한 것이다.

치트시트지금대신
from tensorflow.keras.klayers import ...ModuleNotFoundError — 원본의 오타다keras.layers
model.predict_classes(x)AttributeError (TF 2.6 에서 제거)np.argmax(model.predict(x), axis=-1)
RMSprop(lr=0.0001, decay=1e-6)ValueError: Argument(s) not recognized: {‘lr’}RMSprop(learning_rate=0.0001)
Dense(32, input_dim=100) (첫 층)UserWarningInput(shape=(100,)) 를 앞에 둔다
sklearn.cross_validation (설명문)없다 (sklearn 0.20 에서 제거)sklearn.model_selection
model.save("...h5")아직 된다.keras 를 쓴다

decay 인자도 사라졌다. 학습률을 줄여 가려면 keras.optimizers.schedules 나 ReduceLROnPlateau 콜백을 쓴다.

시험장은 방향이 정확히 반대다

최신 (TF 2.21 / Keras 3.15)시험장 (TF 1.13 / Keras 2.2.4)
predict_classes없다있다. 오히려 이걸 쓴다
lr=없다정상 인자다
input_dim=경고정상 방식이다
History 키accuracyacc
저장 형식.keras.h5 만 있다
importkeras 또는 tensorflow.keraskeras (별도 패키지)

이 글에서 “낡았다”고 표시한 것의 대부분이 시험장에서는 정답이다. 반대로 이 글의 최신 표기를 시험장에 그대로 가져가면 거의 다 깨진다. 그러니 연습 환경을 시험장에 맞추는 것이 가장 안전하고, 그게 어려우면 predict_classes 와 acc 두 개만이라도 기억해 둔다 — 실기에서 가장 자주 걸린다. 나머지 시험장 이야기는 시험장 환경 글에 있다.

출처

DataCamp 의 Python For Data Science Cheat Sheet — Keras 를 보고 다시 쓴 것이다. 원본은 DataCamp 치트시트 페이지에서 받을 수 있고, 공식 문서는 keras.io 다. 확인은 이 글을 쓰려고 따로 만든 가상환경에 TensorFlow 를 설치해서 했고, 결과는 위에 적은 그대로다.

표시는 이 브라우저에만 남는다. 서버로 가는 것은 없다.