机器学习深度学习——权重衰减

👨‍🎓作者简介:一位即将上大四,正专攻机器学习的保研er
🌌上期文章:机器学习&&深度学习——模型选择、欠拟合和过拟合
📚订阅专栏:机器学习&&深度学习
希望文章对你们有所帮助

权重衰减

  • 讨论(思维过一下,后面会总结)
  • 权重衰减
    • 使用均方范数作为硬性限制
    • 使用均方范数作为柔性限制
    • 对最优解的影响
    • 参数更新法则
    • 总结
  • 高维线性回归
  • 从零开始实现
    • 初始化模型参数
    • 定义L2范数乘法
    • 定义训练代码实现
    • 忽略正则化直接训练
    • 使用权重衰减
  • 简洁实现

讨论(思维过一下,后面会总结)

前一节已经描述了过拟合的问题,本节将会介绍一些正则化模型的技术。
之前用了多项式回归的例子,我们可以通过调整拟合多项式的阶数来限制模型容量。而限制特征数量是缓解过拟合的一种常用技术。然而,我们还需要考虑高维输入可能发生的情况。多项式对多变量的自然扩展称为单项式,也可以说是变量幂的成绩。单项式的阶数是幂的和。例如,x12x2和x3x52都是3次单项式。
随着阶数d的增长,带有阶数d的项数迅速增加。给定k个变量,阶数为d的项的个数为:
C k − 1 + d k − 1 = ( k − 1 + d ) ! ( d ) ! ( k − 1 ) ! C_{k-1+d}^{k-1}=\frac{(k-1+d)!}{(d)!(k-1)!} Ck1+dk1=(d)!(k1)!(k1+d)!
因此即使是阶数上的微小变化,也会显著增加我们模型的复杂性。仅仅通过简单的限制特征数量,可能仍然使模型在过简单和过复杂中徘徊。我们需要一个更细粒度的工具来调整函数的复杂性,使其达到一个合适的平衡位置。
在之前已经描述了L2范数和L1范数。
在训练参数化机器学习模型时,权重衰减是最广泛使用的正则化的技术之一,它通常被称为L2正则化。这项技术通过函数与0的距离来衡量函数的复杂度,因为所有的函数f中,f=0在某种意义上是最简单的。但是衡量函数f与0的距离并不简单,这也没有一个正确的答案。
一种简单的方法是通过线性函数f(x)=wTx中的某个向量的范数来度量其复杂性,例如||w||2。要保证权重向量比较小,最常用方法是将其范数作为惩罚项加到最小化损失的问题中。将原来的训练目标最小化训练标签上的预测损失,调整为最小化预测损失和惩罚项之和。如果我们的权重向量增长的太大,我们的学习算法可能更集中于最小化权重范数||w||2。回归线性回归,我们的损失由下式给出:
L ( w , b ) = 1 n ∑ i = 1 n 1 2 ( w T x ( i ) + b − y ( i ) ) 2 L(w,b)=\frac{1}{n}\sum_{i=1}^n\frac{1}{2}(w^Tx^{(i)}+b-y^{(i)})^2 L(w,b)=n1i=1n21(wTx(i)+by(i))2
其中,x(i)是样本i的特征,y(i)是样本i的标签,(w,b)是权重和偏置参数。
为了乘法权重向量的大小,我们现在在损失函数添加||w||2,模型如何平衡这个新的额外乘法的损失?我们通过正则化常数λ来描述这种权衡(这是一个非负超参数,我们使用验证数据拟合):
L ( w , b ) + λ 2 ∣ ∣ w ∣ ∣ 2 L(w,b)+\frac{\lambda}{2}||w||^2 L(w,b)+2λ∣∣w2
对于λ=0,我们恢复了原来的损失函数。对于λ>0,我们限制||w||的大小。这里我们仍然除以2(当我们取一个二次函数的导数时, 2和1/2会抵消)。
对于范数的选择,可以提出两个问题:
1、为什么不选择欧几里得距离?
2、为什么不用L1范数?
对于第1个问题:这样做就是为了通过平方去掉L2范数的平方根,留下权重向量每个分量的平方和,这样就很好进行求导了(此时导数的和就等于和的导数)
对于第2个问题:L2范数比起L1范数,对权重向量的大分量施加了巨大的惩罚,在这里还是L2更适合。
那么L2正则化回归的小批量随机梯度下降更新如下式:
w ← ( 1 − η λ ) w − η ∣ B ∣ ∑ i ∈ B x ( i ) ( w T x ( i ) + b − y ( i ) ) w←(1-ηλ)w-\frac{η}{|B|}\sum_{i∈B}x^{(i)}(w^Tx^{(i)}+b-y^{(i)}) w(1ηλ)wBηiBx(i)(wTx(i)+by(i))
为啥是这个结果可以看后面的推导,这个结论说明:我们根据估计值和观测值之间的差距来更新w,同时也在试图缩小w的大小,这就叫权重衰减(或权重衰退)。
权重衰减为我们提供了一种连续的机制来调整函数复杂度,较小的λ值对应较少约束的w,较大的λ值对w的约束会更大。

