参考:https://blog.csdn.net/u013733326/article/details/79847918

希望大家直接到上面的网址去查看代码,下面是本人的笔记

初始化、正则化、梯度校验

1. 初始化参数:
    1.1:使用0来初始化参数。
    1.2:使用随机数来初始化参数。
    1.3:使用抑梯度异常初始化参数(参见视频中的梯度消失和梯度爆炸)。
2. 正则化模型:
    2.1:使用二范数对二分类模型正则化——L2正则化方法,尝试避免过拟合。
    2.2:使用随机删除节点的方法——dropout正则化方法精简模型,同样是为了尝试避免过拟合。
3. 梯度校验  :对模型使用梯度校验,检测它是否在梯度下降的过程中出现误差过大的情况。

1.导入相关的库

import numpy as np
import matplotlib.pyplot as plt
import sklearn
import sklearn.datasets
import init_utils #第一部分,初始化
import reg_utils #第二部分,正则化
import gc_utils #第三部分,梯度校验
#%matplotlib inline #如果你使用的是Jupyter Notebook,请取消注释。
plt.rcParams['figure.figsize'] = (7.0, 4.0) # set default size of plots
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'

警告:

/Users/user/pytorch/jupyter/-week1/reg_utils.py:: SyntaxWarning: assertion is always true, perhaps remove parentheses?
assert(parameters['W' + str(l)].shape == layer_dims[l], layer_dims[l-])
/Users/user/pytorch/jupyter/-week1/reg_utils.py:: SyntaxWarning: assertion is always true, perhaps remove parentheses?
assert(parameters['W' + str(l)].shape == layer_dims[l], )

2.导入数据

train_X, train_Y, test_X, test_Y = init_utils.load_dataset(is_plot=True)

执行返回图示:

该神经网络目标:建立一个分类器将蓝点和红点分开,建立一个三层网络LINEAR ->RELU -> LINEAR -> RELU -> LINEAR -> SIGMOID

3.初始化参数

首先可见神经网络模型为:

def model(X,Y,learning_rate=0.01,num_iterations=,print_cost=True,initialization="he",is_polt=True):
"""
实现一个三层的神经网络:LINEAR ->RELU -> LINEAR -> RELU -> LINEAR -> SIGMOID 参数:
X - 输入的数据,维度为(, 要训练/测试的数量)
Y - 标签,表示输入为红点还是蓝点【 | 】,维度为(,对应的是输入的数据的标签)
learning_rate - 学习速率
num_iterations - 迭代的次数
print_cost - 是否打印成本值,每迭代1000次打印一次
initialization - 字符串类型,初始化的类型【"zeros" | "random" | "he"】
is_polt - 是否绘制梯度下降的曲线图
返回
parameters - 学习后的参数
"""
grads = {}
costs = []
m = X.shape[] #训练/测试的数量
layers_dims = [X.shape[],,,] #设置神经网络层数 #选择初始化参数的类型
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)
else :
print("错误的初始化参数!程序退出")
exit #开始学习
for i in range(,num_iterations):
#前向传播
a3 , cache = init_utils.forward_propagation(X,parameters) #计算成本
cost = init_utils.compute_loss(a3,Y) #反向传播
grads = init_utils.backward_propagation(X,Y,cache) #更新参数
parameters = init_utils.update_parameters(parameters,grads,learning_rate) #记录成本
if i % == :
costs.append(cost)
#打印成本
if print_cost:
print("第" + str(i) + "次迭代,成本值为:" + str(cost)) #学习完毕,绘制成本曲线
if is_polt:
plt.plot(costs)
plt.ylabel('cost')
plt.xlabel('iterations (per hundreds)')
plt.title("Learning rate =" + str(learning_rate))
plt.show() #返回学习完毕后的参数
return parameters

1)初始化为0

在输入参数中全部初始化为0,参数名为initialization = “zeros”,核心代码:

 parameters['W' + str(l)] = np.zeros((layers_dims[l], layers_dims[l - ]))

代码为:

