【梯度检验】深度学习专项课程学习记录6——实现梯度检验

学习目标

使用Numpy实现梯度检验,理解其原理。

笔记

1.理解梯度检验

导数(梯度)的定义:
∂ J ∂ θ = lim ⁡ ε → 0 J ( θ + ε ) − J ( θ − ε ) 2 ε \frac{\partial J}{\partial \theta} = \lim_{\varepsilon \to 0} \frac{J(\theta + \varepsilon) - J(\theta - \varepsilon)}{2 \varepsilon} θJ=ε0lim2εJ(θ+ε)J(θε)
梯度检验:取一个很小的值,记作 ε \varepsilon ε,代入 J ( θ + ε ) − J ( θ − ε ) 2 ε \frac{J(\theta + \varepsilon) - J(\theta - \varepsilon)}{2 \varepsilon} 2εJ(θ+ε)J(θε)计算得到gradapprox,如果gradapprox和梯度grad差异很小(低于一个阈值,一般取 1 0 − 7 10^{-7} 107),则说明之前求导得到的梯度是正确的。

2.实现梯度检验

2.1 一维梯度检验

  1. 创建一个变量 θ + \theta^{+} θ+ θ + = θ + ε \theta^{+} = \theta + \varepsilon θ+=θ+ε
  2. 创建一个变量 θ − \theta^{-} θ θ − = θ − ε \theta^{-} = \theta - \varepsilon θ=θε
  3. 创建一个变量 J + J^{+} J+ J + = J ( θ + ) J^{+} = J(\theta^{+}) J+=J(θ+)
  4. 创建一个变量 J − J^{-} J J − = J ( θ − ) J^{-} = J(\theta^{-}) J=J(θ)
  5. 创建一个变量 g r a d a p p r o x gradapprox gradapprox g r a d a p p r o x = J + − J − 2 ε gradapprox = \frac{J^{+} - J^{-}}{2 \varepsilon} gradapprox=2εJ+J
  6. 计算 g r a d grad grad g r a d = J ( θ ) grad = J(\theta) grad=J(θ)
  7. 计算 d i f f e r e n c e difference difference d i f f e r e n c e = ∣ ∣ g r a d − g r a d a p p r o x ∣ ∣ 2 ∣ ∣ g r a d ∣ ∣ 2 + ∣ ∣ g r a d a p p r o x ∣ ∣ 2 difference = \frac {\mid\mid grad - gradapprox \mid\mid_2}{\mid\mid grad \mid\mid_2 + \mid\mid gradapprox \mid\mid_2} difference=grad2+gradapprox2gradgradapprox2
  8. 如果 d i f f e r e n c e < 1 0 − 7 difference<10^{-7} difference<107,说明梯度计算正确。

其中, d i f f e r e n c e difference difference的计算用python表示是:

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

2.2 N维梯度检验

N维梯度检验与一维梯度检验不同的是此处的 θ \theta θ不再是标量,而是一个字典(图中parameters),整体的计算思路一致。图中说明了在进行N维梯度检验时要用到的两个函数dictionary_to_vector() 和 vector_to_dictionary() 的用途。
dictionary_to_vector()&vector_to_dictionary().
N维梯度检验(gradient_check_n)的python代码如下:

def gradient_check_n(parameters, gradients, X, Y, epsilon=1e-7, print_msg=False):
    # 创建变量
    parameters_values, _ = dictionary_to_vector(parameters)
    
    grad = gradients_to_vector(gradients)
    num_parameters = parameters_values.shape[0]
    J_plus = np.zeros((num_parameters, 1))
    J_minus = np.zeros((num_parameters, 1))
    gradapprox = np.zeros((num_parameters, 1))
    
    for i in range(num_parameters):
        theta_plus =  np.copy(parameters_values)
        theta_plus[i] =  theta_plus[i][0] + epsilon
        J_plus[i], _ =  forward_propagation_n(X, Y, vector_to_dictionary(theta_plus))

        theta_minus =  np.copy(parameters_values)
        theta_minus[i] =  theta_minus[i][0] -  epsilon
        J_minus[i], _ =  forward_propagation_n(X, Y, vector_to_dictionary(theta_minus))        
        
        gradapprox[i] = (J_plus[i] - J_minus[i]) / (2*epsilon)

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

    return difference

学习时间

2022.6.27

总结

  1. 梯度检验可验证反向传播的梯度与梯度近似值之间的接近度(使用正向传播进行计算);

  2. 梯度检验很慢,用 ∂ J ∂ θ ≈ J ( θ + ε ) − J ( θ − ε ) 2 ε \frac{\partial J}{\partial \theta} \approx \frac{J(\theta + \varepsilon) - J(\theta - \varepsilon)}{2 \varepsilon} θJ2εJ(θ+ε)J(θε)逼近梯度很耗费资源,通常只需检查几次梯度是否正确。

  3. 梯度检验不适用于dropout。先运行不带dropout的梯度检验算法以确保后向传播正确,然后添加dropout。

需要注意的地方

  1. 梯度检验时将参数W,b当作自变量而不是x;
  2. 未完待续。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值