权重衰减

使用均方范数作为硬性限制

1、通过限制参数值的选择范围来控制模型容量:
m i n l ( w , b ) 其中 ∣ ∣ w ∣ ∣ 2 ≤ θ min l(w,b)其中||w||^2≤θ minl(w,b)其中∣∣w2θ
2、通常不限制偏移b(其实限制不限制都差不多)
3、更小的θ意味着更强的正则项

使用均方范数作为柔性限制

1、对每个θ,都可以找到λ使得之前的目标函数等价于
m i n l ( w , b ) + λ 2 ∣ ∣ w ∣ ∣ 2 min l(w,b)+\frac{\lambda}{2}||w||^2 minl(w,b)+2λ∣∣w2
2、上式通过拉格朗日乘子就能证明
3、超参数λ控制了正则项的重要程度
λ = 0 :无作用 λ → ∞ : w ∗ → 0 \lambda=0:无作用\\ \lambda→∞:w^*→0 λ=0:无作用λw0

对最优解的影响

一张图片就能看出来:
在这里插入图片描述

参数更新法则

计算梯度:
∂ ∂ w ( l ( w , b ) + λ 2 ∣ ∣ w ∣ ∣ 2 ) = ∂ l ( w , b ) ∂ w + λ w \frac{\partial}{\partial w}(l(w,b)+\frac{\lambda}{2}||w||^2)=\frac{\partial l(w,b)}{\partial w}+\lambda w w(l(w,b)+2λ∣∣w2)=wl(w,b)+λw
时间t更新参数:
w t + 1 = w t − η ∂ ∂ w 把 ∂ ∂ w 用上式带入,得: w t + 1 = ( 1 − η λ ) w t − η ∂ l ( w t , b t ) ∂ w t w_{t+1}=w_t-η\frac{\partial}{\partial w}\\把\frac{\partial}{\partial w}用上式带入,得:\\w_{t+1}=(1-η\lambda)w_t-η\frac{\partial l(w_t,b_t)}{\partial w_t} wt+1=wtηww用上式带入,得:wt+1=(1ηλ)wtηwtl(wt,bt)
通常ηλ<1,在深度学习中叫作权重衰退
(可以和之前的梯度做比较,会发现也就是在w之前加了个(1-ηλ)的系数,这样就可以做到权重衰退)

总结

1、权重衰退通过L2正则项使得模型参数不会太大,从而控制模型复杂度。
2、正则项权重是控制模型复杂度的超参数。

高维线性回归

我们通过简单例子来演示权重衰减

import torch
from torch import nn
from d2l import torch as d2l

生成一些人工数据集,生成公式如下:
y = 0.05 + ∑ i = 1 d 0.01 x i + σ 其中 σ 符合正态分布 N ( 0 , 0.0 1 2 ) y=0.05+\sum_{i=1}^d0.01x_i+\sigma\\ 其中\sigma符合正态分布N(0,0.01^2) y=0.05+i=1d0.01xi+σ其中σ符合正态分布N(0,0.012)
为了把过拟合体现的更明显,我们的训练集就只有20个(数据越简单越容易过拟合)

