import numpy as np
import matplotlib.pyplot as plt
import sklearn
import sklearn.datasets
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
plt.rcParams['figure.figsize'] = (7.0, 4.0) # set default size of plots
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'
train_X,train_Y,test_X,test_Y=load_dataset()
plt.show()
#我们希望分类器将蓝点和红点分开。
#1.神经网络模型
# 你将使用已经实现了的3层神经网络。 下面是你将尝试的初始化方法:
# 零初始化 :在输入参数中设置initialization = "zeros"。
# 随机初始化 :在输入参数中设置initialization = "random",这会将权重初始化为较大的随机值。
# He初始化 :在输入参数中设置initialization = "he",这会根据He等人(2015)的论文将权重初始化为按比例缩放的随机值。
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
"""
costs=[]
grads={}
m=X.shape[1]
layer_dims=[X.shape[0],10,5,1]
# Initialize parameters dictionary.
if initialization=="zeros":
parameters=initialize_parameters_zeros(layer_dims) #函数在后面
elif initialization=="random":
parameters = initialize_parameters_random(layer_dims) #函数在后面
elif initialization=="he":
parameters = initialize_parameters_he(layer_dims) # 函数在后面
for i in range(num_iterations):
a3,cache=forward_propagation(X,parameters)
cost=compute_loss(a3,Y)
grads=backward_propagation(X,Y,cache)
parameters=update_parameters(parameters,grads,learning_rate)
if print_cost and i%1000==0:
print("Cost after iteration {}: {}".format(i, cost))
costs.append(cost)
plt.plot(costs)
plt.ylabel('cost')
plt.xlabel('iterations (per hundreds)')
plt.title("Learning rate =" + str(learning_rate))
plt.show()
return parameters
#2.零初始化
#将所有参数初始化为零。 稍后你会看到此方法会报错,因为它无法“打破对称性”。总之先尝试一下,看看会发生什么。确保使用正确维度的np.zeros((..,..))。
def initialize_parameters_zeros(layer_dims):
parameters={}
for l in range(1,len(layer_dims)):
parameters["W"+str(l)]=np.zeros((layer_dims[l],layer_dims[l-1]))
parameters["b"+str(l)]=np.zeros((layer_dims[l],1))
assert (parameters['W' + str(l)].shape == (layer_dims[l], layer_dims[l - 1]))
assert (parameters['b' + str(l)].shape == (layer_dims[l], 1))
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"]))
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)
#看一下预测的详细信息和决策边界
print ("predictions_train = " + str(predictions_train))
print ("predictions_test = " + str(predictions_test))
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)
#该模型预测的每个示例都为0。
#通常,将所有权重初始化为零会导致网络无法打破对称性。 这意味着每一层中的每个神经元都将学习相同的东西,并且你不妨训练每一层n_l=1的神经网络,且该网络的性能不如线性分类器,例如逻辑回归。
#权重W应该随机初始化以打破对称性。
#将偏差b初始化为零是可以的。只要随机初始化了W对称性仍然会破坏。
#3.随机初始化
# 将权重初始化为较大的随机值(按*10缩放),并将偏差设为0。 将 np.random.randn(..,..) * 10用于权重,
# 将np.zeros((.., ..))用于偏差。我们使用固定的np.random.seed(..),以确保你的“随机”权重与我们的权重匹配。
def initialize_parameters_random(layer_dims):
np.random.seed(3)
parameters={}
for l in range(1,len(layer_dims)):
parameters["W"+str(l)]=np.random.randn(layer_dims[l],layer_dims[l-1])*10
parameters["b"+str(l)]=np.zeros((layer_dims[l],1))
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"]))
parameters = model(train_X, train_Y, initialization = "random")
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)
print (predictions_train)
print (predictions_test)
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)
#损失一开始很高是因为较大的随机权重值,对于某些数据,最后一层激活函数sigmoid输出的结果非常接近0或1,并且当该示例数据预测错误时,将导致非常高的损失。
# 初始化不当会导致梯度消失/爆炸,同时也会减慢优化算法的速度。
# 训练较长时间的网络,将会看到更好的结果,但是使用太大的随机数进行初始化会降低优化速度。
# 将权重初始化为非常大的随机值效果不佳。
# 初始化为较小的随机值会更好。重要的问题是:这些随机值应为多小?让我们在下一部分中找到答案!
#4. He初始化
def initialize_parameters_he(layer_dims):
np.random.seed(3)
parameters={}
for l in range(1,len(layer_dims)):
parameters["W"+str(l)]=np.random.randn(layer_dims[l],layer_dims[l-1])*np.sqrt(2/layer_dims[l-1])
parameters["b"+str(l)]=np.zeros((layer_dims[l],1))
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"]))
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)
#不同的初始化会导致不同的结果
# 随机初始化用于打破对称性,并确保不同的隐藏单元可以学习不同的东西
# 不要初始化为太大的值
# 初始化对于带有ReLU激活的网络非常有效。
吴恩达神经网络学习-L2W1作业1
最新推荐文章于 2024-05-14 18:00:57 发布