大白话5分钟带你走进人工智能-第十节梯度下降之归一化的各种方式和必要性(5)

本文主要是介绍大白话5分钟带你走进人工智能-第十节梯度下降之归一化的各种方式和必要性(5),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

                                            第十节梯度下降之归一化的各种方式和必要性(5)

上一节中我们讲解了梯度下降的函数最优化算法和梯度下降代码过程,了解了梯度下降的代码实现过程,本节的话我们讲解一个梯度下降之前必要的数据准备,归一化。

先看一个例子,假如你收集到一个数据集,一列是年龄,一列是身高(厘米)。比如体重的数据都是60,65。身高的数据是180,185,你发现它的量纲远远大于age,这样会导致什么?比如身高是W2,体重是W1,假如要根据这些数据预测寿命,比如结果是这样的:

 

体重身高预测年龄
6018070
6518580

因为最后它们相乘相加等于你预测的年龄,那么对数据本身来说量纲比较小的数字,它会乘的W比较大一些。因为体重乘上比较小的数字w1+身高乘以比较大的数字w2,才能等于最后的年龄。这么想好像没什么问题,相当于程序给我们把数据自动修正了,身高数据大,我就自动W小点,预测也不会出问题,虽然看起来没问题,但它在梯度下降的效率上会导致一定的问题。会导致一个什么问题呢? 比如W2小,它越小,是不是越灵敏相当,那么W2动一点就会怎么样?我们先看下上面数据训练模型时如果不做归一化的损失函数的等高线如图:

等高线里面,每一个圆的损失函数是一样的。在这个例子里面,你觉得θ1(即w1)和θ2(即w2),谁是age谁是height?实际上θ2是height,θ1是age,为什么?因为W2是不是小,你动一点点,损失函数会变化的很多,所以图中θ2一点点变化,损失函数就会从一个圆变到另一个圆,所以θ2对应着身高前面的参数。那么这会导致什么问题?我们看下图中的θ1(即w1)和θ2(即w2)的更新参数:

                                                                \theta=\theta-\alpha \cdot \frac{\partial J(\theta)}{\partial(\theta)}

                                                               \frac{\partial J(\theta)}{\theta_{j}}=(h_\theta(x)-y)x_{j}

无论对于W1来说还是W2来说,(h_\theta(x)-y)x_{j}前边部分有区别吗? 没区别吧?那么体现在更新W1和W2的更新的不同,是Xj不同。在θ2的方向上,因为X2比较大,所以θ2方向每次加的都很大,而θ1方向每次加的又比较小,假如最开始在初始点那块,θ2距离自己的终点也就是最后的最优解的点其实很近,而θ1距离自己的终点很远,按理说θ1应该赶紧紧跑两步对不对?而现在变成了θ2在反复的震荡,而θ1在不着急得一步一步走,这样的话会导致你的计算效率变得特别慢。梯度下降的过程中,你想让W2是不是每一步更新更加细致一点,更微小一点,更精准一点,让W1每一步更大刀阔斧一点?所以如果量纲不一致,会导致本来需要一步一步慢慢走的这个维度W2,反倒震荡的特别厉害。W1想让它变化快一点,但X1比较小,会导致它下降的速度反倒慢了,适得其反。讲到这里,有的人会说我调控每一步下降的\theta=\theta-\alpha \cdot \frac{\partial J(\theta)}{\partial(\theta)}中的α,也就是我们的λ,是不是可以控制下每次减的幅度?这里想让大家想一个问题,λ是只有一个数还是说每个维度各有一个λ?如果每个维度各有一个λ就没这问题了,你自己单独的给它们调一下就行了,但是调参又变得复杂了,你有一千个维度,难道你还要手工设一千个λ,还要细致地调吗?不现实。这数根源就是因为只有一个λ管着我所有的W,那么需要大的反倒小了,小的反倒大了。 所以我们怎么办?