def initialize_parameters_zeros(layers_dims):
"""
将模型的参数全部设置为0 参数:
layers_dims - 列表,模型的层数和对应每一层的节点的数量
返回
parameters - 包含了所有W和b的字典
W1 - 权重矩阵,维度为(layers_dims[], layers_dims[])
b1 - 偏置向量,维度为(layers_dims[],)
···
WL - 权重矩阵,维度为(layers_dims[L], layers_dims[L -])
bL - 偏置向量,维度为(layers_dims[L],)
"""
parameters = {} L = len(layers_dims) #网络层数 for l in range(,L): #即每一层的参数w,b都设置为0
parameters["W" + str(l)] = np.zeros((layers_dims[l],layers_dims[l-]))
parameters["b" + str(l)] = np.zeros((layers_dims[l],)) #使用断言确保我的数据格式是正确的
assert(parameters["W" + str(l)].shape == (layers_dims[l],layers_dims[l-]))
assert(parameters["b" + str(l)].shape == (layers_dims[l],)) return parameters

测试:

parameters = initialize_parameters_zeros([,,]) #三层神经元数量
print("W1 = " + str(parameters["W1"]))
print("b1 = " + str(parameters["b1"]))
print("W2 = " + str(parameters["W2"]))
print("b2 = " + str(parameters["b2"]))

返回:

W1 = [[. . .]
[. . .]]
b1 = [[.]
[.]]
W2 = [[. .]]
b2 = [[.]]

可以看到W和b全部被初始化为0了,那么我们使用这些参数来训练模型,结果会怎样呢?

parameters = model(train_X, train_Y, initialization = "zeros",is_polt=True)

返回:

第0次迭代,成本值为:0.6931471805599453
第1000次迭代,成本值为:0.6931471805599453
第2000次迭代,成本值为:0.6931471805599453
第3000次迭代,成本值为:0.6931471805599453
第4000次迭代,成本值为:0.6931471805599453
第5000次迭代,成本值为:0.6931471805599453
第6000次迭代,成本值为:0.6931471805599453
第7000次迭代,成本值为:0.6931471805599453
第8000次迭代,成本值为:0.6931471805599453
第9000次迭代,成本值为:0.6931471805599453
第10000次迭代,成本值为:0.6931471805599455
第11000次迭代,成本值为:0.6931471805599453
第12000次迭代,成本值为:0.6931471805599453
第13000次迭代,成本值为:0.6931471805599453
第14000次迭代,成本值为:0.6931471805599453

可见成本基本没有变化,说明这个模型根本没有学习

图示为:

查看下预测结果:

print ("训练集:")
predictions_train = init_utils.predict(train_X, train_Y, parameters)
print ("测试集:")
predictions_test = init_utils.predict(test_X, test_Y, parameters)

返回:

训练集:
Accuracy: 0.5
测试集:
Accuracy: 0.5

性能确实很差,而且成本并没有真正降低,算法的性能也比随机猜测要好。为什么?让我们看看预测和决策边界的细节:

这里调用init_utils.plot_decision_boundary()函数的时候还是会遇见问题(运行再jupyter notebook时):

'c' argument has  elements, which is not acceptable for use with 'x' with ...

在init_utils.py函数中更改为:

def plot_decision_boundary(model, X, y):
# Set min and max values and give it some padding
x_min, x_max = X[, :].min() - , X[, :].max() +
y_min, y_max = X[, :].min() - , X[, :].max() +
h = 0.01
# Generate a grid of points with distance h between them
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
# Predict the function value for the whole grid
Z = model(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# Plot the contour and training examples
plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
plt.ylabel('x2')
plt.xlabel('x1')
plt.scatter(X[, :], X[, :], c=np.squeeze(y), cmap=plt.cm.Spectral) #更改这里的y
plt.show()

也没有效果,将该函数直接在jupyter中声明,然后直接调用直接plot_decision_boundary()就不会有问题了

细节检测为:

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: init_utils.predict_dec(parameters, x.T), train_X, train_Y)

返回:

predictions_train = [[                                   

             ]]
predictions_test = [[ ]]

图示:

分类失败,该模型预测每个都为0。通常来说,零初始化都会导致神经网络无法打破对称性,最终导致的结果就是无论网络有多少层,最终只能得到和Logistic函数相同的效果。

2)随机初始化

把输入参数设置为随机值,权重初始化为大的随机值。参数名为initialization = “random”,核心代码:

parameters['W' + str(l)] = np.random.randn(layers_dims[l], layers_dims[l - ]) * 

