如何在TensorFlow C++ API中设置轴?Python转C++数学运算遇问题
在TensorFlow C++ API中实现reduce_sum/reduce_mean及轴参数设置
我明白你在Python里用TensorFlow做这类归约运算超顺手,但转到C++时直接踩了坑——下面我会一步步帮你搞定Sum异常的问题,同时教你怎么像Python那样指定轴参数,完美对齐Python的用法。
先回顾Python中的实现
你给出的Python代码逻辑清晰,我帮你格式化好了:
import numpy as np import tensorflow as tf array = np.ndarray(shape=(2, 2, 3), buffer=np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]), dtype=int) mean = tf.reduce_mean(array) sum = tf.reduce_sum(array) with tf.Session() as sess: print(sess.run(mean)) # 输出6 print(sess.run(sum)) # 输出78
这段代码计算的是张量所有元素的全局均值和总和,非常直观。
C++中实现全局归约运算(解决Sum异常)
你写Sum(root.WithOpName("sum"), tens...时出现异常,十有八九是因为参数传递不符合C++ API的要求——TensorFlow C++里的Sum(对应Python的reduce_sum)需要明确输入张量和轴参数(全局归约要指定所有轴),而且会话运行的流程和Python略有差异。
下面是和Python代码完全对应的C++实现,能正确计算全局均值和总和:
#include <tensorflow/core/public/session.h> #include <tensorflow/core/platform/env.h> #include <tensorflow/core/framework/tensor.h> #include <iostream> using namespace tensorflow; int main() { // 构造和Python中完全一致的张量:shape(2,2,3) Tensor input_tensor(DT_INT32, TensorShape({2, 2, 3})); auto input_flat = input_tensor.flat<int>(); int data[] = {1,2,3,4,5,6,7,8,9,10,11,12}; std::copy(data, data+12, input_flat.data()); // 构建计算图 Scope root = Scope::NewRootScope(); auto input = ops::Placeholder(root, DT_INT32); // 全局reduce_sum:指定所有轴[0,1,2],keep_dims默认false(和Python一致) auto sum_op = ops::Sum(root.WithOpName("sum"), input, {0,1,2}); // 全局reduce_mean:同样指定所有轴 auto mean_op = ops::Mean(root.WithOpName("mean"), input, {0,1,2}); // 创建会话并运行计算 SessionOptions options; std::unique_ptr<Session> session(NewSession(options)); TF_CHECK_OK(session->Create(root.graph_def())); std::vector<std::pair<string, Tensor>> inputs = {{"Placeholder", input_tensor}}; std::vector<Tensor> outputs; // 运行sum操作 TF_CHECK_OK(session->Run(inputs, {"sum"}, {}, &outputs)); std::cout << "全局总和:" << outputs[0].scalar<int>() << std::endl; outputs.clear(); // 运行mean操作 TF_CHECK_OK(session->Run(inputs, {"mean"}, {}, &outputs)); std::cout << "全局均值:" << outputs[0].scalar<int>() << std::endl; session->Close(); return 0; }
异常排查小提示
- 如果你没指定轴参数,或者轴参数格式不对(比如不是
std::vector<int>类型),Sum操作肯定会报错; - 要确保输入张量的形状和轴参数匹配,比如不能给2D张量指定轴3;
- 记得用
TF_CHECK_OK宏,它会帮你打印具体的错误信息,排查问题更高效。
在C++中指定轴参数(和Python完全对应)
Python里tf.reduce_sum(array, axis=1)的写法,在C++里只需要把轴参数改成对应的向量就行:
- 想对**第1个轴(从0开始计数)**做归约,就设轴参数为
{1}; - 想对多个轴(比如轴0和轴2)做归约,就设为
{0,2}; - 如果要保留原维度(对应Python的
keepdims=True),可以在调用时加上ops::Sum::KeepDims(true)参数。
举个例子,对前面的张量在轴1上做reduce_sum并保留维度:
// 对轴1做reduce_sum,保留维度,结果形状为(2,1,3) auto sum_axis1_op = ops::Sum(root.WithOpName("sum_axis1"), input, {1}, ops::Sum::KeepDims(true));
这个结果和Python里tf.reduce_sum(array, axis=1, keepdims=True)完全一致。Mean操作的轴参数设置方式和Sum完全相同,只需要把ops::Sum换成ops::Mean即可。
内容的提问来源于stack exchange,提问作者fengshuxin
相关产品推荐
相关产品推荐