我们就需要对数据进行一个归一化。比如我原来原始数据身高是180,170,160,150,我做一个最大最小值归一化,最大最小值归一化公式是:

                                                       x^{\prime}=\frac{x-\min (x)}{\max (x)-\min (x)}

我用X减去最小的X,除以(最大的X,减去最小的X),假设这四个数,180,170,160,150。那么此时180会变成什么?你们根据这算一下。180变成1了,150变成什么了?0了,中间是0到1的一些数相当于就把所有列,如果你都执行这么一遍的话,是不是就变成了所有数都在0到1之间了。这样他们的量纲就一样了。这样我们的损失函数就会从一个椭圆特别椭的圆变成一个比较圆的圆。如下面一样:

因为各个维度的数值通过最大最小值归一化之后会让它两边的步伐速度是一致的,不会存在谁等谁的情况,所以损失函数等高线的图就近似一个相对比较圆的圆。这样会带来更快的收敛步数和更快的收敛速度。除此之外,归一化还有什么好处?对one-hot编码来说,有的维度转变成one-hot编码,比如性别转成one-hot之后男的是0-1 女的是1-0两个维度标识性别,这样相对公平,不至于男的性别是1 ,女的性别是0,这样会给机器学习一种错误的输入,男的比女的大的错误信息,因此需要转成one-hot编码。但假如有的没转成one-hot编码,比如身高,没转one_hot编码的这些维度如果经过最大最小值归一化都给它缩放到零和一之间后,这样跟经过one-hot编码的那些维度的量纲也都一致了,在训练模型的时候,经过处理过的训练集就是一堆你看不懂的数了,比如身高它就不再代表实际物理意义上的高度有多高了,但它是一个高度的评分,越近越1越代表你在这里边越高。例如170和160,经过最大值最小值归一化之后,肯定170更接近数值1。

那么当预测一条新数据的时候,怎么预测? 你还能把原始数据直接丢进去算吗?你是不是需要对新的数据要做最大最小值归一化,用谁的最大值?谁的最小值?用你的训练集中的最大值和训练集中的最小值做归一化,我们称它为经验最大值和经验最小值。好在这些事情不需要你来手工处理,只要你把normalize=true,就可以了。

                      lin_reg = LinearRegression(normalize=True)

这一切的一切底层就帮你做好了。它做的不光是最大最小值归一化,它还要做零均值化,它要把每一个X都减去这一列的平均值。为什么要这么做?比如看下面的例子:

假如你随机到图中这个点了,再接着往下,θ1需要增大减小?增大,对吧?θ2需要增大还是减小?减小。所以θ1需要增大,θ2需要减小,但θ1和θ2怎么算的?咱们看随机梯度下降,对于θ1也好,θ2也好,(h_\theta(x)-y)x_{j}(h_\theta(x)-y)这一项都一样,能影响它到底增大还是减小,是不是取决于它Xj? 所以对于θ1就把X1带进去,对于θ2就把X2代进去。通常训练集里的数据是不是都是正数?如果你不做零均值化的话,所有X都是正数,是不是所有的θ要增都增要减都减。对于这个例子,要想走到最优解,应该这样走,如图:

如果不去处理归一化的话,这会只能θ1也增θ2也增,第一步θ2先少增一点,尽量等一下θ1,θ1多走点, 甚至走过θ1的最优值,然后,θ1减,θ2也减才能走到最后最优解的那个点,它不具备同时一个参数增另一个参数减的这么一个功能。但假如你对它做一个零均值化,比如第二列X2,1.8米,1.7米,1.6米,1.5米,都减去均值后,这就变成了+1.5,+0.5,-0.5,-1.5,这会X是不是就有正有负了?有正有负了之后,是不是它就有可能进行这种有的增有的减的这种下降?所以说normalize里面至少会同时做最大最小值归一化来保证量纲一样和零均值化让所有的维度数值有大有小,这样才能获得更好的梯度下降效率。 如果你不做这些也能得到最优解,就是人家走10步你可能走15步这么一个概念,它效率更低,做了这个能够帮助你下降的更快,更好的找到这个结果。那么来一条新数据,是不是也得减去平均值,减谁的平均值?减你训练集里边的算出来平均值,能理解吗?这个也叫经验平均值。 经验平均值这个东西在深度学习里面一样要这么处理。只要用到梯度下降,就都需要这么处理。只要有梯度下降,均值归一化是必须的,没有均值归一化的话,它下降速率一定会慢好多,因为它老要走曲折的弯路。