为了打破对称性,我们可以随机地把参数赋值。在随机初始化之后,每个神经元可以开始学习其输入的不同功能,这里设置比较大的参数值,因为乘于10,看看会发生什么。

代码:

def initialize_parameters_random(layers_dims):
"""
参数:
layers_dims - 列表,模型的层数和对应每一层的节点的数量
返回
parameters - 包含了所有W和b的字典
W1 - 权重矩阵,维度为(layers_dims[], layers_dims[])
b1 - 偏置向量,维度为(layers_dims[],)
···
WL - 权重矩阵,维度为(layers_dims[L], layers_dims[L -])
b1 - 偏置向量,维度为(layers_dims[L],)
""" np.random.seed() # 指定随机种子
parameters = {}
L = len(layers_dims) # 层数 for l in range(, L):
parameters['W' + str(l)] = np.random.randn(layers_dims[l], layers_dims[l - ]) * #使用10倍缩放
parameters['b' + str(l)] = np.zeros((layers_dims[l], )) #b仍初始化为0 #使用断言确保我的数据格式是正确的
assert(parameters["W" + str(l)].shape == (layers_dims[l],layers_dims[l-]))
assert(parameters["b" + str(l)].shape == (layers_dims[l],)) return parameters

测试:

parameters = initialize_parameters_random([, , ])
print("W1 = " + str(parameters["W1"]))
print("b1 = " + str(parameters["b1"]))
print("W2 = " + str(parameters["W2"]))
print("b2 = " + str(parameters["b2"]))

返回:

W1 = [[ 17.88628473   4.36509851   0.96497468]
[-18.63492703 -2.77388203 -3.54758979]]
b1 = [[.]
[.]]
W2 = [[-0.82741481 -6.27000677]]
b2 = [[.]]

看起来这些参数都是比较大的,我们来看看实际运行会怎么样:

parameters = model(train_X, train_Y, initialization = "random",is_polt=True)
print("训练集:")
predictions_train = init_utils.predict(train_X, train_Y, parameters)
print("测试集:")
predictions_test = init_utils.predict(test_X, test_Y, parameters) print(predictions_train)
print(predictions_test)

警告:

/Users/user/pytorch/jupyter/-week1/init_utils.py:: RuntimeWarning: divide by zero encountered in log
logprobs = np.multiply(-np.log(a3),Y) + np.multiply(-np.log( - a3), - Y)
/Users/user/pytorch/jupyter/-week1/init_utils.py:: RuntimeWarning: invalid value encountered in multiply
logprobs = np.multiply(-np.log(a3),Y) + np.multiply(-np.log( - a3), - Y)

返回:

第0次迭代,成本值为:inf
第1000次迭代,成本值为:0.6250676215287511
第2000次迭代,成本值为:0.5981418252875961
第3000次迭代,成本值为:0.563858109377261
第4000次迭代,成本值为:0.5501823050061752
第5000次迭代,成本值为:0.5444756668990652
第6000次迭代,成本值为:0.5374638179631746
第7000次迭代,成本值为:0.4770885368883873
第8000次迭代,成本值为:0.397834663330821
第9000次迭代,成本值为:0.3934832163377203
第10000次迭代,成本值为:0.39203323866307854
第11000次迭代,成本值为:0.3892818629893498
第12000次迭代,成本值为:0.3861521882410713
第13000次迭代,成本值为:0.38499297516135134
第14000次迭代,成本值为:0.38280470097181446 训练集:
Accuracy: 0.83
测试集:
Accuracy: 0.86
[[ ]]
[[ ]]

图示:

我们来把图绘制出来,看看分类的结果是怎样的。

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: init_utils.predict_dec(parameters, x.T), train_X, train_Y)

图示:

初始化参数如果没有很好地话会导致梯度消失、爆炸,这也会减慢优化算法。如果我们对这个网络进行更长时间的训练,我们将看到更好的结果,但是使用过大的随机数初始化会减慢优化的速度。

3)抑梯度异常(即梯度爆炸或梯度消失)初始化——最好选择该方法

参见梯度消失和梯度爆炸的那一个视频,参数名为initialization = “he”,核心代码:

parameters['W' + str(l)] = np.random.randn(layers_dims[l], layers_dims[l - ]) * np.sqrt( / layers_dims[l - ])

