簡體   English   中英

如何對特征張量執行某些操作?

[英]How to perform certain operations on eigen tensor?

我需要對特征張量執行某些操作。 但我沒有找到任何示例或文檔。

我有兩個張量:

Eigen::Tensor<float,3> feature_buffer(K,45,7); 特征緩沖區.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代碼。 我做了一切,但我被困在最后一步。

有人可以幫我嗎? 我被這一整天困住了。

提前致謝

我相信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上看到相同的代碼。

我根本沒有考慮這里的表現。 我相信你能找到更好的方法來整齊地寫這個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM