- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
随机变量(random variable)是可以随机地取不同值的变量。随机变量可以是离散的或者连续的。简单起见,本文用大写字母 \(X\) 表示随机变量,小写字母 \(x\) 表示随机变量能够取到的值。例如, \(x_1\) 和 \(x_2\) 都是随机变量 \(X\) 可能的取值。随机变量必须伴随着一个概率分布来指定每个状态的可能性.
概率分布(probability distribution)用来描述随机变量或一簇随机变量在每一个可能取到的状态的可能性大小。我们描述概率分布的方式取决于随机变量是离散的还是连续的.
当我们研究的对象是连续型随机变量时,我们用 概率密度函数 (probability density function, PDF )而不是概率质量函数来描述它的概率分布.
更多内容请阅读《花书》第三章-概率与信息论,或者我的文章- 深度学习数学基础-概率与信息论 .
当我们不知道数据真实分布时使用正态分布的原因之一是,正态分布拥有最大的熵,我们通过这个假设来施加尽可能少的结构.
实数上最常用的分布就是正态分布(normal distribution),也称为高斯分布 (Gaussian distribution).
如果随机变量 \(X\) ,服从位置参数为 \(\mu\) 、尺度参数为 \(\sigma\) 的概率分布,且其概率密度函数为
则这个随机变量就称为正态随机变量,正态随机变量服从的概率分布就称 为正态分布 ,记作:
如果位置参数 \(\mu = 0\) ,尺度参数 \(\sigma = 1\) 时,则称为标准正态分布,记作:
此时,概率密度函数公式简化为
正太分布的数学期望值或期望值 \(\mu\) 等于位置参数,决定了分布的位置;其方差 \(\sigma^2\) 的开平方或标准差 \(\sigma\) 等于尺度参数,决定了分布的幅度。正太分布的概率密度函数曲线呈钟形,常称之为 钟形曲线 ,如下图所示
可认为构造正太分布函数,也可通过 np.random.normal 函数生成指定均值和标准差的正态分布随机数,然后基于 matplotlib + seaborn 库 kdeplot 函数绘制概率密度曲线。示例代码如下所示:
import seaborn as sns
x1 = np.random.normal(0, 1, 100)
x2 = np.random.normal(0, 1.5, 100)
x3 = np.random.normal(2, 1.5, 100)
plt.figure(dpi = 200)
sns.kdeplot(x1, label="μ=0, σ=1")
sns.kdeplot(x2, label="μ=0, σ=1.5")
sns.kdeplot(x3, label="μ=2, σ=2.5")
#显示图例
plt.legend()
#添加标题
plt.title("Normal distribution")
plt.show()
以上代码直接运行后,输出结果如下图:
当然也可以自己实现正太分布的概率密度函数,代码和程序输出结果如下
import numpy as np
import matplotlib.pyplot as plt
plt.figure(dpi = 200)
plt.style.use('seaborn-darkgrid') # 主题设置
def nd_func(x, sigma, mu):
"""自定义实现正太分布的概率密度函数
"""
a = - (x-mu)**2 / (2*sigma*sigma)
f = np.exp(a) / (sigma * np.sqrt(2*np.pi))
return f
if __name__ == '__main__':
x = np.linspace(-5, 5)
f = nd_fun(x, 1, 0)
p1, = plt.plot(x, f)
f = nd_fun(x, 1.5, 0)
p2, = plt.plot(x, f)
f = nd_fun(x, 1.5, 2)
p3, = plt.plot(x, f)
plt.legend([p1 ,p2, p3], ["μ=0,σ=1", "μ=0,σ=1.5", "μ=2,σ=1.5"])
plt.show()
训练深度神经网络的复杂性在于,因为前面的层的参数会发生变化导致每层输入的分布在训练过程中会发生变化。这又导致模型需要需要较低的学习率和非常谨慎的参数初始化策略,从而减慢了训练速度,并且具有饱和非线性的模型训练起来也非常困难.
网络层输入数据分布发生变化的这种现象称为内部协变量转移,BN 就是来解决这个问题.
在深度神经网络训练的过程中,由于网络中参数变化而引起网络中间层数据分布发生变化的这一过程被称在论文中称之为 内部协变量偏移 (Internal Covariate Shift).
那么,为什么网络中间层数据分布会发生变化呢?
在深度神经网络中,我们可以将每一层视为对输入的信号做了一次变换(暂时不考虑激活,因为激活函数不会改变输入数据的分布):
其中 \(W\) 和 \(B\) 是模型学习的参数,这个公式涵盖了全连接层和卷积层.
随着 SGD 算法更新参数,和网络的每一层的输入数据经过公式5的运算后,其 \(Z\) 的 分布一直在变化 ,因此网络的每一层都需要不断适应新的分布,这一过程就被叫做 Internal Covariate Shift.
而深度神经网络训练的复杂性在于每层的输入受到前面所有层的参数的影响—因此当网络变得更深时,网络参数的微小变化就会被放大.
网络层需要不断适应新的分布, 导致网络学习速度的降低 .
网络层输入数据容易陷入到非线性的饱和状态并 减慢网络收敛 ,这个影响随着网络深度的增加而放大.
随着网络层的加深,后面网络输入 \(x\) 越来越大,而如果我们又采用 Sigmoid 型激活函数,那么每层的输入很容易移动到非线性饱和区域,此时梯度会变得很小甚至接近于 \(0\) ,导致参数的更新速度就会减慢,进而又会放慢网络的收敛速度.
饱和问题和由此产生的梯度消失通常通过使用修正线性单元激活(ReLU(x)=max(x,0)$),更好的参数初始化方法和小的学习率来解决。然而,如果我们能保证非线性输入的分布在网络训练时保持更稳定,那么优化器将不太可能陷入饱和状态,进而训练也将加速.
白化(Whitening) : 即输入线性变换为具有零均值和单位方差,并去相关.
白化过程由于改变了网络每一层的分布 ,因而改变了网络层中本身数据的表达能力。底层网络学习到的参数信息会被白化操作丢失掉,而且白化计算成本也高.
标准化(normalization) 。
Normalization 操作虽然缓解了 ICS 问题,让每一层网络的输入数据分布都变得稳定,但却导致了数据表达能力的缺失.
论文中给出的 Batch Normalizing Transform 算法计算过程如下图所示。其中输入是一个考虑一个大小为 \(m\) 的小批量数据 \(\cal B\) .
论文中的公式不太清晰,下面我给出更为清晰的 Batch Normalizing Transform 算法计算过程.
设 \(m\) 表示 batch_size 的大小, \(n\) 表示 features 数量,即样本特征值数量。在训练过程中,针对每一个 batch 数据, BN 过程进行的操作是,将这组数据 normalization ,之后对其进行线性变换,具体算法步骤如下
以上公式乘法都为元素乘,即 element wise 的乘法。其中,参数 \(\gamma,\beta\) 是训练出来的, \(\epsilon\) 是为零防止 \(\sigma_B^2\) 为 \(0\) ,加的一个很小的数值,通常为 1e-5 。公式各个符号解释如下
符号 | 数据类型 | 数据形状 |
---|---|---|
\(X\) | 输入数据矩阵 | [m, n] |
\(x_i\) | 输入数据第i个样本 | [1, n] |
\(N\) | 经过归一化的数据矩阵 | [m, n] |
\(n_i\) | 经过归一化的单样本 | [1, n] |
\(\mu_B\) | 批数据均值 | [1, n] |
\(\sigma^2_B\) | 批数据方差 | [1, n] |
\(m\) | 批样本数量 | [1] |
\(\gamma\) | 线性变换参数 | [1, n] |
\(\beta\) | 线性变换参数 | [1, n] |
\(Z\) | 线性变换后的矩阵 | [1, n] |
\(z_i\) | 线性变换后的单样本 | [1, n] |
\(\delta\) | 反向传入的误差 | [m, n] |
其中:
可以看出 BN 本质上是做线性变换.
在论文中,训练一个带 BN 层的网络, BN 算法步骤如下图所示
在训练期间,我们一次向网络提供一小批数据。在前向传播过程中,网络的每一层都处理该小批量数据。 BN 网络层按如下方式执行前向传播计算:
图片来源 这里 .
注意,图中计算均值与方差的无偏估计方法是吴恩达在 Coursera 上的 Deep Learning 课程上提出的方法:对 train 阶段每个 batch 计算的 mean/variance 采用 指数加权平均 来得到 test 阶段 mean/variance 的估计.
在训练期间,它只是计算此 EMA,但不对其执行任何操作。在训练结束时,它只是将该值保存为层状态的一部分,以供在推理阶段使用.
如下图可以展示BN 层的前向传播计算过程数据的 shape ,红色框出来的单个样本都指代单个矩阵,即运算都是在单个矩阵运算中计算的.
图片来源 这里 .
BN 的反向传播过程中,会更新 BN 层中的所有 \(\beta\) 和 \(\gamma\) 参数.
批量归一化(batch normalization)的“批量”两个字,表示在模型的迭代训练过程中,BN 首先计算小批量( mini-batch,如 32)的均值和方差。但是,在推理过程中,我们只有一个样本,而不是一个小批量。在这种情况下,我们该如何获得均值和方差呢?
第一种方法是,使用的均值和方差数据是在训练过程中样本值的平均,即:
这种做法会把所有训练批次的 \(\mu\) 和 \(\sigma\) 都保存下来,然后在最后训练完成时(或做测试时)做下平均.
第二种方法是使用类似动量的方法,训练时,加权平均每个批次的值,权值 \(\alpha\) 可以为0.9:
推理或测试时,直接使用模型文件中保存的 \(\mu_{mov_{i}}\) 和 \(\sigma_{mov_{i}}\) 的值即可.
BN 在 ImageNet 分类数据集上实验结果是 SOTA 的,如下表所示
BN 使得网络中每层输入数据的分布相对稳定,加速模型训练和收敛速度 .
批标准化可以提高学习率 。在传统的深度网络中,学习率过高可能会导致梯度爆炸或梯度消失,以及陷入差的局部最小值。批标准化有助于解决这些问题。通过标准化整个网络的激活值,它可以防止层参数的微小变化随着数据在深度网络中的传播而放大。例如,这使 sigmoid 非线性更容易保持在它们的非饱和状态,这对训练深度 sigmoid 网络至关重要,但在传统上很难实现.
BN 允许网络使用饱和非线性激活函数(如 sigmoid,tanh 等)进行训练,其能缓解梯度消失问题 .
不需要 dropout 和 LRN (Local Response Normalization)层来实现正则化。批标准化提供了类似丢弃的正则化收益,因为通过实验可以观察到训练样本的激活受到同一小批量样例随机选择的影响.
减少对参数初始化方法的依赖 .
最后此篇关于神经网络基础部件-BN层详解的文章就讲到这里了,如果你想了解更多关于神经网络基础部件-BN层详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
全称“Java Virtual Machine statistics monitoring tool”(statistics 统计;monitoring 监控;tool 工具) 用于监控虚拟机的各种运
主要是讲下Mongodb的索引的查看、创建、删除、类型说明,还有就是Explain执行计划的解释说明。 可以转载,但请注明出处。  
1>单线程或者单进程 相当于短链接,当accept之后,就开始数据的接收和数据的发送,不接受新的连接,即一个server,一个client 不存在并发。 2>循环服务器和并发服务器
详解 linux中的关机和重启命令 一 shutdown命令 shutdown [选项] 时间 选项: ?
首先,将json串转为一个JObject对象: ? 1
matplotlib官网 matplotlib库默认英文字体 添加黑体(‘SimHei')为绘图字体 代码: plt.rcParams['font.sans-serif']=['SimHei'
在并发编程中,synchronized关键字是常出现的角色。之前我们都称呼synchronized关键字为重量锁,但是在jdk1.6中对synchronized进行了优化,引入了偏向锁、轻量锁。本篇
一般我们的项目中会使用1到2个数据库连接配置,同程艺龙的数据库连接配置被收拢到统一的配置中心,由DBA统一配置和维护,业务方通过某个字符串配置拿到的是Connection对象。  
实例如下: ? 1
1. MemoryCahe NetCore中的缓存和System.Runtime.Caching很相似,但是在功能上做了增强,缓存的key支持object类型;提供了泛型支持;可以读缓存和单个缓存
argument是javascript中函数的一个特殊参数,例如下文,利用argument访问函数参数,判断函数是否执行 复制代码 代码如下: <script
一不小心装了一个Redis服务,开了一个全网的默认端口,一开始以为这台服务器没有公网ip,结果发现之后悔之莫及啊 某天发现cpu load高的出奇,发现一个minerd进程 占了大量cpu,googl
今天写这个是为了 提醒自己 编程过程 不仅要有逻辑 思想 还有要规范 代码 这样可读性 1、PHP 编程规范与编码习惯最主要的有以下几点: 1 文件说明 2 funct
摘要:虚拟机安装时一般都采用最小化安装,默认没有lspci工具。一台测试虚拟网卡性能的虚拟机,需要lspci工具来查看网卡的类型。本文描述了在一个虚拟机中安装lspci工具的具体步骤。 由于要测试
1、修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统
目录 算术运算符 基本四则运算符 增量赋值运算符 自增/自减运算符 关系运算符 逻
如下所示: ? 1
MapperScannerConfigurer之sqlSessionFactory注入方式讲解 首先,Mybatis中的有一段配置非常方便,省去我们去写DaoImpl(Dao层实现类)的时间,这个
Linux的网络虚拟化是LXC项目中的一个子项目,LXC包括文件系统虚拟化,进程空间虚拟化,用户虚拟化,网络虚拟化,等等,这里使用LXC的网络虚拟化来模拟多个网络环境。 本文从基本的网络设备讲
? 1
我是一名优秀的程序员,十分优秀!