๐ŸงฉTensorflow Certification ์ทจ๋“ํ•˜๊ธฐ - part 9. ์‹ค์ „ (sunspot)

vincaยท2023๋…„ 1์›” 3์ผ
0

๐ŸŒ• AI/DL -Tenserflow Certification

๋ชฉ๋ก ๋ณด๊ธฐ
9/11

ํƒœ์–‘ ํ‘์  ํ™œ๋™(sunspot)

  • Sequence (์‹œ๊ณ„์—ด) ๋ฐ์ดํ„ฐ ๋‹ค๋ฃจ๊ธฐ

For this task you will need to train a neural network to predict sunspot activity using the Sunspots.csv provided.
Your neural network is expected to have an MAE of at least 20, with top marks going to one with an MAE of around 15.
At the bottom is provided some testing code should you want to check before uploading which measures the MAE for you.
Strongly recommend you test your model with this to be able to see how it performs.
Sequence(์‹œํ€€์Šค)

Sunspots.csv๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํƒœ์–‘ ํ‘์  ํ™œ๋™(sunspot)์„ ์˜ˆ์ธกํ•˜๋Š” ์ธ๊ณต์‹ ๊ฒฝ๋ง์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
MAE ์˜ค์ฐจ ๊ธฐ์ค€์œผ๋กœ ์ตœ์†Œ 20์ดํ•˜๋กœ ์˜ˆ์ธกํ•  ๊ฒƒ์„ ๊ถŒ์žฅํ•˜๋ฉฐ, ํƒ‘ ๋žญํ‚น์— ๋“ค๋ ค๋ฉด MAE 15 ๊ทผ์ฒ˜์— ๋„๋‹ฌํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
์•„๋ž˜ ์ฃผ์–ด์ง„ ์ƒ˜ํ”Œ์ฝ”๋“œ๋Š” ๋‹น์‹ ์˜ ๋ชจ๋ธ์„ ํ…Œ์ŠคํŠธ ํ•˜๋Š” ์šฉ๋„๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


Solution

์ˆœ์„œ ์š”์•ฝ

  1. import: ํ•„์š”ํ•œ ๋ชจ๋“ˆ import
  2. ์ „์ฒ˜๋ฆฌ: ํ•™์Šต์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  3. ๋ชจ๋ธ๋ง(model): ๋ชจ๋ธ์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  4. ์ปดํŒŒ์ผ(compile): ๋ชจ๋ธ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  5. ํ•™์Šต (fit): ๋ชจ๋ธ์„ ํ•™์Šต์‹œํ‚ต๋‹ˆ๋‹ค.

1. import ํ•˜๊ธฐ

ํ•„์š”ํ•œ ๋ชจ๋“ˆ์„ import ํ•ฉ๋‹ˆ๋‹ค.

import csv
import tensorflow as tf
import numpy as np
import urllib

from tensorflow.keras.layers import Dense, LSTM, Lambda, Conv1D
from tensorflow.keras.models import Sequential
from tensorflow.keras.callbacks import ModelCheckpoint
from tensorflow.keras.optimizers import SGD
from tensorflow.keras.losses import Huber
url = 'https://storage.googleapis.com/download.tensorflow.org/data/Sunspots.csv'
urllib.request.urlretrieve(url, 'sunspots.csv')

2.1 ์ „์ฒ˜๋ฆฌ (csv ํŒŒ์ผ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ์…‹ ๋งŒ๋“ค๊ธฐ)

csv.reader() ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.

with open('sunspots.csv') as csvfile:
    reader = csv.reader(csvfile, delimiter=',')
    next(reader)
    i = 0
    for row in reader:
        print(row)
        i+=1
        if i > 10:
            break

๋นˆ list๋ฅผ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค. (sunspots, time_step)

sunspots = []
time_step = []

time_step์—๋Š” index ๊ฐ’์„, sunspots์—๋Š” sunspots์˜ ์ •๋ณด๋ฅผ ๋„ฃ์–ด ์ค๋‹ˆ๋‹ค.

with open('sunspots.csv') as csvfile:
    reader = csv.reader(csvfile, delimiter=',')
    # ์ฒซ ์ค„์€ header์ด๋ฏ€๋กœ skip ํ•ฉ๋‹ˆ๋‹ค.
    next(reader)
    for row in reader:
        sunspots.append(float(row[2]))
        time_step.append(int(row[0]))

sunspots์™€ time_step์„ numpy array๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

  • ์ฐธ๊ณ : ๋ชจ๋ธ์€ list ํƒ€์ž…์„ ๋ฐ›์•„๋“ค์ด์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, numpy array ๋กœ ๋ณ€ํ™˜ํ•ด ์ค๋‹ˆ๋‹ค.
series = np.array(sunspots)
time = np.array(time_step)
series.shape, time.shape

์‹œ๊ฐํ™” ํ•ด๋ณด๊ธฐ

import matplotlib.pyplot as plt

plt.figure(figsize=(16, 8))
plt.plot(time, series)
plt.xlabel("Time")
plt.ylabel("Value")
plt.grid(True)

Train Set, Validation Set ์ƒ์„ฑ

3000 ์ธ๋ฑ์Šค๋ฅผ ๊ธฐ์ค€์œผ๋กœ Train / Validation Set๋ฅผ ๋ถ„ํ•  ํ•ฉ๋‹ˆ๋‹ค.

split_time = 3000
time_train = time[:split_time]
time_valid = time[split_time:]

x_train = series[:split_time]
x_valid = series[split_time:]

Window Dataset Loader