对于有些算法,还会使用方差均值标准化来调整数据使模型训练拥有更好的性能。即:

                                                                               x^{\prime}=\frac{x-\overline{x}}{\sigma}

所以归一化方式是进行模型训练前的必要步骤,也是数据处理的关键步骤。下面一节我们将手动实现批量梯度下降和随机梯下降的方式,不调sklearn里面的api

这篇关于大白话5分钟带你走进人工智能-第十节梯度下降之归一化的各种方式和必要性(5)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/309479

相关文章

SpringBoot中@Value注入静态变量方式

《SpringBoot中@Value注入静态变量方式》SpringBoot中静态变量无法直接用@Value注入,需通过setter方法,@Value(${})从属性文件获取值,@Value(#{})用... 目录项目场景解决方案注解说明1、@Value("${}")使用示例2、@Value("#{}"php

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

HTTP 与 SpringBoot 参数提交与接收协议方式

《HTTP与SpringBoot参数提交与接收协议方式》HTTP参数提交方式包括URL查询、表单、JSON/XML、路径变量、头部、Cookie、GraphQL、WebSocket和SSE,依据... 目录HTTP 协议支持多种参数提交方式,主要取决于请求方法(Method)和内容类型(Content-Ty

使用shardingsphere实现mysql数据库分片方式

《使用shardingsphere实现mysql数据库分片方式》本文介绍如何使用ShardingSphere-JDBC在SpringBoot中实现MySQL水平分库,涵盖分片策略、路由算法及零侵入配置... 目录一、ShardingSphere 简介1.1 对比1.2 核心概念1.3 Sharding-Sp

Spring创建Bean的八种主要方式详解

《Spring创建Bean的八种主要方式详解》Spring(尤其是SpringBoot)提供了多种方式来让容器创建和管理Bean,@Component、@Configuration+@Bean、@En... 目录引言一、Spring 创建 Bean 的 8 种主要方式1. @Component 及其衍生注解

python中的显式声明类型参数使用方式

《python中的显式声明类型参数使用方式》文章探讨了Python3.10+版本中类型注解的使用,指出FastAPI官方示例强调显式声明参数类型,通过|操作符替代Union/Optional,可提升代... 目录背景python函数显式声明的类型汇总基本类型集合类型Optional and Union(py

Linux系统管理与进程任务管理方式

《Linux系统管理与进程任务管理方式》本文系统讲解Linux管理核心技能,涵盖引导流程、服务控制(Systemd与GRUB2)、进程管理(前台/后台运行、工具使用)、计划任务(at/cron)及常用... 目录引言一、linux系统引导过程与服务控制1.1 系统引导的五个关键阶段1.2 GRUB2的进化优

IDEA与MyEclipse代码量统计方式

《IDEA与MyEclipse代码量统计方式》文章介绍在项目中不安装第三方工具统计代码行数的方法,分别说明MyEclipse通过正则搜索(排除空行和注释)及IDEA使用Statistic插件或调整搜索... 目录项目场景MyEclipse代码量统计IDEA代码量统计总结项目场景在项目中,有时候我们需要统计

C#和Unity中的中介者模式使用方式

《C#和Unity中的中介者模式使用方式》中介者模式通过中介者封装对象交互,降低耦合度,集中控制逻辑,适用于复杂系统组件交互场景,C#中可用事件、委托或MediatR实现,提升可维护性与灵活性... 目录C#中的中介者模式详解一、中介者模式的基本概念1. 定义2. 组成要素3. 模式结构二、中介者模式的特点