11/28
Q. 정확도로 제대로 된 모델의 성능을 측정을 하기 어려운 사례는 어떤게 있을까?
A. 희귀병 검사결과, 불량품 검출(양불 여부), 스팸메일 분류, 은행 대출 사기, 신용카드 사기, 상장폐지종목 여부,
게임 어뷰저, 광고 어뷰저, 그외 어뷰저
=> 이런 사례는 Accuracy로 측정하면 99.99 % 가 나온다면 제대로 측정하기가 어려움
-> 불균형한 데이터일 때 평가를 내리기 어려움
❗ 현실세계는 대부분 불균형한 데이터
Q. 1종 오류의 사례
-> precision을 사용
A. 스팸 메일, 중고차 성능 판별(성능이 좋지 않은 차량은 좋은 차량으로 판매했을 경우 생명과 직결되는 문제), 유무죄 선고(무고한 사람에게 유죄를 선고하면 문제)
Q. 2종 오류의 사례
-> recall을 사용
A. 암인데 암이 아니라고 예측, 지진이 났는데 대피명령이 없는 예측, 자율주행에서 앞에 사람이있는데 사람이라고 인식하지 못할때
-> 임계값을 직접 정해서 True, False를 결정하게 되는데 보통 0.5 로 하기도 하고 0.3, 0.7 등으로 정하기도 함
-> 기존에는 예측을 할 때 주로 predict 를 사용했지만 predict_proba 를 하게 되면 0,1 등의 클래스 값이 아닌 확률값으로 반환
✒ 임계값 == Threshold
-> 임계값을 낮추게 된다는 것은 그만큼 모델이 Positive라고 예측하는 횟수가 많아진다는 것과 동일한 의미
💥 threshold를 내리면 recall은 올라가고 precision은 내려가게 된다
💥 '공돌이의 수학정리 노트' 정리가 잘 되어있으니 참고!!
https://angeloyeo.github.io/2020/08/05/ROC.html
✒️ zip 은 완전히 다 업로드 되어야 로드가 가능
✒️ csv 는 행기반으로 저장되어 있기 때문에 일부만 업로드 되더라도 불러올 수 있음
🎈 mount 기능 사용하는 법!
(파일 업로드가 느릴 때 구글 드라이브랑 연결하기)
1. 왼쪽 아래에 있는 '<>' 기호인 코드 스니펫 클릭
2. 검색창에 'mount'입력
3. mounting Google~~을 누리고 오른쪽 중간에 있는 삽입 버튼 클릭
4. 새로운 코드가 생성되면서 실행하면 로그인을 하라는 팝업창이 뜸
5. 두번째 생성된 코드를 실행하여 새로만든 폴더인 'data' 폴더 경로를 확인
6. data 폴더 새로 고침하면 foo.txt가 새로 생성
7. pd.read_csv"/gdrive/My Drive/data/creditcard.csv")를 입력하면 원하는 파일을 불러옴
=> 구글 드라이브를 마운트하면 매번 colab에 업로드 하지 않아도 되고 좀 더 빠름
-> 각 클래스마다의 확률을 예측
-> 0,1 일때 각각의 확률을 의미
-> [0.5, 0.5][0.3, 0.7] [0.7, 0.3] 이렇게 나오기도 함
-> 클래스가 여러 개 일 때 이런 확률을 사용해서 예측하기도 함
y_pred_proba = model. predict_proba(X_test)
np.argmax는 값이 가장 큰 인덱스를 반환함
import numpy as np np.argmax(y_pred_proba, axis=1)
predcit로 예측한 결과값과 predict_proba로 예측한 결과값이 똑같다
(y_pred == y_pred_proba_class).mean()
=> 1.0
pd.crosstab(y_test, y_pred)
`from sklearn.metrics import confusion_matrix
cf = confusion_matrix(y_test, y_pred)
sns.heatmap(cf, annot=True, cmap="Blues")`
cr = classification_report(y_test, y_pred)
print(cr)
from sklearn.metrics import f1_score
f1_score(y_test, y_pred)
# precision_score, recall_score
from sklearn.metrics import precision_score, recall_score
print(precision_score(y_test,y_pred))
print(recall_score(y_test, y_pred))
🎈 신용카드 사기에는 recall 측정 지표 사용이 더 적절
🎈 게임에서도 어뷰저가 아닌데 어뷰저로 처리하는 경우가 있음
-> 어뷰저라니 기분 나빠, 게임 접겠다! 라는 고객이 있을 수 있음
-> 그럴 경우는 recall 측정 지표가 더 적합
under-sampling: 더 값이 많은 쪽에서 일부만 샘플링하여 비율을 맞춰주는 방법
: 구현이 쉽지만 전체 데이터가 줄어 머신러닝 모델 성능이 떨어질 우려있음
over-sampling: 더 값이 적은 쪽에서 값을 늘려 비율을 맞춰준 방법
: 어떻게 없던 값을 만들어야 하는지에 대한 어려움이 있음
y.value_counts()
df_1 = df[df['Class']==1]
df_0.shape, df_1.shape
df_under['Class'].value_counts()
sm = SMOTE(random_state = 42)
X_resample, y_resample = sm.fit_resample(X,y)
X_resample.shape, y_resample.shape
f1_score(y_test, y_pred)
precision_score(y_test, y_pred), recall_score(y_test, y_pred)
🔷 precision 예측값 기준 => 1종 오류
🔷 recall 실제값 기준 => 2종 오류
💥 SMOTE를 사용한 오버 샘플링 데이터로 모델을 만들어 예측한 결과 비교
-> 샘플링을 사용하지 않고 데이터를 나눠 학습했을 때와 비교해서 f1_score, precision, recall 값이 모두 높아짐
💥 정답 클래스가 불균형하면 학슴을 제대로 하기 어렵기 때문에 오버 샘플링이나 언더 샘플링으로 정답 클래스를 비슷하게 만들어 주면 더 나은 성능을 냄
: 인공지능 스스로 일정 범주의 데이터를 바탕으로 공통된 특징을 도출하고 그 특징으로 예측값 출력 >> 사람같지만 보다 빠른 학습속도, 원하는 빅데이터를 학습 후 활용 가능
✒️ 1950년대 이전부터 신경망 연구가 있었지만 하드웨어의 한계와 데이터 부족의 이류로 활성화되지 못했음
✒️ 이미지, 사운드, 모션 입력만으로도 딥러닝 모델을 만들어주는 편리한 웹사이트!!!
https://teachablemachine.withgoogle.com/
: 인공 신경망에서 입력층에서 출력층 방향으로 예측값의 연산이 진행되는 과정
-> 입력값은 입력층, 은닉층을 지나며 각 층에서의 가중치와 함께 연산되며, 출력층에서 모든 연산을 마친 예측값 도출
: 순전파와 반대로 출력층에서 입력층 방향으로 계산하면서 가중치를 업데이트
-> 가중치 비율을 조정하여 오차 감소를 진행 >> 다시 순전파 진행으로 오차 감소확인 가능
-> 각각의 가중치를 조정하는 방법/ 속도는 느리지만 안정적인 결과를 얻을 수 있음
1. 시그모이드
: S자형 곡선 또는 시그모이드 곡선을 갖는 수학 함수(e. 로지스틱 함수)
2. tanh-하이퍼 볼릭탄젠트 함수
: sigmoid의 대체로 사용될 수 있음
: 쌍곡선 함수로써 삼각함수와 유사한 성질을 가지고 표준 쌍곡선을 매개 변수로 표시할 때 나오는 함수
11/29
https://www.youtube.com/watch?v=aircAruvnKk
Q. Fully Connected Network 에는 1차원형태로 네트워크에 데이터를 주입해야 하는데 어떻게 비정형 데이터(표형태가 아니라 이미지, 음성, 텍스트 등)를 잘 다룰까
A. 전처리 레이어에서 이미지, 음성, 텍스트 등을 전처리 하는 기능을 따로 제공, 1차원 형태로 네트워크에 데이터를 주입
✒ DNN(Deep Neural Network) => CNN => RNN 순으로 배울 예정!
Q. 왜 28x28 이미지를 입력받을 때 784 로 입력받을까
A. fully connected network에서는 1차원으로만 주입이 가능하기 때문에 네트워크에 데이터를 주입하기 위해
🔷 CNN, RNN 에서는 데이터 전처리를 어떻게 해줄지를 전처리 기능을 제공하고 마지막에는 Fully Connected Network 를 통과하게 된다
-> w == weight의 약자로 보통 가중치로 번역
-> b == bias의 약자로 보통 편향으로 번역
🔷 가중치는 두번째 레이어가 선택하려는 뉴런의 픽셀 패턴을 알려주며 bias는 뉴런이 활성화되려면 가중치의 합이 얼마나 더 높아야 하는지를 알려준다.
-x를 소문자로 사용
-ndim = 차원의 수
🔷 sigmoid: 활성화 함수로 오늘 실습을 할 예정인데 relu, swish 등 다양한 활성화 함수가 있다
Q. sigmoid의 단점
A. 기울기 소실 문제, gradient vanishing
Q. 위 문제를 해결하기 위해 나온 활성화 함수는?
A. ReLu, 리키렐루 함수
Q. dropout 이 무엇일까?
A. 일부 노드를 제거하고 사용하는 것(과대적합 방지하기 위해)
-> 학습속도와는 상관없음
ex)
tf.keras.layers.Dropout(0.2)
-> 128개 중에 20퍼센트를 날리겠다
🔷 MNIST 손글씨 이미지 데이터 셋은 왜 만들었을까~~?
-> 우편번호를 읽어내기 위해!
MNIST: 손으로 쓴 숫자들로 이루어진 대형 데이터베이스 -> 다양한 화상처리 시스템을 트레이낭하기 위해 일반적으로 사용
60,000개의 트레이닝 이미지와 10,000개의 테스트 이미지를 포함
트레이닝 세트의 절반과 테스트 세트의 절반은 NIST의 트레이닝 데이터셋에서 취합하였으며, 그 밖의 트레이닝 세트의 절반과 테스트 세트의 절반은 NIST의 테스트 데이터셋으로부터 취합
예시 코드
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
idx = 38
display(pd.DataFrame(x_train[idx]).style.background_gradient())
sns.heatmap(x_train[idx], cmap="gray")
plt.title(f"label : {y_train[idx]}")
💥 각 이미지에 어떤 값이 있는지 확인하는 법
🔷 output = activation(dot(input, kernel) + bias)
출력 = 활성화함수(행렬곱(input, kernel) + 편향)
🔷 tf.keras.layers.Dense(units=128, activation='relu')
=> units(노드) 개수, 층(레이어)수는 하이퍼파라미터
-> 출력값고 실제값을 비교하여 그 차이를 최소화하는 가중치와 편향의 조합 찾기
: 가중치는 오차를 최소화하는 방향으로 모델이 스스로 탐색(역전파)
:오차계산은 실제 데이터를 비교하며 손실함수(모델의 정확도 평가시 오차를 구하는 수식)를 최소화하는 값을 탁색하기에 알맞은 손실함수를 선정하는것이 중요
🔷 손실함수
: 머신러닝 혹은 딥러닝 모델의 예측값과 사용자가 원하는 실제값의 오차를 의미
: 손실함수의 함수값이 최소화되도록 하는 가중치(weight)와 편향(bias)를 찾는 것이 목표
🔷 경사하강법
: 손실함수의 현재 위치에서 조금씩 손실이 낮아지는 쪽으로 가중치를 움직이며 최솟값을 찾는 방법
🔷 옵티마이저
: 최적화 방법을 결정해주는 방식
: 경사하강법에 기반을 둠
-> local minima에 빠져 global minima를 찾지 못하는 것을 방지하기 위해 사용
-> 오차가 최소가 되는 지점을 찾기 위해 사용
💥 오차가 최소가 되는 지점을 찾기 위한 optimizer, 기울기, 방향, learning rate를 고려
🔷 loss: 손실율 측정(모델이 학습을 하고 결과값이 나오면 실제값과 얼마나 차이가 있는지 평가하는 손실함수)
-> 븐류에서는 주로 크로스 엔트로피를 사용
🔷 metrics: 평가지표
Q. 분류 결과의 품질을 측정하기 위해 Loss 손실함수로 크로스엔트로피를 사용하는데 공식 앞에 마이너스는 왜 있을까?
A. 위 값들은 확률값이기 때문에 양수로 만들어줘야 함
💥 다 더했을 때 1
💥 각 클래스의 확률을 출력
model.fit(x_train, y_train, epochs=5)
-> 여러번 학습을 하면(여러번 실행하면!) loss가 점점 줄어든다
-> 학습을 하며 weight와 bias 값을 업데이트 하기 때문!
픽셀을 펼친 후에는 두 개의 tf.keras.layers.Dense 층이 연속되어 연결됩니다. 이 층을 밀집 연결(densely-connected) 또는 완전 연결(fully-connected) 층이라고 부릅니다. 첫 번째 Dense 층은 128개의 노드(또는 뉴런)를 가집니다. 두 번째 (마지막) 층은 10개의 노드의 소프트맥스(softmax) 층입니다. 이 층은 10개의 확률을 반환하고 반환된 값의 전체 합은 1입니다. 각 노드는 현재 이미지가 10개 클래스 중 하나에 속할 확률을 출력합니다.
🔷 2개라도 기본이 softmax이고 실습할 때는 바이너리 분류를 할 예정이라 sigmoid로 지정할 예정
🔷 텐서플로 VS 파이토치의 차이는 seaborn VS plotnine 처럼 라이브러리 도구의 API 차이
🔷 시각화 할 때도 data, x, y, color(hue) 이런 용어를 알고 있다면 API 가 달라지더라도 비슷하게 사용할 수 있는 것과 유사
🔷 직접 딥러닝 모델을 밑바닥부터 짜서 구현할 수도 있지만, 기능들을 함수나 메서드로 감싸서 코드 여러 줄을 한 두줄의 API 를 호출해서 사용할 수 있게 만들어 놓은 도구
🔷 분류:binary_crossentropy(이진분류)
categorical_crossentropy
(다중분류: one-hot-encoding)
sparse_categorical_crossentropy
(다중분류: ordinal Encoding)
❗❗ 힘들어도 어려워도 겁..먹지 말자..❗❗
❤️1) 다른 모델에 적용한다면 층 구성을 어떻게 할것인가? 입력-은닉-출력층으로 구성된다
2) 예측하고자 하는 값이 분류(이진, 멀티클래스), 회귀인지에 따라 출력층 구성, loss 설정이 달라진다
이건 예제를 몇 개 연습해 보면서 익히는 것을 추천!!
3) 분류, 회귀에 따라 측정 지표 정하기
4) 활성화함수는 relu 를 사용, optimizer 로는 adam 을 사용하면 baseline 정도의 스코어가 나온다
5) fit 을 할 때 epoch 를 통해 여러 번 학습을 진행하는데 이 때, epoch 수가 많을 수록 대체적으로 좋은 성능을 내지만 과대적합(오버피팅)이 될 수도 있다
6) epoch 수가 너무 적다면 과소적합(언더피팅)이 될 수도 있다
plt.axvline(0)
plt.legend()
tanh
plt.plot(x, tf.keras.activations.tanh(x), linestyle='--', label="tanh")
swish
plt.plot(x, tf.keras.activations.swish(x), linestyle='--', label="swish")
relu
plt.plot(x, tf.keras.activations.relu(x), linestyle='--', label="relu")
Q. 당뇨병 여부 예측문제에서는 출력층을 어떻게 구성?
A. 시그모이드로 해야함(당뇨병이다/아니다)
-> 다중분류와 이진분류의 차이를 생각
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(units=128, input_shape=[input_shape]),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
🔷 다중 분류일 때: 활성화함수=softmax, 출력층 n개
🔷 이진 분류일 때: 활성화함수=sigmoid, 출력층 1개
11/30
Q. sigmoid 그래프를 2진 분류에 사용한는 법?
A. 특정 임계값(ex 0.5)을 정해서 크고 작다를 통해 True, False 값으로 판단
-> 임계값은 보통 0.5를 사용하지만 다른 값을 사용하기도 함
(y_pred.flatten() > 0.5).astype(int)
Q. 바이너리이면 결과가 2개 나와야 하는게 아닌가?
A. 소프트 맥스라면 2개가 나온다
-> 바이너리로 했기 때문에 예측값이 각 row 당 하나씩 나옴
-> y_pred = model.predict(X_test)
로 나오는 값은 확률값(sigmoid) 0~1 사이의 값을 가진다
💥 바이너리를 사용하고 sigmoid를 사용한다면 결과는 1개가 나옴
🎈 성능 변경
1) 레이어
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(units=128, input_shape=[input_shape]),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(1, activation='sigmoid')
])
✒️ 보통 레이어 구성을 2의 제곱으로 사용하지만 꼭 그렇지는 않아도 된다
🎈1. 히든 레이어 추가
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(units=128, input_shape=[input_shape]),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(1, activation='sigmoid')
])
-> 히든 레이어 수를 더 늘릴 수 있다.
🎈2. unit 수 변경
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(units=128, input_shape=[input_shape]),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(1, activation='sigmoid')
])
-> 128을 2의 제곱으로 변경(꼭 제곱 아니어도 되긴 함)
🎈3. 활성화함수: activation 함수 변경
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(units=128, input_shape=[input_shape]),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(1, activation='sigmoid')
])
-> relu, swish, elu, selu 등등
2) 학습
history = model.fit(X_train, y_train, epochs=500, validation_split=0.4,
callbacks=[PrintDot(), early_stop], verbose = 0)
🎈1. epochs 수
history = model.fit(X_train, y_train, epochs=500, validation_split=0.4,
callbacks=[PrintDot(), early_stop], verbose = 0)
-> 수를 늘리면 늘릴수록 좋은 결과가 나오지만 너무 늘리면 과대적합 될 수 있음
🎈2. validation_split 비율
history = model.fit(X_train, y_train, epochs=500, validation_split=0.4,
callbacks=[PrintDot(), early_stop], verbose = 0)
🔷 drop-out 코드는 바로 위 layer에만 적용된다
-> 모든 레이어에 적용하고 싶으면 모든 레이어 밑에 drop-out 코드를 작성해줘야한다
💥 loss: 손실함수, 회귀는 MSE, MAE, 분류는 바이너리와 멀티클래스에 따라 나누어짐, 훈련에 사용해서 가중치와 편향을 업데이트
💥 metric: 평가지표, 회귀는 MSE, MAE, 분류일 때는 accuracy, 검증에 사용
Q. 분류일 때 사용하는 loss의 종류?
A, crossentropy
💥 보통은 정형데이터는 딥러닝보다는 머신러닝이 대체적으로 좋은 성능을 내기도 한다. 물론 딥러닝이 좋은 성능을 낼때도 있다!
💥 중요한 것은 데이터 전처리와 피처엔지니어링이 성능에 더 많은 영향을 준다는 것!!!
💥 garbage in garbage out: 좋은 데이터를 통해 모델을 만드는게 성능에 가장 중요한 역할
Q. 스케일값이 클때는?!
A. 정규화를 하자
-> Min-Max, standard, robust
-> standard, min-max, robust => 스케일만 바꿀 뿐이지 분포는 변하지 않는다
horsepower = np.array(train_features['Horsepower'])
horsepower_normalizer = layers.Normalization(input_shape=[1,], axis=None)
horsepower_normalizer.adapt(horsepower)
horsepower_model = tf.keras.Sequential([
horsepower_normalizer,
layers.Dense(units=1)
])
Q. 레이어 구성에서 출력층의 분류와 회귀의 차이는?
A. 분류는(n, activation='softmax'), (1, activation='sigmoid')
회귀는 항등함수 -> 그대로 출력
Q. 분류와 회귀 실습간의 loss의 차이는?
A. 분류: crossentropy 회귀: mae, mse 등
def build_and_compile_model(norm):
model = keras.Sequential([
norm,
layers.Dense(64, activation='relu'),
layers.Dense(64, activation='relu'),
layers.Dense(1)
])
model.compile(loss='mean_absolute_error',
optimizer=tf.keras.optimizers.Adam(0.001))
return model
-> loss='mean_absolute_error': loss값을 보니 회귀 모델이다!!
항등함수로 출력
layers.Dense(1)
-> 값 하나로 출력됨
선형회귀를 사용했을 때와 loss 값이 어떤 차이가 있나?
-> 선형회귀를 사용했을때보다 DNN을 사용했을 때 성능이 나아짐을 확인
(loss 값이 작은게 성능이 좋은 것)
🔷 선형입력 다중회귀
🔷 DNN 다중회귀
-> 이 값은 오차가 작게 나와야 잘 예측한 모델
1) 정형데이터 입력층 input_shape
2) 정규화 레이어의 사용 => 직접 정규화해도 된다
3) 출력층이 분류와 다르게 구성이 된다는 점
4) loss 설정이 분류, 회귀에 따라 다르다.
5) 입력변수(피처)를 하나만 사용했을 때보다 여러 변수를 사용했을 때 성능이 더 좋아졌다. => 반드시 여러 변수를 사용한다라고 해서 성능이 좋아지지 않을 수도 있지만 너무 적은 변수로는 예측모델을 잘 만들기 어렵다는 점을 알수 있다.
💥 loss는 훈련 손실값, val_loss는 검증 손실값
Q. 어떻게 해야 val 결과가 나올까?
A. validation_split 지정
Q. validation_split은 어디서 지정?
A. model.fit할때
-> model.fit(X_train, y_train, epochs, validation_split)
Q. dnn_model.predict(test_features).flatten() 예측 결과 뒤에 flatten() 이 있는 이유는 무엇일까
A. 2차원 값을 1차원 형태로 만들어주기 위해서(tesnsorflow같은 경우 예측값이 기본으로 2차원으로 나옴)
input shape값을 구하기
input_shape = train.shape[1]
레이어를 만들기: 분류와 동일하지만 회귀는 출력을 하나로 함!
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(units=128, input_shape = [input_shape]),
tf.keras.layers.Dense(128, activation='selu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(1)
])
-> 마지막 줄 Dense(1)만 다름!
dir(tf.keras.optimizers)
model.compile(optimizer=optimizer,
loss=['mean_absolute_error'],
metrics=["mae", "mse"])
early_stop = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=10) history = model.fit(X_train, y_train, epochs=1000, verbose=0, callbacks=[early_stop], validation_split = 0.2)
🔷1. 딥러닝 모델을 조정하여서 회귀 딥러닝 모델 생성
(분류 모델과 다르게 Dense 출력 유닛 1로 설정, Compile에서 loss, metrics 변경)
🔷2. 자원과 시간을 아끼기 위해서 학습 과정 중 성능이 비슷하면 멈출 수 있도록 EarlyStopping 설정
(tf.keras.callbacks.EarlyStopping)
(tf.keras.callbacks.EarlyStopping -> 성능이 비슷함에도 남은 epochs가 많이 남았다면 시간이 아까우니까~~~)
🔷3. 학습 과정에서 validation_split을 설정하여 검증 데이터셋도 설정
(모델이 과적합인지 과소적합인지 제 성능을 하는지 확인하기 위해서-> model.fit(validation_split=0.2)))
🔷4. 딥러닝 모델을 학습
(model.fit)
🔷5. 학습한 모델의 성능을 history 표를 보면서 측정
(여기서 우리 전에 배웠던 loss, mae, mse 지표를 보면서 모델이 잘 예측했는지 평가하기)
-> 검증모델에서의 지표와 비교를 해보고(val_loss, val_mae, val_mse 등등) 과대적합이 됐는지, 과소적합이 됐는지도 볼 수 있다
❤️ 출처: 오늘코드
❤️ 출처: 멋쟁이 사자처럼 AI school