# ์œˆ๋„์šฐ ์‚ฌ์ด์ฆˆ
window_size=30
# ๋ฐฐ์น˜ ์‚ฌ์ด์ฆˆ
batch_size = 32
# ์…”ํ”Œ ์‚ฌ์ด์ฆˆ
shuffle_size = 1000
def windowed_dataset(series, window_size, batch_size, shuffle_buffer):
    series = tf.expand_dims(series, axis=-1)
    ds = tf.data.Dataset.from_tensor_slices(series)
    ds = ds.window(window_size + 1, shift=1, drop_remainder=True)
    ds = ds.flat_map(lambda w: w.batch(window_size + 1))
    ds = ds.shuffle(shuffle_buffer)
    ds = ds.map(lambda w: (w[:-1], w[1:]))
    return ds.batch(batch_size).prefetch(1)

train_set์™€ validation_set๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

train_set = windowed_dataset(x_train, 
                             window_size=window_size, 
                             batch_size=batch_size,
                             shuffle_buffer=shuffle_size)

validation_set = windowed_dataset(x_valid, 
                                  window_size=window_size,
                                  batch_size=batch_size,
                                  shuffle_buffer=shuffle_size)

3. ๋ชจ๋ธ ์ •์˜ (Sequential)

from IPython.display import Image

Image('https://i.stack.imgur.com/NmYZJ.png')

model = Sequential([
    tf.keras.layers.Conv1D(60, kernel_size=5,
                         padding="causal",
                         activation="relu",
                         input_shape=[None, 1]),
    tf.keras.layers.LSTM(60, return_sequences=True),
    tf.keras.layers.LSTM(60, return_sequences=True),
    tf.keras.layers.Dense(30, activation="relu"),
    tf.keras.layers.Dense(10, activation="relu"),
    tf.keras.layers.Dense(1),
    tf.keras.layers.Lambda(lambda x: x * 400)
])

๋ชจ๋ธ ๊ฒฐ๊ณผ ์š”์•ฝ

model.summary()

4. ์ปดํŒŒ์ผ (compile)

Optimizer๋Š” SGD(Stochastic Gradient Descent) ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • lr(learning_rate): ํ•™์Šต๋ฅ ์ž…๋‹ˆ๋‹ค.
  • momentum: ๋ชจ๋ฉ˜ํ…€ (๊ฐ€์ค‘์น˜) ์ž…๋‹ˆ๋‹ค.
optimizer = SGD(lr=1e-5, momentum=0.9)

Huber Loss: MSE์™€ MAE๋ฅผ ์ ˆ์ถฉํ•œ ํ›„๋ฒ„ ์†์‹ค(Huber loss)

loss= Huber()

model.compile()์‹œ ์šฐ๋ฆฌ๊ฐ€ ํŠœ๋‹ํ•œ optimizer์™€ loss๋ฅผ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.

model.compile(loss=loss,
              optimizer=optimizer,
              metrics=["mae"])

ModelCheckpoint: ์ฒดํฌํฌ์ธํŠธ ์ƒ์„ฑ

val_loss ๊ธฐ์ค€์œผ๋กœ epoch ๋งˆ๋‹ค ์ตœ์ ์˜ ๋ชจ๋ธ์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•˜์—ฌ, ModelCheckpoint๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

  • checkpoint_path๋Š” ๋ชจ๋ธ์ด ์ €์žฅ๋  ํŒŒ์ผ ๋ช…์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  • ModelCheckpoint์„ ์„ ์–ธํ•˜๊ณ , ์ ์ ˆํ•œ ์˜ต์…˜ ๊ฐ’์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
checkpoint_path = 'tmp_checkpoint.ckpt'
checkpoint = ModelCheckpoint(checkpoint_path, 
                             save_weights_only=True, 
                             save_best_only=True, 
                             monitor='val_mae',
                             verbose=1)

5. ํ•™์Šต (fit)

epochs=100
history = model.fit(train_set, 
                    validation_data=(validation_set), 
                    epochs=epochs, 
                    callbacks=[checkpoint],
                   )

ํ•™์Šต ์™„๋ฃŒ ํ›„ Load Weights (ModelCheckpoint)

ํ•™์Šต์ด ์™„๋ฃŒ๋œ ํ›„์—๋Š” ๋ฐ˜๋“œ์‹œ load_weights๋ฅผ ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด, ์—ด์‹ฌํžˆ ModelCheckpoint๋ฅผ ๋งŒ๋“  ์˜๋ฏธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

# checkpoint ๋ฅผ ์ €์žฅํ•œ ํŒŒ์ผ๋ช…์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
model.load_weights(checkpoint_path)

์˜ค์ฐจ ๋ฐ ์ •ํ™•๋„ ์‹œ๊ฐํ™”

ํ•™์Šต Loss (์˜ค์ฐจ) / accuracy (์ •ํ™•๋„)์— ๋Œ€ํ•œ ์‹œ๊ฐํ™”

import matplotlib.pyplot as plt
plt.figure(figsize=(12, 9))
plt.plot(np.arange(1, epochs+1), history.history['loss'])
plt.plot(np.arange(1, epochs+1), 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, epochs+1), history.history['mae'])
plt.plot(np.arange(1, epochs+1), history.history['val_mae'])
plt.title('MAE / Val MAE', fontsize=20)
plt.xlabel('Epochs')
plt.ylabel('MAE')
plt.legend(['mae', 'val_mae'], fontsize=15)
plt.show()

profile
๋ถ‰์€ ๋ฐฐ ์˜ค์ƒ‰ ๋”ฑ๋‹ค๊ตฌ๋ฆฌ ๊ฐœ๋ฐœ์ž ๐ŸฆƒCloud & DevOps

0๊ฐœ์˜ ๋Œ“๊ธ€