当前位置:   article > 正文

4.Eigen Tensor详解【三】_eigen tensor sum

eigen tensor sum

目录

 七 相关API说明

6.降维运算

7.扫描操作

8 .卷积操作

9.几何运算

(1) reshape(const Dimensions& new_dims)

(2) shuffle(const Shuffle& shuffle)

(3) stride(const Strides& strides)

(4) slice(const StartIndices& offsets, const Sizes& extents)

(5) chip(const Index offset, const Index dim)

(6)reverse(const ReverseDimensions& reverse)


 

 七 相关API说明

6.降维运算

降维运算返回的tensor比原始tensor具有更少的维度,返回的tensor的值是通过对原始tensor的值切片应用一个降维算子来计算的。切片的维度可以手动指定(切片指的是需要获取元素的下标)

 所有的降维操作都采用一个类型为<TensorType>::Dimensions的参数,该参数可以设定为int数组。

如下代码所示

  1. void testReduction()
  2. {
  3. // Create a tensor of 2 dimensions
  4. Eigen::Tensor<int, 2> a(2, 3);
  5. a.setValues({ {1, 2, 3}, {6, 5, 4} });
  6. //
  7. Eigen::array<int, 1> dims = { 1 }; //沿着第二个维度降维
  8. Eigen::array<int, 1> dims2 = { 0 }; //沿着第一个维度降维
  9. // maximum 返回的是某个维度的最大值
  10. Eigen::Tensor<int, 1> b = a.maximum(dims);
  11. cout << "a" << endl << a << endl << endl;
  12. cout << "b" << endl << b << endl << endl;
  13. Eigen::Tensor<int, 1> c = a.maximum(dims2);
  14. cout << "c" << endl << c << endl << endl;
  15. }

下面沿着两个维度降维

  1. void testReduction2()
  2. {
  3. Eigen::Tensor<float, 3, Eigen::ColMajor> a(2, 3, 4);
  4. a.setValues({ {{0.0f, 1.0f, 2.0f, 3.0f},
  5. {7.0f, 6.0f, 5.0f, 4.0f},
  6. {8.0f, 9.0f, 10.0f, 11.0f}},
  7. {{12.0f, 13.0f, 14.0f, 15.0f},
  8. {19.0f, 18.0f, 17.0f, 16.0f},
  9. {20.0f, 21.0f, 22.0f, 23.0f}} });
  10. //a有三个维度,我们沿着前两个维度降维,降维的结果是一个一维的Tensor,
  11. Eigen::Tensor<float, 1, Eigen::ColMajor> b =a.maximum(Eigen::array<int, 2>({ 0, 1 }));
  12. cout << "b" << endl << b << endl << endl;
  13. }

沿着所有维度降维

作为降维的一个特例,可以不传入任何参数,沿着所有的维度进行降维,如下代码所示

  1. void testReduction3()
  2. {
  3. Eigen::Tensor<float, 3> a(2, 3, 4);
  4. a.setValues({ {{0.0f, 1.0f, 2.0f, 3.0f},
  5. {7.0f, 6.0f, 5.0f, 4.0f},
  6. {8.0f, 9.0f, 10.0f, 11.0f}},
  7. {{12.0f, 13.0f, 14.0f, 15.0f},
  8. {19.0f, 18.0f, 17.0f, 16.0f},
  9. {20.0f, 21.0f, 22.0f, 23.0f}} });
  10. cout << "a:" << endl << a << endl << endl;
  11. Eigen::Tensor<float, 0> b = a.sum();
  12. cout << "b" << endl << b << endl << endl;
  13. }

