神经网络中的损失函数正则化和 Dropout 并手写代码实现

简介: 神经网络中的损失函数正则化和 Dropout 并手写代码实现

640.png


在深度神经网络中最常用的方法是Regularization和dropout。在本文中,我们将一起理解这两种方法并在python中实现它们

Regularization  正则化

正则化通过在损失函数的末尾添加额外的惩罚项来帮助防止模型过度拟合。

640.png

其中m是批次大小。所示的正则化称为L2正则化,而L2对权重应用平方,而L1正则化则采用绝对值,其形式为| W |。

当权重过多或权重太大时,附加的额外项会增加损失,并且可调整因子λ着重说明了我们要对权重进行多少惩罚。

为什么添加惩罚会有助于防止过度拟合?

直观的理解是,在最小化新损失函数的过程中,某些权重将减小至接近零,因此相应的神经元将对我们的结果产生非常小的影响,就好像我们正在使用 更少的神经元。

前向传播:在前进过程中,我们只需更改损失函数。

defcompute_loss(A, Y, parameters, reg=True, lambd=.2):
"""With L2 regularizationparameters: dict with 'W1', 'b1', 'W2', ..."""assertA.shape==Y.shapen_layer=len(parameters)//2m=A.shape[1]
s=np.dot(Y, np.log(A.T)) +np.dot(1-Y, np.log((1-A).T))
loss=-s/mifreg:
p=0foriinrange(1, n_layer+1):
p+=np.sum(np.square(parameters['W'+str(i)]))
loss+= (1/m)*(lambd/2)*preturnnp.squeeze(loss)

反向传播:L2正则化的反向传播实际上是直接的,我们只需要添加L2项的梯度即可。

640.png

defbackward(params, cache, X, Y, lambd=0.2):
"""params: weight [W, b]cache: result [A, Z]Y: shape (1, m)"""grad= {}
n_layers=int(len(params)/2)
m=Y.shape[1]
cache['A0'] =Xforlinrange(n_layers, 0, -1):
A, A_prev, Z=cache['A'+str(l)], cache['A'+str(l-1)], cache['Z'+str(l)]
W=params['W'+str(l)]
ifl==n_layers:
dA=-np.divide(Y, A) +np.divide(1-Y, 1-A)
ifl==n_layers:
dZ=np.multiply(dA, sigmoid_grad(A, Z))
else:
dZ=np.multiply(dA, relu_grad(A, Z))
#withanextragradientattheend, othertermswouldremainthesamedW=np.dot(dZ, A_prev.T)/m+ (lambd/m)*Wdb=np.sum(dZ, axis=1, keepdims=True)/mdA=np.dot(W.T, dZ)
grad['dW'+str(l)] =dWgrad['db'+str(l)] =dbreturngrad

训练过程:像往常一样,我们在二元分类的情况下测试我们的模型,并比较有无正则化的模型。

没有正则化的模型

640.png

有正则化的模型

640.png

实际上,当迭代次数增加时,该模型将继续过拟合,从而导致除法运算出错,造成这种问题的原因可能是在正向过程中,结果A太接近于0。

相反,具有正则化的模型不会过拟合。

Dropout

Dropout通过随机关闭某些输出单元来防止过度拟合。

640.png

在上述过程中,在每次迭代中,层[2]上的某些单元将被随机关闭,这意味着在正向过程中将工作的神经元更少,因此简化了神经网络的整体结构。

同时,训练后的模型将更加健壮,因为该模型不再可以依赖任何特定的神经元(因为在此过程中它们可能会被静音),因此所有其他神经元都需要在训练中学习。

前向传播:你可以理解为Dropout是在前向传播过程中增加了一层。

一般情况下,正向传播方程如下:

640.png

其中g是激活函数。现在,通过Dropout将一个额外的图层应用于A ^ [l]。

添加了Dropout如下:

640.png

其中D是Dropout层。Dropout层中的关键因素是keep_prob参数,该参数指定保留每个单元的可能性。假设keep_prob = 0.8,我们将有80%的机会保持每个输出单位不变,而有20%的机会将其设置为0。

该实现将为结果A添加一个额外的掩码。假设我们有一个包含四个元素的输出A ^ {[l]},如下所示,

640.png

我们希望在保持其余部分不变的情况下使第三个单元关闭,我们需要的是形状相同的矩阵,并按以下方式进行元素逐次乘法,

640.png

前向传播:

defforward(X):
#intermediatelayerusereluasactivation#lastlayerusesigmoidn_layers=int(len(params)/2)
A=Xcache= {}
foriinrange(1, n_layers):
W, b=params['W'+str(i)], params['b'+str(i)]
Z=np.dot(W, A) +bA=relu(Z)
#dropoutkeep_prob=keep_probs[i-1]
D=np.random.rand(A.shape[0], A.shape[1])
D= (D<keep_prob).astype(int)
A=np.multiply(D, A)
#rescaleA=A/keep_probcache['Z'+str(i)] =Zcache['A'+str(i)] =Acache['D'+str(i)] =D#lastlayerW, b=params['W'+str(i+1)], params['b'+str(i+1)]
Z=np.dot(W, A) +bA=sigmoid(Z)
cache['Z'+str(i+1)] =Zcache['A'+str(i+1)] =Areturncache, A

在这里,我们将D初始化为与A相同的形状,并根据keep_prob将其转换为0和1矩阵。

