유사한 용도의 알고리즘들을 선택하여 모델을 훈련시켜보고 최적의 성능을 보이는 알고리즘 선택
ex. SVM, KNN
ex. RNN, LSTM, GRU
: 두 개 이상의 모델을 섞어서 사용
: 명령어가 입력되는 순서대로 데이터를 처리하는 직렬 처리 방식(한 번에 하나의 명령어만 처리하기 때문에 ALU가 많을 필요가 없음)
: 서로 다른 명령어를 동시에 병렬적으로 처리
: 데이터 범위를 사용자가 원하는 범위로 제한
: 모델 복잡도를 줄이기 위해 제약을 두는 방법
: 평균 0, 표준편차 1인 형태의 데이터로 만드는 방법
: 기울기 소멸이나 기울기 폭발 등의 문제를 해결하기 위한 방법
# 배치 정규화가 적용되지 않은 모델 생성
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, BatchNormalization
# 입력층 (4,0) 형태, 유닛 64개
# 밀집층 유닛 128개, 64개 각 2개씩, 렐루 활성화함수
# 출력층 유닛 3개, 소프트맥스 활성화함수
model1 = Sequential([
Dense(64, input_shape=(4,), activation="relu"),
Dense(128, activation='relu'),
Dense(128, activation='relu'),
Dense(64, activation='relu'),
Dense(64, activation='relu'),
Dense(3, activation='softmax')
]);
model1.summary()
model1.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
history1 = model1.fit(
X_train,
y_train,
epochs=1000,
validation_split=0.25,
batch_size=40,
verbose=2
)
# 손실과 정확도 평가
loss_and_metrics = model1.evaluate(X_test, y_test)
print('## 손실과 정확도 평가 ##')
print(loss_and_metrics) # [0.5316773653030396, 0.9333333373069763]
# 정확도 시각화
%matplotlib inline
import matplotlib.pyplot as plt
fig, loss_ax = plt.subplots()
acc_ax = loss_ax.twinx()
loss_ax.plot(history1.history['loss'], 'y', label='train loss')
loss_ax.plot(history1.history['val_loss'], 'r', label='val loss')
acc_ax.plot(history1.history['accuracy'], 'b', label='train acc')
acc_ax.plot(history1.history['val_accuracy'], 'g', label='val acc')
loss_ax.set_xlabel('epoch')
loss_ax.set_ylabel('loss')
acc_ax.set_ylabel('accuray')
loss_ax.legend(loc='lower right')
acc_ax.legend(loc='upper right')
plt.show()
validation loss는 시간이 흐를수록 감소해야하지만 증가함. 훈련 정확도가 100%에 가깝고 훈련 손실값이 0에 가까움.
-> 훈련 데이터에 대한 정확도는 높지만, 검증 데이터에 대한 정확도는 낮음(과적합)
-> 배치 정규화를 적용하여 해결(신경망의 층이 깊어질수록 학습할 때 가정했던 입력 분포가 변화하여 엉뚱한 학습이 진행되는 것을 입력 분포를 고르게 맞추어 해결)
# 배치 정규화가 적용된 모델 생성
from tensorflow.keras.initializers import RandomNormal, Constant
model2 = Sequential([
Dense(64, input_shape=(4,), activation="relu"),
BatchNormalization(),
Dense(128, activation='relu'),
BatchNormalization(),
Dense(128, activation='relu'),
BatchNormalization(),
Dense(64, activation='relu'),
BatchNormalization(),
Dense(64, activation='relu'),
BatchNormalization(
momentum=0.95,
epsilon=0.005,
beta_initializer=RandomNormal(mean=0.0, stddev=0.05),
gamma_initializer=Constant(value=0.9)
),
Dense(3, activation='softmax')
]);
model2.summary()
model2.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
history2 = model2.fit(
X_train,
y_train,
epochs=1000,
validation_split=0.25,
batch_size=40,
verbose=2
)
# 손실과 정확도 평가
loss_and_metrics = model2.evaluate(X_test, y_test)
print('## 손실과 정확도 평가 ##')
print(loss_and_metrics) # [0.07776810228824615, 0.9666666388511658]
BatchNormalization
: 훈련할 때 일정 비율의 뉴런만 사용, 나머지 뉴런에 해당하는 가중치는 업데이트하지 않음
#드롭아웃이 적용되지 않은 모델을 생성
encoder = info.features['text'].encoder
model = tf.keras.Sequential([
tf.keras.layers.Embedding(encoder.vocab_size, 64),
tf.keras.layers.LSTM(64),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid')
])
#성능 향상을 위해 LSTM 대신 Bidirectional RNN로 바꾸고 드롭아웃을 적용
model = tf.keras.Sequential([
tf.keras.layers.Embedding(encoder.vocab_size, 64),
tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64, return_sequences=True)),
tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(32)),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(1, activation='sigmoid')
])
model.summary()
model.compile(loss='binary_crossentropy',
optimizer=tf.keras.optimizers.Adam(1e-4),metrics=['accuracy'])
history = model.fit(train_batches, epochs=5, validation_data=test_batches, validation_steps=30)
#드롭아웃은 제거하고, Bidirectional RNN만 적용했을 때
model = tf.keras.Sequential([
tf.keras.layers.Embedding(encoder.vocab_size, 64),
tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid')
])
model.summary()
model.compile(loss='binary_crossentropy',
optimizer=tf.keras.optimizers.Adam(1e-4),metrics=['accuracy'])
history = model.fit(train_batches, epochs=5, validation_data=test_batches, validation_steps=30)
뉴럴 네트워크가 과적합을 회피하는 규제 기법
# 조기종료를 적용하지 않은 모델
model = Sequential()
model.add(Embedding(max_features,
embedding_dims,
input_length=maxlen))
model.add(Dropout(0.2))
model.add(Conv1D(filters,
kernel_size,
padding='valid',
activation='relu',
strides=1))
model.add(GlobalMaxPooling1D())
model.add(Dense(hidden_dims))
model.add(Dropout(0.2))
model.add(Activation('relu'))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.summary()
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
validation_split=0.2,
callbacks=[cp_callback])
from tensorflow.keras.models import load_model
model = load_model(checkpoint_path)
scores = model.evaluate(x_test, y_test, verbose=1)
print(f'Score: {model.metrics_names[0]} of {scores[0]}; {model.metrics_names[1]} of {scores[1]*100}%')
# Score: loss of 1.9403566122055054; accuracy of 87.11199760437012%
#조기 종료를 적용한 모델
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
keras_callbacks = [
EarlyStopping(monitor='val_loss', patience=30, mode='min', min_delta=0.0001),
ModelCheckpoint(checkpoint_path, monitor='val_loss', save_best_only=True, mode='min')
]
model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
validation_split=0.2,
callbacks=keras_callbacks)
# Score: loss of 1.5000197887420654; accuracy of 86.9599997997284%