0.前言 与 Eigen库的使用整理

[C++ 基于Eigen库实现CRN前向推理]

前言:背景 与 Eigen库的使用整理

1. 前言

最近要用C++ 实现一下CRN网络的前向推理过程,了解了一下相关的库,决定使用Eigen提供的Tensor作为数据结构,并使用一些Eigen的常规的库函数。(纯C++实现嵌套的循环太多层了,容易写迷糊了,先降低难度写一波)


2. C++ Eigen库的使用

Eigen是可以用来进行线性代数、矩阵、向量操作等运算的C++库,它里面包含了很多算法。它的License是MPL2。它支持多平台。

Eigen采用源码的方式提供给用户使用,在使用时只需要包含Eigen的头文件即可进行使用。之所以采用这种方式,是因为Eigen采用模板方式实现,由于模板函数不支持分离编译,所以只能提供源码而不是动态库的方式供用户使用。

在找资料的时候发现了Eigen 矩阵操作与Matlab的对应关系,虽然在这个项目里没有用到,但后面可能会用到,先码住,链接在这

2.1 下载与导入
  • 第一步

Eigen下载地址官网在这,直接去官网下载解压包,解压到本地。
在这里插入图片描述
我这路径为E:\eigen-3.4.0,版本为3.4.0。

  • 第二步
    把Eigen-3.4.0目录中的需要用到的包复制到对应C++项目的目录下,本文就用到Eigen核心和unsupported中的Tensor。
    在这里插入图片描述
  • 第三步
    在CmakeList中添加lib,红框圈起来的部分就是Eigen的引用啦。至于上面的一大串是MATLAB库的导入,不用管就好了。
    在这里插入图片描述
  • 第四步
    到这里就差不多能用啦,写个初始化测试一下:
    int main() {
         
    	Eigen::Vector<double, 3> point(2, 1, 1);
        cout << point << endl;
        return 0;
    }	
    >>>>>
    2
    1
    1
    
    如果还是不行,可以尝试重启一下编译器,或者File->Reload CMake Project

2.2 Tensor的初始化

这里只讲Tensor的用法,Matrix 和Vector的教程网上很多。
Tensor数据类型不在Eigen/Core 和Eigen/Dense中,而是需要额外引用unsupported。

#include <unsupported/Eigen/CXX11/Tensor>

简单声明:Tensor声明格式如Eigen::Tensor<data_type,n_dim>,data_type是数据类型,n_dim是多维矩阵的维度。这里声明了一个2维矩阵,但是没有定义具体的大小,在输出时为空。

	Eigen::Tensor<double, 2> a;
	std::cout << a << std::endl;
	(blank)

在看指定具体大小的情况↓,可以看到为矩阵随机分配了初始值,矩阵只有在指定大小(即为其分配空间时才会产生内容)。通过resize方式,也可以进行初始化

    Eigen::Tensor<float, 2> var(2, 3);
    cout << var << endl;
    -1.83108e+23 -1.82998e+23            0
 	7.00649e-43  7.00649e-43            0

    Eigen::Tensor<float, 2> var;
    var.resize(2, 3);
    cout << var << endl;
    -2.6161e+31 -2.61461e+31            0
 	5.73131e-43  5.73131e-43            0

几种初始化函数
常数初始化

	var.setConstant(12.3f);
	cout << "Constant: " << endl << var << endl << endl;
	=>
	Constant:
	12.3 12.3 12.3
	12.3 12.3 12.3

置零初始化

	Eigen::Tensor<float, 2> var(2, 3);
    var.setZero();
    cout << "Constant: " << endl << var << endl << endl;
    =>
    Constant:
	0 0 0
	0 0 0

赋值初始化

	Eigen::Tensor<float, 2> var(2, 3);
    var.setValues({
   {
   0.0f, 1.0f, 2.0f},
                   {
   3.0f, 4.0f, 5.0f}});
    cout << "Constant: " << endl << var << endl << endl;
    =>
    Constant:
	0 1 2
	3 4 5

