前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深度学习神经网络中权重的初始化

深度学习神经网络中权重的初始化

作者头像
夜雨飘零
发布2020-05-06 11:37:20
7420
发布2020-05-06 11:37:20
举报
文章被收录于专栏:CSDN博客

原文博客:Doi技术团队 链接地址:https://blog.doiduoyi.com/authors/1584446358138 初心:记录优秀的Doi技术团队学习经历

目录

文章目录

  • 目录
  • 前言
  • 模型函数
  • 零初始化
  • 随机初始化
  • He初始化
  • 总结
  • 参考资料

前言

良好的初始化权重有以下的好处:

  • 加快梯度下降的收敛速度
  • 增加梯度下降收敛到较低训练(和泛化)错误的几率

所以一个良好的初始化也是非常重要的,这里尝试三种初始化化方式:

  1. 零初始化,将权重参数初始化为零。
  2. 随机初始化,使用随机的方式,初始化权重参数。
  3. He初始化,这个公式的初始化方式。

我们来尝试这个三种方法吧。

模型函数

编写一个model函数,使用这个函数可以测试各种初始化权重参数的效果。 在编写model函数之前,我们先要导入对于依赖包,其中有些依赖包可以在这里下载

代码语言:javascript
复制
# coding=utf-8
import numpy as np
from init_utils import compute_loss, forward_propagation, backward_propagation
from init_utils import update_parameters, predict, load_dataset

# 加载图像数据集:蓝色/红点在圆圈中
train_X, train_Y, test_X, test_Y = load_dataset()

其中使用的数据集是这个样子的:

然后就可以编写model函数了。

代码语言:javascript
复制
def model(X, Y, learning_rate=0.01, num_iterations=15000, print_cost=True, initialization="he"):
    """
    实现一个三层神经网络:LINEAR>RELU->LINEAR->RELU->LINEAR->SIGMOID。

    Arguments:
    X -- 输入数据,形状(2,样本数量)
    Y -- 真正的“标签”向量(包含0代表红点;(1)形状(1,样本数目)
    learning_rate -- 梯度下降的学习速率。
    num_iterations -- 运行梯度下降的迭代次数。
    print_cost -- 如果是真的,打印每1000次迭代的成本。
    initialization -- 选择使用哪个初始化(“0”、“随机”或“He”)

    Returns:
    parameters -- 由模型学习的参数。
    """

    global parameters
    grads = {}
    costs = []  # to keep track of the loss
    m = X.shape[1]  # number of examples
    layers_dims = [X.shape[0], 10, 5, 1]

    # 字典初始化参数。
    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)

    # 循环(梯度下降)
    for i in range(0, num_iterations):

        # 前向传播: LINEAR -> RELU -> LINEAR -> RELU -> LINEAR -> SIGMOID.
        a3, cache = forward_propagation(X, parameters)

        # Loss
        cost = compute_loss(a3, Y)

        # 反向传播。
        grads = backward_propagation(X, Y, cache)

        # 更新参数。
        parameters = update_parameters(parameters, grads, learning_rate)

        # 每1000次迭代打印一次损失。
        if print_cost and i % 1000 == 0:
            print("Cost after iteration {}: {}".format(i, cost))
            costs.append(cost)
    return parameters

零初始化

在神经网络中初始化的参数有两种类型:

代码语言:javascript
复制
def initialize_parameters_zeros(layers_dims):
    """
    Arguments:
    layer_dims——python数组(list),包含每个层的大小。

    Returns:
    parameters -- 包含参数的python字典 "W1", "b1", ..., "WL", "bL":
                    W1 -- 形状权重矩阵(layers_dims[1], layers_dims[0])
                    b1 -- 形状偏置向量(layers_dims[1], 1)
                    ...
                    WL -- 形状权重矩阵(layers_dims[L], layers_dims[L-1])
                    bL -- 形状的偏置向量(layers_dims[L], 1)
    """

    parameters = {}
    L = len(layers_dims)  # 网络中的层数

    for l in range(1, L):
        parameters['W' + str(l)] = np.zeros((layers_dims[l], layers_dims[l - 1]))
        parameters['b' + str(l)] = np.zeros((layers_dims[l], 1))
    return parameters

然后运行测试一下,会看cost并不怎么收敛,这是因为它没有“破坏对称性”。

代码语言:javascript
复制
if __name__ == "__main__":
    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)

输出的日志信息:

代码语言:javascript
复制
Cost after iteration 0: 0.69314718056
Cost after iteration 1000: 0.69314718056
Cost after iteration 2000: 0.69314718056
Cost after iteration 3000: 0.69314718056
Cost after iteration 4000: 0.69314718056
Cost after iteration 5000: 0.69314718056
Cost after iteration 6000: 0.69314718056
Cost after iteration 7000: 0.69314718056
Cost after iteration 8000: 0.69314718056
Cost after iteration 9000: 0.69314718056
Cost after iteration 10000: 0.69314718056
Cost after iteration 11000: 0.69314718056
Cost after iteration 12000: 0.69314718056
Cost after iteration 13000: 0.69314718056
Cost after iteration 14000: 0.69314718056
On the train set:
Accuracy: 0.5
On the test set:
Accuracy: 0.5

