问题描述
吴恩达《深度学习》编程作业L1W4的作业1中,L层神经网络 初始化使用的代码:
def initialize_parameters_deep(layer_dims):
np.random.seed(3)
parameters = {}
L = len(layer_dims)
for l in range(1, L):
parameters['W' + str(l)] = np.random.randn(layer_dims[l],layer_dims[l-1]) * 0.01
parameters['b' + str(l)] = np.zeros((layer_dims[l],1))
return parameters
注意:其中W初始化时,np.random.randn(layer_dims[l],layer_dims[l-1]) * 0.01
那么在L1W4作业2中,我理所当然的也用了 * 0.01,最后的结果为:
训练集: Accuracy: 0.66
测试集: Accuracy: 0.34
与答案给出的预期输出:
0次迭代后的损失:
0.6930497356599888
100次迭代后的损失:
0.6464320953428849
…
2400次迭代后的损失:
0.048554785628770206
训练集预期输出: Accuracy: 0.99
测试集预期输出: Accuracy: 0.72
相差太大了
问题分析
在做的过程中,如果使用的是dnn_app_utils_v2.py中的initialize_parameters_deep
可以发现它使用的是:
parameters['W' + str(l)] = np.random.randn(layer_dims[l], layer_dims[l-1]) / np.sqrt(layer_dims[l-1])
我将初始化代码也改成 / np.sqrt(layer_dims[l-1]) 后,运行结果:
训练集: Accuracy: 0.99
测试集: Accuracy: 0.80
![](https://i-blog.csdnimg.cn/blog_migrate/c8c666a927678c78c9dac7d4c648b0b2.png)
在测试集上的预测,比吴恩达的效果要好一些
问题原因:
不同的激活函数的初始化方法是不同的,(吴老师的视频当时只是说还有其他的方法,并没有详细的解释)例如:
1.激活函数为tanh时,令W的方差为 :
w[l] = np.random.randn(n[l],n[l-1])*np.sqrt(1/n[l-1])
2.激活函数是ReLU,权重w的初始化一般令其方差为 :
w[l] = np.random.randn(n[l],n[l-1])*np.sqrt(2/n[l-1])
3.Yoshua Bengio提出一种初始化w的方法,令其方差为 :
w[l] = np.random.randn(n[l],n[l-1])*np.sqrt(2/(n[l-1]+n[l]))
再讨论
根据吴恩达的作业要求,我们使用的激活函数是ReLU,那照理说*np.sqrt(2/n[l-1])的效果会更好
运行出来的结果为:
![](https://i-blog.csdnimg.cn/blog_migrate/578927bfd6420babfcec192e73d94f69.png)
训练集预期输出: Accuracy: 0.96
测试集预期输出: Accuracy: 0.74
在训练集上的预测,比吴恩达的效果要差一点
在测试集上的预测,比吴恩达的效果要好0.02
但是比/ np.sqrt(layer_dims[l-1]) 也就是tanh的初始化方法要差
有没有大佬能回答一下,感谢!