C++ – C++实现Python numpy的矩阵维度转置算法,例如(N,H,W,C)转换为(N,C,H,W)
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)为例,请看一下代码。
<code class="language-python line-numbers">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) </code>
输出结果:
<code class="language-bash line-numbers">[[[[ 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] </code>
在以上的python代码中使用了0-23个常数先组成了(1,2,3,4)的四维矩阵
<code class="language-bash line-numbers">[[[[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] [[12 13 14 15] [16 17 18 19] [20 21 22 23]]]] </code>
,事实上该四维矩阵在内存中的排列如下:
<code class="language-bash line-numbers">[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23] </code>
然后使用了np.transpose对维度排列进行了变换,从(N,H,W,C)转换为(N,C,H,W),修改后矩阵在内存中的排列如下:
<code class="language-bash line-numbers">[ 0 4 8 12 16 20 1 5 9 13 17 21 2 6 10 14 18 22 3 7 11 15 19 23] </code>
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)位置的值,这样就完成了矩阵的维度变换。
<code class="language-cpp line-numbers">#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; } </code>
打印结果:
1.3 python、C++结果比较
从最后的输出结果上看,C++维度变换的结果与python的结果一致,说明变换正确,其它维度的变换可以参考以上思想,举一反三。
本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:C++ – C++实现Python numpy的矩阵维度转置算法,例如(N,H,W,C)转换为(N,C,H,W)
原文链接:https://www.stubbornhuang.com/1759/
发布于:2021年10月15日 17:35:27
修改于:2023年06月26日 21:10:45
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论
49