机器学习周报(11.11-11.17)
文章目录
摘要
本周主要对前几周学过的知识进行了复习和相关基础知识的查缺补漏,主要包括深度学习的基础知识。以及学习了如何运用爱因斯坦标示法让PyTorch张量变换的代码更容易编写。
Abstract
This week, I mainly reviewed the knowledge I learned in the previous weeks and checked for any gaps in related basic knowledge, including the basics of deep learning. And learned how to use Einstein notation to make the code for PyTorch tensor transformations easier to write.
1 深度学习基本知识
深度学习定义: 一般是指通过训练多层网络结构对未知数据进行分类或回归
深度学习是使用深度神经网络来学习数据的表示和提取特征。这些网络由多个层次组成,每一层都执行特定的数据变换,从而将数据从原始形式转换为更高层次、更抽象的表达。
深度学习分类::有监督学习方法–深度前馈网络、卷积神经网络、循环神经网络等;
无监督学习方法–深度信念网、深度玻尔兹曼机,深度自编码器等。
2 神经网络基础
2.1 神经网络组成
神经网络结构: 每一层神经元接收前一层神经元的输出作为输入,并经过线性转变和非线性变换后产生输出。这些输出再作为下一层神经元的输入,直到最后一层产生模型的最终输出。
人工神经网络(Artificial Neural Networks,简写为ANNS)是一种模仿动物神经网络行为特征,进行分布式并行信息处理的算法数学模型。这种网络依靠系统的复杂程度,通过调整内部大量节点之间相互连接的关系,从而达到处理信息的目的,并具有自学习和自适应的能力。神经网络类型众多,其中最为重要的是多层感知机。为了详细地描述神经网络,我们先从最简单的神经网络说起。
神经网络常用模型结构
其中圆形节点表示一个神经元,方形节点表示一组神经元。
下图包含了大部分常用的模型:
2.2 前向传播和反向传播
神经网络的计算主要有两种:
- 前向传播(foward propagation,FP)作用于每一层的输入,通过逐层计算得到输出结果;
- 反向传播(backward propagation,BP)作用于网络的输出,通过计算梯度由深到浅更新网络参数。
前向传播
假设上一层结点ij,k,…等一些结点与本层的结点w有连接,那么结点w就是通过上一层的i ,j,k,…等结点以及对应的连接权值进行加权和运算,最终结果再加上一个偏置项(图中为了简单省略了),最后在通过一个非线性函数(即激活函数),如ReLu,sigmoid等函数,最后得到的结果就是本层结点w的输出。
最终不断的通过这种方法一层层的运算,得到输出层结果。
反向传播
反向传播阶段,首先计算损失函数对输出层激活值的导数,即损失函数相对于输出层参数的梯度。然后,将这个梯度通过链式法则传播到隐藏层,逐层计算每个权重的梯度。最后,利用这些梯度,通过梯度下降或其他优化算法更新每个权重,使得损失函数在下一次迭代中更小。
3 超参数
超参数: 在机器学习的上下文中,超参数是在开始学习过程之前设置值的参数,而不是通过训练得到的参数数据。通常情况下,需要对超参数进行优化,给学习机选择一组最优超参数,以提高学习的性能和效果。
超参数通常存在于:
- 定义关于模型的更高层次的概念,如复杂性或学习能力。
- 不能直接从标准模型培训过程中的数据中学习,需要预先定义。
- 可以通过设置不同的值,训练不同的模型和选择更好的测试值来决定
超参数具体来讲比如算法中的学习率(learning rate)、梯度下降法迭代的数量(iterations)、隐藏层数目(hidden layers)、隐藏层单元数目、激活函数(activation function)都需要根据实际情况来设置,这些数字实际上控制了最后的参数和的值,所以它们被称作超参数。
如何寻找超参数的最优值?
- 猜测和检查:根据经验或直觉,选择参数,一直迭代。
- 网格搜索:让计算机尝试在一定范围内均匀分布的一组值。
- 随机搜索:让计算机随机挑选一组值等
3.2 学习率
学习率通常用符号η表示,决定了在每次参数更新时,模型参数沿着负梯度方向前进的距离,即在优化算法中,学习率控制着每次更新模型参数时,参数沿着梯度方向移动的步长大小。
3.2.1 自适应学习率
- AdaGrad:根据梯度大小自动调节学习率;
- RMSProp:与AdaGrad不同的是,RMSProp可以动态调整梯度的重要程度;
- Adam:在RMSProp的基础上加上动量,是最常用的优化器。
3.2.2 学习率调度
- 学习率退火(衰减):η 随时间逐渐减少;
- 预热: η \eta η先变大后逐渐减小。因为统计的结果需要足够多的数据才精准,一开始统计结果 σ 是不精准的。所以开始学习率比较小是用来探索收集一些有关误差表面的情报,此时 η \eta η较大,更利于收集有关 σ 的统计数据,等 σ 统计得比较精准以后,再让学习率慢慢爬升,同时 η \eta η开始减小。
4 归一化
4.1.1批量归一化
批量归一化(BN)是一种正则化技术,它通过对每一层的输入进行归一化处理,使得每一层的输入分布相对稳定,从而加速网络的收敛速度,提高模型的泛化性能。批量归一化能够减少内部协变量偏移,即训练过程中由于数据分布变化而导致的网络参数更新不稳定的问题。此外,批量归一化还可以减少模型的过拟合风险,因为它降低了网络对训练数据中微小变化的敏感性。
4.1.2 特征归一化
在数据预处理阶段,对整个数据集的所有特征进行预处理。将不同特征的数据范围缩放到相同的尺度上,以便模型公平的评估每一个特征的重要性。
5 激活函数
激活函数(Activation functions)对于人工神经网络模型去学习、理解非常复杂和非线性的函数来说具有十分重要的作用。它们将非线性特性引入到我们的网络中。如下图,在神经元中,输入的 inputs 通过加权,求和后,还被作用了一个函数,这个函数就是激活函数。引入激活函数是为了增加神经网络模型的非线性。没有激活函数的每层都相当于矩阵相乘。就算你叠加了若干层之后,无非还是个短阵相乘。
为什么要使用激活函数?
- 激活函数对模型学习、理解非常复杂和非线性的函数具有重要作用。
- 激活函数可以引入非线性因素。如果不使用激活函数,则输出信号仅是一个简单的线性函数。线性函数一个一级多项式,线性方程的复杂度有限,从数据中学习复杂函数映射的能力很小。没有激活函数,神经网络将无法学习和模拟其他复杂类型的数据,例如图像、视频、音频、语音等。
- 激活函数可以把当前特征空间通过一定的线性映射转换到另一个空间,让数据能够更好的被分
为什么激活函数需要非线性函数?
- 假若网络中全部是线性部件,那么线性的组合还是线性,与单独一个线性分类器无异。这样就做不到用非线性来逼近任意函数。
- 使用非线性激活函数 ,以便使网络更加强大,增加它的能力,使它可以学习复杂的事物,复杂的表单数据,以及表示输入输出之间非线性的复杂的任意函数映射。使用非线性激活函数,能够从输入输出之间生成非线性映射。
常见激活函数
-
Sigmoid函数
特点:将任意实值压缩到0和1之间,常用于二分类问题的输出层。但因其梯度消失问题(当输入值非常大或非常小时,梯度接近0),在深度网络中较少使用。 -
Tanh函数
特点:将任意实值压缩到-1和1之间,输出以0为中心,有助于加快收敛速度。但它同样存在梯度消失问题。 -
ReLU函数
特点:当输入为正时,输出等于输入;当输入为负时,输出为0。ReLU解决了梯度消失问题(在输入为正时),计算简单且高效,是目前最常用的激活函数之一。然而,它可能导致“神经元死亡”问题,即某些神经元可能永远不会被激活。 -
Leak ReLU函数
特点:旨在解决ReLU的“神经元死亡”问题,通过允许小的负梯度通过,保持神经元在训练过程中的活性。 -
PReLU函数
特点:增加了模型的灵活性,允许网络自动调整负输入部分的斜率。 -
ELU函数
特点:结合了ReLU和Sigmoid的优点,对于负输入值,输出逐渐趋近于0但不等于0,有助于缓解梯度消失问题,并有助于捕获负值的输入信息。 -
Softmax函数
特点:常用于多分类问题的输出层,将输出转换为概率分布,每个类别的输出值在0和1之间,且所有类别的输出值之和为1。
6 爱因斯坦标示法与PyTorch联合
运用爱因斯坦标示法让PyTorch张量变换的代码更容易编写
代码:
import torch
from einops import rearrange, reduce, repeat
x = torch.randn(2, 3, 4, 5) # 4D tensor: bs*ic*h*w
# 1.转置
# 例:交换第1、2维
out1 = x.transpose(1, 2)
out2 = rearrange(x, 'b i h w -> b h i w') # 字母任意,也可以是abcd->acbd
flag = torch.allclose(out1, out2) # 验证两个tensor是否按元素相等
print(flag) # True
# 2.变形
out1 = x.view(-1, x.shape[-2], x.shape[-1]) # x.reshape(6, 4, 5)
out2 = rearrange(x, 'b i h w -> (b i) h w') # 例:将前两维合并成1个维度,四维变三维
out3 = rearrange(out2, '(b i) h w -> b i h w', b=2) # 三维变四维,指定b=2,不然不知道是1*6或2*3或3*2或6*1
flag = torch.allclose(out1, out2)
print(flag) # True
flag = torch.allclose(x, out3)
print(flag) # True
# 3.image2patch
x = torch.randn(2, 3, 6, 6)
out1 = rearrange(x, 'b i (h1 p1) (w1 p2) -> b (h1 w1) (p1 p2 i)', p1=3, p2=3) # p1,p2是patch的高度和宽度,不能统一成p,会报错
# 下面两句与上面一句相同
out1 = rearrange(x, 'b i (h1 p1) (w1 p2) -> b i (h1 w1) (p1 p2)', p1=3, p2=3) # [2,3,4,9]
out2 = rearrange(out1, 'b i n a -> b n (i a)') # [2,4,27]
print(out2.shape) # [batch_size, num_patches, patch_depth]
# 4.求平均池化等
out1 = reduce(x, 'b i h w -> b i h', reduction='mean') # 对最后一维进行平均池化
out2 = reduce(x, 'b i h w -> b i h 1', 'sum') # 对最后一维求和,并保持维度不变
out3 = reduce(x, 'b i h w -> b i', 'max') # 对 h 和 w 维进行最大池化
print(out1.shape) # [2,3,6]
print(out2.shape) # [2,3,6,1]
print(out3.shape) # [2,3]
# 5.堆叠张量
tensor_list = [x, x, x]
out1 = rearrange(tensor_list, 'n b i h w -> n b i h w')
print(out1.shape) # torch.Size([3, 2, 3, 6, 6]) 列表在第0维堆叠成张量
# 6.扩维
out1 = rearrange(x, 'b i h w -> b i h w 1') # 类似于 torch.unsqueeze
print(out1.shape) # [2, 3, 6, 6, 1]
# 7.复制
out2 = repeat(out1, 'b i h w 1 -> b i h w 2') # 类似于 torch.tile
print(out2.shape) # [2, 3, 6, 6, 2]
out3 = repeat(x, 'b i h w -> b i (2 h) (2 w)')
print(out3.shape) # [2, 3, 12, 12]
注意:有的是用repeat,有的是rearrange,有的是reduce,注意分辨。
总结
在进行后续相关知识的学习中,发现前面的基础知识有缺漏,进行了简单的复习和查缺补漏确保后续学习的顺利进行。
原文地址:https://blog.csdn.net/weixin_51923997/article/details/143821617
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!