🔸 compile() method 사용해서 loss function과 optimizer를 지정하고 어떤 metrics을 사용해서 regression할지 결정
🔸 Optionally, specify a list of extra metrics to compute during training and evaluation
model.compile(loss="sparse_categorical_crossentropy", optimizer="sgd", metrics=["accuracy"])
🔸 위 코드의 loss = "sparse_categorical_crossentropy" 와 같은 의미
🔸 multiclass output with integer labels(sparse labels)일 경우 사용하는 loss function
🔹 integer label로 하나씩 mapping될 수 있고 그러한 output이 3개 이상의 multiclass를 가질 경우 사용
🔸 categorical_crossentropy: multiclass output with one-hot encoding labels
🔹 one-hot code: 8개의 bit가 있고 1의 위치에 따라 class 결정
ex. binary encoding의 경우 0000,0001,0010 등으로 진행, one-hot code의 경우 00000001, 00000010,00000100 등으로 진행
🔸 cf) binay classification의 경우 binary_crossentropy 사용
🔸 binary code와 one-hot code (binary(=sparse) label과 one-hot label)변환
🔹 Binary->One-hot: keras.utils.to_categorical() function
🔹 One-hot->Binary: np.argmax() function with axis=1
💡 loss function 달라지면 학습 결과 달라짐
🔸 train 진행하면서 각 iteration마다 learning rate를 어떻게 적용할지
🔸 Stochastic Gradient Descent 방식
🔸 default learning rate는 0.01이고 바꾸고 싶으면 SGD(learningrate=x)로 작성(이때 x는 원하는 learning rate 값)
💡 optimizer는 학습 속도와 효율에 영향 미침
Stochastic Gradient Descent
: Loss Function을 계산할 때, 전체 데이터(Batch) 대신 일부 데이터의 모음(Mini-Batch)를 사용하여 Loss Function을 계산
🔸 regression할 때 어떤 값을 가지고 평가할 것인지
history = model.fit(X_train, y_train, epochs=30, validation_data=(X_valid, y_valid))
🔸 epoch: 학습을 얼마나 진행할지, validation을 지정하지 않았을 경우 validation_split=0.1 하면 train data가 90%, validation data가 10%
🔸 60,000개의 train_full 중 55,000개를 train data로, 5,000개를 validation data로 설정했음
🔸 epoch을 30으로 지정했으므로 55,000개의 train data를 훈련시키고 5,000개의 validation으로 검증하는 하나의 epoch이 30번 진행됨
🔸 결과에서 보이는 첫번째 loss와 accuracy는 55,000개의 train data에 대한 결과이고, 두번째 나타난 val_loss와 val_accuracy는 5,000개의 validation data에 대한 결과
🔸 훈련 출력 시에는 validation set을 제외한 train data의 개수가 한 epoch 구성
🔸 학습 속도 확인할 때, 3s 보다 2ms/step과 같이 step 더 정확함
🔸 Loss/accuracy: how well the model really performs
🔹 model이 얼마나 좋은 성능을 가지고 있는지
🔸 If performance on the training set is much better than on the validation set => model is probably overfitting (or there is a bug, such as a data mismatch)
🔹 performance는 loss와 accuracy 의미
🔹 일반적으로 train set의 loss와 accuracy가 validation set보다 성능이 좋게 나타나는데, 그 차이가 너무 크면 overfitting된 것
💡 Good sign of training
1. Training loss decreases 2. validation accuracy increase 3. training and validation accuracies are close 4. reasonable validation accuracy
🔸 class마다 비슷한(충분한) 숫자의 data를 가지고 있는 것이 좋음
🔸 전체적인 data set의 개수를 유지하기 위해 사용
🔸 data가 충분하지 않은 class에 더 큰 weight 부여
🔸 data가 충분한 class는 훈련하면서 더 자주 사용되므로 weight에 영향을 많이 미치기 때문
🔸 각 instance마다 서로 다른 weight 부여
🔸 Ex. Labeled by experts and using a crowdsourcing platform => give more weight to the experts
🔹 전문가가 label한 instance는 대중이 label한 instance보다 더 높은 weight 부여
🔸 class_weight와 sample_weight를 모두 사용할 경우 weight multiplied한 weight 부여
💡 history plot 코드
import pandas as pd
import matplotlib.pyplot as plt
pd.DataFrame(history.history).plot(figsize=(8,5))
plt.grid(True)
plt.gca().set_ylim(0,1) #set the vertical range to [0,1]
plt.show()
🔸 위에 작성한 history plot의 x축은 epoch을 의미
🌟 그래프 분석
1. train loss와 train accuracy가 각각 훈련 끝에 validation loss와 validation accuracy보다 성능이 좋아야함
2. train loss는 학습 초기에 급격하게 떨어져야함. 훈련 전반적으로 loss는 accuracy가 올라가는 것보다 더 빠른 속도로 떨어짐. accuracy는 기울기가 작아 saturation된 것으로 판단할 수 있기 때문에 성능이 개선되어있는지 볼 때에는 loss값을 봐야함.
3. train accuracy와 validation accuracy는 나란히 가야함. 차이가 많이 날 경우 overfitting 발생한 것
🔸validation loss는 각 epoch이 끝날 때 한 번에 계산되는데, training loss는 각 epoch의 running mean을 의미. 즉 train loss는 한 epoch에 여러 minibatch가 존재하는데, minibatch가 끝날 때마다 그 전의 loss와의 평균을 계산해 나타냄. 따라서 처음 하나의 minibatch의 loss가 0.7, 그 다음 minibatch의 loss가 0.5이면 그 다음 minibatch의 총 loss는 평균인 0.6이 됨. 따라서 실제 minibatch의 loss 값은 그래프 상의 loss보다 더 작음
🔸 validation loss가 epoch이 끝날 때까지 계속해서 작아지고 있으므로 epoch 수를 늘려 훈련을 더 진행해야함
🔸 model parameter는 weight와 bias 의미
🔸 model hyperparameter는 # of layers, # of neurons per layer, type of activation
🔸 training hyperparameter: batch size, # of epoch 등
🔸 test set으로 evaluate한 값이 generalization error
🔸 출력으로 train data의 개수만큼 한 epoch으로 나타남
model.evaluate(X_test, y_test)
💡 train은 forward pass와 backward pass 모두 거치고, evaluate는 forward pass만 하기 때문에 시간 짧게 소요
🔸 train 또는 test data set에 존재하지 않는 새로운 data prediction(= inference)
🔸 But fashion MNIST의 경우 새로운 instance가 없기 때문에 X_test 중 하나의 data 사용
import numpy as np
X_new = X_test[:3]
y_proba = model.predict(X_new)
y_proba.round(2) #소수점 2자리까지 표기
y_pred = np.argmax(y_proba, axis=-1) #y_proba 중 가장 값이 큰 argument 출력
np.array(class_names)[y_pred] #해당 class와 class name mapping, 각 class가 어떤 것인지 모르므로 별도로 표기해 출력
y_new = y_test[:3] #위 코드까지가 실제로 사용되고 결과값은 없는 경우가 많으므로 위 결과를 믿고 사용해야함.
y_new
🔸 분석
1. y_proba한 결과를 소수점 2자리까지 표기한 결과를 보면, 첫번째 list는 X_test[0]이 해당 item일 각각의 확률 나타내고 두번째, 세번째 list도 각각 2번째 instance, 3번째 instance를 나타냄
ex. 첫번째 instance는 0,1,2,3,4번째 class일 확률이 0, 5번째 class일 확률이 0.03, 6번째일 확률이 0, 7번째일 확률이 0.01, 8번째일 확률이 0, 9번째일 확률이 0.96으로 9번째 class인 Ankle boot로 predict
🌟 지금까지 classification MLP building. 이제 regression MLP building
🌟 Regression
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
housing = fetch_california_housing()
X_train_full, X_test, y_train_full, y_test = train_test_split(housing.data, housing.target)
X_train, X_valid, y_train, y_valid = train_test_split(X_train_full, y_train_full)
scaler = StandardScaler() #fashion MNIST에서 255로 나눈 것이 scaling
X_train = scaler.fit_transform(X_train) #fit_transform()은 학습시키고 변환
X_valid = scaler.transform(X_valid) #transform은 변환만
X_test = scaler.transform(X_test)
Standard
모든 data(instance)를 평균이 0이고 분산이 1인 정규 분포로 만드는 것
🔸 classification의 경우 multiclass 였으므로 출력이 여러개였지만, regression의 경우 output neuron이 하나이므로 activation function은 없어야함
🔸 그 외에는 classification과 동일
🔸 noisy dataset의 경우 overfitting이 발생할 확률이 높아 hidden layer를 하나만 설정하고, neuron도 적게 설정해 단순한 모델 사용
model = keras.models.Sequential([
keras.layers.Dense(30, activation="relu", input_shape=X_train.shape[1:]),
keras.layers.Dense(1)])
model.compile(loss="mean_squared_error", optimizer="sgd")
history = model.fit(X_train, y_train, epochs=20, validation_data=(X_valid, y_valid))
mse_test = model.evaluate(X_test, y_test)
X_new = X_test[:3]
y_pred = model.predict(X_new)
🔸 layer 생성 시 input_shape=X_train.shape[1:]을 한 이유는 X_train.shape만 했을 경우 => 앞의 11610은 입력으로 들어갈 데이터의 수
🔸 regression에서는 mse를 보고 얼마나 학습이 잘 되었는지 확인