题目要求如下:
首先定义激活函数,这里需要定义sigmoid激活函数和relu激活函数,以及它们的导数,如下所示:
1 | import numpy as np |
然后还是提供数据,代码如下:
1 | def produce_data(): |
然后就是定义神经网络的结构和训练过程,如下所示:
1 | class MLP(object): |
见上面的代码,网络设置的超参包括,隐层的神经元数目,迭代终止的阈值数,激活函数类型和学习率。这里当MLP预测的标签和真实标签之间的直小于阈值时,网络停止训练,并且打印出误差和迭代次数的曲线图,以便直观反映分类器在学习时的性能。
下面代码是画图曲线,直观反映数据各个区域被划分的情况,代码如下所示:
1 | def plot_decision_boundary(pred_func, X, y, title=None): |
最后是输出结果,这里我们分成两个:
sigmoid激活函数输出结果
很显然,按照要求隐层的神经元数目为2,阈值设为0.01,学习率调为0.55时发现此时sigmoid收敛最快,所以测试如下:
1 | nn = MLP(hidden_num=2,limit=0.01,activation='sigmoid',lr=0.55) |
迭代了584208次收敛
[[0.0031447 ]
[0.98899742]
[0.98899742]
[0.0148501 ]]
可以看出一共迭代了584208次才收敛,这无疑是一个很长的时间。
relu激活函数输出结果
这里除了学习率,其他参数设置同上,这里发现学习率为0.048时对于relu函数收敛最快,测试如下:
1 | nn = MLP(hidden_num=2,limit=0.01,activation='relu',lr=0.048) |
迭代了23451次收敛
[[0. ]
[0.98167616]
[0.97657768]
[0. ]]
虽然相对sigmoid迭代的很快,但是收敛过程却并不稳定。
结论
1.relu函数的收敛速度比sigmoid函数快很多,所以我们一般使用relu函数做激活函数比较多。
2.sigmoid函数收敛过程比relu更加稳定,对初值的选择也不是很挑剔,其鲁棒性比较好。