随机初始化

    Eigen::Tensor<float, 2> var(2, 3);
    var.setRandom();
    cout << "Constant: " << endl << var << endl << endl;
    Constant:
	0.896227 0.872269 0.605188
	0.290171  0.24641 0.251816

2.3 Tensor常用库函数
  • 重塑-reshape
    可以看到Eigen的Tensor是Col-Major的,所以存储顺序为0.896277,0.290171,0.872269…,重塑完按照(3,2)的形状分配。这里与Pytorch的矩阵reshape结果是不一致的
    Eigen::Tensor<float, 2> var(2, 3);
    var.setRandom();
    cout << "Constant: " << endl << var << endl << endl;
    Eigen::array<int, 2> new_shape{
   3, 2};
    auto vat_T = var.reshape(new_shape);
    cout << "Constant: " << endl << vat_T << endl << endl;
    Constant:
	0.896227 0.872269 0.605188
	0.290171  0.24641 0.251816
	
	Constant:
	0.896227  0.24641
	0.290171 0.605188
	0.872269 0.251816
	
	Pytorch.reshpe:
	0.896227 0.872269
	0.605188 0.290171
	0.24641 0.251816
  • 填充-Padding
    采用auto或者声明变量的形式保存pad函数的返回值都可以,不同的是auto类型保存的是PadOp,是一个操作,后续怎么操作也不清楚,希望有知道的大佬指点一二。用Tensor变量保存的话就是赋值存储了,后续正常按Tensor操作就可以。
	auto d0 = std::make_pair(1, 2);
	auto d1 = std::make_pair(2, 1);
	// auto dims = std::experimental::make_array(d0, d1); // 便利的写法
	Eigen::array<std::pair<int, int>, 2> dims{
   d0, d1};
	auto padded = var.pad(dims, -1);
	// Eigen::Tensor<float,2> padded;
	// padded = var.pad(dims,-1);
	std::cout << padded << std::endl;
	=>
	Constant:
	0.896227 0.872269 0.605188
	0.290171  0.24641 0.251816

      -1       -1       -1       -1       -1       -1
      -1       -1 0.896227 0.872269 0.605188       -1
      -1       -1 0.290171  0.24641 0.251816       -1
      -1       -1       -1       -1       -1       -1<
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Eigen 是一个 C++ 模板,用于线性代数和数值计算。它提供了高性能的矩阵和向量操作,以及许多常用的数学函数和算法。下面是 Eigen 的基本使用说明: 1. 安装:你可以从 Eigen 的官方网站(https://eigen.tuxfamily.org/)下载最新版本的源代码,并将其包含在你的项目中。 2. 包含头文件:在你的 C++ 代码中,使用 `#include <Eigen/Dense>` 来包含 Eigen 的主要头文件。 3. 定义矩阵和向量:Eigen 提供了 `Matrix` 和 `Vector` 类模板来定义矩阵和向量。你可以使用不同的数据类型(例如 float、double)和大小来实例化这些类。 ```cpp #include <Eigen/Dense> int main() { // 定义一个 3x3 的矩阵 Eigen::Matrix3d matrix; // 定义一个 3 维向量 Eigen::Vector3d vector; // ... return 0; } ``` 4. 矩阵和向量操作:Eigen 提供了丰富的运算符和函数,用于执行矩阵和向量的各种操作,如矩阵乘法、转置、逆等。 ```cpp #include <Eigen/Dense> #include <iostream> int main() { Eigen::Matrix2d A; Eigen::Vector2d b; // 矩阵赋值 A << 1, 2, 3, 4; // 向量赋值 b << 5, 6; // 矩阵乘法 Eigen::Vector2d result = A * b; // 输出结果 std::cout << result << std::endl; return 0; } ``` 5. 其他功能:Eigen 还提供了许多其他功能,如特征值分解、奇异值分解、QR 分解等。你可以通过查阅 Eigen 的官方文档来了解更多详细的使用方法和示例代码。 以上是 Eigen 的基本使用说明,希望对你有所帮助!如有更多问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值