如果使用图表来显示的话,是这样子的:

随机初始化

随机初始化可以打破对称,让我们随机初始化权重。在随机初始化之后,每个神经元可以继续学习其输入的不同功能。我们只是随机初始化权重参数,偏差还是继续初始化为零。

代码语言:javascript
复制
def initialize_parameters_random(layers_dims):
    """
    Arguments:
    layer_dims -- python数组(list),包含每个层的大小。

    Returns:
    parameters -- 包含参数的python字典 "W1", "b1", ..., "WL", "bL":
                    W1 -- 形状权重矩阵(layers_dims[1], layers_dims[0])
                    b1 -- 形状偏置向量(layers_dims[1], 1)
                    ...
                    WL -- 形状权重矩阵(layers_dims[L], layers_dims[L-1])
                    bL -- 形状的偏置向量(layers_dims[L], 1)
    """

    parameters = {}
    L = len(layers_dims)  # 表示层数的整数。

    for l in range(1, L):
        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))
    return parameters

运行一下,可以看到已经破坏了对称性,模型并开始收敛了。

代码语言:javascript
复制
if __name__ == "__main__":
    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)

输出的日志如下,看到在0次迭代的时候是“inf”,这是因为数值舍入的:

代码语言:javascript
复制
Cost after iteration 0: inf
Cost after iteration 1000: 0.386009576858
Cost after iteration 2000: 0.276065073598
Cost after iteration 3000: 0.267517603676
Cost after iteration 4000: 0.261640832949
Cost after iteration 5000: 0.254131922349
Cost after iteration 6000: 0.31200805047
Cost after iteration 7000: 0.243035498545
Cost after iteration 8000: 0.22011133348
Cost after iteration 9000: 0.217258906612
Cost after iteration 10000: 0.214850990347
Cost after iteration 11000: 0.212760572669
Cost after iteration 12000: 0.210936153771
Cost after iteration 13000: 0.209300028106
Cost after iteration 14000: 0.207868192424
On the train set:
Accuracy: 0.883333333333
On the test set:
Accuracy: 0.85

如果用图表来显示的话,是这个样子的:

He初始化

He初始化跟上面的随机初始化类似initialize_parameters_random(...)。唯一的区别是,不是np.random.randn(..,..)*10的乘以10,而是乘以2dimension of the previous layer\sqrt{\frac{2}{\text{dimension of the previous layer}}}dimension of the previous layer2​​,这是He初始化为具有ReLU激活的图层推荐的内容。

代码语言:javascript
复制
def initialize_parameters_he(layers_dims):
    """
    Arguments:
    layer_dims -- python数组(list),包含每个层的大小。

    Returns:
    parameters -- 包含参数的python字典 "W1", "b1", ..., "WL", "bL":
                    W1 -- 形状权重矩阵(layers_dims[1], layers_dims[0])
                    b1 -- 形状偏置向量(layers_dims[1], 1)
                    ...
                    WL -- 形状权重矩阵(layers_dims[L], layers_dims[L-1])
                    bL -- 形状的偏置向量(layers_dims[L], 1)
    """

    np.random.seed(3)
    parameters = {}
    L = len(layers_dims) - 1  # 表示层数的整数

    for l in range(1, L + 1):
        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))
    return parameters

运行这个初始化方式。

代码语言:javascript
复制
if __name__ == "__main__":
    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)

输出的日志信息是:

代码语言:javascript
复制
Cost after iteration 0: 0.883053746342
Cost after iteration 1000: 0.687982591973
Cost after iteration 2000: 0.675128626452
Cost after iteration 3000: 0.652611776889
Cost after iteration 4000: 0.608295897057
Cost after iteration 5000: 0.530494449172
Cost after iteration 6000: 0.413864581707
Cost after iteration 7000: 0.311780346484
Cost after iteration 8000: 0.236962153303
Cost after iteration 9000: 0.185972872092
Cost after iteration 10000: 0.150155562804
Cost after iteration 11000: 0.123250792923
Cost after iteration 12000: 0.0991774654653
Cost after iteration 13000: 0.0845705595402
Cost after iteration 14000: 0.0735789596268
On the train set:
Accuracy: 0.993333333333
On the test set:
Accuracy: 0.96

如果用图表来显示的话,应该是:

总结

最后使用一个表格的方式来总结一下我们使用三个不同的初始化方式的训练准确率。

Model

Train accuracy

Problem/Comment

3-layer NN with zeros initialization

50%

fails to break symmetry

3-layer NN with large random initialization

83%

too large weights

3-layer NN with He initialization

99%

recommended method

参考资料

  1. http://deeplearning.ai/

该笔记是学习吴恩达老师的课程写的。初学者入门,如有理解有误的,欢迎批评指正!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/04/15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
    • 文章目录
    • 前言
    • 模型函数
    • 零初始化
    • 随机初始化
    • He初始化
    • 总结
    • 参考资料
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档