C++ – C++实现Python numpy的矩阵维度转置算法,例如(N,H,W,C)转换为(N,C,H,W)
本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:C++ – C++实现Python numpy的矩阵维度转置算法,例如(N,H,W,C)转换为(N,C,H,W)
原文链接:https://www.stubbornhuang.com/1759/
发布于:2021年10月15日 17:35:27
修改于:2021年10月15日 17:35:27

1 C++实现Python numpy的矩阵维度转置算法,例如(N,H,W,C)转换为(N,C,H,W)
1.1 python中使用numpy进行矩阵维度变换
在python中常常使用numpy的transpose对矩阵的维度进行转换,这里以(N,H,W,C)转换为(N,C,H,W)为例,请看一下代码。
import numpy as np
if __name__ == '__main__':
a = np.arange(0,24,1)
N = 1
H = 2
W = 3
C = 4
a = np.reshape(a,[1,2,3,4])
print(a)
a_copy = a
test_copy = a
print(a.flatten())
# N.H,W,C -> N,C,H,W
a_copy = np.transpose(a_copy,[0,3,1,2])
print(a_copy.flatten())
# 使用数组transpose
a_new = []
for n in range(N):
for c in range(C):
for h in range(H):
for w in range(W):
a_new.append(test_copy[n,h,w,c])
print(a_new)
输出结果:
[[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]]
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
[ 0 4 8 12 16 20 1 5 9 13 17 21 2 6 10 14 18 22 3 7 11 15 19 23]
[0, 4, 8, 12, 16, 20, 1, 5, 9, 13, 17, 21, 2, 6, 10, 14, 18, 22, 3, 7, 11, 15, 19, 23]
在以上的python代码中使用了0-23个常数先组成了(1,2,3,4)的四维矩阵
[[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]]
,事实上该四维矩阵在内存中的排列如下:
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
然后使用了np.transpose对维度排列进行了变换,从(N,H,W,C)转换为(N,C,H,W),修改后矩阵在内存中的排列如下:
[ 0 4 8 12 16 20 1 5 9 13 17 21 2 6 10 14 18 22 3 7 11 15 19 23]
1.2 在C++中对矩阵进行维度变换
平时在使用TensorRT部署工业模型的时候,经常需要将数据变换为深度学习模型需要的维度数据,这里面就少不了对原有的数据做最后的维度变换输入到深度学习模型中进行推理,如果数据维度变换不正确,直接会导致推理结果出错。但是在C++中并没有numpy这么好用的库,TensorRT的模型输入数据往往被抽象为一个一维数组,那么如何进行维度变换呢?
在C++中对矩阵数据进行(N,H,W,C)转换为(N,C,H,W)的代码如下,其核心思想就是:将原矩阵中的第(N,H,W,C)个值赋值给transpose后的矩阵的(N,C,H,W)位置的值,这样就完成了矩阵的维度变换。
#include <iostream>
#include <string>
int main()
{
int N = 1;
int H = 2;
int W = 3;
int C = 4;
float temp_int[24] = { 0, 1, 2, 3, 4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 };
float temp_int_transpose[24] = { 0 };
// [N,H,W,C] -> [N,C,H,W]
for (int n = 0; n < N; ++n)
{
for (int c = 0; c < C; ++c)
{
for (int h = 0; h < H; ++h)
{
for (int w = 0; w < W; ++w)
{
int old_index = n * H * W * C + h * W * C + w * C + c;
int new_index = n * C * H * W + c * H * W + h * W + w;
temp_int_transpose[new_index] = temp_int[old_index];
std::cout << temp_int_transpose[new_index] << ",";
}
}
}
}
getchar();
return 0;
}
打印结果:

1.3 python、C++结果比较
从最后的输出结果上看,C++维度变换的结果与python的结果一致,说明变换正确,其它维度的变换可以参考以上思想,举一反三。
当前分类随机文章推荐
- C++ - return this和return *this的含义和区别 阅读169次,点赞0次
- C++ - 随机洗牌算法,std::random_shuffle和std::shuffle 阅读1077次,点赞1次
- C++ - std::string输出双引号到字符串 阅读2664次,点赞0次
- C++ - std::numeric_limits
简介与使用,用于获取指定数据类型的最大值与最小值 阅读74次,点赞0次 - C++ - 我的代码风格备忘 阅读649次,点赞0次
- C++ - C++实现Python numpy的矩阵维度转置算法,例如(N,H,W,C)转换为(N,C,H,W) 阅读3319次,点赞3次
- C++读取Shp文件并将Shp转化为DXF 阅读2943次,点赞1次
- C++STL容器 - std::vector构造方式与分配值方式总结 阅读583次,点赞0次
- C++STL容器 - std::map查找元素与判断键值是否存在方法总结 count,find,contains,equal_range,lower_bound,upper_bound 阅读789次,点赞0次
- C++ - 控制台程序在控制台窗口可变参数格式化带颜色输出日志信息 阅读2898次,点赞0次
全站随机文章推荐
- 一文带你从欧拉角的角度搞懂左手坐标系到右手坐标系的转换 阅读13233次,点赞18次
- Pac - 自定义Pac的编写和语法规则 阅读4983次,点赞0次
- C++11 - 委托机制的实现TinyDelegate 阅读1204次,点赞0次
- C++ - sleep睡眠函数总结 阅读738次,点赞0次
- UnrealEngine4 - 获取UE4最后的渲染缓存数据BackBuffer 阅读4651次,点赞3次
- 工具网站推荐 - 免费的在线视频剪切网站 阅读1922次,点赞1次
- OpenCV - cv::VideoWriter::fourcc可支持的视频编码格式 阅读1746次,点赞0次
- 姿态估计之Openpose-Body25数据集骨骼关节keypoint标注对应 阅读7609次,点赞5次
- Python - 使用flask_sockets库构建websocket服务器 阅读2802次,点赞0次
- WordPress - 通过Server酱发送微信通知给微信 阅读2867次,点赞0次
评论
164