下面列出来相关的函数
 

  1. <Operation> sum(const Dimensions& new_dims)
  2. <Operation> sum()
  3. <Operation> mean(const Dimensions& new_dims)
  4. <Operation> mean()
  5. <Operation> maximum(const Dimensions& new_dims)
  6. <Operation> maximum()
  7. <Operation> minimum(const Dimensions& new_dims)
  8. <Operation> minimum()
  9. //prod()
  10. <Operation> prod(const Dimensions& new_dims)
  11. <Operation> prod()
  12. <Operation> all(const Dimensions& new_dims)
  13. <Operation> all()
  14. <Operation> any(const Dimensions& new_dims)
  15. <Operation> any()
  16. <Operation> reduce(const Dimensions& new_dims, const Reducer& reducer)
  1. void testReduction4()
  2. {
  3. // Create a tensor of 2 dimensions
  4. Eigen::Tensor<int, 2> a(3, 3);
  5. a.setValues({ {1, 2, 3}, {6, 5, 4},{8, 9, 10} });
  6. //
  7. Eigen::array<int, 1> dims = { 1 }; //沿着第二个维度降维
  8. Eigen::array<int, 1> dims2 = { 0 }; //沿着第一个维度降维
  9. Eigen::Tensor<int, 1> maximum = a.maximum(dims);
  10. cout << "a" << endl << a << endl << endl;
  11. cout << "maximum(dims):" << endl << a.maximum(dims) << endl << endl;
  12. cout << "maximum():" << endl << a.maximum() << endl << endl;
  13. cout << "sum(dims):" << endl << a.sum(dims) << endl << endl;
  14. cout << "sum():" << endl << a.sum() << endl << endl;
  15. cout << "mean(dims):" << endl << a.mean(dims) << endl << endl;
  16. cout << "mean():" << endl << a.mean() << endl << endl;
  17. cout << "minimum(dims):" << endl << a.minimum(dims) << endl << endl;
  18. cout << "minimum():" << endl << a.minimum() << endl << endl;
  19. //返回相应维度元素的乘积
  20. cout << "prod(dims):" << endl << a.prod(dims) << endl << endl;
  21. cout << "prod():" << endl << a.prod() << endl << endl;
  22. //如果相应维度的元素都是大于0 ,则相应维度的降维结果为1 ,否则为0
  23. cout << "all(dims):" << endl << a.all(dims) << endl << endl;
  24. cout << "all():" << endl << a.all() << endl << endl;
  25. //如果相应维度的元素某个大于0 ,则相应维度的降维结果为1 ,否则为0
  26. cout << "any(dims):" << endl << a.any(dims) << endl << endl;
  27. cout << "any():" << endl << a.any() << endl << endl;
  28. }

7.扫描操作

Scan操作返回与原始tensor同维度的tensor,该操作沿着指定的轴执行“包含扫描”,即:它计算降维操作的运行总数(沿着降维轴),如果是求和操作,那么它计算的是沿着降维轴的累加求和

  1. void testScan()
  2. {
  3. // Create a tensor of 2 dimensions
  4. Eigen::Tensor<int, 2> a(2, 3);
  5. a.setValues({ {1, 2, 3}, {4, 5, 6} });
  6. // Scan it along the second dimension (1) using summation
  7. Eigen::Tensor<int, 2> b = a.cumsum(1);
  8. Eigen::Tensor<int, 2> c = a.cumprod(1);
  9. // The result is a tensor with the same size as the input
  10. cout << "a" << endl << a << endl << endl;
  11. cout << "cumsum" << endl << b << endl << endl;
  12. cout << "cumpord" << endl << c << endl << endl;
  13. }

8 .卷积操作

<Operation> convolve(const Kernel& kernel, const Dimensions& dims)

卷积操作跟图像课程里面讲的卷积一样,这里不再详述

  1. void testConvolve()
  2. {
  3. Eigen::Tensor<float, 4, Eigen::RowMajor> input(3, 3, 7, 11);
  4. Eigen::Tensor<float, 2, Eigen::RowMajor> kernel(2, 2);
  5. Eigen::Tensor<float, 4, Eigen::RowMajor> output(3, 2, 6, 11);
  6. input.setRandom();
  7. kernel.setRandom();
  8. Eigen::array<int, 2> dims= { 1, 2 }; // Specify second and third dimension for convolution.
  9. output = input.convolve(kernel, dims);
  10. cout << "Kernel:" << endl << kernel << endl;
  11. cout << "Output:" << endl << output << endl;
  12. //下面手工计算卷积,对比结果
  13. for (int i = 0; i < 3; ++i) {
  14. for (int j = 0; j < 2; ++j) {
  15. for (int k = 0; k < 6; ++k) {
  16. for (int l = 0; l < 11; ++l) {
  17. const float result = output(i, j, k, l);
  18. const float expected = input(i, j + 0, k + 0, l) * kernel(0, 0) +
  19. input(i, j + 1, k + 0, l) * kernel(1, 0) +
  20. input(i, j + 0, k + 1, l) * kernel(0, 1) +
  21. input(i, j + 1, k + 1, l) * kernel(1, 1);
  22. cout << result << "," << expected << endl;
  23. }
  24. }
  25. }
  26. }
  27. }

9.几何运算

这些运算得到的张量与原来的张量维数不同。它们可以用来访问张量的片,用不同的维度查看它们,或者用附加数据填充张量

(1)<Operation> reshape(const Dimensions& new_dims)

