Eigen张量0秩转1秩后reshape再broadcast出现乱码数值问题
Eigen张量reshape+broadcast后出现乱码数值的问题排查与解决
问题描述
我编写了如下代码,先将1秩张量通过maximum操作压缩为0秩张量,再将其reshape为长度1的1秩张量,随后通过broadcast扩展为原1秩张量的长度,用于后续与原张量的计算。
//reduces a rank 1 tensor to a rank 0 tensor. Tensor<double,0> columnmaximum = input_tensor.maximum(this->imposed_dim).eval(); std::cout << "colmax is\n" << columnmaximum << std::endl; this->columnbroadcast = Eigen::array<int,1> ({M}); this->rank1base = Eigen::array<int,1> ({1}); //expands it back out to a full column. columnshape is just Tensor<double,1> columnmaximum_rk2 = columnmaximum.reshape(this->rank1base).broadcast(this->columnbroadcast); std::cout << "colmaxrk2 is\n" << columnmaximum_rk2 << std::endl;
但输出出现异常:
colmax is -2 colmaxrk2 is -2 0.238402 3.91433e-310 -3.33086 -2
我希望使用reshape+broadcast的方式而非setConstant,以便后续应用到更高维张量(如2秩张量)的复杂统计场景。请问这些乱码数值的成因是什么?是否存在基础使用错误?
问题成因与解决方法
核心错误:临时视图的生命周期问题
Eigen的reshape操作返回的是延迟计算的视图对象(TensorReshaped),它并不持有独立的数据,只是对原0秩张量columnmaximum的引用。当你直接链式调用broadcast时,生成的TensorBroadcasting对象同样是视图,而中间的TensorReshaped临时对象会在语句执行完毕后立即销毁,导致columnmaximum_rk2引用了已释放的内存空间,最终输出乱码(未初始化内存的随机值)。
修复方案
需要先将reshape后的视图显式求值,生成持有独立数据的张量,再执行broadcast操作:
//reduces a rank 1 tensor to a rank 0 tensor. Tensor<double,0> columnmaximum = input_tensor.maximum(this->imposed_dim).eval(); std::cout << "colmax is\n" << columnmaximum << std::endl; this->columnbroadcast = Eigen::array<int,1> ({M}); this->rank1base = Eigen::array<int,1> ({1}); // 先将reshape结果求值为独立的1秩张量 Tensor<double,1> reshaped_max = columnmaximum.reshape(this->rank1base).eval(); // 基于独立张量进行broadcast Tensor<double,1> columnmaximum_rk2 = reshaped_max.broadcast(this->columnbroadcast); std::cout << "colmaxrk2 is\n" << columnmaximum_rk2 << std::endl;
适配更高维场景的说明
这种修复方式完全适用于2秩及更高维张量的复杂统计场景。只需调整对应的维度参数(比如Eigen::array<int,2>),同样遵循先eval生成独立张量,再执行broadcast的流程,就能避免悬空引用问题,保证操作的安全性和正确性。
内容的提问来源于stack exchange,提问作者KeynesCoeFen
相关产品推荐
相关产品推荐

