심층신경망 실습🦄
- 새로운 모델 생성 : model20 변수명 사용
- epoch 20번 반복 수행
- 프로그래스바가 보이도록 훈련시 출력하기
- 손실 및 정확도 곡선 각각 그려주세요~
* 함수 정의
def model_fn(a_layer = None):
"""모델 생성"""
model = keras.Sequential()
"""입력층(1차원 전처리계층) 추가"""
model.add(keras.layers.Flatten(input_shape = (28,28)))
"""100개의 출력을 담당하는 은닉계층 추가, 활성화 함수 relu"""
model.add(keras.layers.Dense(100, activation="relu"))
"""추가할 은닉계층이 있는 경우만 실행됨"""
if a_layer:
model.add(a_layer)
"""출력층"""
model.add(keras.layers.Dense(10, activation="softmax"))
"""모델 반환"""
return model
"""모델 생성 계층 확인하기"""
print(f"{model.summary()}")
* 함수 호출
model20 = model_fn()
model20
* 모델 설정하기
model20.compile(loss="sparse_categorical_crossentropy", metrics="accuracy")
* 모델 훈련하기
history20=model20.fit(train_scaled, train_target, epochs=20, verbose=1)
* 훈련에 대한 손실 및 정확도 곡선을 하나의 그래프로 그리기
def loss_accuracy_one_plt(model_name):
plt.title(f"Epoch20 - Loss & Acc")
plt.plot(model_name.epoch, model_name.history["loss"])
plt.plot(model_name.epoch, model_name.history["accuracy"])
plt.xlabel("epoch")
plt.ylabel(f"loss & acc")
plt.grid()
plt.legend(["loss", "acc"])
"""이미지로 저장 시키기"""
plt.savefig(f"./saveFig/Epoch20-loss_acc.png")
plt.show()
loss_accuracy_one_plt(history20)
훈련 및 검증에 대한 손실 및 정확도 모두 표현하기 🦄
* 훈련과 검증을 동시에 수행하기
- validation_data : 검증 데이터를 이용해서 성능평가(evaluate)를 동시에 수행함
* 함수 호출
model = model_fn()
model
* 모델 설정하기
model.compile(loss="sparse_categorical_crossentropy", metrics="accuracy")
* 모델 훈련하기
history = model.fit(
train_scaled, train_target, epochs=20, verbose=1, validation_data=(val_scaled, val_target)
)
* 훈련에 대한 4가지 정보를 가져다 사용할 수 있다.
history.history.keys()
출력 : dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])
* 훈련과 검증에 대한 손실(loss) 곡선
plt.title("Epoch - Train & Val Loss")
plt.plot(history.epoch, history.history["loss"])
plt.plot(history.epoch, history.history["val_loss"])
plt.xlabel("epoch")
plt.ylabel("loss")
plt.grid()
plt.legend(["Train", "Val"])
"""이미지로 저장 시키기"""
plt.savefig(f"./saveFig/Epoch-Train_Val_loss.png")
plt.show()
해석🪄 : 훈련 손실율이 검증 손실율 그래프보다 작을때가 과소적합이 덜 일어나므로 적당함.
x=2일때가 가장 차이가 적으므로 좋은 시점임.
* 훈련과 검증에 대한 정확도(accuracy) 곡선
plt.title("Epoch - Train & Val accuracy")
plt.plot(history.epoch, history.history["accuracy"])
plt.plot(history.epoch, history.history["val_accuracy"])
plt.xlabel("epoch")
plt.ylabel("accuracy")
plt.grid()
plt.legend(["Train", "Val"])
"""이미지로 저장 시키기"""
plt.savefig(f"./saveFig/Epoch-Train_Val_accuracy.png")
plt.show()
해석🪄 : 훈련 할수록 과대적합이 일어나고 있음 (그래프 사이간격 멀어짐), 가장 근접했을 때가 좋은 epoch.
옵티마이저 adam 사용 🦄
* 과적합 해소하기
- model 변수명으로 신규 모델 만들기
→ 옵티마이저 adam 사용
- 훈련 및 검증 동시에 훈련시킨 후 손실 및 검증 곡선 그려서 과적합 여부 확인하기
* 함수 호출
model = model_fn()
model
* 모델 설정하기
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics="accuracy")
* 모델 훈련하기
history=model.fit(train_scaled, train_target, epochs=200, verbose=1, validation_data=(val_scaled, val_target))
* 훈련과 검증에 대한 손실(loss) 곡선
plt.title("Epoch - Train & Val Loss (Adam)")
plt.plot(history.epoch, history.history["loss"])
plt.plot(history.epoch, history.history["val_loss"])
plt.xlabel("epoch")
plt.ylabel("loss")
plt.grid()
plt.legend(["Train", "Val"])
"""이미지로 저장 시키기"""
plt.savefig(f"./saveFig/Epoch-Train_Val_loss(Adam).png")
plt.show()
* 훈련과 검증에 대한 정확도(accuracy) 곡선
plt.title("Epoch - Train & Val accuracy (Adam)")
plt.plot(history.epoch, history.history["accuracy"])
plt.plot(history.epoch, history.history["val_accuracy"])
plt.xlabel("epoch")
plt.ylabel("accuracy")
plt.grid()
plt.legend(["Train", "Val"])
"""이미지로 저장 시키기"""
plt.savefig(f"./saveFig/Epoch-Train_Val_accuracy(Adam).png")
plt.show()
해석🪄 과대적합이 발생하고 있다. 올라가다가 꺽이는 지점(val기준)이 가장 좋은 지점
성능 규제하기 - 드롭아웃(Dropout)🦄
* 성능 규제
- 성능(과적합 여부 포함)을 높이기 위한 방법
- 보통 전처리 계층을 사용하게 됩니다.
- 전처리 계층은 훈련에 영향을 미치지 않음
* 성능 규제 방법 → 드롭 아웃(Dropout())
* 드롭아웃(Dropout)
- 훈련 과정 중 일부 특성들을 랜덤하게 제외 시켜서 과대적합을 해소하는 방법
- 딥러닝에서 자주 사용되는 전처리 계층으로 성능 개선에 효율적으로 사용됨
* 사용방법
- 계층의 중간에 은닉층(hidden layer)로 추가하여 사용됨 ;보통 은닉계층 전에 넣어줌
- 훈련에 관여하지는 않음 → 데이터에 대한 전처리라고 보시면 됩니다.
ex)keras.layers.Dropout(0.3)
Dropout(0.3) : 사용되는 특성 30% 정도를 제외하기
** 조금 멍청하게 만드는 방법...(똑똑해지는 것을 방지)
* 모델 생성하기
dropout_layer = keras.layers.Dropout(0.3)
model = model_fn(dropout_layer)
model.summary()
* 모델 설정하기
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics="accuracy")
* 모델 훈련하기
history=model.fit(train_scaled, train_target, epochs=200, verbose=1, validation_data=(val_scaled, val_target))
↓
* 모델 훈련하기 2차 (훈련과 검증데이터가 근접한 epoch를 찾아서 다시 훈련시켜봄)
history=model.fit(train_scaled, train_target, epochs=14, verbose=1, validation_data=(val_scaled, val_target))
* 훈련과 검증에 대한 손실(loss) 곡선
plt.title("Epoch - Train & Val Loss (Adam-Dropout)")
plt.plot(history.epoch, history.history["loss"], marker=".")
plt.plot(history.epoch, history.history["val_loss"], marker=".")
plt.xlabel("epoch")
plt.ylabel("loss")
plt.grid()
plt.legend(["Train", "Val"])
"""이미지로 저장 시키기"""
plt.savefig(f"./saveFig/Epoch-Train_Val_loss(Adam-Dropout).png")
plt.show()
해석🪄
- 7.5 epoch를 기점으로 그 전에는 과소적합이 나타나고 그 이후에는 점점 진행할 수록 과대적합이 나타나고 있다.
- 가장 근접했을 8정도가 적당한 시점으로 보인다.
* 훈련과 검증에 대한 정확도(accuracy) 곡선
plt.title("Epoch - Train & Val accuracy (Adam-Dropout)")
plt.plot(history.epoch, history.history["accuracy"] , marker="." )
plt.plot(history.epoch, history.history["val_accuracy"] , marker="." )
plt.xlabel("epoch")
plt.ylabel("accuracy")
plt.grid()
plt.legend(["Train", "Val"])
"""이미지로 저장 시키기"""
plt.savefig(f"./saveFig/Epoch-Train_Val_accuracy(Adam-Dropout).png")
plt.show()
해석🪄
- 훈련이 위로가야됨, 10을 이후로 과대적합 , 12일때 가장 근접해보이므로 정확도를 보았을때 12가 적당해 보임.
- 두 그래프 모두 과소적합이 일어나지 않으면서 과대적합이 크게 일어나지 않아야하고 손실율이 낮으면서 정확도가 좋은 지점은 12가 되는거 같다.
모델 저장 및 복원하기 🦄
<모델 저장하는 방법>
* 가중치만 저장하기
- 모델이 훈련하면서 찾아낸 가중치 값들만 저장하기
- 모델 자체가 저장되지는 않습니다.
- 모델 신규생성 > 저장된 가중치 불러와서 반영 > 예측 진행
- 별도로 훈련(fit)은 하지 않아도 됩니다.
* 모델 자체 저장하기
- 저장된 모델을 불러와서 > 예측 진행
가중치 저장 및 불러들이기
* 가중치 저장하기
- save_weights() : 가중치 저장하기
- 저장시 사용되는 확장자는 보통 h5를 사용합니다.
model.save_weights("./model/model_weights.h5")
* 저장된 가중치 불러들이기
- load_weights () : 가중치 불러오기
"""1. 모델 생성"""
model_weight = model_fn(keras.layers.Dropout(0.3))
model_weight.summary()
"""2. 가중치 적용하기"""
model_weight.load_weights("./model/model_weights.h5")
"""이후 부터는 바로 예측으로 사용"""
모델 자체 저장하기
* 모델 자체 저장하기
- save()
model.save("./model/model_all.h5")
* 모델 자체 불러들이기
- load_model()
model_all = keras.models.load_model("./model/model_all.h5")
model_all.summary()
"""이후부터는 바로 예측으로 사용 가능"""
예측하기
* 예측하기
pred_data = model_all.predict(val_scaled)
"""첫번째 값만 추출"""
pred_data[0]
출력 : array([4.2536481e-11, 2.3170347e-15, 9.8706080e-13, 8.7341098e-12,
1.1521755e-10, 1.7207690e-06, 5.6376002e-14, 4.6494847e-08,
9.9999821e-01, 1.0138960e-14], dtype=float32)
- np.argmax() : 배열에서 가장 큰 값을 가지는 인덱스를 추출
import numpy as np
np.argmax(pred_data[0]), val_target[0]
출력 : (8, 8)
해석🪄 8번째 인덱스 값이 가장 값이 크게 나왔다. 예측 성공
* 예측 결과의 모든 행에 대해서 가장 높은 값을 가지는 열의 인덱스 위치 추출
- axis=1 : 열 단위로 뽑아라
val_pred = np.argmax(pred_data, axis=1)
val_pred
출력 : array([8, 8, 7, ..., 8, 8, 6], dtype=int64)
정답갯수, 오답갯수, 정답률, 오답률을 출력
<내 코드>
true = 0
false = len(val_pred)
for x, y in zip(val_pred, val_target):
# print(f"x : {x}, y : {y}")
if x == y:
true += 1
false -= 1
true_per = true/len(val_pred)*100
false_per = false/len(val_pred)*100
print(f"정답갯수 : {true} / 오답갯수 : {false}")
print(f"정답률 : {true_per:.2f}% / 오답률 : {false_per:.2f}%")
출력 : 정답갯수 : 10525 / 오답갯수 : 1475
정답률 : 87.71% / 오답률 : 12.29%
<강사님 코드>
# ok = np.sum(val_pred == val_target)
ok = len(val_pred[val_pred == val_target])
no = np.sum(val_pred != val_target)
ok_p = ok / len(val_target)
no_p = no / len(val_target)
ok, no, ok_p, no_p
출력 : (10525, 1475, 0.8770833333333333, 0.12291666666666666)
성능향상 - 콜백(Callback) 함수 🦄
< 성능향상 - 콜백함수>
* 콜백함수(Callback Function)
- 모델 훈련 중에 특정 작업(함수)를 호출할 수 있는 기능
- 훈련(fit)시에 지정하는 함수를 호출하는 방식
- 훈련 중에 발생시키는 "이벤트"라고 생각하시면 됩니다.
- 별도의 계층은 아니며, 속성(매개변수)으로 정의됩니다.
* 콜백함수 종류
- ModelCheckpoint()
: epoch 마다 모델을 저장하는 방식
: 단, 앞에서 실행된 훈련 성능보다 높아진 경우에만 저장됨
- EarlyStopping()
: 훈련이 더이상 좋아지지 않으면 훈련(fit)을 종료시키는 방식
: 일반적으로 ModelCheckpoint()와 함께 사용
ModelCheckPoint 콜백함수
1. 모델 생성하기
model = model_fn(keras.layers.Dropout(0.3))
model.summary()
2. 모델 설정하기
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics="accuracy")
3. 콜백함수 생성하기
< 콜백함수 - ModelCheckpoint >
* 콜백함수 생성
- 훈련(fit) 전에 생성합니다.
- save_best_only = True
: 이전에 수행한 검증 손실율보다 좋을 때 마다 훈련모델 자동 저장시키기
: 훈련이 종료되면, 가장 좋은 모델만 저장되어 있습니다.
- save_best_only = False
: epoch마다 훈련모델 자동 저장 시키기
- 저장된 모델은 : 모델 자체가 저장되는 방식으로 추후 불러들인 후 바로 예측으로 사용 가능
checkpoint_cb = keras.callbacks.ModelCheckpoint(
### 모델 저장 경로 설정
"./model/best_model.h5",
### 모델 저장 방법 설정
save_best_only = True
)
checkpoint_cb
<keras.callbacks.ModelCheckpoint at 0x1c0973051f0>
4. 모델 훈련 시키기 - 콜백함수 적용
< 콜백함수 - ModelCheckpoint >
* 콜백함수로 훈련시키기
- fit()함수 내에 콜백함수 매개변수에 정의
- 콜백함수 리스트 형식으로 정의
ex) checkpoint_cb = keras.callbacks.ModelCheckpoint("./model/best_model.h5", save_best_only = True)
ex) callbacks = [checkpoint_cb]
history = model.fit(
train_scaled, train_target, epochs=10, verbose=1,
validation_data=(val_scaled, val_target),
### 콜백함수에 대한 매개변수 : 리스트 타입으로 정의
callbacks = [checkpoint_cb]
)
5.콜백함수를 통해 저장된 모델 불러들이기
model_cp_cb = keras.models.load_model("./model/best_model.h5")
model_cp_cb.summary()
"""성능 평가"""
model_cp_cb.evaluate(val_scaled, val_target)
EarlyStopping 콜백함수
< 콜백함수 - EarlyStopping>
* EarlyStopping()
- 훈련 성능이 더 이상 좋아지지 않으면 훈련을 종료시킴
- 과대적합을 해소하는데 좋음(과대 적합이 발생하기 전에 종료시킴)
- 보통 콜백함수 ModelCheckpoint()와 함께 사용함
- patience=2 : 더 이상 좋아지지 않는 epoch의 갯수 지정
가장 좋은 시점의 epoch 이후 2번 더 수행 후 그래도 좋아지지 않으면 종료시킨다는 의미
- restore_best_weights=True : 가장 낮은 검증 손실을 나타낸 모델의 하이퍼파라메터로 모델을 업데이트 시킴
ex) early_stopping_cb = keras.callbacks.EarlyStopping(patience=2, restore_best_weights=True)
ex) callbacks = [checkpoint_cb, early_stopping_cb]
1. 모델 생성하기
model = model_fn(keras.layers.Dropout(0.3))
model.summary()
2. 모델 설정하기
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics="accuracy")
3. 콜백함수 생성하기
"""ModelCheckPoint()"""
checkpoint_cb = keras.callbacks.ModelCheckpoint("./model/best_model.h5", save_best_only = True)
"""EarlyStopping()"""
early_stopping_cb = keras.callbacks.EarlyStopping(patience=2, restore_best_weights=True)
4. 모델 훈련 시키기 - 콜백함수 적용
history = model.fit(
train_scaled, train_target, epochs=100, verbose=1,
validation_data=(val_scaled, val_target),
### 콜백함수에 대한 매개변수 : 리스트 타입으로 정의
callbacks = [checkpoint_cb, early_stopping_cb]
)
해석🪄
- Epoch 8/100이 시점의 데이터가 정확하다는 뜻( -2 해야함 why? patience=2 했으므로)
- loss: 0.3358 - accuracy: 0.8759 - val_loss: 0.3310 - val_accuracy: 0.8789
5. 콜백함수를 통해 저장된 모델 불러들이기
model_f= keras.models.load_model("./model/best_model.h5")
model_f.summary()
"""성능 평가"""
print(model_f.evaluate(train_scaled, train_target))
print(model_f.evaluate(val_scaled, val_target))
'인공지능 > 딥러닝' 카테고리의 다른 글
[딥러닝DL] DNN 분류데이터사용 (1) | 2024.01.05 |
---|---|
[딥러닝DL] DNN 회귀데이터 사용 (1) | 2024.01.05 |
[딥러닝DL] 심층신경망(DNN) 훈련 및 성능향상 - verbose, epoch, history, 시각화 (2) | 2024.01.03 |
[딥러닝] 신경망계층 추가방법 및 성능향상방법 - 옵티마이저 (1) | 2024.01.03 |
[딥러닝] 인공신경망 훈련모델 맛보기 (1) | 2023.12.29 |