神经网络中的损失函数正则化和 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

目录
相关文章
用MASM32按Time Protocol(RFC868)协议编写网络对时程序中的一些有用的函数代码
用MASM32按Time Protocol(RFC868)协议编写网络对时程序中的一些有用的函数代码
|
5月前
|
机器学习/深度学习 存储 算法
回声状态网络(Echo State Networks,ESN)详细原理讲解及Python代码实现
本文详细介绍了回声状态网络(Echo State Networks, ESN)的基本概念、优点、缺点、储层计算范式,并提供了ESN的Python代码实现,包括不考虑和考虑超参数的两种ESN实现方式,以及使用ESN进行时间序列预测的示例。
277 4
回声状态网络(Echo State Networks,ESN)详细原理讲解及Python代码实现
|
3月前
|
机器学习/深度学习 网络架构 计算机视觉
目标检测笔记(一):不同模型的网络架构介绍和代码
这篇文章介绍了ShuffleNetV2网络架构及其代码实现,包括模型结构、代码细节和不同版本的模型。ShuffleNetV2是一个高效的卷积神经网络,适用于深度学习中的目标检测任务。
132 1
目标检测笔记(一):不同模型的网络架构介绍和代码
|
4月前
|
安全 C#
某网络硬盘网站被植入传播Trojan.DL.Inject.xz等的代码
某网络硬盘网站被植入传播Trojan.DL.Inject.xz等的代码
|
4月前
|
机器学习/深度学习
小土堆-pytorch-神经网络-损失函数与反向传播_笔记
在使用损失函数时,关键在于匹配输入和输出形状。例如,在L1Loss中,输入形状中的N代表批量大小。以下是具体示例:对于相同形状的输入和目标张量,L1Loss默认计算差值并求平均;此外,均方误差(MSE)也是常用损失函数。实战中,损失函数用于计算模型输出与真实标签间的差距,并通过反向传播更新模型参数。
|
4月前
|
机器学习/深度学习 自动驾驶 搜索推荐
深度学习之探索神经网络、感知器与损失函数
在当今的数字化时代,深度学习作为一种强大的机器学习技术,正在迅速改变着我们的生活方式。无论是智能推荐系统、自动驾驶车辆还是语音识别应用,深度学习都在背后默默地发挥作用。
71 1
|
5月前
|
安全 网络安全 开发者
探索Python中的装饰器:简化代码,增强功能网络安全与信息安全:从漏洞到防护
【8月更文挑战第30天】本文通过深入浅出的方式介绍了Python中装饰器的概念、用法和高级应用。我们将从基础的装饰器定义开始,逐步深入到如何利用装饰器来改进代码结构,最后探讨其在Web框架中的应用。适合有一定Python基础的开发者阅读,旨在帮助读者更好地理解并运用装饰器来优化他们的代码。
|
5月前
|
数据采集 量子技术 双11
【2023 年第十三届 MathorCup 高校数学建模挑战赛】C 题 电商物流网络包裹应急调运与结构优化问题 建模方案及代码实现
本文提供了2023年第十三届MathorCup高校数学建模挑战赛C题的详细建模方案及代码实现,针对电商物流网络中的包裹应急调运与结构优化问题,提出了包括时间序列分析在内的多种数学模型,并探讨了物流网络的鲁棒性。
81 2
【2023 年第十三届 MathorCup 高校数学建模挑战赛】C 题 电商物流网络包裹应急调运与结构优化问题 建模方案及代码实现
完成切换网络+修改网络连接图标提示的代码框架
完成切换网络+修改网络连接图标提示的代码框架
|
5月前
|
达摩院 供应链 JavaScript
网络流问题--仓储物流调度【数学规划的应用(含代码)】阿里达摩院MindOpt
本文通过使用MindOpt工具优化仓储物流调度问题,旨在提高物流效率并降低成本。首先,通过考虑供需匹配、运输时间与距离、车辆容量、仓库储存能力等因素构建案例场景。接着,利用数学规划方法,包括线性规划和网络流问题,来建立模型。在网络流问题中,通过定义节点(资源)和边(资源间的关系),确保流量守恒和容量限制条件下找到最优解。文中还详细介绍了MindOpt Studio云建模平台和MindOpt APL建模语言的应用,并通过实例展示了如何声明集合、参数、变量、目标函数及约束条件,并最终解析了求解结果。通过这些步骤,实现了在满足各仓库需求的同时最小化运输成本的目标。

热门文章

最新文章