代码:

def initialize_parameters_he(layers_dims):
"""
参数:
layers_dims - 列表,模型的层数和对应每一层的节点的数量
返回
parameters - 包含了所有W和b的字典
W1 - 权重矩阵,维度为(layers_dims[], layers_dims[])
b1 - 偏置向量,维度为(layers_dims[],)
···
WL - 权重矩阵,维度为(layers_dims[L], layers_dims[L -])
b1 - 偏置向量,维度为(layers_dims[L],)
""" np.random.seed() # 指定随机种子
parameters = {}
L = len(layers_dims) # 层数 for l in range(, L):
parameters['W' + str(l)] = np.random.randn(layers_dims[l], layers_dims[l - ]) * np.sqrt( / layers_dims[l - ])
parameters['b' + str(l)] = np.zeros((layers_dims[l], )) #使用断言确保我的数据格式是正确的
assert(parameters["W" + str(l)].shape == (layers_dims[l],layers_dims[l-]))
assert(parameters["b" + str(l)].shape == (layers_dims[l],)) return parameters

测试:

parameters = initialize_parameters_he([, , ])
print("W1 = " + str(parameters["W1"]))
print("b1 = " + str(parameters["b1"]))
print("W2 = " + str(parameters["W2"]))
print("b2 = " + str(parameters["b2"]))

返回:

W1 = [[ 1.78862847  0.43650985]
[ 0.09649747 -1.8634927 ]
[-0.2773882 -0.35475898]
[-0.08274148 -0.62700068]]
b1 = [[.]
[.]
[.]
[.]]
W2 = [[-0.03098412 -0.33744411 -0.92904268 0.62552248]]
b2 = [[.]]

这样就基本把参数W初始化到了1附近,我们来实际运行一下看看效果:

parameters = model(train_X, train_Y, initialization = "he",is_polt=True)
print("训练集:")
predictions_train = init_utils.predict(train_X, train_Y, parameters)
print("测试集:")
init_utils.predictions_test = init_utils.predict(test_X, test_Y, parameters)

返回:

第0次迭代,成本值为:0.8830537463419761
第1000次迭代,成本值为:0.6879825919728063
第2000次迭代,成本值为:0.6751286264523371
第3000次迭代,成本值为:0.6526117768893807
第4000次迭代,成本值为:0.6082958970572938
第5000次迭代,成本值为:0.5304944491717495
第6000次迭代,成本值为:0.4138645817071794
第7000次迭代,成本值为:0.3117803464844441
第8000次迭代,成本值为:0.23696215330322556
第9000次迭代,成本值为:0.18597287209206836
第10000次迭代,成本值为:0.15015556280371817
第11000次迭代,成本值为:0.12325079292273551
第12000次迭代,成本值为:0.09917746546525935
第13000次迭代,成本值为:0.08457055954024278
第14000次迭代,成本值为:0.07357895962677366 训练集:
Accuracy: 0.9933333333333333
测试集:
Accuracy: 0.96

图示:

可见效果很好,绘制预测情况:

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: init_utils.predict_dec(parameters, x.T), train_X, train_Y)

图示:

总结:

  • 不同的初始化方法可能导致性能最终不同
  • 随机初始化有助于打破对称,使得不同隐藏层的单元可以学习到不同的参数。
  • 初始化时,初始值不宜过大。
  • He初始化搭配ReLU激活函数常常可以得到不错的效果。

  在深度学习中,如果数据集没有足够大的话,可能会导致一些过拟合的问题。过拟合导致的结果就是在训练集上有着很高的精确度,但是在遇到新的样本时,精确度下降会很严重。

为了避免过拟合的问题,接下来我们要讲解的方式就是正则化。
接下来可见吴恩达课后作业学习2-week1-2正则化—不发布

