This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Interpreting the output of a Deep Learning network after TIDL conversion has been applied



Hi there, 

I have a Deep Learning network of the following structure: 

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(dim_x,dim_y,3))) 
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(16, (3,3), activation='relu'))
model.add(layers.AveragePooling2D((2,2)))
model.add(layers.Conv2D(8, (3,3), activation='relu'))
model.add(layers.AveragePooling2D((2,2)))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(2))
model.add(layers.Softmax())

The output of this network when in the Python Tensorflow environment is an array of 2 numbers, each element of the array is the probability that the input to the classifier network is either "false" or "true". 

i.e. its a very simple classifier network that looks for the presence of a white square on a black background 

I have converted this network for use on an AM57xx processor using the TIDL tool and now I wish to know how to correctly interpret the output of the network. I do not have any TI example code as I am using a BeagleBone AI 


Below are the code snippets for the important parts of the code I am currently running: 

 configuration.numFrames = 0;
    configuration.inData = "/var/lib/cloud9/img_0.png";
    configuration.netBinFile = "/var/lib/cloud9/Ziath/models/BBAI_model_test/probability_colour_cnn_classifier_net.bin";
    configuration.paramsBinFile = "/var/lib/cloud9/Ziath/models/BBAI_model_test/probability_colour_cnn_classifier_param.bin";  
    configuration.preProcType = 2;
    configuration.inWidth = 100;
    configuration.inHeight = 100;
    configuration.inNumChannels = 3;
    configuration.enableApiTrace = true;
    configuration.runFullNet = true;


imgutil::PreprocessImage(src, eop->GetInputBufferPtr(), configuration);

int = tf_postprocess((uchar*) eop->GetOutputBufferPtr(), selected_items_size, selected_items, configuration, label_count);

int tf_postprocess(uchar *in, int selected_items_size, int * selected_items, Configuration & configuration, int label_count)
{
  int top_candidates = 3; 
  const int k = top_candidates;
  int rpt_id = -1;

  typedef std::pair<uchar, int> val_index;
  
  auto cmp = [](val_index &left, val_index &right) { return left.first > right.first; };
  std::priority_queue<val_index, std::vector<val_index>, decltype(cmp)> queue(cmp);
  
  #ifdef DEBUG
    std::bitset<8> x(in[0]);
    std::cout << "Start PostProcess" << std::endl;
    std::cout << "input: " << x << std::endl;
  #endif 
  
  
  // initialize priority queue with smallest value on top
  for (int i = 0; i < k; i++) {
    if(configuration.enableApiTrace) {
        std::bitset<8> y(in[i]);
        std::cout << "push(" << i << "):"  << y << std::endl;
    }
                  
    queue.push(val_index(in[i], i));
  }
  // for rest input, if larger than current minimum, pop mininum, push new val
  for (int i = k; i < label_count; i++)
  {
    if (in[i] > queue.top().first)
    {
      queue.pop();
      queue.push(val_index(in[i], i));
    }
  }

  // output top k values in reverse order: largest val first
  std::vector<val_index> sorted;
  while (! queue.empty())
   {
    sorted.push_back(queue.top());
    queue.pop();
  }
  

  for (int i = 0; i < k; i++)
  {
      int id = sorted[i].second;
      
      #ifdef DEBUG
        std::cout << "id is: " << id << std::endl;
      #endif

      if (tf_expected_id(id, selected_items_size, selected_items))
      {
        rpt_id = id;
      }
  }
  
  printf("#####rpt_id = %i\n\r", rpt_id);
  return rpt_id;
}

The top 3 returned candidates for my input images are as follows: 

img_0 (square present)
push(0):11001000
push(1):01110101
push(2):00011001

img_1 (no square)
push(0):11001000
push(1):00000101
push(2):10001011

img_2 (square present)
push(0):11001000
push(1):00000101
push(2):01101111

img_3 (square present)
push(0):11001000
push(1):10100101
push(2):11010010

img_4 (square present)
push(0):11001000
push(1):00100101
push(2):11101111

img_5 (no square)
push(0):11001000
push(1):11000101
push(2):01110001

img_6 (square present)
push(0):11001000
push(1):10000101
push(2):00111010

img_7 (no square)
push(0):11001000
push(1):00000101
push(2):01100110

If anyone could point me in the correct direction for interpreting the output of the network on the AM57xx device, that would be brilliant 

Thanks!