TensorFlow C++图像分类:如何将二维像素向量作为输入
嘿,我来帮你搞定这个问题!你已经走到创建张量这一步了,剩下的就是把二维向量的亮度像素值正确填充进去,然后喂给计算图做预测,我给你一步步拆解清楚:
第一步:先对齐模型的输入要求
首先你得确认训练好的模型对输入张量的要求:
- 形状:绝大多数图像分类模型的输入是
[batch_size, height, width, channels](TensorFlow默认的NHWC格式),因为你是灰度图,所以channels=1;如果是单张图片预测,batch_size=1,所以最终形状应该是[1, H, W, 1](H是你的二维向量行数,W是列数)。 - 数据类型:大部分模型用
float32,所以你需要把int类型的像素值转成float。 - 归一化规则:要和训练时一致,比如有的模型要求像素值归一化到0-1(除以255),有的是减均值再除以标准差,这一步不能错,否则预测结果会乱。
第二步:把二维向量转换成连续的一维数据
TensorFlow的张量需要连续的内存块,所以你得先把std::vector<std::vector<int>>展平成一维数组,同时做类型转换和归一化:
// 假设你的二维亮度像素向量是vec2d int img_height = vec2d.size(); int img_width = vec2d[0].size(); std::vector<float> flattened_data; flattened_data.reserve(img_height * img_width); // 预分配内存提升效率 // 遍历二维向量,转成float并按要求归一化 for (const auto& row : vec2d) { for (int pixel_val : row) { // 这里示例是归一化到0-1范围,根据你的模型调整 flattened_data.push_back(static_cast<float>(pixel_val) / 255.0f); } }
第三步:填充张量并设置输入
接下来把一维数据填充到张量里,如果你之前创建的张量形状不对,建议重新创建符合要求的张量:
// 定义输入张量的形状:[batch_size=1, height, width, channels=1] tensorflow::TensorShape input_shape({1, img_height, img_width, 1}); // 创建float32类型的张量 tensorflow::Tensor input_tensor(tensorflow::DT_FLOAT, input_shape); // 获取张量的可写映射,把flattened_data复制进去 auto input_tensor_map = input_tensor.tensor<float, 4>(); std::copy(flattened_data.begin(), flattened_data.end(), input_tensor_map.data());
第四步:运行会话完成预测
最后就是把这个张量喂给计算图的输入节点,运行会话得到预测结果:
// 假设你已经初始化好了session和graph,输入节点名称是"input",输出节点是"predictions" std::vector<std::pair<std::string, tensorflow::Tensor>> feed_dict = { {"input", input_tensor} }; std::vector<tensorflow::Tensor> outputs; // 执行预测 tensorflow::Status run_status = session->Run(feed_dict, {"predictions"}, {}, &outputs); if (!run_status.ok()) { std::cerr << "预测出错:" << run_status.ToString() << std::endl; return -1; } // 处理输出结果,比如取出分类概率 auto output_probs = outputs[0].tensor<float, 2>(); // 输出形状是[1, num_classes],遍历每个类别的概率 for (int i = 0; i < output_probs.dimension(1); ++i) { std::cout << "类别 " << i << " 的概率:" << output_probs(0, i) << std::endl; }
几个要注意的细节
- 如果你的模型输入是NCHW格式(比如部分卷积模型),那张量形状要改成
[1, 1, img_height, img_width],填充数据时也要注意顺序。 - 确保你的二维向量尺寸和模型要求的输入尺寸一致,比如模型要求224x224,那你的vec2d必须是224行224列,否则要先做resize处理。
- 要是你之前创建的张量是正确形状的,也可以直接用
tensor.tensor<float,4>()获取映射后复制数据,不用重新创建。
内容的提问来源于stack exchange,提问作者Satinger
相关产品推荐
相关产品推荐