n_train, n_test, num_inputs, batch_size = 20, 100, 200, 5
true_w, true_b = torch.ones((num_inputs, 1)) * 0.01, 0.05
train_data = d2l.synthetic_data(true_w, true_b, n_train)
train_iter = d2l.load_array(train_data, batch_size)
test_data = d2l.synthetic_data(true_w, true_b, n_test)
test_iter = d2l.load_array(test_data, batch_size, is_train=False)

从零开始实现

下面从头开始实现权重衰减,只需将L2的平方惩罚添加到原始目标函数值。

初始化模型参数

def init_params():w = torch.normal(0, 1, size=(num_inputs, 1), requires_grad=True)b = torch.zeros(1, requires_grad=True)return [w, b]

定义L2范数乘法

我们这边是在原来的L2基础上加上了平方,从而去除了他的根号。

def l2_penalty(w):return torch.sum(w.pow(2)) / 2

定义训练代码实现

下面将模型与训练数据集进行拟合,并在测试数据集上进行评估。其中线性网络与平方损失是没有变化的,唯一的变化只是现在增加了惩罚项。

def train(lambd):w, b = init_params()# lambda X相当于定义了一个net()函数,不好理解少用net, loss = lambda X: d2l.linreg(X, w, b), d2l.squared_lossnum_epochs, lr = 100, 0.003animator = d2l.Animator(xlabel='epochs', ylabel='loss', yscale='log',xlim=[5, num_epochs], legend=['train', 'test'])for epoch in range(num_epochs):for X, y in train_iter:# 增加L2范数惩罚项# 广播机制使L2_penalty(w)成为一个长度为batch_size的向量l = loss(net(X), y) + lambd * l2_penalty(w)l.sum().backward()d2l.sgd([w, b], lr, batch_size)if (epoch + 1) % 5 == 0:animator.add(epoch + 1, (d2l.evaluate_loss(net, train_iter, loss),d2l.evaluate_loss(net, test_iter, loss)))print('w的L2范数是:', torch.norm(w).item())

忽略正则化直接训练

此时,我们使用lambd=0来禁止权重衰减,运行代码以后,训练误差会减少,但是测试误差却没有减少,说明出现了严重的过拟合。

train(lambd=0)
d2l.plt.show()

运行结果:

w的L2范数是: 13.375638008117676

运行图片:
在这里插入图片描述

使用权重衰减

这里的训练误差增大,但测试误差减小,这正是期望从正则化中得到的效果。

train(lambd=3)
d2l.plt.show()

运行结果:

w的L2范数是: 0.35898885130882263

运行图片:
在这里插入图片描述

简洁实现

由于权重衰减在神经网络优化中很常用,深度学习框架就将权重衰减集成到优化算法中,以便与任何损失函数结合使用。此外,这种集成还有计算上的好处,允许在不增加任何额外的计算开销的情况下向算法中添加权重衰减。由于更新的权重衰减部分仅依赖于每个参数的当前值,因此优化器必须至少接触每个参数一次。
在下面的代码中,我们在实例化优化器时直接通过weight_decay指定weight decay超参数。 默认情况下,PyTorch同时衰减权重和偏移。 这里我们只为权重设置了weight_decay,所以偏置参数b不会衰减。