返回输入张量的view,该张量已被重新构造为指定的新维。参数new_dims是一个索引值数组。得到的张量的秩等于元素的个数。

  1. void testReshape()
  2. {
  3. Eigen::Tensor<float, 2, Eigen::ColMajor> a(2, 3);
  4. a.setValues({ {0.0f, 100.0f, 200.0f}, {300.0f, 400.0f, 500.0f} });
  5. //说明: array 的类型需要为Eigen:DenseIndex ,如果是int, 则编译不过
  6. Eigen::array<Eigen::DenseIndex, 1> one_dim = { 3 * 2 };
  7. Eigen::Tensor<float, 1, Eigen::ColMajor> b = a.reshape(one_dim);
  8. array<Eigen::DenseIndex, 3> three_dims = { {3, 2, 1} };
  9. Eigen::Tensor<float, 3, Eigen::ColMajor> c = a.reshape(three_dims);
  10. cout << "a" << endl << a << endl;
  11. cout << "b" << endl << b << endl;
  12. cout << "c" << endl << c << endl;
  13. }

(2)<Operation> shuffle(const Shuffle& shuffle)

返回输入张量的副本,该张量的维数已根据指定的排列重新排序。参数是一个索引值数组。它的大小是输入张量的秩。它必须包含0、1、…,秩- 1(顺序根据需要随便设置)。输出张量的第i维等于输入张量的第i维洗牌的大小。

  1. void testShuffle()
  2. {
  3. Eigen::Tensor<float, 3> input(2, 3, 3);
  4. input.setRandom();
  5. Eigen::array<Eigen::DenseIndex, 3> shuffle = { 1, 2, 0 };
  6. Eigen::Tensor<float, 3> output = input.shuffle(shuffle);
  7. cout << "input:" << endl << input << endl;
  8. cout << "output:" << endl << output << endl;
  9. cout << (output.dimension(0) == 3) <<endl;
  10. cout << (output.dimension(1) == 3) << endl;
  11. cout << (output.dimension(2) == 2) << endl;
  12. }

(3)<Operation> stride(const Strides& strides)

返回一个子张量,从原来张量中按照strides的步长取元素

  1. void testStrides()
  2. {
  3. Eigen::Tensor<int, 2> a(4, 3);
  4. a.setValues({ {0, 100, 200}, {300, 400, 500}, {600, 700, 800}, {900, 1000, 1100} });
  5. Eigen::array<Eigen::DenseIndex, 2> strides = { 3, 2 };
  6. Eigen::Tensor<int, 2> b = a.stride(strides);
  7. cout << "a" << endl << a << endl;
  8. cout << "b" << endl << b << endl;
  9. }

(4)<Operation> slice(const StartIndices& offsets, const Sizes& extents)

返回给定张量的子张量。对于每个维i,切片是由存储在输入张量的偏移量[i]和偏移量[i] +区段[i]之间的系数构成的

  1. void testSlice()
  2. {
  3. Eigen::Tensor<int, 2> a(4, 3);
  4. a.setValues({ {0, 100, 200}, {300, 400, 500},
  5. {600, 700, 800}, {900, 1000, 1100} });
  6. Eigen::array<Eigen::DenseIndex, 2> offsets = { 1, 0 };
  7. Eigen::array<Eigen::DenseIndex, 2> extents = { 2, 2 };
  8. Eigen::Tensor<int, 2> slice = a.slice(offsets, extents);
  9. cout << "a" << endl << a << endl;
  10. cout << "slice:" << endl << slice << endl;
  11. }

(5)<Operation> chip(const Index offset, const Index dim)

chip是slice的特殊形式,

  1. void testChip()
  2. {
  3. Eigen::Tensor<int, 2> a(4, 3);
  4. a.setValues({ {0, 100, 200}, {300, 400, 500},
  5. {600, 700, 800}, {900, 1000, 1100} });
  6. Eigen::Tensor<int, 1> row_3 = a.chip(2, 0);
  7. Eigen::Tensor<int, 1> col_2 = a.chip(1, 1);
  8. cout << "a" << endl << a << endl;
  9. cout << "row_3" << endl << row_3 << endl;
  10. cout << "col_2" << endl << col_2 << endl;
  11. }

(6)<Operation>reverse(const ReverseDimensions& reverse)

返回输入张量的一个视图,该视图在维的一个子集上反转系数的顺序。参数reverse是一个布尔值数组,指示系数的顺序是否应该在每个维上反转(true表示反转,false表示不反转)。这个操作保持了输入张量的维数。

  1. void testReserve()
  2. {
  3. Eigen::Tensor<int, 2> a(4, 3);
  4. a.setValues({ {0, 100, 200}, {300, 400, 500},
  5. {600, 700, 800}, {900, 1000, 1100} });
  6. Eigen::array<bool, 2> reverse = { true, false }; //表示第一维反转,第二维不反转
  7. Eigen::Tensor<int, 2> b = a.reverse(reverse);
  8. cout << "a" << endl << a << endl << "b" << endl << b << endl;
  9. }

 

相关测试代码见:https://github.com/Mayi-Keiji/EigenTest.git

结束~~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/79231
推荐阅读
相关标签
  

闽ICP备14008679号