从零构建深度学习推理框架-1 简介和Tensor

这篇具有很好参考价值的文章主要介绍了从零构建深度学习推理框架-1 简介和Tensor。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

源代码作者:https://github.com/zjhellofss

本文仅作为个人学习心得领悟 ,将原作品提炼,更加适合新手

什么是推理框架?

深度学习推理框架用于对已训练完成的神经网络进行预测,也就是说,能够将深度训练框架例如Pytorch、Tensorflow中定义的算法移植到中心侧和端侧,并高效执行。与训练框架不同的是,深度学习推理框架没有梯度反向传播功能,因为算法模型文件中的权重系数已经被固化,推理框架只需要读取、加载并完成对新数据的预测即可。

模型加载阶段

训练完成的模型被放置在两个文件中,一个是模型定义文件,一个是权重文件

ONNX文件是将模型定义文件和权重文件合二为一的文件格式。

关于维度的预备知识

在Tensor张量中,共有三维数据进行顺序存放,分别是Channels(维度),Rows(行高), Cols(行宽),

三维矩阵我们可以看作多个连续的二维矩阵组成,最简单的方法就是std::vector<std::vector<std::vector<float>>>,但是这种方法非常不利于数据的访问(尤其是内存不连续的问题 、修改以及查询,特别是在扩容的时候非常不方便。不能满足使用需求

不连续会造成数组访问慢的问题,在这里我用chrono做了测试:

#include<iostream>
#include <gtest/gtest.h>
#include <armadillo>
#include <glog/logging.h>
#include <vector>
#include <chrono>
#define TICK(x) auto bench_##x = std::chrono::steady_clock::now();
#define TOCK(x) std::cout << #x ": " << std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::steady_clock::now() - bench_##x).count() *1000000<< "ns" << std::endl;
using namespace std;
int m = 10000 , n = 10000 , channel = 2;
TEST(test_compare_vector , speed2D){
    LOG(INFO)<<"Test of vector & cube"<<endl;
    vector<vector<float>> matA (m , vector<float>(n , 1));
    TICK(2D);
    for (int  i = 0; i <matA.size(); i++)
    {
        for (int j = 0; j < matA[0].size(); j++)
        {
            matA[i][j] = matA[i][j]*matA[j][i];
        }
    }
    TOCK(2D);
        arma::fcube matB( m , n , 1 , arma::fill::ones);
    TICK(cube);
        for (int  i = 0; i <m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            matB(i , j , 0) = matB(i , j , 0)*matB( j , i , 0);
        }
    }
    TOCK(cube);


}

从零构建深度学习推理框架-1 简介和Tensor,Infer,c++

因此,综合考虑灵活性和开发的难易度,作者在这里以Armadillo类中的arma::mat(矩阵 matrix)类和arma::cube 作为数据管理(三维矩阵)类来实现Tensor 库中类的主体,一个cube由多个matrix组成,cube又是Tensor类中的数据实际管理者。一块连续的大内存分配开始写一个tensor,工作量会特别大,折中!

 作者设计的类是以arma::cube为基础实现了Tensor我们主要是提供了更方便的访问方式和对外接口 

从零构建深度学习推理框架-1 简介和Tensor,Infer,c++

 上图即为Tensor与cube的对应关系。

从零构建深度学习推理框架-1 简介和Tensor,Infer,c++

 cube一般有多个维度,在channel维度上有多个matrix。

arma::cube(2,5,3),表示当前的三维矩阵共有2个矩阵构成,每个矩阵都是5行3列的。如果放在我们项目中会以这形式提供 Tensor tensor(2,5,3)

下图是这种情况下的三维结构图,可以看出一个Cube一共有两个Matrix,也就是共有两个Channel。一个Channel放一个Matrix. Matrix的行宽均为Rows和Cols.

从零构建深度学习推理框架-1 简介和Tensor,Infer,c++

 Tensor类方法总览

从零构建深度学习推理框架-1 简介和Tensor,Infer,c++

这里的很多都不需要我们重新去造轮子

比如Fill(float value)就可以直接调用cube里的fill:

