深度学习框架发展到今天,目前在架构上大体已经基本上成熟并且逐渐趋同。无论是国外的Tensorflow、PyTorch,亦或是国内最近开源的MegEngine、MindSpore,目前基本上都是支持EagerMode和GraphMode两种模式。
AI嵌入式框架
OneFlow & 清华计图Jittor & 华为深度学习框架MindSpore & 旷视深度学习框架MegEngine(天元) & caffe & Google的TFBOYS & Facebook的Pytorch & XLA
严格意义来说TVM和Jittor都不算深度学习框架,TVM和Jittor更多的是一套独立的深度学习编译器。我们可以将导出的模型文件通过TVM或者Jittor离线编译成一个Serving的模块,从而可以在云上或者端上部署模型的预测服务。
华为 mindspore
清华计图Jittor gt
依赖: sudo apt install python3.7-dev libomp-dev pip3 install pybind11 numpy tqdm pillow astunparse six wheel
pybind11使用问题 https://zhuanlan.zhihu.com/p/52619334
旷视深度学习框架MegEngine gt
模型可视化超好用的工具
使用自动代码生成技术TVM优化深度学习算子的一些思考
基于ARM-v8的Tengine GEMM教程
Caffe 是一个深度学习框架,由 Berkeley Vision and Learning Center (BVLC) 开发。它使用 C++ 编写,并提供了 Python 和 MATLAB 接口。Caffe 的设计目标是为研究和实验提供一个清晰和高效的架构。
在 Caffe 中,模型通常被组织为一系列的层(layers),这些层通过数据流(data blobs)进行连接。每个层都从底部的层(bottom layers)接收输入数据,并产生输出数据,这些数据随后被传递给顶部的层(top layers)。
主要类对象
caffe大致可以分为三层结构blob,layer,net。
数据的保存,交换以及操作都是以blob的形式进行的,
layer是模型和计算的基础,
net整和并连接layer,
solver则是模型的优化求解。
数据Blob 是Caffe的基本数据结构, 4维的数组(Num, Channels, Height, Width)
layer主要定义了三种运算,setup,forward,backward
在Layer内部,数据主要有两种传递方式,正向传导(Forward)和反向传导(Backward)。
Forward和Backward有CPU和GPU(部分有)两种实现。
Caffe中所有的Layer都要用这两种方法传递数据。
Layer类派生出来的层类通过实现这两个虚函数,产生了各式各样功能的层类。
Forward是从根据bottom计算top的过程,Backward则相反(根据top计算bottom)。
注意这里为什么用了一个包含Blob的容器(vector),
对于大多数Layer来说输入和输出都各连接只有一个Layer,然而对于某些Layer存在一对多的情况,
比如LossLayer和某些连接层。
在网路结构定义文件(*.proto)中每一层的参数bottom和top数目就决定了vector中
Net是由一些列层组成的有向无环图DAG,
一个典型的Net开始于data layer ----> 从磁盘中加载数据----> 终止于loss layer。
(计算和重构目标函数。)
这个是我们使用Proto创建出来的深度网络对象,这个类负责了深度网络的前向和反向传递。
Layer之间的连接由一个文本文件描述。
网络模型初始化Net::Init()会产生blob和layer并调用 Layer::SetUp。
在此过程中Net会报告初始化进程(大量网络载入信息)。这里的初始化与设备无关。
在初始化之后通过Caffe::set_mode()设置Caffe::mode()来选择运行平台CPU或GPU,结果是相同的。
Solver通过协调Net的前向计算和反向梯度计算来进行参数更新,从而达到loss的目的。
目前Caffe的模型学习分为两个部分:
1. 由Solver进行优化、更新参数;
2. 由Net计算出loss和gradient。
solver具体的工作:
1、用于优化过程的记录,创建 训练网络 和 测试网络。
2、用过 forward 和 backward 过程来迭代优化更新参数。
3、周期性的用测试网络评估模型性能。TestAll()
4、优化过程中记录模型和solver状态的快照。
前向传播是从底部层到顶部层的数据流过程。在这个过程中,每一层都会根据其权重和配置来计算其输出。这些输出随后会作为下一层的输入。
反向传播是从顶部层到底部层的过程,用于计算梯度并更新模型的权重。在这个过程中,每一层都会计算其关于输入数据的梯度,并将这些梯度传递给前一层。
使用 Caffe 通常涉及定义网络结构(通常使用 .prototxt 文件)、准备数据、设置训练参数以及运行训练和测试。
.prototxt 文件用于定义 Caffe 网络的结构和参数。你可以使用文本编辑器或专门的工具(如 Netscope Editor)来查看和编辑这些文件。
Netscope Editor 是一个在线工具,允许你直观地查看和编辑 Caffe 的 .prototxt 文件。它提供了一个可视化的界面,让你能够更容易地理解网络的结构和连接。
在 Caffe 中,你可以通过设置层的参数来指定权重的初始化方法。权重初始化对于模型的训练和性能至关重要。你可以查看 include/caffe/filler.hpp 文件来了解可用的初始化方法。
iter_size 是求解器参数中的一个选项。Caffe 会在每个随机梯度下降步骤中累积 iter_size * batch_size 个实例的梯度。当由于内存限制而无法使用大批量大小时,增加 iter_size 可以获得更稳定的梯度。
test_iter 指定了测试循环中需要执行的迭代次数。每次迭代会计算一批测试图像。
test_interval 定义了多久执行一次测试。它指定了在执行多少次训练迭代(每次迭代计算一批训练图像)后进行一次测试。
一个 epoch 指的是模型遍历完整个训练集所需的迭代次数。迭代次数等于训练图像数量除以批量大小。
lr_policy 是学习率策略,它定义了如何在训练过程中调整学习率。通常设置为 “step”,意味着学习率会在每个预定义的步骤后减少。
fixed: 保持base_lr不变.
step: 如果设置为step,则还需要设置一个stepsize, 返回base_lr * gamma ^ (floor(iter / stepsize)),其中iter表示当前的迭代次数
exp: 返回base_lr * gamma ^ iter, iter为当前迭代次数
inv: 如果设置为inv,还需要设置一个power, 返回base_lr * (1 + gamma * iter) ^ (- power)- multistep: 如果设置为multistep,则还需要设置一个stepvalue。这个参数和step很相似,step是均匀等间隔变化,而multistep则是根据 stepvalue值变化
poly: 学习率进行多项式误差, 返回 base_lr (1 - iter/max_iter) ^ (power)- sigmoid: 学习率进行sigmod衰减,返回 base_lr ( 1/(1 + exp(-gamma * (iter - stepsize))))
在Layer中 输入数据input data用bottom表示,
输出数据 output data用top表示。
每一层军定义了三种操作:
1. setup(Layer初始化),
2. forward(正向传导,根据input计算output),
3. backward(反向传导计算,根据output计算input的梯度)。
forward和backward有GPU(大部分)和CPU两个版本的实现。
还有其他一些特有的操作
power
scale
permute