
Gradient(기울기)
각 파라미터에 대한 비용 함수의 변화량
Learning rate
실제로 기울기 방향으로 얼마나 이동할지를 결정하는 값(스텝 크기)
파라미터 업데이트 규칙(Gradient Descent)
Repeat
=> 모델을 만들어 가기 위한 하이퍼 파라미터
=> 얼마나 최적화를 잘 했는지가 중요하다
# [Tensorflow Code]
def grad(hypothesis, labels):
with tf.GradientTape() as tape:
loss_value = loss_fn(hypothesis, labels)
return tape.gradient(loss_value, [W,b])
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
optimizer.apply_gradients(grads_and_vars=zip(grads,[W,b]))

learning rate는 한 번에 얼마나 이동하는지 결정하는 값이다.
즉, learning rate가 크면 한 번에 많이 이동하고, 작으면 한 번에 작게 이동한다.
=> 학습이 잘 되면 epoch 동안 cost는 떨어진다.
=> 학습이 안 되면 cost가 점점 증가할 수 있다.
=> learning rate가 너무 크면 오버슈팅(overshooting) 현상이 발생하여 오히려 학습도가 떨어질 수 있다.
=> 반대로 너무 작으면 최적값을 찾는 시간이 너무 길어지게 된다.
=> 그래서 일반적으로 를 많이 사용함.
=> 또는 Adam optimizer를 사용할 경우 도 쓴다.
# Train Log
Iter: 0, Loss: 6.0257, Learning Rate: 0.1000
Iter: 1000, Loss: 0.3723, Learning Rate: 0.0960
Iter: 2000, Loss: 0.2779, Learning Rate: 0.0922
Iter: 3000, Loss: 0.2293, Learning Rate: 0.0885
Iter: 4000, Loss: 0.1977, Learning Rate: 0.0849
Iter: 5000, Loss: 0.1750, Learning Rate: 0.0815
# [Tensorflow Code]
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)

learning rate 값을 정했다 하더라도 학습 과정에서 learning rate를 적절히 조절하는 것이 중요하다.
= Learning rate Decay
학습을 하다 보면 더 이상 learning rate를 줄이지 않아도 되는 구간이 있다.
=> 이때 learning rate를 조절함으로써 cost를 더 줄일 수 있다(= decay).
Step decay : epoch 또는 validation loss 기준으로 일정 스텝별 조절
Exponential decay :
1/t decay :
# [Tensorflow Code]
learning_rate = tf.train.exponential_decay(
starter_learning_rate,
global_step,
1000,
0.96,
staircase=True
)
# tf.train.exponential_decay / tf.train.inverse_time_decay
# tf.train.natural_exp_decay / tf.train.piecewise_constant
# tf.train.polynomial_decay
def exponential_decay(epoch):
starter_rate = 0.01
k = 0.96
exp_rate = starter_rate * np.exp(-k * epoch)
return exp_rate

Feature들의 스케일을 맞춰 주는 것이 중요하다.
값의 범위가 너무 다르면 학습이 불안정해질 수 있다.
표준화와 정규화의 수식은 다음과 같다.
표준화: Standardization(Mean Distance)
정규화: Normalization(0–1)
# [Python Code (numpy)]
# Standardization
standardization = (data - np.mean(data, axis=0)) / np.sqrt(
np.sum((data - np.mean(data, axis=0))**2, axis=0) / data.shape[0]
)
# Normalization (0~1)
normalization = (data - np.min(data, axis=0)) / (
np.max(data, axis=0) - np.min(data, axis=0)
)
: 데이터를 잘 처리하기 위해서는 쓸모없는 데이터(노이즈 데이터)를 없애는 것이 가장 중요하다.

Overfitting(과적합)
: 모델이 훈련 데이터에 너무 치중되어 있는 현상(새로운 데이터 성능 저하)
# [sklearn Code]
from sklearn.decomposition import PCA
pca = PCA(n_components=3)
pca.fit(X)
X = pca.transform(X)