void Tensor<float>::Fill(float value) {
  CHECK(!this->data_.empty());
  this->data_.fill(value);
}

再比如这个at:

float &Tensor<float>::at(uint32_t channel, uint32_t row, uint32_t col) {
  CHECK_LT(row, this->rows());
  CHECK_LT(col, this->cols());
  CHECK_LT(channel, this->channels());
  return this->data_.at(row, col, channel);
}

再难一些的就需要我们自己去实现了:

Fill(vector)方法实现:

TEST(test_tensor, fill) {
  using namespace kuiper_infer;
  Tensor<float> tensor(3, 3, 3);
  ASSERT_EQ(tensor.channels(), 3);
  ASSERT_EQ(tensor.rows(), 3);
  ASSERT_EQ(tensor.cols(), 3);

  std::vector<float> values;
  for (int i = 0; i < 27; ++i) {
    values.push_back((float) i);
  }
  tensor.Fill(values);
  LOG(INFO) << tensor.data();

  int index = 0;
  for (int c = 0; c < tensor.channels(); ++c) {
    for (int r = 0; r < tensor.rows(); ++r) {
      for (int c_ = 0; c_ < tensor.cols(); ++c_) {
        ASSERT_EQ(values.at(index), tensor.at(c, r, c_));
        index += 1;
      }
    }
  }
  LOG(INFO) << "Test1 passed!";
}

padding功能实现:

 文章来源地址https://www.toymoban.com/news/detail-606183.html


TEST(test_tensor, padding1) {
  using namespace kuiper_infer;
  Tensor<float> tensor(3, 3, 3);
  ASSERT_EQ(tensor.channels(), 3);
  ASSERT_EQ(tensor.rows(), 3);
  ASSERT_EQ(tensor.cols(), 3);

  tensor.Fill(1.f); // 填充为1
  tensor.Padding({1, 1, 1, 1}, 0); // 边缘填充为0
  ASSERT_EQ(tensor.rows(), 5);
  ASSERT_EQ(tensor.cols(), 5);
  int index = 0;
  // 检查一下边缘被填充的行、列是否都是0
  for (int c = 0; c < tensor.channels(); ++c) {
    for (int r = 0; r < tensor.rows(); ++r) {
      for (int c_ = 0; c_ < tensor.cols(); ++c_) {
        if (c_ == 0 || r == 0) {
          ASSERT_EQ(tensor.at(c, r, c_), 0);
        }
        index += 1;
      }
    }
  }
  LOG(INFO) << "Test2 passed!";
}

再谈谈Tensor类中数据的排布

我们以具体的图片作为例子,来讲讲Tensor中数据管理类arma::cube的数据排布方式Tensor类是arma::cube对外更方便的接口,所以说armadillo::cube怎么管理内存的,Tensor类就是怎么管理内存的。希望大家的能理解到位。如下图中的一个Cube,Cube的维度是2,每个维度上存放的是一个Matrix,一个Matrix中的存储空间被用来存放一张图像(lena) 。一个框内(channel)是一个Matrix,Matrix1存放在Cube第1维度(channel 1)上,Matrix2存放在Cube的第2维度上(channel 2). Matrix1和Matrix2的Rows和Cols均代表着图像的高和宽,在本例中就是512和384。

从零构建深度学习推理框架-1 简介和Tensor,Infer,c++

从零构建深度学习推理框架-1 简介和Tensor,Infer,c++

 

