栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ Eigen3库Tensor操作整理(持续更新)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ Eigen3库Tensor操作整理(持续更新)

目录
    • 项目引入
    • 类型转换
      • C++ 数组转Eigen::Tensor(包含reshape操作)
    • Tensor操作
      • concatenate
      • transpose
      • reshape

项目引入

VS2019环境下

  1. 点击<项目>
  2. 管理NuGet程序包
  3. 搜索Eigen3,安装即可

    在项目源代码添加头文件
#include 
类型转换 C++ 数组转Eigen::Tensor(包含reshape操作)

例如从float数组转到储存类型为float的Tensor

  1. float数组转Eigen::TensorMap
  2. Eigen::TensorMap类型转换回Eigen::Tensor
#include 
#include 

int main()
{
	// 定义一个一维数组,在下面将其转换为2x2的tensor
    float arr[] = { 0.1, 0.2, 0.3, 0.4 };
    // 定义转换的Eigen::TensorMap,同时做了一个reshape操作
    auto mapped_t = Eigen::TensorMap>(arr, 2, 2);
    std::cout << typeid(mapped_t).name() << std::endl;
    // 强制转换为Tensor
    auto result = Eigen::Tensor(mapped_t);
    std::cout << typeid(result).name() << std::endl;
    std::cout << result << std::endl;
}

输出

class Eigen::TensorMap,0,struct Eigen::MakePointer>
class Eigen::Tensor
0.1 0.3
0.2 0.4

上面的操作与python numpy的narray.reshape()是一致的。下面代码是对narray.reshape()的实现。已验证与上面结果一致。

Eigen::Tensor reshape(float* oneDimArray, int channel,int height, int width)
{
    const int frameSize = height * width;
    const auto length = channel * height * width;
    int index = 0;
    Eigen::Tensor result(channel, height, width);
    for (int c = 0; c < channel; c++)
    {
        for (int w = 0; w < width; w++)
        {
            for (int h = 0; h < height; h++)
            {
                index = c * frameSize + w * height + h;
                float value = oneDimArray[index];
                result(c, h, w) = value;
            }
        }
    }
    return result;
}
Tensor操作 concatenate
#include 
#include 

int main()
{
	// 创建一个2维,2x2的tensor
    Eigen::Tensor a(2, 2);
    Eigen::Tensor b(2, 2);
    // 给tensor设置默认值
    a.setConstant(1.0);
    b.setConstant(2.0);
    // 从维度0进行拼接
    auto res = a.concatenate(b, 0);
    std::cout << res << std::endl;
}

输出结果:

1 1
1 1
2 2
2 2
transpose
#include 
#include 
using namespace std;
int main()
{
    Eigen::Tensor m(2, 3, 3);
    m.setValues(
        {
            {{1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}},
            {{10, 11, 12},
            {13, 14, 15},
            {16, 17, 18}}
        });

    Eigen::array shuffling({ 2, 1, 0});

    Eigen::Tensor transposed = m.shuffle(shuffling);

    cout << transposed(0, 0, 0) << ',' << transposed(0, 0, 1) << endl;
    cout << transposed(0, 1, 0) << ',' << transposed(0, 1, 1) << endl;
    cout << transposed(0, 2, 0) << ',' << transposed(0, 2, 1) << endl;
    cout << transposed(1, 0, 0) << ',' << transposed(1, 0, 1) << endl;
    cout << transposed(1, 1, 0) << ',' << transposed(1, 1, 1) << endl;
    cout << transposed(1, 2, 0) << ',' << transposed(1, 2, 1) << endl;
    cout << transposed(2, 0, 0) << ',' << transposed(2, 0, 1) << endl;
    cout << transposed(2, 1, 0) << ',' << transposed(2, 1, 1) << endl;
    cout << transposed(2, 2, 0) << ',' << transposed(2, 2, 1) << endl;
}

输出

1,10
4,13
7,16
2,11
5,14
8,17
3,12
6,15
9,18

该操作与python的numpy库的ndarray.transpose一致

import numpy as np

mat = [
            [[1, 2, 3],
            [4, 5, 6],
            [7, 8, 9]],
            [[10, 11, 12],
            [13, 14, 15],
            [16, 17, 18]]
        ]
mat = np.array(mat)
mat = mat.transpose(2, 1, 0)
print(mat[0][0][0], mat[0][0][1])
print(mat[0][1][0], mat[0][1][1])
print(mat[0][2][0], mat[0][2][1])
print(mat[1][0][0], mat[1][0][1])
print(mat[1][1][0], mat[1][1][1])
print(mat[1][2][0], mat[1][2][1])
print(mat[2][0][0], mat[2][0][1])
print(mat[2][1][0], mat[2][1][1])
print(mat[2][2][0], mat[2][2][1])

输出

1 10
4 13
7 16
2 11
5 14
8 17
3 12
6 15
9 18
reshape
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/510824.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号