import torch
from torch import nn
from d2l import torch as d2ln_train, n_test, num_inputs, batch_size = 20, 100, 200, 5
true_w, true_b = torch.ones((num_inputs, 1)) * 0.01, 0.05
train_data = d2l.synthetic_data(true_w, true_b, n_train)
train_iter = d2l.load_array(train_data, batch_size)
test_data = d2l.synthetic_data(true_w, true_b, n_test)
test_iter = d2l.load_array(test_data, batch_size, is_train=False)def train_concise(wd):net = nn.Sequential(nn.Linear(num_inputs, 1))for param in net.parameters():param.data.normal_()loss = nn.MSELoss(reduction='none')num_epochs, lr = 100, 0.003# 偏置参数没有衰减trainer = torch.optim.SGD([{"params": net[0].weight, 'weight_decay': wd},{"params": net[0].bias}], lr=lr)animator = d2l.Animator(xlabel='epochs', ylabel='loss', yscale='log',xlim=[5, num_epochs], legend=['train', 'test'])for epoch in range(num_epochs):for X, y in train_iter:trainer.zero_grad()l = loss(net(X), y)l.mean().backward()trainer.step()if (epoch + 1) % 5 == 0:animator.add(epoch + 1,(d2l.evaluate_loss(net, train_iter, loss),d2l.evaluate_loss(net, test_iter, loss)))print('w的L2范数:', net[0].weight.norm().item())

测试运行:

train_concise(0)
d2l.plt.show()

运行结果:

w的L2范数: 14.566418647766113

运行图片:
在这里插入图片描述
测试运行:

train_concise(3)
d2l.plt.show()

运行结果:

w的L2范数: 0.45850494503974915

运行图片:
在这里插入图片描述
运行后的图和之前的图相同,但是它们运行得更快,更容易实现。对于复杂问题,这一好处将变得更加明显。
后序的内容,在深层网络的所有层上,都会应用权重衰减。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/19673.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue2.0基础

1、概述 Vue(读音/vju/,类似于view)是一套用于构建用户界面的渐进式框架,发布于2014年2月。与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层(也就是可以理解为HTMLCSSJS)&#xff…

使用Idea提交项目到远程仓库

使用Idea提交项目到远程仓库 1.在Idea中打开本地要推送的项目2.创建远程仓库并提交 1.在Idea中打开本地要推送的项目 tips: 首先你得有git工具,没有的话可以参考下面的这篇文章 git与gitee结合使用,提交代码,文件到远程仓库 从导航栏中选择 V…

uC-OS2 V2.93 STM32L476 移植:系统移植篇

前言 上一篇已经 通过 STM32CubeMX 搭建了 NUCLEO-L476RG STM32L476RG 的 裸机工程,并且下载了 uC-OS2 V2.93 的源码,接下来,开始系统移植 开发环境 win10 64位 Keil uVision5,MDK V5.36 uC-OS2 V2.93 开发板:NUC…

安全狗V3.512048版本绕过

安全狗安装 安全狗详细安装、遇见无此服务器解决、在windows中命令提示符中进入查看指定文件夹手动启动Apache_安全狗只支持 glibc_2.14 但是服务器是2.17_黑色地带(崛起)的博客-CSDN博客 安全狗 safedogwzApacheV3.5.exe 右键电脑右下角安全狗图标-->选择插件-->安装…

untiy代码打压缩包,可设置密码

1、简单介绍: 用的是一个插件SharpZipLib,在vs的Nuget下载,也可以去github下载https://github.com/icsharpcode/SharpZipLib 用这个最主要的是因为,这个不用请求windows的文件读写权限,关于这个权限我搞了好久&#…

【设计模式——学习笔记】23种设计模式——命令模式Command(原理讲解+应用场景介绍+案例介绍+Java代码实现)

案例引入 有一套智能家电,其中有照明灯、风扇、冰箱、洗衣机,这些智能家电来自不同的厂家,我们不想针对每一种家电都安装一个手机App来分别控制,希望只要一个app就可以控制全部智能家电要实现一个app控制所有智能家电的需要&…

Jenkins 自动化部署实例讲解,另附安装教程!

【2023】Jenkins入门与安装_jenkins最新版本_丶重明的博客-CSDN博客 也可以结合这个互补看 前言 你平常在做自己的项目时,是否有过部署项目太麻烦的想法?如果你是单体项目,可能没什么感触,但如果你是微服务项目,相…

JVM的组件、自动垃圾回收的工作原理、分代垃圾回收过程、可用的垃圾回收器类型

详细画的图片 https://www.processon.com/diagraming/64c8aa11c07d99075d934311 官方网址 https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html 相关概念 年轻代是所有新对象被分配和老化的地方。当年轻代填满时,这会导致minor …