: 학습 과정에서 특정 값을 추가하여 정규화(규제) 할 수 있다.
=> 값을 term으로 줌으로써 해결
Model:
Cost function:
=> Linear regression의 cost function에다가 를 줌으로써 정규화 효과를 줄 수 있다.
=> 즉, 손실 함수에 "패널티"를 추가하여 파라미터가 너무 커지거나 복잡해지지 못하게 한다.
# [Tensorflow Code]
L2_loss = tf.nn.l2_loss(w) # output = sum(t ** 2) / 2
Overfitting을 줄이는 대표적인 방법
import tensorflow as tf
import numpy as np
# 예제 데이터 중간중간에 너무 큰 값들이 있다.
# => 이를 normalization을 통해 전처리 해 준다.
xy = np.array([
[828.659973, 833.450012, 908100, 828.349976, 831.659973],
[823.02002, 828.070007, 1828100, 821.655029, 828.070007],
[819.929993, 824.400024, 1438100, 818.97998, 824.159973],
[816, 820.958984, 1008100, 815.48999, 819.23999],
[819.359985, 823, 1188100, 818.469971, 818.97998],
[819, 823, 1198100, 816, 820.450012],
[811.700012, 815.25, 1098100, 809.780029, 813.669983],
[809.51001, 816.659973, 1398100, 804.539978, 809.559998]
], dtype=np.float32)
# x(입력 특징들)과 y(타깃 값)를 분리
x_train = xy[:, 0:-1]
y_train = xy[:, [-1]]
# Normalization (0~1)
# x_new = (x - x_min) / (x_max - x_min)
def normalization(data):
# 각 열(column)별로 min-max 정규화 (0~1 구간)
numerator = data - np.min(data, 0)
denominator = np.max(data, 0) - np.min(data, 0)
return numerator / denominator
xy = normalization(xy)
Linear regression
dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(len(x_train))
W = tf.Variable(tf.random_normal([4, 1]), dtype=tf.float32)
b = tf.Variable(tf.random_normal([1]), dtype=tf.float32)
# 예측값 계산
def linearReg_fn(features):
hypothesis = tf.matmul(features, W) + b
return hypothesis
# 실제 loss에서 정규화된 값을 구하게 된다.
def l2_loss(loss, beta=0.01):
W_reg = tf.nn.l2_loss(W) # output = sum(t ** 2) / 2
loss = tf.reduce_mean(loss + W_reg * beta)
return loss
# 실제 가설과 y값의 차이의 최소값을 구함.
# flag를 통해 적용 여부를 결정함.
# 이상치 값을 정규화 시키는 과정
def loss_fn(hypothesis, labels, flag=False):
cost = tf.reduce_mean(tf.square(hypothesis - labels))
if flag:
cost = l2_loss(cost)
return cost

