在 C++ 中索引张量流输出张量
Indexing tensorflow output tensor in c++
我正在使用 C++ API 加载图表 (*.pb)。该图已在 Python 中使用图的输入形状定义进行设置和训练:tf.placeholder(tf.float32, [None, 84, 84, 1], name='in'
。这应该允许任意批量大小。
在开始会话并加载图形后,我拍摄了一个矩形灰度 OpenCV Mat 图像,并将其拆分为较小的正方形图像,将它们调整为所需的输入大小并将它们存储在一个向量中:
cv::Size smallSize(splitLength, img_in.size().height);
std::vector<Mat> input_Images;
int y = 0;
for (int x = 0; x < img_in.cols; x += smallSize.width)
{
cv::Rect rect = cv::Rect(x,y, smallSize.width, smallSize.height);
cv::Mat temp = cv::Mat(img_in, rect);
cv::Size s(height_out, width_out);
cv::resize(temp,process_img,s,0,0,cv::INTER_CUBIC);
input_Images.push_back(process_img);
}
然后我将这个数组写入tensorflow张量:
tensorflow::Tensor input_tensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({input_Images.size(), height_out, width_out, 1}));
auto input_tensor_mapped = input_tensor.tensor<float, 4>();
for (int i = 0; i < input_Images.size(); i++) {
Mat image = input_Images[i];
const float * source_data = (float*) image.data;
for (int h = 0; h < image.rows; ++h) {
const float* source_row = source_data + (h * image.cols * image.channels());
for (int w = 0; w < image.cols; ++w) {
const float* source_pixel = source_row + (w * image.channels());
for (int c = 0; c < image.channels(); ++c) {
const float* source_value = source_pixel + c;
input_tensor_mapped(i, h, w, c) = *source_value;
}
}
}
}
我得到一个形状为 [16,84,84,1] 的张量。然后我运行 session:
session_create_status = session_deepcytometry->Run({{ inputLayer, nn_input_tensor}},{outputLayer},{},&finalOutput);
这似乎工作得很好。当我 运行 std::cout finalOutput[0].DebugString() << "\n";
我得到输出: stringTensor<type: float shape: [16,4] values: [7.8605752 10.652889 -24.507538]...>
在批量大小为 1 的情况下,它显示:stringTensor<type: float shape: [1,4] values: [7.8605752 10.652889 -24.507538]...>
finalOutput.size();
在任何一种情况下都是 1。
如果批量大小为 1,我使用简单循环检索 class 分数:
for(int i=0; i<nClasses; i++){
result.push_back(finalOutput[0].flat<float>()(i));
}
现在的问题是,如果批量大小为 16,我该怎么做?
您应该像开始时一样访问张量。如果输出形状的秩为 2,则使用
auto finalOutputTensor = finalOutput[0].tensor<float, 2>();
和
for(int b=0; b<BatchSize;b++)
for(int i=0; i<nClasses; i++){
cout << b << "th output for class "<<i<<" is "<< finalOutputTensor(b, i) <<end;
}
在处理平面张量的情况下(作为等效替代方案),您还可以使用
for(int b=0; b<BatchSize;b++)
for(int i=0; i<nClasses; i++){
cout << b << "th output for class "<<i<<" is "<< finalOutput[0].flat<float>()(b * nClasses + i) << end;
}
我正在使用 C++ API 加载图表 (*.pb)。该图已在 Python 中使用图的输入形状定义进行设置和训练:tf.placeholder(tf.float32, [None, 84, 84, 1], name='in'
。这应该允许任意批量大小。
在开始会话并加载图形后,我拍摄了一个矩形灰度 OpenCV Mat 图像,并将其拆分为较小的正方形图像,将它们调整为所需的输入大小并将它们存储在一个向量中:
cv::Size smallSize(splitLength, img_in.size().height);
std::vector<Mat> input_Images;
int y = 0;
for (int x = 0; x < img_in.cols; x += smallSize.width)
{
cv::Rect rect = cv::Rect(x,y, smallSize.width, smallSize.height);
cv::Mat temp = cv::Mat(img_in, rect);
cv::Size s(height_out, width_out);
cv::resize(temp,process_img,s,0,0,cv::INTER_CUBIC);
input_Images.push_back(process_img);
}
然后我将这个数组写入tensorflow张量:
tensorflow::Tensor input_tensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({input_Images.size(), height_out, width_out, 1}));
auto input_tensor_mapped = input_tensor.tensor<float, 4>();
for (int i = 0; i < input_Images.size(); i++) {
Mat image = input_Images[i];
const float * source_data = (float*) image.data;
for (int h = 0; h < image.rows; ++h) {
const float* source_row = source_data + (h * image.cols * image.channels());
for (int w = 0; w < image.cols; ++w) {
const float* source_pixel = source_row + (w * image.channels());
for (int c = 0; c < image.channels(); ++c) {
const float* source_value = source_pixel + c;
input_tensor_mapped(i, h, w, c) = *source_value;
}
}
}
}
我得到一个形状为 [16,84,84,1] 的张量。然后我运行 session:
session_create_status = session_deepcytometry->Run({{ inputLayer, nn_input_tensor}},{outputLayer},{},&finalOutput);
这似乎工作得很好。当我 运行 std::cout finalOutput[0].DebugString() << "\n";
我得到输出: stringTensor<type: float shape: [16,4] values: [7.8605752 10.652889 -24.507538]...>
在批量大小为 1 的情况下,它显示:stringTensor<type: float shape: [1,4] values: [7.8605752 10.652889 -24.507538]...>
finalOutput.size();
在任何一种情况下都是 1。
如果批量大小为 1,我使用简单循环检索 class 分数:
for(int i=0; i<nClasses; i++){
result.push_back(finalOutput[0].flat<float>()(i));
}
现在的问题是,如果批量大小为 16,我该怎么做?
您应该像开始时一样访问张量。如果输出形状的秩为 2,则使用
auto finalOutputTensor = finalOutput[0].tensor<float, 2>();
和
for(int b=0; b<BatchSize;b++)
for(int i=0; i<nClasses; i++){
cout << b << "th output for class "<<i<<" is "<< finalOutputTensor(b, i) <<end;
}
在处理平面张量的情况下(作为等效替代方案),您还可以使用
for(int b=0; b<BatchSize;b++)
for(int i=0; i<nClasses; i++){
cout << b << "th output for class "<<i<<" is "<< finalOutput[0].flat<float>()(b * nClasses + i) << end;
}