Zah*_*abd 2 c++ eigen tensorflow
我正在运行一个 Tensorflow 模型,返回一个 3D 数组作为输出,但我无法从张量中获取该数据数组。
我确实打印了模型输出的形状,没有任何问题。
std::vector<tf::Tensor> outputs;
auto start_inference = std::chrono::high_resolution_clock::now();
_status = _session->Run({inputs}, {"k2tfout_0", "k2tfout_1"}, {}, &outputs);
if (!_status.ok())
{
std::cerr << _status.ToString() << std::endl;
return 0;
}
unsigned int output_img_n0 = outputs[0].shape().dim_size(0);
unsigned int output_img_h0 = outputs[0].shape().dim_size(1);
unsigned int output_img_w0 = outputs[0].shape().dim_size(2);
unsigned int output_img_c0 = outputs[0].shape().dim_size(3);
Run Code Online (Sandbox Code Playgroud)
该代码运行时没有任何错误,并显示了数组的形状。但是,我仍然无法从输出 Tensor 对象中获取数据。
唯一的功能是
float_t *plant_pointer = outputs[1].flat<float_t>().data();
Run Code Online (Sandbox Code Playgroud)
但它破坏了阵列形状。
编辑:
张量的输出形状是 [num,high,width,channel] === [1,480,600,3]。因此,输出是模型的语义分割图像的图像。我只想要没有第一个暗淡的图像部分,它总是为 1。
本tensorflow::Tensor类可以通过多种方法访问其内容。随着.flat您获得数组的扁平版本,.tensor为您提供完整的特征张量,然后还有其他一些类似.vec/ .matrix(例如.tensor维度数固定为 1 或 2)和flat_inner_dims/ flat_outer_dims/ flat_inner_outer_dims(为您提供一些维度折叠的张量)。您可以使用最适合您的那一种。在这种情况下,例如,如果要打印张量中的所有值,则可以使用.flat并计算相应的偏移量,或者.tensor如果您知道维数为 4,则使用:
std::vector<tf::Tensor> outputs;
auto start_inference = std::chrono::high_resolution_clock::now();
_status = _session->Run({inputs}, {"k2tfout_0", "k2tfout_1"}, {}, &outputs);
if (!_status.ok())
{
std::cerr << _status.ToString() << std::endl;
return 0;
}
unsigned int output_img_n0 = outputs[0].shape().dim_size(0);
unsigned int output_img_h0 = outputs[0].shape().dim_size(1);
unsigned int output_img_w0 = outputs[0].shape().dim_size(2);
unsigned int output_img_c0 = outputs[0].shape().dim_size(3);
for (unsigned int ni = 0; ni < output_img_n0; ni++)
{
for (unsigned int hi = 0; hi < output_img_h0; hi++)
{
for (unsigned int wi = 0; wi < output_img_w0; wi++)
{
for (unsigned int ci = 0; ci < output_img_c0; ci++)
{
float_t value;
// Get vaule through .flat()
unsigned int offset = ni * output_img_h0 * output_img_w0 * output_img_c0 +
hi * output_img_w0 * output_img_c0 +
wi * output_img_c0 +
ci;
value = outputs[0].flat<float_t>()(offset);
// Get value through .tensor()
value = outputs[0].tensor<float_t, 4>()(ni, hi, wi, ci);
std::cout << "output[0](" << ni << ", " << hi << ", " << wi << ", " << ci << ") = ";
std::cout << value << std::endl;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,尽管这些方法创建的Eigen::TensorMap对象并不昂贵,但您可能更愿意只调用它们一次,然后多次查询张量对象。例如:
// Make tensor
tf::TTypes<float_t, 4>::Tensor outputTensor0 = outputs[0].tensor<float_t, 4>();
// Query tensor multiple times
for (...)
{
std::cout << outputTensor0(ni, hi, wi, ci) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
编辑:
如果您想获得指向张量数据的指针(例如,从同一缓冲区构建另一个对象,避免复制或迭代),您也可以这样做。一种选择是使用该.tensor_data方法,该方法返回 a tensorflow::StringPiece,而后者又是 a absl::string_view,它只是 的 polyfill std::string_view。所以.data这个对象的方法会给你一个指向张量的底层字节缓冲区的指针(注意文档中的警告.tensor_data:“底层张量缓冲区被引用”,所以不要让返回的对象在使用时被销毁缓冲)。因此,您可以这样做:
tf::StringPiece output0Str = outputs[0].tensor_data();
const char* output0Ptr = output0Str.data();
Run Code Online (Sandbox Code Playgroud)
但是,这为您提供了一个指针,char因此您必须将其强制转换才能将其用作浮点数。它应该是安全的,但它看起来很丑,所以你可以让 Eigen 为你做。所有 Eigen 对象都有一个.data方法,该方法将其类型的指针返回到底层缓冲区。例如:
const float_t* output0Ptr = outputs[0].flat<float_t>().data();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3602 次 |
| 最近记录: |