이번 포스팅은 모두를 위한 딥러닝 lab 10에 대한 본문 및 코드 요약입니다.
Lab 10-1 :Relu activation function
● problem of sigmod
기존 neural network learning:
- 입력이 들어가면 출력이 나옴
- 실제 정답(ground truth) - output = loss
- loss미분 값을 역전파하며 학습이 진행됨
- 역전파로 전달되는 loss를 미분한 것을 gradent = 그래프의 기울기
- Signoid Activation Function의 그래프: 가운데 그래프 기울기는 0보다 큼, 양 끝은 0에 가까움
시그노이드 함수의 문제점: 기울기가 매우작으면 neural network학습시 기울기를 전달받아 학습하는데 Vanishing Gradient 문제 발생(네트워크 deep한 경우 0에 가까운 기울기들이 연속으로 곱해져 소실되는 현상)
● Why Relu ?
𝑓 (𝑥) = max(0, 𝑥)
= > 어떠한 숫자 값 x를 받았을때 0보다 큰 양수의 값이면 0를 출력, x가 0보다 작으면 그 값을 0으로 출력
0보다 크면, y=x(기울기=1), 전달이 잘 됨, 0보다 작으면, 음수의 값 전달이 안됨
--> 간단하면서 성능 향상
이 외의 Activation Function: sigmoid, tanh relu, elu, selu(tf.keras.activations 안에 있음)
- 음수 부분일때의 문제점을 해결= leaky relu (tf.keras.layers에 있음)
: relu는 0보다 작을때 0을 출력, leaky relu 는 음수일때 a*x값(알파는 매우 작은 값)
- mnist 이용 (각 이미지와 라벨 리턴)
import tensorflow as tf
import numpy as np
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.datasets import mnist
from time import time
import os
# Checkpoint function
def load(model, checkpoint_dir):
print(" [*] Reading checkpoints...")
ckpt = tf.train.get_checkpoint_state(checkpoint_dir)
if ckpt :
ckpt_name = os.path.basename(ckpt.model_checkpoint_path)
checkpoint = tf.train.Checkpoint(dnn=model)
checkpoint.restore(save_path=os.path.join(checkpoint_dir, ckpt_name))
counter = int(ckpt_name.split('-')[1])
print(" [*] Success to read {}".format(ckpt_name))
return True, counter
else:
print(" [*] Failed to find a checkpoint")
return False, 0
def check_folder(dir):
if not os.path.exists(dir):
os.makedirs(dir)
return dir
# Data load & pre-processing function
def load_mnist() :
# 4개의 output: (60000), (10000)
(train_data, train_labels), (test_data, test_labels) = mnist.load_data()
# 넘파이의 expand_dims을 이용해 채널 추가 [batch_size, height, width, channel]
train_data = np.expand_dims(train_data, axis=-1) # [N, 28, 28] -> [N, 28, 28, 1]
test_data = np.expand_dims(test_data, axis=-1) # [N, 28, 28] -> [N, 28, 28, 1]
train_data, test_data = normalize(train_data, test_data)
# one-hot-incoding: 배열로 true값을 나타냄
train_labels = to_categorical(train_labels, 10) # [N,] -> [N, 10]
test_labels = to_categorical(test_labels, 10) # [N,] -> [N, 10]
return train_data, train_labels, test_data, test_labels
def normalize(train_data, test_data): # [0~255]->[0~1]
train_data = train_data.astype(np.float32) / 255.0
test_data = test_data.astype(np.float32) / 255.0
return train_data, test_data
# Performance function
def loss_fn(model, images, labels):
logits = model(images, training=True)
loss = tf.reduce_mean(tf.keras.losses.categorical_crossentropy(y_pred=logits, y_true=labels,
from_logits=True))
return loss
# 정확도, argmax: logic값이 가장 큰 위치
def accuracy_fn(model, images, labels):
logits = model(images, training=False)
prediction = tf.equal(tf.argmax(logits, -1), tf.argmax(labels, -1))
accuracy = tf.reduce_mean(tf.cast(prediction, tf.float32))
return accuracy
def grad(model, images, labels):
with tf.GradientTape() as tape:
loss = loss_fn(model, images, labels)
return tape.gradient(loss, model.variables)
# create network
# Model function
def flatten() :
return tf.keras.layers.Flatten()
def dense(label_dim, weight_init) :
return tf.keras.layers.Dense(units=label_dim, use_bias=True, kernel_initializer=weight_init)
def relu() :
return tf.keras.layers.Activation(tf.keras.activations.relu)
# Create model (class version)
class create_model_class(tf.keras.Model):
def __init__(self, label_dim):
super(create_model_class, self).__init__()
weight_init = tf.keras.initializers.RandomNormal()
self.model = tf.keras.Sequential()
self.model.add(flatten())
# [N,784]->[N,256]->[N,256]
for i in range(2):
self.model.add(dense(256, weight_init))
self.model.add(relu())
self.model.add(dense(label_dim, weight_init)) # [N, 256]->[N,10]
def call(self, x, training=None, mask=None):
x = self.model(x)
return x
# Create model (function version)
def create_model_function(label_dim) :
weight_init = tf.keras.initializers.RandomNormal()
model = tf.keras.Sequential()
model.add(flatten())
for i in range(2) :
model.add(dense(256, weight_init))
model.add(relu())
model.add(dense(label_dim, weight_init))
return model
# Define data & hyper-parameter
""" dataset """
train_x, train_y, test_x, test_y = load_mnist()
""" parameters """
learning_rate = 0.001
batch_size = 128
training_epochs = 1
training_iterations = len(train_x) // batch_size
label_dim = 10
train_flag = True
""" Graph Input using Dataset API """ # 이미지, 라벨 네트워크에 넣음
train_dataset = tf.data.Dataset.from_tensor_slices((train_x, train_y)).\
shuffle(buffer_size=100000).\ # size보다 크다면 데이터 섞음
prefetch(buffer_size=batch_size).\ # 학습 전에 미리 메모리에 올려둠
batch(batch_size, drop_remainder=True)
test_dataset = tf.data.Dataset.from_tensor_slices((test_x, test_y)).\
shuffle(buffer_size=100000).\
prefetch(buffer_size=len(test_x)).\
batch(len(test_x))
# Define model & optimizer & writer
""" Model """
network = create_model_function(label_dim)
""" Training """
optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)
""" Writer """
checkpoint_dir = 'checkpoints'
logs_dir = 'logs'
model_dir = 'nn_relu'
checkpoint_dir = os.path.join(checkpoint_dir, model_dir)
check_folder(checkpoint_dir)
checkpoint_prefix = os.path.join(checkpoint_dir, model_dir)
logs_dir = os.path.join(logs_dir, model_dir)
# Restore checkpoint & start train or test phase
if train_flag :
checkpoint = tf.train.Checkpoint(dnn=network)
# 네트워크 오류시 재학습
# create writer for tensorboard
summary_writer = tf.summary.create_file_writer(logdir=logs_dir)
start_time = time()
# restore check-point if it exits
could_load, checkpoint_counter = load(network, checkpoint_dir)
if could_load:
start_epoch = (int)(checkpoint_counter / training_iterations)
counter = checkpoint_counter
print(" [*] Load SUCCESS")
else:
start_epoch = 0
start_iteration = 0
counter = 0
print(" [!] Load failed...")
# train phase
with summary_writer.as_default(): # for tensorboard
for epoch in range(start_epoch, training_epochs):
for idx, (train_input, train_label) in enumerate(train_dataset):
grads = grad(network, train_input, train_label)
optimizer.apply_gradients(grads_and_vars=zip(grads, network.variables))
train_loss = loss_fn(network, train_input, train_label)
train_accuracy = accuracy_fn(network, train_input, train_label)
for test_input, test_label in test_dataset:
test_accuracy = accuracy_fn(network, test_input, test_label)
tf.summary.scalar(name='train_loss', data=train_loss, step=counter)
tf.summary.scalar(name='train_accuracy', data=train_accuracy, step=counter)
tf.summary.scalar(name='test_accuracy', data=test_accuracy, step=counter)
print(
"Epoch: [%2d] [%5d/%5d] time: %4.4f, train_loss: %.8f, train_accuracy: %.4f, test_Accuracy: %.4f" \
% (epoch, idx, training_iterations, time() - start_time, train_loss, train_accuracy,
test_accuracy))
counter += 1
checkpoint.save(file_prefix=checkpoint_prefix + '-{}'.format(counter))
# test phase
else :
_, _ = load(network, checkpoint_dir)
for test_input, test_label in test_dataset:
test_accuracy = accuracy_fn(network, test_input, test_label)
print("test_Accuracy: %.4f" % (test_accuracy))
# Test accuracy : 96.22 %
Lab10-2 Weight Initialization
w초기화로 이용되는 Xavier(glorot), He
● Xavier
loss최처 찾는것이 학습의 목표-> 실제 loss그래프 복잡,local min이나 saddile에 도달하는 문제 발생
시작지점을 좋게(랜덤x, 평균 = 0, cin, cout값을 이용해 분산 설정) 설정
He : 랠루 함수에 특화된 w초기화 법-> 평균 = 0, 분산은 Xavier * 2
# Restore checkpoint & start train or test phase
if train_flag :
checkpoint = tf.train.Checkpoint(dnn=network)
# create writer for tensorboard
summary_writer = tf.summary.create_file_writer(logdir=logs_dir)
start_time = time()
# restore check-point if it exits
could_load, checkpoint_counter = load(network, checkpoint_dir)
if could_load:
start_epoch = (int)(checkpoint_counter / training_iterations)
counter = checkpoint_counter
print(" [*] Load SUCCESS")
else:
start_epoch = 0
start_iteration = 0
counter = 0
print(" [!] Load failed...")
# train phase
with summary_writer.as_default(): # for tensorboard
for epoch in range(start_epoch, training_epochs):
for idx, (train_input, train_label) in enumerate(train_dataset):
grads = grad(network, train_input, train_label)
optimizer.apply_gradients(grads_and_vars=zip(grads, network.variables))
train_loss = loss_fn(network, train_input, train_label)
train_accuracy = accuracy_fn(network, train_input, train_label)
for test_input, test_label in test_dataset:
test_accuracy = accuracy_fn(network, test_input, test_label)
tf.summary.scalar(name='train_loss', data=train_loss, step=counter)
tf.summary.scalar(name='train_accuracy', data=train_accuracy, step=counter)
tf.summary.scalar(name='test_accuracy', data=test_accuracy, step=counter)
print(
"Epoch: [%2d] [%5d/%5d] time: %4.4f, train_loss: %.8f, train_accuracy: %.4f, test_Accuracy: %.4f" \
% (epoch, idx, training_iterations, time() - start_time, train_loss, train_accuracy,
test_accuracy))
counter += 1
checkpoint.save(file_prefix=checkpoint_prefix + '-{}'.format(counter))
# test phase
else :
_, _ = load(network, checkpoint_dir)
for test_input, test_label in test_dataset:
test_accuracy = accuracy_fn(network, test_input, test_label)
print("test_Accuracy: %.4f" % (test_accuracy))
# Test accuracy : 96.88 %
- Define loss, Experiments (parameters), Experiments (Eager mode) : relu와 동일, Activate Function만 수정(W초기화 변경)-> 성능 향상
- 출발지점 변화를 통한 성능향상
Lab10-3 Dropout
- test 못맞춤=새로운 데이터에 맞추지 못하는 경향 有
- good일 때 fitting됨 -> drop out은 최적의 fitting도와주는 Regularization
- 학습시 노드(뉴런)활용시 모든 노드 활용x, 일부분만 가지고 학습(랜덤하게 설정)
- 모든 부분을 가지고 판단 -> drop out: 일부 특성으로 인지
# Restore checkpoint & start train or test phase
if train_flag :
checkpoint = tf.train.Checkpoint(dnn=network)
# create writer for tensorboard
summary_writer = tf.summary.create_file_writer(logdir=logs_dir)
start_time = time()
# restore check-point if it exits
could_load, checkpoint_counter = load(network, checkpoint_dir)
if could_load:
start_epoch = (int)(checkpoint_counter / training_iterations)
counter = checkpoint_counter
print(" [*] Load SUCCESS")
else:
start_epoch = 0
start_iteration = 0
counter = 0
print(" [!] Load failed...")
# train phase
with summary_writer.as_default(): # for tensorboard
for epoch in range(start_epoch, training_epochs):
for idx, (train_input, train_label) in enumerate(train_dataset):
grads = grad(network, train_input, train_label)
optimizer.apply_gradients(grads_and_vars=zip(grads, network.variables))
train_loss = loss_fn(network, train_input, train_label)
train_accuracy = accuracy_fn(network, train_input, train_label)
for test_input, test_label in test_dataset:
test_accuracy = accuracy_fn(network, test_input, test_label)
tf.summary.scalar(name='train_loss', data=train_loss, step=counter)
tf.summary.scalar(name='train_accuracy', data=train_accuracy, step=counter)
tf.summary.scalar(name='test_accuracy', data=test_accuracy, step=counter)
print(
"Epoch: [%2d] [%5d/%5d] time: %4.4f, train_loss: %.8f, train_accuracy: %.4f, test_Accuracy: %.4f" \
% (epoch, idx, training_iterations, time() - start_time, train_loss, train_accuracy,
test_accuracy))
counter += 1
checkpoint.save(file_prefix=checkpoint_prefix + '-{}'.format(counter))
# test phase
else :
_, _ = load(network, checkpoint_dir)
for test_input, test_label in test_dataset:
test_accuracy = accuracy_fn(network, test_input, test_label)
# Test accuracy : 95.91 %
Lab10-4 Batch Normalization
- 이전 : 네트워크가 이미지를 받아 인지를 확인하는 네트워크
--> input으로 들어온 데이터의 분포
- 네트워크 layer 지나가며 변형됨
- 학습이 어려워짐=Internal Covariate Shift 현상
Batch Normalization의 목표 = Internal Covariate Shift 현상을 막자!
(각각의 분포를 Normalization-> 항상 일정한 배치를 유지)
입력, 배치들의 평균, 배치들의 분산 이용해 평준화 --> 감마, 베타 (학습이 되는 파라미터) x'을 레이어에 다시 추가 --> 모든 배치 동일하게 학습
if train_flag :
checkpoint = tf.train.Checkpoint(dnn=network)
# create writer for tensorboard
summary_writer = tf.summary.create_file_writer(logdir=logs_dir)
start_time = time()
# restore check-point if it exits
could_load, checkpoint_counter = load(network, checkpoint_dir)
if could_load:
start_epoch = (int)(checkpoint_counter / training_iterations)
counter = checkpoint_counter
print(" [*] Load SUCCESS")
else:
start_epoch = 0
start_iteration = 0
counter = 0
print(" [!] Load failed...")
# train phase
with summary_writer.as_default(): # for tensorboard
for epoch in range(start_epoch, training_epochs):
for idx, (train_input, train_label) in enumerate(train_dataset):
grads = grad(network, train_input, train_label)
optimizer.apply_gradients(grads_and_vars=zip(itertools.repeat(grads), network.trainable_variables))
train_loss = loss_fn(network, train_input, train_label)
train_accuracy = accuracy_fn(network, train_input, train_label)
for test_input, test_label in test_dataset:
test_accuracy = accuracy_fn(network, test_input, test_label)
tf.summary.scalar(name='train_loss', data=train_loss, step=counter)
tf.summary.scalar(name='train_accuracy', data=train_accuracy, step=counter)
tf.summary.scalar(name='test_accuracy', data=test_accuracy, step=counter)
print(
"Epoch: [%2d] [%5d/%5d] time: %4.4f, train_loss: %.8f, train_accuracy: %.4f, test_Accuracy: %.4f" \
% (epoch, idx, training_iterations, time() - start_time, train_loss, train_accuracy,
test_accuracy))
counter += 1
checkpoint.save(file_prefix=checkpoint_prefix + '-{}'.format(counter))
# test phase
else :
_, _ = load(network, checkpoint_dir)
for test_input, test_label in test_dataset:
test_accuracy = accuracy_fn(network, test_input, test_label)
print("test_Accuracy: %.4f" % (test_accuracy))
- 순서 사용
출처: [TensorFlow] Lab-10-1 Relu - YouTube
'AI' 카테고리의 다른 글
[ai-2team] 4. Neural Networks (0) | 2021.01.27 |
---|---|
[ai-2team] 3. Learning rate, Data preprocessing, Overfitting, Data set (0) | 2021.01.23 |
[ai-2team] 2. Multi-variable linear regression, Logistic regression, Softmax Classifier (0) | 2021.01.15 |
[AI-3Team] 소프트맥스 회귀(Softmax Regression) 다중 클래스 분류 (0) | 2021.01.13 |
[ai-1team] 6. Recurrent Neural Network (0) | 2021.01.08 |