我有一系列形状为
[B, n, C]
的张量,其中 B
和 C
具有恒定大小,并且 n 在张量之间变化(例如,n in [1, 5]
)。我想将所有这些张量连接成一个形状为 [B, k, C]
的张量,其中 k
是 n
所有值的总和。在 numpy 中,这将是:
import numpy as np
batch_size = 2
num_channels = 4
values = []
for i in range(0, 5):
tensor = np.ones([batch_size, i+1, num_channels]) * i
values.append(tensor)
print(np.concatenate(values, axis=1))
结果
[[[0. 0. 0. 0.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]
[2. 2. 2. 2.]
[2. 2. 2. 2.]
[2. 2. 2. 2.]
[3. 3. 3. 3.]
[3. 3. 3. 3.]
[3. 3. 3. 3.]
[3. 3. 3. 3.]
[4. 4. 4. 4.]
[4. 4. 4. 4.]
[4. 4. 4. 4.]
[4. 4. 4. 4.]
[4. 4. 4. 4.]]
[[0. 0. 0. 0.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]
[2. 2. 2. 2.]
[2. 2. 2. 2.]
[2. 2. 2. 2.]
[3. 3. 3. 3.]
[3. 3. 3. 3.]
[3. 3. 3. 3.]
[3. 3. 3. 3.]
[4. 4. 4. 4.]
[4. 4. 4. 4.]
[4. 4. 4. 4.]
[4. 4. 4. 4.]
[4. 4. 4. 4.]]]
如何在 Eigen 中实现这一目标?
我找到了使用切片的解决方案:
#include <Eigen/Core>
#include <Eigen/Dense>
#include <iostream>
#include <vector>
#include "eigen3/unsupported/Eigen/CXX11/Tensor"
using IndexType = EIGEN_DEFAULT_DENSE_INDEX_TYPE;
using TensorType3D = Eigen::Tensor<float, 3, Eigen::RowMajor, IndexType>;
int main() {
// Initialization:
// Tensors of size [B, i+1, C], with i in [0, 4]. Each of this
// has i as its value.
TensorType3D output(2, 15, 4);
std::vector<TensorType3D> values;
for (int i = 0; i < 5; ++i) {
TensorType3D input(2, i + 1, 4);
for (int j = 0; j < 2; ++j) {
for (int m = 0; m < i + 1 + 1; ++m) {
for (int k = 0; k < 4; ++k) {
input(j, m, k) = i;
}
}
}
values.push_back(input);
}
// Assign values via slicing.
int previous = 0;
for (int i = 0; i < values.size(); ++i) {
const int size = values[i].dimension(1);
output.slice(Eigen::array<Eigen::Index, 3>{0, previous, 0},
Eigen::array<Eigen::Index, 3>{2, size, 4}) = values[i];
previous += size;
}
std::cout << output << "\n";
return 0;
}
输出相当于Python的:
0 0 0 0
1 1 1 1
1 1 1 1
2 2 2 2
2 2 2 2
2 2 2 2
3 3 3 3
3 3 3 3
3 3 3 3
3 3 3 3
4 4 4 4
4 4 4 4
4 4 4 4
4 4 4 4
4 4 4 4
0 0 0 0
1 1 1 1
1 1 1 1
2 2 2 2
2 2 2 2
2 2 2 2
3 3 3 3
3 3 3 3
3 3 3 3
3 3 3 3
4 4 4 4
4 4 4 4
4 4 4 4
4 4 4 4
4 4 4 4
.concatenate
:
#include <unsupported/Eigen/CXX11/Tensor>
#include <iostream>
int main(){
Eigen::Tensor<int,3> A(2,5,4);
Eigen::Tensor<int,3> B(2,7,4);
Eigen::Tensor<int,3> C = A.concatenate(B, 1); // Concatenate along axis 1 of A
std::cout << C.dimensions();
}
打印
[2, 12, 4]
。