美文网首页
神经网络实践之初始化权重参数

神经网络实践之初始化权重参数

作者: 此间不留白 | 来源:发表于2019-10-18 19:11 被阅读0次

    前言

    机器学习的应用层面中,已经了解了神经网络中的一些有关实践层面的一些参数包括方差,偏差,权重初始化,几种正则化的方法,和梯度检验等相关知识,本篇文章是深度学习课程的配套作业,将会通过代码实现深度学习应用层面的一些参数配置,提高神经网络的性能。

    初始化权重参数

    神经网络的第一项任务就是初始化权重参数,一些好的初始化权重参数有利于提高网络性能和加快网络训练速度。
    利用python实现初始化权重的过程如下所示:

    • 导入相关包
      首先,需要导入相关初始化权重参数用到的相关库,并且完成一些数据可视化的基本设置,如下代码所示:
    import numpy as np
    import matplotlib.pyplot as plt
    import sklearn
    import sklearn.datasets
    # 绘图的一些默认参数
    %matplotlib inline
    plt.rcParams['figure.figsize'] = (7.0, 4.0) #设置图片m默认大小
    plt.rcParams['image.interpolation'] = 'nearest'
    plt.rcParams['image.cmap'] = 'gray'
    
    • 加载数据集并可视化
      这些数据集是通过调用sklearn库生成的一些随机数据,这些随机数据按照颜色分为两类的二维随机数据,这些训练数据分为训练集和测试集,在二维图形中大致按照圆形分布,具体实现如下代码所示:
    def load_dataset():
        np.random.seed(1)
        train_X, train_Y = sklearn.datasets.make_circles(n_samples=300, noise=.05)
        np.random.seed(2)
        test_X, test_Y = sklearn.datasets.make_circles(n_samples=100, noise=.05)
        # 可视化数据
        plt.scatter(train_X[:, 0], train_X[:, 1], c=train_Y, s=40, cmap=plt.cm.Spectral);
        train_X = train_X.T
        train_Y = train_Y.reshape((1, train_Y.shape[0]))
        test_X = test_X.T
        test_Y = test_Y.reshape((1, test_Y.shape[0]))
        return train_X, train_Y, test_X, test_Y
    

    对于神经网络模型,将会利用三种不同的方式实现权重参数的随机初始化,并比较这三种初始化方式的优劣,具体如下所示:

    搭建神经网络模型

    在完成参数初始化之前,首先完成整个网络模型的搭建。整个网络模型的结构是一个三层的神经网络,整个神经网络模型的实现过程,在一步步构建一个神经网络中有详细的介绍,在此不再多做说明。只考虑每次设置不同的权重参数初始化方式,比较模型性能。

    def model(X, Y, learning_rate = 0.01, num_iterations = 15000, print_cost = True, initialization = "he"):
        """
       三层神经网络的模型结构: LINEAR->RELU->LINEAR->RELU->LINEAR->SIGMOID.
        
        参数:
        X -- 输入数据 矩阵形状是(2, 样本数量)
        Y -- 输出标签,1代表红点,0代表蓝点,向量形状 (1, 样本数量)
        learning_rate -- 梯度下降的学习率
        num_iterations -- 运行梯度下降的迭代次数
        print_cost -- 打印出每1000次迭代之后的损失
        initialization -- 初始化权重参数的方式选择
     ("zeros","random" or "he")
        
      返回值:模型学习的参数
        """
            
        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)
            
            # 计算损失
            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)
                
        # 绘制模型损失图像
        plt.plot(costs)
        plt.ylabel('cost')
        plt.xlabel('iterations (per hundreds)')
        plt.title("Learning rate =" + str(learning_rate))
        plt.show()
        
        return parameters
    
    

    0初始化

    0初始化,也就是将所有的权重参数设为0,具体实现代码如下所示:

    def initialize_parameters_zeros(layers_dims):
        """
       参数说明:
        layer_dims -- 神经网络的层数,一个列表,其中的值代表这一层的单元数量,长度代表神经网络的层数
        Returns:
        返回一个存储参数的python字典
                  
        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
    

    运行以上代码后,输出结果如下所示:


    采用参数0初始化之后的梯度下降过程如下所示,可以看出,将初始化参数全部设为0之后,运行多次梯度下降算法之后,损失值一直保持不变,训练集和测试集的输出全是0,分类精度只有0.5,说明权重参数0初始化并不是一种可行的办法。

    随机初始化

    权重参数的随机初始化即是将每一层的权重参数w^{[l]}初始化为随机高斯分布(取值范围为(-1,1)),并将其乘以10,偏置参数b^{[l]}初始化为0,具体的实现代码如下所示:

    
    def initialize_parameters_random(layers_dims):
        
        np.random.seed(3)               #固定随机种子
        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
    

    运行一下代码,并输出模型损失和性能如下所示:

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

    注意:

    • 可以看出,刚开始迭代时,损失非常高,达到了正无穷,这是因为刚开始设置的权重参数非常大,对于sigmoid函数来说,很容易导致输出接近0或者1,从而导致最后的损失函数中的log(a^{[3]}) = log(0) =- inf

    • 初始化参数过大或者过小可能会导致梯度爆炸或者梯度消失,可能会导致训练速度减慢。

    • 如果对该网络进行更长时间的训练,训练精度可能会更高,但是会花费更长的时间。

    He初始化

    He初始化是2015年以它的发明者命名的,这种初始化方法采用了对权重使用比例因为的方法,也就是对权重参数w^{[l]}乘以比例因子\frac{1}{\sqrt{(n^{[l-1]})}}的方法,具体实现方式如下所示:

    
    def initialize_parameters_he(layers_dims):
       
        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(1/layers_dims[l-1])
            parameters['b' + str(l)] = np.zeros((layers_dims[l],1))
         
            
        return parameters
    

    输出结果如下所示:

    梯度下降过程中的迭代如下所示,随着迭代次数的增加,损失一直在降低,并且训练集和测试集的精度分别达到了99%和93%:


    最后,绘制决策边界如下所示:

    相关文章

      网友评论

          本文标题:神经网络实践之初始化权重参数

          本文链接:https://www.haomeiwen.com/subject/qnovmctx.html