吴恩达课后作业学习2-week1-1 初始化的更多相关文章

  1. 吴恩达课后作业学习2-week1-2正则化

    参考:https://blog.csdn.net/u013733326/article/details/79847918 希望大家直接到上面的网址去查看代码,下面是本人的笔记 4.正则化 1)加载数据 ...

  2. 吴恩达课后作业学习1-week4-homework-two-hidden-layer -1

    参考:https://blog.csdn.net/u013733326/article/details/79767169 希望大家直接到上面的网址去查看代码,下面是本人的笔记 两层神经网络,和吴恩达课 ...

  3. 吴恩达课后作业学习1-week4-homework-multi-hidden-layer -2

    参考:https://blog.csdn.net/u013733326/article/details/79767169 希望大家直接到上面的网址去查看代码,下面是本人的笔记 实现多层神经网络 1.准 ...

  4. 吴恩达课后作业学习1-week2-homework-logistic

    参考:https://blog.csdn.net/u013733326/article/details/79639509 希望大家直接到上面的网址去查看代码,下面是本人的笔记 搭建一个能够 “识别猫” ...

  5. 吴恩达课后作业学习1-week3-homework-one-hidden-layer

    参考:https://blog.csdn.net/u013733326/article/details/79702148 希望大家直接到上面的网址去查看代码,下面是本人的笔记 建立一个带有隐藏层的神经 ...

  6. 吴恩达课后作业学习2-week3-tensorflow learning-1-基本概念

    参考:https://blog.csdn.net/u013733326/article/details/79971488 希望大家直接到上面的网址去查看代码,下面是本人的笔记  到目前为止,我们一直在 ...

  7. 吴恩达课后作业学习2-week2-优化算法

    参考:https://blog.csdn.net/u013733326/article/details/79907419 希望大家直接到上面的网址去查看代码,下面是本人的笔记 我们需要做以下几件事:  ...

  8. 吴恩达课后作业学习2-week3-tensorflow learning-1-例子学习

    参考:https://blog.csdn.net/u013733326/article/details/79971488 使用TensorFlow构建你的第一个神经网络 我们将会使用TensorFlo ...

  9. 吴恩达课后作业学习2-week1-3梯度校验

    参考:https://blog.csdn.net/u013733326/article/details/79847918 希望大家直接到上面的网址去查看代码,下面是本人的笔记 5.梯度校验 在我们执行 ...

随机推荐

  1. 洛谷P4704 太极剑(乱搞)

    题意 题目链接 Sol 不会正解 写了发暴力过了,貌似跑的还挺快?.. // luogu-judger-enable-o2 // luogu-judger-enable-o2 #include< ...

  2. 开发Spring过程中几个常见异常(一)

    异常一:java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory 原因:未导入有关日志管理的jar包或者未添加到路径. ...

  3. 观察者模式与.NET的delegate、event机制

    1.引言 最近在写一些程序玩的时候,接触到了delegate(委托)和event(事件),网上查找了很多的资料,有些博文说可以把delegate近似当做C++当中的函数指针来看,由于自己本身对C++的 ...

  4. JVM调优(二)经验参数设置

    调优设置具体解析 堆大小设置 JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理内存限制.32位系统下,一般限制在1.5 ...

  5. Android深入四大组件(九)Content Provider的启动过程

    前言 Content Provider做为四大组件之一,通常情况下并没有其他的组件使用频繁,但这不能作为我们不去深入学习它的理由.关于Content Provider一篇文章是写不完的,这一篇文章先来 ...

  6. [Objective-C]编程艺术 笔记整理

    看了<禅与 Objective-C 编程艺术>,发现不少平时不注意的或注意但没有系统总结的东西,特此记录一下. 这次没有整理完,后续更新会结合手里的一些其他资料整理. 新博客wossone ...

  7. 账号配置vue版本的扫码下单以及对店铺进行装修的步骤

    新版vue配置说明文档 管理员后台: 1.配置管理-店铺配置(子账号)-扫码点餐tab页-开启vue版 2.配置管理-店铺配置(主账号)-扫码点餐tab页-开通装修配置 商家后台: 1.主账号-门店设 ...

  8. MS SQL批量生成作业脚本方法介绍总结

    在迁移或升级SQL Server数据库服务器时,很多场景下我们不能还原msdb,所以我们必须手工迁移SQL Server相关作业.如果手工生成每一个作业的脚本话,费时又费力,其实SQL Server中 ...

  9. shell编程-输出(六)

    echo输出echo指令用于字符串的输出 格式:echo 字符串 直接输出字符串:string echo 'this is string-output' 用双引号,这儿也可以省略引号 转义字符:\ e ...

  10. HTML—标签与表格 、框架

    1.标签 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3 ...