深度学习 1
- 区别
- 传统机器学习:特征工程【找出可能影响结果的那些变量】
- 神经网络:不需要处理原始数据,只要定义一个神经网络模型,然后把数据传输给它,让他自己学习什么特征有用
- 神经网络 – 复杂函数集
- 三要素: 模型,算力,数据
- 三部曲:
- 准备数据
- 定义模型 损失函数 优化器
- 训练~
- 应用
- 计算机视觉
- 自然语言处理
- 智能服务
- pytorch 深度学习框架
- 动态图支持 – 实时查看各个层的变化
- GPU 加速 – 更多计算单元 适合并行计算(CPU,GPU – 一个大学教授,一群小学生)
- 分布式
- 强大的生态系统
- 数学
- 极限
- 导数
- 泰勒公式 – 任何无穷阶可导函数可表现为简单幂函数之和
- 偏导数
- 梯度 – f对所有
xi
偏导数的向量
深度学习2 定义模型,损失函数,优化器
定义模型,损失函数和优化器
-
模型
-
σ ( W x + b ) \sigma(\boldsymbol{W}x+b) σ(Wx+b)
-
其中 σ \sigma σ 是一个非线性函数 ,线性函数的模拟能力很弱,单纯的叠加结果仍然是线性函数,所以需要激活函数,让卷积层的深度更有意义 t a n h tanh tanh , R e L U ReLU ReLU
-
-
损失函数
- 模型输出值和真实值之间的差距
-
优化器
- 更新参数的策略 ,最简单的优化器–随机梯度下降
训练模型
目的 调整模型的参数,使得Loss最小
梯度下降方法 – 求Loss对W和b的梯度,以找到Loss最快下降方向
x
′
=
x
−
η
y
′
(
x
)
x'=x- \eta \ y'(x)
x′=x−η y′(x)
其中
η
\eta
η 为学习率 – 更新步长的正标量
使用pytorch定义神经网络结构
- 自动微分
- 线性模型
torch.nn.Linear(input_size,output_size)
- 权重
linear_layer.weight
;偏置linear_layer.bias
- 在深度学习中,单层的线性模型也被称为全连接层
FC fully connected layers
- 损失函数和优化器
torch.nn.MSELoss()
常用于回归任务 结果是一个值torch.nn.CrossEntroyLoss()
常用于分类任务 结果是一个类别- η \eta η 决定更新的幅度 ,太小会导致训练速度缓慢,太大会导致模型在最低点左右横跳无法收敛-- η \eta η不应该是一个定值,前期取值大可以加速训练,然后随着迭代的次数增加而减小
- 尽量避免模型停留在局部最低 – 人们让参数更新有了惯性,即便梯度为0,也会继续往前滑一段
- 常用的优化器
torch.optim.Adam
自适应学习率优化器 – 学习率通常大torch.optim.SGD
随机梯度优化器 – 学习率通常小optimizer.zero_grad()
清空上一轮梯度 ->loss.backward()
计算梯度 ->optimizer.step()
优化参数
- 超参数
hyper Parameter
- 和需要训练的参数区别
- 学习率 网络各层维度 训练次数
- 构建全连接神经网络
- 定义网络结构 在
__init()__
中定义需要使用的层,在forward()
方法中计算网络输出 - 实例化网络 – 可调用对象
- 调用可调用对象
- 😁 图片的维度 【高,宽,通道】;pytorch要求图片的张量为【通道,高,宽】,需要
torchvision.transforms.ToTensor()
- 网络识别图片中的数字通常不会输出0~9 ,因为0~9只是类别不同,但是数字有大小之分;一般输出一个10维向量,每一维度上的数字表示模型认为是该类别的可能性
_,predicted = torch.max(outputs,1)
torch.max
返回的第一个是最大值 使用无意义变量接收;第二个返回值是最大值所在的位置 使用predicted
接收
- 定义网络结构 在
神经网络调优
- 数据与模型规模匹配
- 数据过少 模型巨大–过拟合
- 数据多 小规模模型 – 欠拟合
- 特征缩放
- 通常表示像素时使用0-255 ,但在深度学习领域常归到 -1-1 或者 0-1 附近,可以明显提高模型的收敛速度
- 归一化 x ′ = x − m i n ( x ) m a x ( x ) − m i n ( x ) x' = \frac{x-min(x)} {max(x)-min(x)} x′=max(x)−min(x)x−min(x)
- 标准化 x ′ = x − x ˉ σ x'=\frac{x-\bar x }{\sigma} x′=σx−xˉ ( x ˉ \bar x xˉ 平均值, σ \sigma σ标准差)
- 数据集
- 如果要标明图片中的物体坐标,则需要增加输出的值,由形式上一维[classIndex] 变成 五维[ClassIndex,x,y,h,w] 。同样采用梯度下降法训练 。这样模型便可以学会图片的物体是什么以及坐标 长宽
- 但事实上 我们不是只改变网络输出层就可以得到我们想要的效果。关键在于我们需要有对应的数据集,模型要学会找到物体的位置,我们的数据中就需要人工标注种类以及位置
深度学习3-- 卷积神经网络 迁移学习 梯度消失
卷积?
卷积神经网络能够大大减少网络的参数量
图像*采样器(卷积核)=
图像与采样器相似程度越高 他们的内积得到的值越大
我们启发得到一种寻找图片上特征的方式 – 让采样器与其进行内积计算
如果图片是一张猫或者狗的图片,采样器为猫的胡子,显然在猫的图片上能在胡子的位置输出一个较大的值表示找到了,并提高模型认为图片是猫的概率
这样的运算被称为卷积运算,受生物学启发。当动物看到不同的物体,大脑的激活区域不同–神经网络中有不同的采样器,负责寻找图像上不同形状的物体
尽管抽样器看起来很小,但神经网络可以叠加多层😀
底层的卷积核 抽取局部,简单的特征 – 直线、曲线、折线
中层的卷积层抽取稍微复杂的特征 – 人脸,汽车轮胎
高层卷积层抽取整体复杂的特征 – 人,车,狗
-
向量内积
-
向量卷积、
C o n v R e s u l t S i z e = S r c S i z e − K e r n e l S i z e + 2 × P a d d i n g S t r i d e + 1 ConvResultSize= \frac{SrcSize-KernelSize+2\times Padding}{Stride} +1 ConvResultSize=StrideSrcSize−KernelSize+2×Padding+1
C o n v R e s u l t S i z e ConvResultSize ConvResultSize 卷积结果尺寸S r c S i z e SrcSize SrcSize 输入尺寸
K e r n e l S i z e KernelSize KernelSize 卷积核尺寸
P a d d i n g Padding Padding填充数
S t r i d e Stride Stride步长
-
矩阵卷积
-
二维卷积
卷积神经网络
往往最后一层输出层为全连接层,其他层是卷积+池化的组合
卷积层
Conv2d
需要传入的参数为输入通道、输出通道 – 采样器个数、采样器的大小、采样器移动步长
填充数 [ ( W − 1 ) ∗ S + F − W ] / 2 [(W-1)*S+F-W]/2 [(W−1)∗S+F−W]/2
池化层
Pooling Layer
或者下采样层 --减少计算量而设计的一种层
- 最大池化层
- 平均池化层
因为卷积和池化通常是同时出现的,可以使用torch.nn.Sequential
将卷积、池化、激活装起来作为一层,调用Sequential
时,这三个层都会被依次执行
流程:
-
设置超参数
-
下载数据集
-
使用
PyTorch
提供的DataLoader
以分批乱序的形式加载数据 -
构建卷积神经网络
将卷积层的结果拉成向量再通过全连接层
-
实例化模型
-
设置损失函数 优化器
-
训练模型
-
检验模型再测试集上的准确性
迁移学习
迁移学习也就是在大规模数据集上对训练得到的预训练模型进行微调,以便能够快速获得能够完成自定义任务的网络方法
PyTorchHub
以及TorchVision
都提供预训练模型
pretrained=True
表示下载预训练参数,否则表示只有网络结构
根据需要替换其中的层
例如替换resnet18
的最后一层使输出的维度为n,完成n分类任务
model = torchvision.models.resnet18(pretrained=True)
model.fc = torch.nn.Linear(512,num_classes)
如果我们收集的数据只有几百张或者几千张,不足以训练大型模型,可以直接下载已经在大数据上训练完成的模型并使用自己搜集的数据集进行微调,实现更快的收敛并完成任务
梯度消失
反向传播导数
W 1 g r a d = W 5 ∗ W 4 ∗ . . . ∗ W 2 ∗ x 1 \bold{W_1}grad=W_5*W_4*...*W_2*x_1 W1grad=W5∗W4∗...∗W2∗x1
也就是传播过程中会有关于 W \bold{W} W的激活函数求导结果连乘 ,随着网络层数增多,这个连乘链变得越来越长,类似指数的缩小,由于 W \bold{W} W是按照标准正态分布初始化,往往在(-1,1)区间连乘结果很快就会接近0
反之,若W初始化过大,就会产生梯度爆炸,也就是梯度快速增长超过计算机可以表示的最大浮点数
解决方式:
残差网络的基本单元一种名为残差块的层,层中提供了捷径
把输入复制一份,然后加在经过各个卷积层的最终结果上面。在反向传播的时候,梯度可以通过捷径传递,缓解梯度消失的问题
目标检测
YOLO
输出 [ v , c 1 , c 2 , x , y , h , w ] [v,c_1,c_2,x,y,h,w] [v,c1,c2,x,y,h,w] v表示图中是否有物体,c1,c2为onehot编码表示种类,x,y,h,w定位位置以及物体宽和高
将图片切分为多个块,每个块内产生一个输出
FasterRCNN
- 找到物体所在区域(自动划区) RPN网络
- 在划出的每个区域上识别物体
相比YOLOv1 将更多的工作交给模型自己学习
可能含有物体的区域被称为候选区域(ROI)
首先需要构造出更可能多的、各种形状的区域Anchor
实用工具
图像处理
- Matplotlib
- PIL
- TorchVision
- OpenCV
- 原则
保存与加载模型
深度学习 4
循环神经网络
RNN是应对序列数据的经典网络 – 有记忆的神经网络
每一时刻的输出
y
<
t
n
>
=
σ
(
W
′
y
<
t
n
−
1
>
+
W
x
<
t
n
>
+
b
)
y^{<t_n>}=\sigma(\bold{W'}y^{<t_n-1>}+\bold{W}x^{<t_n>}+b)
y<tn>=σ(W′y<tn−1>+Wx<tn>+b)
长短期记忆 LSTM
相对RNN,它所共享的神经网络更为复杂,可以应对反复使用网络导致参数指数叠加造成梯度消失的问题
基本结构在普通全连接神经网络上加了3个控制门
- 输入门 Input Gate Z i Z_i Zi是否接收输入信号
- 输出门 Output Gate Z o Z_o Zo是否向外输出信号
- 遗忘门 Forget Gate Z f Z_f Zf是否清除记忆信号
不同之处:4 个输入
Z
,
Z
i
,
Z
o
,
Z
f
Z,Z_i ,Z_o,Z_f
Z,Zi,Zo,Zf ,一个输出y
torch.nn.LSTM()
自然语言处理
WordEmbedding
为了将文字转化为数字,需要对文字进行编码
希望 : 词义相近的编码在向量空间上的距离较近,词义不同的词汇在向量空间相距较远。
method : 能输出编码的神经网络
- 基于计数的WordVector生成
如何表示两向量的相似程度?内积
随机初始化所有词汇的向量,然后让其中任意两个词汇AB之间的内积尽量接近他们在同一文本中的出现次数N(A,B)。使用梯度下降方法优化
W o r d V e c ( A ) ∙ W o r d V e c ( B ) → N ( A , B ) WordVec(A) \bullet WordVec(B ) \to N(A,B) WordVec(A)∙WordVec(B)→N(A,B) - 基于预测的WordVector生成
构造一个神经网络,通过上一个单词预测接下来可能出现的单词,然后将网络的第一层拿出来即为WordEmbedding 层
W ( n − 1 ) W_(n-1) W(n−1) 是上一个单词的One-Hot Encoding(人为设置), p ( W n ) p(W_n) p(Wn)是当前位置所有单词出现的概率(大量统计) ,模型的任务是让自己的输出接近这个 p ( W n ) p(W_n) p(Wn)
Sequence ToSequence Model
处理序列数据比较流行的架构
- 编码层 分析输入序列 Encoder
- 解码器 生成输出序列 Decoder
Transformer
- 编码层 分析输入序列 Encoder
- 解码器 生成输出序列 Decoder
- 😯 Self-Attention Layer ??