如何对特征张量进行某些操作?



我需要对特征张量进行一些操作。但是我没有找到任何例子或文档。

我有两个张量

特征:Tensor feature_buffer.setZero ();

VectorXi number_buffer (K);

我需要对张量进行以下操作

feature_buffer[:, :, -3:] = feature_buffer[:, :, :3] - 
feature_buffer[:, :, :3].sum(axis=1, keepdims=True)/number_buffer.reshape(K, 1, 1)

以上代码为numpy代码。我什么都做了,可就是做不到最后一步。

有人能帮我一下吗?这一整天我都受不了了。

Thanks in advance

我认为numpy-运算在两个维度不匹配的地方是病态的。我对numpy ndarray操作不是很熟悉,所以这可能是我的一个简单的误解,但如果该操作成功,我的猜测是numpy可以在一些维度匹配时做出有根据的猜测…

也就是说,我得到了你想要完成的要点,所以我在下面一步一步地写下了等效的c++代码。我对操作进行了一些自由的重新解释,以使维度正确匹配:最后,如果不是完全相同的操作,我希望通过阅读语法可以澄清问题。

#include <unsupported/Eigen/CXX11/Tensor>
int main(){
long d0 = 10; // This is "K"
long d1 = 10;
long d2 = 10;
Eigen::Tensor<float,3> feature_buffer(d0,d1,d2);
Eigen::Tensor<float,1> number_buffer(d0);
feature_buffer.setRandom();
number_buffer.setRandom();
// Step 1) Define numpy "feature_buffer[:,:,-3:]" in C++
std::array<long,3> offsetA = {0, 0, d2-3};
std::array<long,3> extentA = {d0,d1,3};
auto feature_sliceA        = feature_buffer.slice(offsetA,extentA);
// Note: feature_sliceA is a "slice" object: it does not own the data in feature_buffer,
//       it merely points to a rectangular subregion inside of feature_buffer.
//       If you'd rather make a copy of that data, replace "auto" with "Eigen::Tensor<float,3>".
// Step 2) Define numpy "feature_buffer[:, :, :3]" in C++
std::array<long,3> offsetB = {0, 0, 0};
std::array<long,3> extentB = {d0,d1,3};
auto feature_sliceB        = feature_buffer.slice(offsetA,extentA);
// Step 3) Perform the numpy operation "feature_buffer[:, :, :3].sum(axis=1, keepdims=True)"
std::array<long,1> sumDims         = {1};
std::array<long,3> newDims         = {d0,1,3}; // This takes care of "keepdims=True": d1 is summed over, then kept as size 1.
Eigen::Tensor<float,3> feature_sum = feature_sliceB.sum(sumDims).reshape(newDims);
// Step 4) The numpy division "feature_buffer[:, :, :3].sum(axis=1, keepdims=True)/number_buffer.reshape(K, 1, 1)"
//         looks ill-formed: There are fewer elements in [:, :, :3] than in number_buffer.reshape(K, 1, 1).
//         To go head, we could interpret this as dividing each of the 3 "columns" (in dimension 2) by number_buffer:
//         Something like: "feature_sum/number_buffer.reshape(d0, 1, 3)"
std::array<long,3> numBcast         = {1,1,3};
std::array<long,3> numDims          = {d0,1,1};
Eigen::Tensor<float,3> number_bcast = number_buffer.reshape(numDims).broadcast(numBcast);

// Step 5) Perform the division operation
Eigen::Tensor<float,3> feature_div = feature_sum/number_bcast;

// Step 6) Perform the numpy subtraction 
//         "feature_buffer[:, :, :3] - feature_buffer[:, :, :3].sum(axis=1, keepdims=True)/number_buffer.reshape(K, 1, 1)
//         in our current program this corresponds to 
//              "feature_sliceB - feature_div"
//          Actually, this is also ill-formed, since: 
//              feature_sliceB has dimensions (d0, d1, 3) = (10, 10, 3)
//              feature_div    has dimensions (d0,  1, 3) = (10,  1, 3)
//
//          To go ahead we can reinterpret once again: Assume the subtraction happens once for each dimension 1.
//          We use broadcast again to copy the contents of feature_div d1 times along dimension 1
std::array<long,3> divBcast = {1,10,1};
Eigen::Tensor<float,3> feature_div_bcast = feature_div.broadcast(divBcast);

// Step 7) Perform the main assignment operation
feature_sliceA = feature_sliceB - feature_div_bcast;
}

您可以在godbolt上看到相同的代码。

我在这里根本没有考虑性能。我相信你能找到更好的方法把它写得更整齐。

相关内容

  • 没有找到相关文章

最新更新