到了这里,关于从零构建深度学习推理框架-1 简介和Tensor的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 主流开源深度学习框架简介

    本文目录: 一、TensorFlow深度学习框架 二、PyTorch深度学习框架 三、Keras深度学习框架 四、Caffe深度学习框架 五、中国深度学习开源框架状况 六、几种框架的对比 七、其他统计数据 当下,有许多主流的开源深度学习框架供开发者使用。 主要包括TensorFlow、PyTorch、Keras、Caffe等

    2024年02月11日
    浏览(43)
  • KuiperInfer深度学习推理框架-源码阅读和二次开发(2):算子开发流程(以sigmoid为例)

    前言 :KuiperInfer是一个从零实现一个高性能的深度学习推理库,中文教程已经非常完善了。本系列博客主要是自己学习的一点笔记和二次开发的教程,欢迎更多的AI推理爱好者一起来玩。这篇写一下算子开发流程,以sigmoid算子为例,为下一节我们自己手写算子打下基础。 目录

    2023年04月24日
    浏览(43)
  • 从零实现深度学习框架——Transformer从菜鸟到高手(一)

    💡本文为🔗[从零实现深度学习框架]系列文章内部限免文章,更多限免文章见 🔗专栏目录。 本着“ 凡我不能创造的,我就不能理解 ”的思想,系列文章会基于纯Python和NumPy从零创建自己的类PyTorch深度学习框架。 Transformer是继MLP、RNN、CNN之后的第四大特征提取器,也是第四

    2024年02月14日
    浏览(42)
  • AI框架:9大主流分布式深度学习框架简介

    转载翻译Medium上一篇关于分布式深度学习框架的文章 https://medium.com/@mlblogging.k/9-libraries-for-parallel-distributed-training-inference-of-deep-learning-models-5faa86199c1fmedium.com/@mlblogging.k/9-libraries-for-parallel-distributed-training-inference-of-deep-learning-models-5faa86199c1f 大型深度学习模型在训练时需要大量内

    2024年02月09日
    浏览(48)
  • R语言构建深度学习的框架:reticulate

    构建虚拟环境 进入R,安装reticulate包,该包建立R语言和python之间的关系。 出现各种bug bug1: Error: Installation of TensorFlow not found 解决方案: 进入/home/u19111010045/.local/share/r-miniconda/envs/r-reticulate的r-reticulate环境中,安装tensorflow bug2: If this call came from a _pb2.py file, your generated code is

    2024年02月13日
    浏览(40)
  • 【Spring教程23】Spring框架实战:从零开始学习SpringMVC 之 SpringMVC简介与SpringMVC概述

    欢迎大家回到《Java教程之Spring30天快速入门》,本教程所有示例均基于Maven实现,如果您对Maven还很陌生,请移步本人的博文《如何在windows11下安装Maven并配置以及 IDEA配置Maven环境》,本文的上一篇为《Spring事务角色与 Spring事务属性、事务传播行为》 从这一节开始,我们开始

    2024年02月03日
    浏览(59)
  • 从零实现深度学习框架——Seq2Seq模型尝试优化

    本着“ 凡我不能创造的,我就不能理解 ”的思想,本系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导。 💡系列文章完整目录: 👉点此👈 要深入理解深度学习,从零开始创建的经验非常重要,从自己可以理解的角度出发,尽

    2024年02月12日
    浏览(39)
  • 【Spring教程30】Spring框架实战:从零开始学习SpringMVC 之 Rest风格简介与RESTful入门案例

    欢迎大家回到《Java教程之Spring30天快速入门》,本教程所有示例均基于Maven实现,如果您对Maven还很陌生,请移步本人的博文《如何在windows11下安装Maven并配置以及 IDEA配置Maven环境》,本文的上一篇为《SpringMVC 之 服务器响应》 REST(Representational State Transfer),表现形式状态转

    2024年02月04日
    浏览(51)
  • 从零实现深度学习框架——带Attentiond的Seq2seq机器翻译

    本着“ 凡我不能创造的,我就不能理解 ”的思想,本系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导。 要深入理解深度学习,从零开始创建的经验非常重要,从自己可以理解的角度出发,尽量不使用外部完备的框架前提下,实

    2024年02月15日
    浏览(96)
  • PyTorch 之 简介、相关软件框架、基本使用方法、tensor 的几种形状和 autograd 机制

    本文参加新星计划人工智能(Pytorch)赛道:https://bbs.csdn.net/topics/613989052 PyTorch 是一个基于 Torch 的 Python 开源机器学习库,用于自然语言处理等应用程序。它主要由 Facebook 的人工智能小组开发,不仅能够实现强大的 GPU 加速,同时还支持动态神经网络,这一点是现在很多主流框架

    2024年01月18日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包