is_decay = True
starter_learning_rate = 0.1
if is_decay:
global_step = tf.Variable(0, trainable=False)
learning_rate = tf.train.exponential_decay(
starter_learning_rate, # 초기 학습률
global_step, # 몇 번 업데이트했는지
50, # decay_steps
0.96, # decay_rate
staircase=True # 계단식 감소 여부
)
optimizer = tf.train.GradientDescentOptimizer(learning_rate)
else:
optimizer = tf.train.GradientDescentOptimizer(
learning_rate=starter_learning_rate
)
def grad(features, labels, l2_flag):
with tf.GradientTape() as tape:
loss_value = loss_fn(linearReg_fn(features), labels, l2_flag)
return tape.gradient(loss_value, [W, b]), loss_value
for step in range(EPOCHS):
for features, labels in tfe.Iterator(dataset):
features = tf.cast(features, tf.float32)
labels = tf.cast(labels, tf.float32)
grads, loss_value = grad(features, labels, False)
optimizer.apply_gradients(
grads_and_vars=zip(grads, [W, b]),
global_step=global_step
)
if step % 10 == 0:
print(
"Iter: {}, Loss: {:.4f}, Learning Rate: {:.8f}".format(
step,
loss_value,
optimizer._learning_rate()
)
)
import os
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2" # 0: INFO, 1: WARNING, 2: ERROR, 3: FATAL
import tensorflow as tf
import numpy as np
tf.get_logger().setLevel('ERROR')
# 4-1. sample data + normalization -------------------------------------------
# 예제 데이터 중간중간에 너무 큰 값들이 있다.
# => 이를 normalization을 통해 전처리 해 준다.
xy = np.array([
[828.659973, 833.450012, 908100, 828.349976, 831.659973],
[823.02002, 828.070007, 1828100, 821.655029, 828.070007],
[819.929993, 824.400024, 1438100, 818.97998, 824.159973],
[816., 820.958984, 1008100, 815.48999, 819.23999],
[819.359985, 823., 1188100, 818.469971, 818.97998],
[819., 823., 1198100, 816., 820.450012],
[811.700012, 815.25, 1098100, 809.780029, 813.669983],
[809.51001, 816.659973, 1398100, 804.539978, 809.559998],
], dtype=np.float32)
# x(입력 특징들)과 y(타깃 값)를 분리
x_train_raw = xy[:, 0:-1]
y_train_raw = xy[:, [-1]]
# Normalization (0~1)
# x_new = (x - x_min) / (x_max - x_min)
def normalization(data):
# 각 열(column)별로 min-max 정규화 (0~1 구간)
numerator = data - np.min(data, 0)
denominator = np.max(data, 0) - np.min(data, 0)
return numerator / denominator
# xy 전체를 normalization 한 뒤 다시 x/y를 나눠도 됨
xy_norm = normalization(xy)
x_train = xy_norm[:, 0:-1]
y_train = xy_norm[:, [-1]]
# tf.data.Dataset 구성
dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(len(x_train))
# 4-2. L2 Norm (모델, L2 loss 정의) ------------------------------------------
# 파라미터 초기화
W = tf.Variable(tf.random.normal([4, 1]), dtype=tf.float32, name="weight")
b = tf.Variable(tf.random.normal([1]), dtype=tf.float32, name="bias")
# 예측값 계산
def linearReg_fn(features):
hypothesis = tf.matmul(features, W) + b
return hypothesis
# 실제 loss에서 정규화된 값을 구하게 된다.
def l2_loss(loss, beta=0.01):
# output = sum(t ** 2) / 2
W_reg = tf.nn.l2_loss(W)
loss = tf.reduce_mean(loss + W_reg * beta)
return loss
# 실제 가설과 y값의 차이의 최소값을 구함.
# flag를 통해 L2 적용 여부를 결정함.
def loss_fn(hypothesis, labels, flag=False):
cost = tf.reduce_mean(tf.square(hypothesis - labels))
if flag:
cost = l2_loss(cost)
return cost
# 4-3. Learning Decay (학습 루프) -------------------------------------------
is_decay = True
starter_learning_rate = 0.1
EPOCHS = 101
if is_decay:
lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(
initial_learning_rate=starter_learning_rate,
decay_steps=50, # decay_steps=50 과 동일 의미
decay_rate=0.96,
staircase=True,
)
optimizer = tf.keras.optimizers.SGD(learning_rate=lr_schedule)
else:
optimizer = tf.keras.optimizers.SGD(learning_rate=starter_learning_rate)
def grad(features, labels, l2_flag):
with tf.GradientTape() as tape:
hypothesis = linearReg_fn(features)
loss_value = loss_fn(hypothesis, labels, l2_flag)
grads = tape.gradient(loss_value, [W, b])
return grads, loss_value
def train():
for step in range(EPOCHS):
for features, labels in dataset:
features = tf.cast(features, tf.float32)
labels = tf.cast(labels, tf.float32)
grads, loss_value = grad(features, labels, l2_flag=True)
optimizer.apply_gradients(zip(grads, [W, b]))
if step % 10 == 0:
# 현재 learning rate 확인 (schedule 사용 시)
if callable(optimizer.learning_rate):
current_lr = optimizer.learning_rate(optimizer.iterations).numpy()
else:
current_lr = optimizer.learning_rate.numpy()
print(
"Iter: {}, Loss: {:.6f}, Learning Rate: {:.8f}".format(
step,
float(loss_value.numpy()),
float(current_lr),
)
)
if __name__ == "__main__":
print("TensorFlow version:", tf.__version__)
train()
print("Trained W:", W.numpy())
print("Trained b:", b.numpy())
# Tensorflow Code
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
train_images = train_images / 255.0 # (60000, 28, 28)
test_images = test_images / 255.0 # (10000, 28, 28)
model = keras.Sequential([
keras.layers.Flatten(input_shape=(28, 28)),
keras.layers.Dense(128, activation=tf.nn.relu),
keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(train_images, train_labels, epochs=5)
test_loss, test_acc = model.evaluate(test_images, test_labels)
predictions = model.predict(test_images)
np.argmax(predictions[0]) # 9 Label
# Tensorflow Code
imdb = keras.datasets.imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
word_index = imdb.get_word_index()
# The first indices are reserved
word_index = {k: (v + 3) for k, v in word_index.items()}
word_index["<PAD>"] = 0
word_index["<START>"] = 1
word_index["<UNK>"] = 2 # unknown
word_index["<UNUSED>"] = 3
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
train_data = keras.preprocessing.sequence.pad_sequences(
train_data,
value=word_index["<PAD>"],
padding='post',
maxlen=256
)
model = keras.Sequential()
model.add(keras.layers.Embedding(vocab_size, 16))
model.add(keras.layers.GlobalAveragePooling1D())
model.add(keras.layers.Dense(16, activation=tf.nn.relu))
model.add(keras.layers.Dense(1, activation=tf.nn.sigmoid))
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(partial_x_train, partial_y_train, epochs=40,
validation_data=(x_val, y_val))
# TensorFlow Code
from keras.datasets import cifar100
(x_train, y_train), (x_test, y_test) = cifar100.load_data(label_mode='fine')
모두를 위한 딥러닝 강좌 2
https://www.youtube.com/watch?v=7eldOrjQVi0&list=PLQ28Nx3M4Jrguyuwg4xe9d9t2XE639e5C
모두를 위한 딥러닝 강좌 2
https://www.youtube.com/watch?v=7eldOrjQVi0&list=PLQ28Nx3M4Jrguyuwg4xe9d9t2XE639e5C