深度学习框架
- Caffe
- tensorflow
- 框架是深度学习的库;
- 编程时需要import
应用优势
- 框架的出现降低了入门的门槛;
- 不需要从复杂的神经网络开始编写代码;
- 根据需要,使用已有的模型;
- 模型的参数经过训练得到;
- 可以在已有的模型基础上增加自己的layer;
- 在顶端选择自己的分类器和优化算法;
- 没有框架是完美的;
- 不同的框架适用的领域不完全一致;
- 深度学习框架提供了一系列深度学习的组件;
- 实现了一些通用的算法;
- 新的算法需要用户自己定义;
- 调用函数接口使用用户定义的新算法;
五个核心组件
- 张量(Tensor);
- 基于张量的各种操作(Operation);
- 计算图(Computation Graph)
- 自动微分(Automatic Differentiation)工具;
- BLAS、cuBLAS、cuDNN等拓展包;
张量
- 所有深度学习框架中最核心的组件;
- 后续的所有运算和优化算法都是基于张量的;
- 几何代数中定义的张量是局域向量和矩阵的推广;
- 标量视为零阶张量;
- 矢量视为一阶张量;
- 矩阵视为二阶张量;
- 四阶张量表示一个含多张图片的数据集;
- 四个维度分别为;
- 图片在数据集中的编号:N;
- 图片高度:H;
- 图片宽度:W;
- 色彩数据:C;
张量的优势
- 将各种数据抽象成张量;
- 输入神经网络模型进行后续处理;
- 是一种非常必要且高效的策略;
- 数据处理完成后;
- 将张量转换回想要的格式;
基于张量的操作
- 整个神经网络就是针对张量操作的一系列过程;
- 张量操作包含:矩阵乘法、卷积、池化、LSTM等
基于张量计算的一些问题
- 整合张量操作,输出期望的结果需要考虑一些问题;
- 张量操作的种类和数量繁多,管理可能变得困难;
- 各张量操作之间的关系难以厘清;
- 多个操作的并行和顺序执行的选择;
- 如何协同不同的底层设备;
- 如何避免冗余操作;
计算图
- 计算图的出现是为了解决张量操作的相关问题;
- 计算图作为前后端之间的中间表示:Intermediate Representations;
- 可带来良好的交互性;
- Tensor对象作为数据结构;
- 函数、方法作为操作类型;
- 特定的操作类型应用于特定的数据结构;
- 计算图可以使开发者宏观上俯瞰整个神经网络的内部结构;
- 类似于编译器可以从整个代码的角度决定寄存器分配一样;
- 计算图宏观上可以决定代码运行时GPU的内存分配;
- 分布式环境中不同底层设备间的协作方式;
- 计算图也可用于模型调试;
- 可以实时输出操作类型的文本描述;
自动微分工具
- 计算图让模型训练的梯度计算模块化、自动化--自动微分法;
- 将神经网络视为多非线性过程组成的复杂函数体;
- 计算图模块化的表征了函数体内部的逻辑关系;
- 微分此函数体(求模型梯度)的方法变为在计算图中完整的从输入到输出进行遍历的过程;
拓展包
- 高级语言较低级语言消耗更多的cpu周期;
- 对结构复杂的神经网络,运算缓慢成了一个天然缺陷;
- 低级语言优化编程难度很高;
- 大部分的基础操作有公开的最有解决方案;
- 利用这些现成的解决方案是一个显著的加速手段;
主流深度学习框架
顶级深度学习框架四大阵营
国内深度学习框架
MindSpore
- 厂商:华为
- 特点:
- 支持端、边、云独立的和协同的统一训练和推理框架;
- 2020.03.28日开源
PaddlePaddle
- 厂商:百度
- github100%开源,没有内部版本
- 能够应用于自然语言处理、图像识别、推荐引擎等
- 优势在于开放的多个领先的预训练中文模型;
XDL(X-Deep Learning)
- 厂商:阿里巴巴
- 应用于阿里妈妈的广告业务算法框架是开源的;
- 主要针对广告的深度学习问题的解决;
- 是上层高级API框架;
- 不是底层框架;
- 需要采用桥接方式配合TensorFlow和MXNet作为单节点使用;
- 依赖阿里的特定部署环境
MACE
- 厂商:小米
- 针对移动芯片特性进行大量优化;
- 小米手机广泛应用;
- 主要应用场景为人像模式、场景识别;
- 框架采用类似Caffe2的描述文件定义模型;
- 能方便的部署移动应用;
- 目前该框架是TensorFlow和Caffe的模型转换工具;
- 其他框架定义的模型能够很快的支持。
ONNX
- 开放神经网络交换:ONNX(Open Neural Network Exchange)
- 最初由微软和Facebook联合发布;
- 亚马逊加入后,发布了V1版本;
- 宣布支持ONNX的公司:AMD,ARM,华为,IBM,英特尔,Qualcomm;
- 是一个表示深度学习模型的开放格式;
- 用户可以更轻松的在不同框架之间转移模型;
- 比如用户可以使用PyTorch建立模型,使用MXNet运行该模型
TensorFlow
- 是一个采用数据流图(data flow graphs)进行数值计算的开源软件库;
- 节点(Nodes)在图中表示数学操作;
- 图中的线(edges)表示节点间相互联系的多维数据(张量);
- 架构灵活,开在多平台展开计算;
TensorFlow基本用法
- 使用图(graph)来表示计算任务;
- 在会话(Session)的上下文(context)中执行图;
- 使用Tensor表示数据;
- 通过变量Variable维护状态;
- 使用feed和fetch为任意操作赋值或获取数据;
TensorFlow概述
- 是一个编程系统;
- 使用图来表示计算任务;
- 图中节点表示operation,称为op;
- 一个op获取0个或多个Tensor,计算产生0个或多个Tensor;
- 一个Tensor是一个类型化的多维数组;
- 比如一个小的图像集可以表示为一个思维浮点数组;
- 四个维度分别为:【batch,height,width,channels】;
- TensorFlow按图计算,图必须在会话里被启动;
- 会话将图的op分发到CPU或GPU设备上,同时提供执行op的方法;
- 方法执行后将产生的Tensor返回;
- python语言中返回的tensor是numpy的ndarray对象;
TensorFlow图构建
- 创建源op;
- 源op不需要任何输入,比如常量constant;
- 源op的输出给到其他op进行计算;
- 在Session中启动图;
- 关闭session释放资源。
TensorFlow张量
- 构件图的过程输出的结果是一个Tensor;
- 该Tensor由三个属性构成:Name、shape、type
- Name:表示张量的名称,是张量的唯一标识;
- 可以在每个op上添加name属性对节点命名;
- Name的值表示该张量莱滋第几个输出结果(编号从0开始);
- Shape:表示张量的维度;
- type:表示张量的类型,每个张量具有唯一的类型;
- 运算过程中需要保证张量类型的一致;
TensorFlow常见张量类型
TensorFlow变量
- 变量Variable维护图执行过程中的状态信息;
- 通常将一个统计模型中的参数表示为一组变量;
- 比如,将一个神经网络的权重作为一个变量存储在一个Tensor中;
- 训练过程中,重复运行训练图,不断更新该tensor。
TensorFlow fetch/feed
- Fetch:取回操作的输出内容;
- 使用session对象的run()调用执行图,传入一些tensor;
- 这些tensor帮用户取回结果;
- Feed:使用一个tensor值临时替换一个操作的输出结果;
- 提供feed数据作为run()调用的参数;
- feed只在调用它的方法内有效,方法结束,feed消失;
- 最常见的是将某些特殊的操作指定为feed操作;
- 标记的方法是使用tf.placeholder()为这些操作创建占位符;
Placeholder
- placeholder是一个数据初始化的容器;
- 与变量最大的不同是placeholder定义的是模版;
- 可以在session阶段运行;
- 利用feed_dict字典结构给placeholder填充内容;
- 不需要每次提前定义好变量的值;
- 大大提高了代码的利用率;
TensorBoard
- TensorBoard是TensorFlow内置的一个可视化工具;
- 通过将TensorFlow输出的日志信息可视化;
- 使得对TensorFlow程序的理解、调试、优化更为简单高效;
- TensorBoard的可视化依赖于TensorFlow输出的日志文件;
- tensorflow和TensorBoard在不同的程序中运行;
TensorBoard实例
- 生成一个具有写权限的日志文件对象;
- 将当前命名空间的计算图写进日志文件;
python
writer=tf.summary.FileWriter('logs',tf.get_default_graph())
writer.close()
#启动tensorboard服务(在命令行启动)
tensorboard --logdir logs
#启动tensorboard服务后,复制地址病在本地浏览器中打开
TensorBoard 1.14.0 at Http://Cam-L1E00050:6006/(Press CTRL+C to quit)
TensorFlow版本选择
- TensorFlow版本的兼容性较差;
- 各大公司目前仍较多使用1版本;
- 迁移成本较高;
TensorFlow1
- 静态图
- 需要session run
TensorFlow2
- 动态图
- 不需要session run
TensorFlow2下使用TensorFlow1的代码
python
import tensorflow.compat.v1 as tf
tf.compat.v1.disable_eager_execution()
#或者
tf.disable_v2_behavior()
PyTorch
- Torch的python版本;
- 由Facebook开源的神经网络框架;
- 专门针对GPU加速的深度神经网络(DNN)编程;
- Torch是一个经典的对多维矩阵数据操作的张量库;
- 在机器学习和其他数学密集型应用中应用广泛;
- 具有动态计算图,根据需要实时改变计算图;
- Torch语言采用Lua,国内比较小众;
- 逐渐被支持python的TensorFlow抢走用户;
- PyTorch是经典的机器学习库Torch的端口;
- PyTorch为python语言的使用者提供了舒适的写代码选择;
- PyTorch是基于Python的科学计算包;
- 替代numpy发挥GPU潜能;
- 提供了高度灵活性和效率的深度学习实验平台。
PyTorch的优势
简洁
- 设计追求最少封装,避免重复造轮子;
- 不像TensorFlow具有session、graph、operation、names_scope、variable、tensor、layer等全新的概念;
- 遵循tensor-->variable(autograd)-->nn.Module三个抽象层次;
- 上述三个层次由低到高,代表高维数组(张量)、自动求导(变量)、神经网络(层、模块);
- 上述三者之间联系紧密、可同时修改和操作;
速度
- 灵活性不以速度为代价;
- 速度胜过TensorFlow和Keras等框架
易用
- 面向对象设计的最优雅者;
- 接口设计来源于Torch;
- Torch的接口设计以灵活易用而著称;
- Keras受Torch的启发而开发;
活跃的社区
- 完整的文档
- 循序渐进的指南;
- 作者亲自维护论坛,供用户交流;
- Facebook人工智能研究院提供强力支持
PyTorch常用工具包
- torch:类似Numpy的张量库,支持GPU;
- torch.autograd:基于type的自动区别库,支持Torch中的所有可区分张量;
- torch.nn:追求最大灵活性,与autograd深度整合;
- torch.optim:与torch.nn一起使用的优化包,含SGD\RMSProp\LBFGS\Adam,标准优化方式;
- torch.multiprocessing:python多进程并发,进程之间torch tensor内存共享;
- torch.utils:数据载入器,具有训练器和其他便利功能;
- torch.legacy(.nn/.optim):向后兼容,从Torch移植;
PyTorch特别注意
- OpenCV的默认通道为:H*W*C;
- PyTorch的默认通道为:C*H*W;
- TensorFlow两者都支持;
理解PyTorch
- Numpy风格的Tensor操作;
- Tensor API参考了Numpy的设计;
- 变量自动求导:在计算过程形成的计算图中,变量可方便的计算自己对目标函数的梯度;
- 高层封装神经网络层与函数优化;
- 网络层封装在torch.nn模块中;
- 损失函数由torch.nn.functional模块提供;
- 优化函数由torch.optim模块提供;
PyTorch 张量类型
PyTorch Tensor创建接口
PyTorch Tensor对象方法
PyTorch自动求导
- tensor对象通过一系列运算可以组成动态图
- 每个tensor对象有以下几个求导属性
PyTorch神经网络
- torch.nn模块提供创建网络的基础构件
- 这些层继承自Module类;
- 可训练的层使用module;
- 不需要训练的层比如softmax,可以使用funcational中的函数;
Pytorch较重要的神经网络层组件
- nn.functional模块中提供层的函数实现
PyTorch神经网络构建
- torch.nn.Module提供了神经网络的基类;
- 实现神经网络时要继承此模块;
- 在初始化函数中创建网络要包含的层;
- 实现forward函数完成前向计算;
- 自动求导机制会处理网络的反向计算;
- 将需要训练的层写在init函数中;
- 将不需要训练参数的层在forward方法中调用相应的函数实现层功能
PyTorch神经网络构建步骤
- 写好网络;
- 编写数据的标签和路径索引;
- 将数据送到网络;
PyTorch优化算法
original-loss:
- 整个训练集上的loss
minibatch-loss
- 在一个mini batch上的loss
BGD
- 最原始的梯度下降算法;
- 想计算original-loss,需要使用训练集全部数据;
- 训练数据过大时,BGD可能造成内存不够用,可使用SGD
SGD
- 又称online梯度下降,随机梯度下降;
- 每次估计梯度时,只用一个或几个batch训练样本;
- 近似计算original-loss时,只使用一个mini batch,用minibatch-loss上的梯度近似original-loss的梯度
mini-batch SGD算法特点
- 训练神经网络时;
- 将数据拆解成一小批一小批的进行训练;
- 这是常用的mini-batch SGD训练算法;
- 该算法能够带来很好的训练速度;
- 但并不总能达到最优解,而是在最优解附近徘徊;
- mini-batch SGD算法需要用户提供一个合适的学习率;
- 学习率太小,导致网络训练收敛慢;
- 学习率太大,优化的幅度跳过函数的最优点;
- 理想的网络在优化时损失函数有很好的收敛速度,幅度摆动又不会太大;
Momentum
- 目标是加速学习;
- 对于处理高曲率的梯度,小但一致的梯度,带噪声的梯度时效果较好;
- 累计以往梯度指数衰减移动的均值,且沿该方向继续移动;
- --损失函数在前t-1轮迭代中累计的权重梯度动量;
- --损失函数在前t-1轮迭代中累计的偏置梯度动量;
- --梯度累计的一个指数,一般设置为0.9;
- --网络的学习率
- --损失函数反向传播时计算得到的权重梯度;
- --损失函数反向传播时计算得到的偏置梯度;
- 利用类似于移动指数加权平均的方法来对网络参数进行平滑处理;
- 使得梯度的摆动幅值变得更小;
RMSProp(Root Mean Square Prop)
- 为进一步优化损失函数在参数更新中摆动幅度过大,引入RMSProp算法;
- RMSProp算法对权重w和偏置b的梯度使用微分平方加权平均数;
- t轮迭代的公式如下;
- --损失函数在前t-1轮迭代中累计的权重梯度动量;
- --损失函数在前t-1轮迭代中累计的偏置梯度动量;
- --梯度累计的一个指数,一般设置为0.9;
- --网络的学习率
- --损失函数反向传播时计算得到的权重梯度;
- --损失函数反向传播时计算得到的偏置梯度;
- 该算法对梯度计算了微分平方加权平均数;
- 该方法有利于消除摆动幅度大的方向,修正摆动幅度;
- 使各维度摆动幅度都较小,另一方面,网络收敛更快;
- 防止分母为零,使用很小的数值进行平滑,一般为;
Adam
- Adam(Adapative Moment Estimation)
- 将Momentum算法和RMSProp算法结合使用;
- 参数和以上两者一致;
- 在训练开始时需要初始化梯度的累积量和平方累积量;
- 训练的第t轮,计算得到Momentum和RMSProp的参数更新;
- 移动指数平均在迭代开始初期与初始值的差异较大;
- 需要对上面几个值做偏差修正;
- 通过上述公式可以求得参数梯度累积量的修正值;
- 接下来根据Momentum和RMSProp算法的结合计算权重w和偏置b的参数更新;
- Adam中的与Momentum算法中的一样,一般取值0.9;
- 对应RMSProp算法中的值,一般取值0.999;
- 是一个平滑项,一般取值;
- 需要在训练的时候微调;