For this task you will train a classifier for Iris flowers using the Iris dataset
The final layer in your neural network should look like: tf.keras.layers.
Dense(3, activation=tf.nn.softmax)
The input layer will expect data in the shape (4,)
We've given you some starter code for preprocessing the data
You'll need to implement the preprocess function for data.map
์ด ์์ ์์๋ Iris ๋ฐ์ดํฐ ์ธํธ๋ฅผ ์ฌ์ฉํ์ฌ Iris ๊ฝ ๋ถ๋ฅ๊ธฐ๋ฅผ ํ๋ จ์ํต๋๋ค.
์ ๊ฒฝ๋ง์ ๋ง์ง๋ง ๊ณ์ธต์ tf.keras.layers์ ๊ฐ์์ผํฉ๋๋ค.
Dense(3, activation='softmax')
์ ๋ ฅ ๋ ์ด์ด๋ ๋ชจ์์ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ํฉ๋๋ค (4,)
๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ๋ฅผ์ํ ์คํํฐ ์ฝ๋๋ฅผ ์ ๊ณตํ์ต๋๋ค
data.map์ ๋ํ ์ ์ฒ๋ฆฌ ๊ธฐ๋ฅ์ ๊ตฌํํด์ผํฉ๋๋ค.
ํ์ํ ๋ชจ๋์ import ํฉ๋๋ค.
import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds
from tensorflow.keras.layers import Dense
from tensorflow.keras.models import Sequential
from tensorflow.keras.callbacks import ModelCheckpoint
tensorflow-datasets๋ฅผ ํ์ฉํฉ๋๋ค.
train_dataset
์ valid_dataset
์ ๋ง๋ค๊ณ 80% : 20%๋ก ๋ถํ ํฉ๋๋ค.
train_dataset = tfds.load('iris', split='train[:80%]')
valid_dataset = tfds.load('iris', split='train[80%:]')
๋จผ์ , ์ํ์์๋ ๋ค์๊ณผ ๊ฐ์ ์ ์ฒ๋ฆฌ ์๊ตฌ ์กฐ๊ฑด์ด ์์ต๋๋ค.
- label ๊ฐ์ one-hot encoding ํ ๊ฒ
- feature (x), label (y)๋ฅผ ๋ถํ ํ ๊ฒ
def preprocess(data): # ์ฝ๋๋ฅผ ์ ๋ ฅํ์ธ์ x = data['features'] y = data['label'] y = tf.one_hot(y, 3) return x, y
๋ง๋ ์ ์ฒ๋ฆฌ ํจ์(preprocessing)๋ฅผ dataset์ mappingํ๊ณ , batch_size๋ ์ง์ ํฉ๋๋ค.
batch_size=10
train_data = train_dataset.map(preprocess).batch(batch_size)
valid_data = valid_dataset.map(preprocess).batch(batch_size)
### 3. **์ด๋ฏธ์ง ์ ๊ทํ (Normalization)**
์ด์ Modeling์ ํ ์ฐจ๋ก์ ๋๋ค.
Sequential
๋ชจ๋ธ ์์์ ์ธต์ ๊น๊ฒ ์์ ์ฌ๋ ค ์ฃผ๋ฉด ๋ฉ๋๋ค.
input_shape
๋ Iris ๊ฝ ๋ฐ์ดํฐ์
์ X์ feature ๊ฐฏ์๊ฐ 4๊ฐ ์ด๋ฏ๋ก (4, )๋ก ์ง์ ํฉ๋๋ค.activation='relu'
๋ฅผ ์ ์ฉํฉ๋๋ค.model = tf.keras.models.Sequential([
# input_shape๋ X์ feature ๊ฐฏ์๊ฐ 4๊ฐ ์ด๋ฏ๋ก (4, )๋ก ์ง์ ํฉ๋๋ค.
Dense(512, activation='relu', input_shape=(4,)),
Dense(256, activation='relu'),
Dense(128, activation='relu'),
Dense(64, activation='relu'),
Dense(32, activation='relu'),
# Classification์ ์ํ Softmax, ํด๋์ค ๊ฐฏ์ = 3๊ฐ
Dense(3, activation='softmax'),
])
model.summary()
optimizer
๋ ๊ฐ์ฅ ์ต์ ํ๊ฐ ์๋๋ ์๊ณ ๋ฆฌ์ฆ์ธ 'adam'์ ์ฌ์ฉํฉ๋๋ค.loss
์ค์ sigmoid
์ธ ๊ฒฝ์ฐ: binary_crossentropy
softmax
์ธ ๊ฒฝ์ฐ: categorical_crossentropy
sparse_categorical_crossentropy
)metrics
๋ฅผ 'acc' ํน์ 'accuracy'๋ก ์ง์ ํ๋ฉด, ํ์ต์ ์ ํ๋๋ฅผ ๋ชจ๋ํฐ๋ง ํ ์ ์์ต๋๋ค.์ ์ฒ๋ฆฌ ๋จ๊ณ์์ one-hot encoding ์ ํด์ฃผ์์ต๋๋ค. ๋ฐ๋ผ์, categorical_crossentropy
๋ฅผ ์ง์ ํด์ฃผ๋ฉด ๋ฉ๋๋ค.
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])
val_loss
๊ธฐ์ค์ผ๋ก epoch ๋ง๋ค ์ต์ ์ ๋ชจ๋ธ์ ์ ์ฅํ๊ธฐ ์ํ์ฌ, ModelCheckpoint๋ฅผ ๋ง๋ญ๋๋ค.
checkpoint_path
๋ ๋ชจ๋ธ์ด ์ ์ฅ๋ ํ์ผ ๋ช
์ ์ค์ ํฉ๋๋ค.ModelCheckpoint
์ ์ ์ธํ๊ณ , ์ ์ ํ ์ต์
๊ฐ์ ์ง์ ํฉ๋๋ค.checkpoint_path = "my_checkpoint.ckpt"
checkpoint = ModelCheckpoint(filepath=checkpoint_path,
save_weights_only=True,
save_best_only=True,
monitor='val_loss',
verbose=1)
validation_data
๋ฅผ ๋ฐ๋์ ์ง์ ํฉ๋๋ค.epochs
์ ์ ์ ํ๊ฒ ์ง์ ํฉ๋๋ค.callbacks
์ ๋ฐ๋ก ์์์ ๋ง๋ checkpoint๋ฅผ ์ง์ ํฉ๋๋ค.history = model.fit(train_data,
validation_data=(valid_data),
epochs=20,
callbacks=[checkpoint],
)
ํ์ต์ด ์๋ฃ๋ ํ์๋ ๋ฐ๋์ load_weights
๋ฅผ ํด์ฃผ์ด์ผ ํฉ๋๋ค.
๊ทธ๋ ์ง ์์ผ๋ฉด, ์ด์ฌํ ModelCheckpoint๋ฅผ ๋ง๋ ์๋ฏธ๊ฐ ์์ต๋๋ค.
# checkpoint ๋ฅผ ์ ์ฅํ ํ์ผ๋ช
์ ์
๋ ฅํฉ๋๋ค.
model.load_weights(checkpoint_path)
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 9))
plt.plot(np.arange(1, 21), history.history['loss'])
plt.plot(np.arange(1, 21), history.history['val_loss'])
plt.title('Loss / Val Loss', fontsize=20)
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend(['loss', 'val_loss'], fontsize=15)
plt.show()
plt.figure(figsize=(12, 9))
plt.plot(np.arange(1, 21), history.history['acc'])
plt.plot(np.arange(1, 21), history.history['val_acc'])
plt.title('Acc / Val Acc', fontsize=20)
plt.xlabel('Epochs')
plt.ylabel('Acc')
plt.legend(['acc', 'val_acc'], fontsize=15)
plt.show()
model.evaluate(x_valid, y_valid)