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

深度神经网络初始化、正则化、梯度校验

作者头像
lovelife110
发布2021-01-14 14:50:19
4990
发布2021-01-14 14:50:19
举报
文章被收录于专栏:爱生活爱编程爱生活爱编程

初始化

深度神经网络模型中,以单个神经元为例,该层(

l
l

)的输入个数为n,其输出为:

z=w_1x_1+w_2x_2+\cdots+w_nx_n
z=w_1x_1+w_2x_2+\cdots+w_nx_n
a=g(z)
a=g(z)

这里忽略了常数项b。为了让z不会过大或者过小,思路是让w与n有关,且n越大,w应该越小才好。这样能够保证z不会过大。一种方法是在初始化w时,令其方差为

\frac1n
\frac1n

。激活函数是tanh,相应的python代码为:

代码语言:javascript
复制
parameters['W'] = np.random.randn(n[l], n[l - 1]) * np.sqrt(1 / n[l - 1])

激活函数是ReLU,权重w的初始化一般令其方差为

\frac2n
\frac2n

正则化

L2正则化

也可以表示为:

||w^{[l]}||
||w^{[l]}||

称为Frobenius范数,一个矩阵的Frobenius范数就是计算所有元素平方和再开方

python代码例子,在计算J成本函数时加上正则化成本,假设有w1,w2,w3:

代码语言:javascript
复制
L2_regularization_cost = lambd * (np.sum(np.square(W1)) + np.sum(np.square(W2)) + np.sum(np.square(W3))) / (2 * m)

在反向传播时,使用以下公式计算梯度

\frac{d}{dW} ( \frac{1}{2}\frac{\lambda}{m} W^2) = \frac{\lambda}{m} W
\frac{d}{dW} ( \frac{1}{2}\frac{\lambda}{m} W^2) = \frac{\lambda}{m} W
dw^{[l]}=dw^{[l]}_{before}+\frac{\lambda}{m}w^{[l]}
dw^{[l]}=dw^{[l]}_{before}+\frac{\lambda}{m}w^{[l]}

python代码:

代码语言:javascript
复制
dW3 = (1 / m) * np.dot(dZ3, A2.T) + ((lambd * W3) / m)

Dropout正则化

Dropout的原理就是每次迭代过程中随机将其中的一些节点失效。当我们关闭一些节点时,我们实际上修改了我们的模型。背后的想法是,在每次迭代时,我们都会训练一个只使用一部分神经元的不同模型。随着迭代次数的增加,我们的模型的节点会对其他特定节点的激活变得不那么敏感,因为其他节点可能在任何时候会失效。 正向传播python代码:

代码语言:javascript
复制
    D1 = np.random.rand(A1.shape[0], A1.shape[1])  # 步骤1:初始化矩阵D1 = np.random.rand(..., ...)
    D1 = D1 < keep_prob  # 步骤2:将D1的值转换为0或1(使​​用keep_prob作为阈值)
    A1 = A1 * D1  # 步骤3:舍弃A1的一些节点(将它的值变为0或False)
    A1 = A1 / keep_prob  # 步骤4:缩放未舍弃的节点(不为0)的值

除以 keep_prob。这样做的话我们通过缩放就在计算成本的时候仍然具有相同的期望值。

假设第l层有50个神经元,经过dropout后,有10个神经元停止工作,这样只有40神经元有作用。那么得到的al只相当于原来的80%。缩放后,能够尽可能保持al的期望值相比之前没有大的变化。

后向传播:

使用正向传播存储在缓存中的掩码D1,python代码

代码语言:javascript
复制
    dA1 = dA1 * D1  # 步骤1:使用正向传播期间相同的节点,舍弃那些关闭的节点(因为任何数乘以0或者False都为0或者False)
    dA1 = dA1 / keep_prob  # 步骤2:缩放未舍弃的节点(不为0)的值

梯度检查

\theta^{+} = \theta + \varepsilon
\theta^{+} = \theta + \varepsilon
\theta^{-} = \theta - \varepsilon
\theta^{-} = \theta - \varepsilon
J^{+} = J(\theta^{+})
J^{+} = J(\theta^{+})
J^{-} = J(\theta^{-})
J^{-} = J(\theta^{-})
gradapprox = \frac{J^{+} - J^{-}}{2 \varepsilon}
gradapprox = \frac{J^{+} - J^{-}}{2 \varepsilon}

接下来,计算梯度的反向传播值,最后计算误差:

当difference小于

10^{-7}
10^{-7}

时,我们通常认为我们计算的结果是正确的。

python代码

代码语言:javascript
复制
def gradient_check(x,theta,epsilon=1e-7):
    """
    参数:
        x  - 一个实值输入
        theta  - 参数,也是一个实数
        epsilon  - 使用公式(3)计算输入的微小偏移以计算近似梯度

    返回:
        近似梯度和后向传播梯度之间的差异
    """

    #使用公式的计算gradapprox。
    thetaplus = theta + epsilon                               
    thetaminus = theta - epsilon                              
    J_plus = forward_propagation(x, thetaplus)                
    J_minus = forward_propagation(x, thetaminus)              
    gradapprox = (J_plus - J_minus) / (2 * epsilon)           

    #检查gradapprox是否足够接近backward_propagation()的输出
    grad = backward_propagation(x, theta)

    numerator = np.linalg.norm(grad - gradapprox)                      
    denominator = np.linalg.norm(grad) + np.linalg.norm(gradapprox)    
    difference = numerator / denominator                               

    if difference < 1e-7:
        print("梯度检查:梯度正常!")
    else:
        print("梯度检查:梯度超出阈值!")

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 初始化
  • 正则化
  • Dropout正则化
  • 梯度检查
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档