안녕하세요, HELLO
오늘은 DeepLearning.AI에서 진행하는 앤드류 응(Andrew Ng) 교수님의 딥러닝 전문화의 두 번째 과정인 "Improving Deep Neural Networks: Hyperparameter Tuning, Regularization and Optimization"을 정리하려고 합니다.
"Improving Deep Neural Networks: Hyperparameter Tuning, Regularization and Optimization"의 강의 목적은 '랜덤 초기화, L2 및 드롭아웃 정규화, 하이퍼 파라미터 튜닝, 배치 정규화 및 기울기 검사와 같은 표준 신경망 기술' 등을 배우며, 강의는 아래와 같이 구성되어 있습니다.
~ Practical Aspects of Deep Learning
~ Optimization Algorithms
~ Hyperparameter Tuning, Batch Normalization and Programming Frameworks
"Improving Deep Neural Networks" (Andrew Ng)의 1주차 "Initialization"의 실습 내용입니다.
초기화(initialization)를 통해 딥러닝 성능을 높일 수 있습니다.
- Gradient Descent의 수렴 속도 상승 (Speed up the convergence of gradient descent)
- Gradient Descent가 더 낮은 training error에 수렴하는 확률을 증가시킴 (Increase the odds of gradient descent converging to a lower training (and generalization) error)
CHAPTER 1. 'Packages'
CHAPTER 2. 'Loading the Dataset'
CHAPTER 3. 'Neural Network Model'
CHAPTER 4. 'Zero Initialization'
CHAPTER 5. 'Random Initialization'
CHAPTER 6. 'He Initialization'
CHAPTER 7. 'Conclusion'
CHAPTER 1. 'Packages'
이번 실습에서 사용될 라이브러리입니다.
import numpy as np
import matplotlib.pyplot as plt
import sklearn
import sklearn.datasets
from public_tests import *
from init_utils import sigmoid, relu, compute_loss, forward_propagation, backward_propagation
from init_utils import update_parameters, predict, load_dataset, plot_decision_boundary, predict_dec
%matplotlib inline
plt.rcParams['figure.figsize'] = (7.0, 4.0) # set default size of plots
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'
%load_ext autoreload
%autoreload 2
# load image dataset: blue/red dots in circles
# train_X, train_Y, test_X, test_Y = load_dataset()
CHAPTER 2. 'Loading the Dataset'
우선 이번 실습에서 분류해야 될 planar dataset입니다.
이번 목표는 blue와 red point들의 구역을 분리하는 것입니다.
train_X, train_Y, test_X, test_Y = load_dataset()
CHAPTER 3. 'Neural Network Model'
신경망 3층인 3-layer NN을 사용해 3가지 초기화 방법을 사용해 결과를 비교해보겠습니다.
1. Zero initialization (0으로 초기화)
2. Random initialization (랜덤 초기화)
3. He initialization (He et al의 논문에서 사용된 초기화 방법)
이때 모델은 initialization 파라미터에서 'zeros, random, he'를 통해 초기화 방법을 설정합니다.
def model(X, Y, learning_rate = 0.01, num_iterations = 15000, print_cost = True, initialization = "he"):
"""
Implements a three-layer neural network: LINEAR->RELU->LINEAR->RELU->LINEAR->SIGMOID.
Arguments:
X -- input data, of shape (2, number of examples)
Y -- true "label" vector (containing 0 for red dots; 1 for blue dots), of shape (1, number of examples)
learning_rate -- learning rate for gradient descent
num_iterations -- number of iterations to run gradient descent
print_cost -- if True, print the cost every 1000 iterations
initialization -- flag to choose which initialization to use ("zeros","random" or "he")
Returns:
parameters -- parameters learnt by the model
"""
grads = {}
costs = [] # to keep track of the loss
m = X.shape[1] # number of examples
layers_dims = [X.shape[0], 10, 5, 1]
# Initialize parameters dictionary.
if initialization == "zeros":
parameters = initialize_parameters_zeros(layers_dims)
elif initialization == "random":
parameters = initialize_parameters_random(layers_dims)
elif initialization == "he":
parameters = initialize_parameters_he(layers_dims)
# Loop (gradient descent)
for i in range(num_iterations):
# Forward propagation: LINEAR -> RELU -> LINEAR -> RELU -> LINEAR -> SIGMOID.
a3, cache = forward_propagation(X, parameters)
# Loss
cost = compute_loss(a3, Y)
# Backward propagation.
grads = backward_propagation(X, Y, cache)
# Update parameters.
parameters = update_parameters(parameters, grads, learning_rate)
# Print the loss every 1000 iterations
if print_cost and i % 1000 == 0:
print("Cost after iteration {}: {}".format(i, cost))
costs.append(cost)
# plot the loss
plt.plot(costs)
plt.ylabel('cost')
plt.xlabel('iterations (per hundreds)')
plt.title("Learning rate =" + str(learning_rate))
plt.show()
return parameters
CHAPTER 4. 'Zero Initialization'
모든 W와 b를 0으로 초기화하는 방법입니다. 해당 방법으로 학습하면 모델이 대칭이 되는 것을 피하는 'symmetry breaking'에 실패하게 되며, 딥러닝 알고리즘이 제대로 동작하지 않습니다.
# GRADED FUNCTION: initialize_parameters_zeros
def initialize_parameters_zeros(layers_dims):
"""
Arguments:
layer_dims -- python array (list) containing the size of each layer.
Returns:
parameters -- python dictionary containing your parameters "W1", "b1", ..., "WL", "bL":
W1 -- weight matrix of shape (layers_dims[1], layers_dims[0])
b1 -- bias vector of shape (layers_dims[1], 1)
...
WL -- weight matrix of shape (layers_dims[L], layers_dims[L-1])
bL -- bias vector of shape (layers_dims[L], 1)
"""
parameters = {}
L = len(layers_dims) # number of layers in the network
for l in range(1, L):
#(≈ 2 lines of code)
# parameters['W' + str(l)] =
# parameters['b' + str(l)] =
# YOUR CODE STARTS HERE
parameters['W'+str(l)] = np.zeros((layers_dims[l], layers_dims[l-1]))
parameters['b'+str(l)] = np.zeros((layers_dims[l], 1))
# YOUR CODE ENDS HERE
return parameters
parameters = initialize_parameters_zeros([3, 2, 1])
print("W1 = " + str(parameters["W1"]))
print("b1 = " + str(parameters["b1"]))
print("W2 = " + str(parameters["W2"]))
print("b2 = " + str(parameters["b2"]))
initialize_parameters_zeros_test(initialize_parameters_zeros)
영 초기화(zeros initialization)를 통해 모델을 아래 코드로 15,000회 훈련하면, 다음과 같은 결과가 나옵니다.
parameters = model(train_X, train_Y, initialization = "zeros")
print ("On the train set:")
predictions_train = predict(train_X, train_Y, parameters)
print ("On the test set:")
predictions_test = predict(test_X, test_Y, parameters)
결과는 매우 좋지 않습니다. Cost는 감소하지 않고, 딥러닝 알고리즘 성능도 좋아지지 않습니다.
plt.title("Model with Zeros initialization")
axes = plt.gca()
axes.set_xlim([-1.5,1.5])
axes.set_ylim([-1.5,1.5])
plot_decision_boundary(lambda x: predict_dec(parameters, x.T), train_X, train_Y)
모든 파라미터 가중치 W를 0으로 초기화하게 되면, break symmetry에 실패하게 됩니다.. 이것은 각 layer의 모든 neuron이 같은 값으로 학습됩니다.
결론적으로,
1. 파라미터 가중치 W는 break symmetry를 위해 랜덤 하게 초기화해야 됩니다.
2. 다만, 편차 bias인 b는 0으로 초기화해도 무관합니다.
CHAPTER 5. 'Random Initialization'
break symmetry(함수가 대칭이 되는 것을 피함)을 위해서 모든 파라미터 가중치 W를 랜덤 하게 초기화합니다. 랜덤 초기화를 하면, 각 neuron은 각기 다른 함수로 학습하게 됩니다.
이때 가중치를 랜덤으로 초기화 하지만, 매우 큰 값(* 10)으로 초기화하여 진행해보겠습니다.
(np.random.randn * 10 → np.random.randn는 평균 0, 분산이 1인 정규분포를 만드는 함수입니다)
# GRADED FUNCTION: initialize_parameters_random
def initialize_parameters_random(layers_dims):
"""
Arguments:
layer_dims -- python array (list) containing the size of each layer.
Returns:
parameters -- python dictionary containing your parameters "W1", "b1", ..., "WL", "bL":
W1 -- weight matrix of shape (layers_dims[1], layers_dims[0])
b1 -- bias vector of shape (layers_dims[1], 1)
...
WL -- weight matrix of shape (layers_dims[L], layers_dims[L-1])
bL -- bias vector of shape (layers_dims[L], 1)
"""
np.random.seed(3) # This seed makes sure your "random" numbers will be the as ours
parameters = {}
L = len(layers_dims) # integer representing the number of layers
for l in range(1, L):
#(≈ 2 lines of code)
# parameters['W' + str(l)] =
# parameters['b' + str(l)] =
# YOUR CODE STARTS HERE
parameters['W' + str(l)] = np.random.randn(layers_dims[l], layers_dims[l-1]) * 10
parameters['b' + str(l)] = np.zeros((layers_dims[l], 1))
# YOUR CODE ENDS HERE
return parameters
parameters = initialize_parameters_random([3, 2, 1])
print("W1 = " + str(parameters["W1"]))
print("b1 = " + str(parameters["b1"]))
print("W2 = " + str(parameters["W2"]))
print("b2 = " + str(parameters["b2"]))
initialize_parameters_random_test(initialize_parameters_random)
랜덤 초기화(random initialization)를 통해 모델을 아래 코드로 15,000회 훈련하면, 다음과 같은 결과가 나옵니다.
plt.title("Model with large random initialization")
axes = plt.gca()
axes.set_xlim([-1.5,1.5])
axes.set_ylim([-1.5,1.5])
plot_decision_boundary(lambda x: predict_dec(parameters, x.T), train_X, train_Y)
1. Cost는 처음에 매우 큰 값으로 시작합니다. 랜덤 초기화가 초기에 매우 큰 값으로 sigmoid 예측값이 대부분 0이나 1이기 때문입니다. 그래서 실제 label과 다르게 예측한 경우에 매우 큰 loss가 발생하게 됩니다.
2. 좋지 않은 초기화(Pool initialization)는 최적화 알고리즘을 느리게 만들며, vanishing/exploding gradients를 일으킵니다.
3. 큰 수로 초기화를 하게 되면 최적화 속도는 느려집니다.
CHAPTER 6. 'He Initialization'
'He Initialization'은 ReLU activation을 사용하는 layer에서 사용되는 것을 추천합니다.
# GRADED FUNCTION: initialize_parameters_he
def initialize_parameters_he(layers_dims):
"""
Arguments:
layer_dims -- python array (list) containing the size of each layer.
Returns:
parameters -- python dictionary containing your parameters "W1", "b1", ..., "WL", "bL":
W1 -- weight matrix of shape (layers_dims[1], layers_dims[0])
b1 -- bias vector of shape (layers_dims[1], 1)
...
WL -- weight matrix of shape (layers_dims[L], layers_dims[L-1])
bL -- bias vector of shape (layers_dims[L], 1)
"""
np.random.seed(3)
parameters = {}
L = len(layers_dims) - 1 # integer representing the number of layers
for l in range(1, L + 1):
#(≈ 2 lines of code)
# parameters['W' + str(l)] =
# parameters['b' + str(l)] =
# YOUR CODE STARTS HERE
parameters['W' + str(l)] = np.random.randn(layers_dims[l], layers_dims[l-1]) * np.sqrt(2./layers_dims[l-1])
parameters['b' + str(l)] = np.zeros((layers_dims[l], 1))
# YOUR CODE ENDS HERE
return parameters
parameters = initialize_parameters_he([2, 4, 1])
print("W1 = " + str(parameters["W1"]))
print("b1 = " + str(parameters["b1"]))
print("W2 = " + str(parameters["W2"]))
print("b2 = " + str(parameters["b2"]))
initialize_parameters_he_test(initialize_parameters_he)
# parameters
He initialization를 통해 모델을 아래 코드로 15,000회 훈련하면, 다음과 같은 결과가 나옵니다.
parameters = model(train_X, train_Y, initialization = "he")
print ("On the train set:")
predictions_train = predict(train_X, train_Y, parameters)
print ("On the test set:")
predictions_test = predict(test_X, test_Y, parameters)
plt.title("Model with He initialization")
axes = plt.gca()
axes.set_xlim([-1.5,1.5])
axes.set_ylim([-1.5,1.5])
plot_decision_boundary(lambda x: predict_dec(parameters, x.T), train_X, train_Y)
CHAPTER 7. 'Conclusion'
3가지의 초기화 방법을 비교하면 다음과 같습니다.
이를 통해 아래와 같이 정리할 수 있습니다.
- 다른 초기화는 다른 결괏값으로 예측합니다. (zeros, random(with big number), he)
- 랜덤 값으로 초기화하면 break symmetry 되고, hidden unit들은 서로 다른 값을 학습합니다.
- 큰 값으로 초기화하면, 최적화 속도가 느려집니다.
- He Initialization은 ReLU activation을 가지는 layer에서 잘 동작합니다.
■ 마무리
"Improving Deep Neural Networks" (Andrew Ng)의 1주차 "Initialization"의 실습을 정리해봤습니다.
그럼 오늘 하루도 즐거운 나날 되길 기도하겠습니다
좋아요와 댓글 부탁드립니다 :)
감사합니다.
'COURSERA' 카테고리의 다른 글
week 1_Gradient Checking 실습 (Andrew Ng) (0) | 2022.02.18 |
---|---|
week 1_Regularization 실습 (Andrew Ng) (0) | 2022.02.18 |
week 1_Practical Aspects of Deep Learning 연습문제 (Andrew Ng) (0) | 2022.02.18 |
week 1_Setting up optimization problem (Andrew Ng) (0) | 2022.02.18 |
week 1_Regularization neural network (Andrew Ng) (0) | 2022.02.16 |
댓글