请注意,dropout后,结果A需要重新缩放!由于在此过程中某些神经元被静音,因此需要增加左神经元以匹配预期值。

反向传播:过程是将相同的函数D屏蔽为相应的dA。

#dummycode, fullversionneedstobeinsideaClassdefbackward(self, cache, X, Y, keep_probs):
"""cache: result [A, Z]Y: shape (1, m)"""grad= {}
n_layers=int(len(self.params)/2)
m=Y.shape[1]
cache['A0'] =Xforlinrange(n_layers, 0, -1):
A, A_prev, Z=cache['A'+str(l)], cache['A'+str(l-1)], cache['Z'+str(l)]
W=self.params['W'+str(l)]
ifl==n_layers:
dA=-np.divide(Y, A) +np.divide(1-Y, 1-A)
ifl==n_layers:
dZ=np.multiply(dA, self.sigmoid_grad(A, Z))
else:
#dropoutversionD=cache['D'+str(l)]
dA=np.multiply(dA, D)
#rescaledA=dA/keep_probs[l-1]
dZ=np.multiply(dA, self.relu_grad(A, Z))
dW=np.dot(dZ, A_prev.T)/mdb=np.sum(dZ, axis=1, keepdims=True)/mdA=np.dot(W.T, dZ)
grad['dW'+str(l)] =dWgrad['db'+str(l)] =dbreturngrad

反向传播方程式与一般的神经网络网络中引入的方程式相同。唯一的区别在于矩阵D。除最后一层外,所有其他具有丢失的层将对dA施加相应的蒙版D。

注意,在反向传播中,dA也需要重新缩放。

结论

正则化和dropout都被广泛采用以防止过度拟合,正则化通过在损失函数的末尾添加一个额外的惩罚项来实现,并通过在正向过程中随机地使某些神经元静音来使其退出以使网络更加简洁来实现正则化。

最后所有的代码都可以在这里找到:https://github.com/MJeremy2017/deep-learning/tree/main/regularization

目录
相关文章
|
27天前
|
JSON 监控 安全
Julia企业网络监控的实现:科学计算代码解析
使用Julia语言进行企业网络监控,通过定义带宽利用率和延迟等指标及阈值来检测网络状态。示例代码展示了如何监控带宽和延迟,当超过阈值时触发警报。此外,还介绍了如何通过HTTP请求将监控数据自动提交到网站,以便及时处理网络问题,保障网络安全和稳定性。
72 0
|
1月前
|
机器学习/深度学习 算法 PyTorch
RPN(Region Proposal Networks)候选区域网络算法解析(附PyTorch代码)
RPN(Region Proposal Networks)候选区域网络算法解析(附PyTorch代码)
254 1
|
2月前
|
机器学习/深度学习 编解码 文件存储
YOLOv8改进 | 2023Neck篇 | BiFPN双向特征金字塔网络(附yaml文件+代码)
YOLOv8改进 | 2023Neck篇 | BiFPN双向特征金字塔网络(附yaml文件+代码)
272 0
|
2月前
|
机器学习/深度学习 算法 PyTorch
python手把手搭建图像多分类神经网络-代码教程(手动搭建残差网络、mobileNET)
python手把手搭建图像多分类神经网络-代码教程(手动搭建残差网络、mobileNET)
46 0
|
2月前
|
机器学习/深度学习 测试技术 Ruby
YOLOv8改进 | 主干篇 | 反向残差块网络EMO一种轻量级的CNN架构(附完整代码 + 修改教程)
YOLOv8改进 | 主干篇 | 反向残差块网络EMO一种轻量级的CNN架构(附完整代码 + 修改教程)
93 0
|
2月前
|
机器学习/深度学习 测试技术 Ruby
YOLOv5改进 | 主干篇 | 反向残差块网络EMO一种轻量级的CNN架构(附完整代码 + 修改教程)
YOLOv5改进 | 主干篇 | 反向残差块网络EMO一种轻量级的CNN架构(附完整代码 + 修改教程)
132 2
|
4天前
|
机器学习/深度学习 PyTorch TensorFlow
TensorFlow、Keras 和 Python 构建神经网络分析鸢尾花iris数据集|代码数据分享
TensorFlow、Keras 和 Python 构建神经网络分析鸢尾花iris数据集|代码数据分享
15 0
|
4天前
|
机器学习/深度学习 算法 TensorFlow
【视频】神经网络正则化方法防过拟合和R语言CNN分类手写数字图像数据MNIST|数据分享
【视频】神经网络正则化方法防过拟合和R语言CNN分类手写数字图像数据MNIST|数据分享
|
4天前
|
传感器 存储 监控
编写Arduino代码:构建物联网设备,实现上网行为管理软件对网络的实时监控
使用Arduino和ESP8266/ESP32等Wi-Fi模块,结合传感器监控网络活动,本文展示了如何编写代码实现实时监控并自动将数据提交至网站。示例代码展示如何连接Wi-Fi并检测网络状态,当连接成功时,通过HTTP POST请求将“Network activity detected.”发送到服务器。通过调整POST请求的目标URL和数据,可将监控数据上传至所需网站进行处理和存储。
28 0
|
1月前
|
机器学习/深度学习 PyTorch 算法框架/工具
卷积神经元网络中常用卷积核理解及基于Pytorch的实例应用(附完整代码)
卷积神经元网络中常用卷积核理解及基于Pytorch的实例应用(附完整代码)
20 0

热门文章

最新文章