Rust dyn - 动态分发 trait 对象

dyn - 动态分发 trait 对象 dyn是关键字,用于指示一个类型是动态分发(dynamic dispatch),也就是说,它是通过trait object实现的。这意味着这个类型在编译期间不确定,只有在运行时才能确定。 practice tr…

《Spring Boot源码解读与原理分析》书籍推荐

Spring Boot 1.0.0 早在2014年就已经发布,只不过到了提倡“降本增效”的今天,Spring Boot才引起了越来越多企业的关注。Spring Boot是目前Java EE开发中颇受欢迎的框架之一。依托于底层Spring Framework的基础支撑,以及完善强大的特性设计&am…

设计模式之中介者模式

中介者模式 用一个中介对象来封装一系列的对象交互。中介者使得各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变他们之间的交互。 电脑主板的功能就类似于一个中介者 经典中介者模式UML 例子 经典的中介者模式 package com.tao.Ya…

Excel快捷键F1-F9详解:掌握实用快捷操作,提升工作效率

Excel是广泛应用于办公场景的优质电子表格软件,然而,许多人只是使用鼠标点击菜单和工具栏来完成操作,而忽略了快捷键的威力。在本文中,我们将详解Excel中的F1-F9快捷键,帮助您掌握实用的快捷操作,提升工作效…

leetcode(力扣)剑指 Offer 16. 数值的整数次方 (快速幂)

文章目录 题目描述思路分析完整代码 题目描述 实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。不得使用库函数,同时不需要考虑大数问题。 示例 1: 输入:x 2.00000, n 10 输出:10…

通向架构师的道路之Apache整合Tomcat

一、先从J2EE工程的通用架构说起 这是一个通用的Web即B/S工程的架构,它由: Web Server App Server DB Server 三大部分组成,其中: Web Server 置于企业防火墙外,这个防火墙,大家可以认为是…

c语言(函数)

目录 何为函数 库函数 自定义函数 二分查找数组下标 链式访问 函数的声明 函数定义 递归 正向打印数字 打印字符个数 使用临时变量 递归(不使用临时变量) n的阶乘 一般形式 递归 斐波那契数 递归 正常做法 何为函数 在计算机科学中,子程序是一个…

单片机外部晶振故障后自动切换内部晶振——以STM32为例

单片机外部晶振故障后自动切换内部晶振——以STM32为例 作者日期版本说明Dog Tao2023.08.02V1.0发布初始版本 文章目录 单片机外部晶振故障后自动切换内部晶振——以STM32为例背景外部晶振与内部振荡器STM32F103时钟系统STM32F407时钟系统 代码实现系统时钟设置流程时钟源检测…

spring AOP学习

概念 面向切面编程横向扩展动态代理 相关术语 动态代理 spring在运行期,生成动态代理对象,不需要特殊的编译器 Spring AOP的底层就是通过JDK动态代理或者CGLIb动态代理技术为目标Bean执行横向织入 目标对象实现了接口,spring使用JDK的ja…

Redis 集群 (cluster)

是什么 官网:Redis cluster specification | Redis 由于数据量过大,单个Master复制集难以承担,因此需要对多个复制集进行集群,形成水平扩展每个复制集只负责存储整个数据集的一部分,这就是Redis的集群,其作…

【机器学习】西瓜书习题3.5Python编程实现线性判别分析,并给出西瓜数据集 3.0α上的结果

参考代码 结合自己的理解,添加注释。 代码 导入相关的库 import numpy as np import pandas as pd import matplotlib from matplotlib import pyplot as plt导入数据,进行数据处理和特征工程 得到数据集 D { ( x i , y i ) } i 1 m , y i ∈ { 0 ,…

VR 变电站事故追忆反演——正泰电力携手图扑

VR(Virtual Reality,虚拟现实)技术作为近年来快速发展的一项新技术,具有广泛的应用前景,支持融合人工智能、机器学习、大数据等技术,实现更加智能化、个性化的应用。在电力能源领域,VR 技术在高性能计算机和专有设备支…