How to increase BatchSize using Tensorflow C ++ API?

I took the code at https://gist.github.com/kyrs/9adf86366e9e4f04addb (which takes an opvv cv :: Mat image as input and converts it to a tensor) and I am using it to tag images with the inception_v3_2016_08_28_frozen.pb model . specified in the Tensorflow tutorial ( https://www.tensorflow.org/tutorials/image_recognition#usage_with_the_c_api ). Everything worked fine when using score 1. However, when I increase the batch size to 2 (or more), the size of the finalOutput (which is of type std :: vector) is zero.

Here's the code to reproduce the error:

// Only for VisualStudio
#define COMPILER_MSVC
#define NOMINMAX

#include <string>
#include <iostream>
#include <fstream>

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include "tensorflow/core/public/session.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/framework/tensor.h"

int batchSize = 2;
int height = 299;
int width = 299;
int depth = 3;

int mean = 0;
int stdev = 255;

// Set image paths
cv::String pathFilenameImg1 = "D:/IMGS/grace_hopper.jpg";
cv::String pathFilenameImg2 = "D:/IMGS/lenna.jpg";

// Set model paths
std::string graphFile = "D:/Tensorflow/models/inception_v3_2016_08_28_frozen.pb";
std::string labelfile = "D:/Tensorflow/models/imagenet_slim_labels.txt";
std::string InputName = "input";
std::string OutputName = "InceptionV3/Predictions/Reshape_1";


void read_prepare_image(cv::String pathImg, cv::Mat &imgPrepared) {

       // Read Color image:
       cv::Mat imgBGR = cv::imread(pathImg);

       // Now we resize the image to fit Model expected sizes:
       cv::Size s(height, width);
       cv::Mat imgResized;
       cv::resize(imgBGR, imgResized, s, 0, 0, cv::INTER_CUBIC);

       // Convert the image to float and normalize data:
       imgResized.convertTo(imgPrepared, CV_32FC1);
       imgPrepared = imgPrepared - mean;
       imgPrepared = imgPrepared / stdev;

}

int main()
{
       // Read and prepare images using OpenCV:
       cv::Mat img1, img2;
       read_prepare_image(pathFilenameImg1, img1);
       read_prepare_image(pathFilenameImg2, img2);

       // creating a Tensor for storing the data
       tensorflow::Tensor input_tensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({ batchSize, height, width, depth }));
       auto input_tensor_mapped = input_tensor.tensor<float, 4>();

       // Copy images data into the tensor:
       for (int b = 0; b < batchSize; ++b) {

             const float * source_data;

             if (b == 0) 
                    source_data = (float*)img1.data;
             else 
                    source_data = (float*)img2.data;

             for (int y = 0; y < height; ++y) {

                    const float* source_row = source_data + (y * width * depth);
                    for (int x = 0; x < width; ++x) {

                           const float* source_pixel = source_row + (x * depth);
                           const float* source_B = source_pixel + 0;
                           const float* source_G = source_pixel + 1;
                           const float* source_R = source_pixel + 2;

                           input_tensor_mapped(b, y, x, 0) = *source_R;
                           input_tensor_mapped(b, y, x, 1) = *source_G;
                           input_tensor_mapped(b, y, x, 2) = *source_B;

                    }
             }
       }

       // Load the graph:
       tensorflow::GraphDef graph_def;
       ReadBinaryProto(tensorflow::Env::Default(), graphFile, &graph_def);

       // create a session with the graph
       std::unique_ptr<tensorflow::Session> session_inception(tensorflow::NewSession(tensorflow::SessionOptions()));
       session_inception->Create(graph_def);

       // run the loaded graph 
       std::vector<tensorflow::Tensor> finalOutput;
       session_inception->Run({ { InputName,input_tensor } }, { OutputName }, {}, &finalOutput);

       // Get Top 5 classes:
       std::cerr << "final output size = " << finalOutput.size() << std::endl;
       tensorflow::Tensor output = std::move(finalOutput.at(0));
       auto scores = output.flat<float>();
       std::cerr << "scores size=" << scores.size() << std::endl;

       std::ifstream label(labelfile);
       std::string line;

       std::vector<std::pair<float, std::string>> sorted;

       for (unsigned int i = 0; i <= 1000; ++i) {
             std::getline(label, line);
             sorted.emplace_back(scores(i), line);
       }

       std::sort(sorted.begin(), sorted.end());
       std::reverse(sorted.begin(), sorted.end());
       std::cout << "size of the sorted file is " << sorted.size() << std::endl;
       for (unsigned int i = 0; i< 5; ++i)
             std::cout << "The output of the current graph has category  " << sorted[i].second << " with probability " << sorted[i].first << std::endl;

}

      

Miss anything? Any ideas?

Thanks in advance!

+3


source to share


1 answer


I had the same problem. When I switched to the model used at https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/benchmark (in another version) large batch sizes work correctly.



Note that you need to resize the input from 299,299.3 to 224,224.3 and the input and output level names to: input: 0 and output: 0

0


source







All Articles