RegCNN_TF_Graph.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////////////////////////
2 // Class: RegCNNGraph modified from the original code from R.Sulej
3 // Authors: Ilsoo Seong - iseong@uci.edu
4 // Authors: R.Sulej (Robert.Sulej@cern.ch), from DUNE, FNAL/NCBJ, Sept. 2017
5 // P.Plonski, from DUNE, WUT, Sept. 2017
6 //
7 // Interface to run Tensorflow graph saved to a file. First attempts, quite functional.
8 // modified from tf_graph.cc
9 //
10 ////////////////////////////////////////////////////////////////////////////////////////////////////
11 
13 
15 #include "tensorflow/core/platform/env.h"
16 
17 //#include "tensorflow/core/kernels/conv_3d.h"
18 
19 // -------------------------------------------------------------------
20 tf::RegCNNGraph::RegCNNGraph(const char* graph_file_name, const unsigned int &ninputs, const std::vector<std::string> & outputs, bool & success)
21 {
22  success = false; // until all is done correctly
23 
24  auto status = tensorflow::NewSession(tensorflow::SessionOptions(), &fSession);
25  if (!status.ok())
26  {
27  std::cout << status.ToString() << std::endl;
28  return;
29  }
30 
31  tensorflow::GraphDef graph_def;
32  status = tensorflow::ReadBinaryProto(tensorflow::Env::Default(), graph_file_name, &graph_def);
33  if (!status.ok())
34  {
35  std::cout << status.ToString() << std::endl;
36  return;
37  }
38 
39  size_t ng = graph_def.node().size();
40 
41  // uncomment following to print debug info
42  //std::cout<<"debug info :"<<graph_file_name<<" has "<<ng<<" nodes"<<std::endl;
43  //for (size_t i= 0; i< ng; ++i) {
44  // auto node = graph_def.node()[i];
45  // std::cout<<i<<" "<<node.name()<<" "<<node.op();
46  // for (auto iter=node.attr().cbegin(); iter!=node.attr().cend(); ++iter) {
47  // std::cout<<" "<<iter->first;
48  // }
49  // std::cout<<std::endl;
50  //}
51 
52 
53  // set input names
54  std::string ss("input_");
55  for (unsigned int ii = 0; ii < ninputs; ++ii){
56  fInputNames.push_back(graph_def.node()[ii].name());
57  //std::string inname(ss+std::to_string(ii+1));
58  //fInputNames.push_back(inname);
59  //std::cout<< graph_def.node()[ii].name() << std::endl;
60  }
61 
62 
63  // last node as output if no specific name provided
64  if (outputs.empty()) { fOutputNames.push_back(graph_def.node()[ng - 1].name()); }
65  else // or last nodes with names containing provided strings
66  {
68  for (size_t n = 0; n < ng; ++n)
69  {
70  name = graph_def.node()[n].name();
71  auto pos = name.find("/");
72  if (pos != std::string::npos) { basename = name.substr(0, pos); }
73  else { continue; }
74 
75  bool found = false;
76  for (const auto & s : outputs)
77  {
78  if (name.find(s) != std::string::npos) { found = true; break; }
79  }
80  if (found)
81  {
82  if (!last.empty() && (basename != current))
83  {
84  fOutputNames.push_back(last);
85  }
86  current = basename;
87  last = name;
88  }
89  }
90  if (!last.empty()) { fOutputNames.push_back(last); }
91  }
92  if (fOutputNames.empty())
93  {
94  std::cout << "Output nodes not found in the graph." << std::endl;
95  return;
96  }
97 
98 
99  status = fSession->Create(graph_def);
100  if (!status.ok())
101  {
102  std::cout << status.ToString() << std::endl;
103  return;
104  }
105 
106  success = true; // ok, graph loaded from the file
107  std::cout<<"ok, graph loaded from the file"<<std::endl;
108 }
109 
111 {
112  auto status = fSession->Close();
113  if (!status.ok()) {
114  std::cout << "RegCNNGraph::dtor: " << "Close failed." << std::endl;
115  }
116  delete fSession;
117 }
118 // -------------------------------------------------------------------
119 
120 std::vector<float> tf::RegCNNGraph::run(
121  const std::vector< std::vector<float> > & x)
122 {
123  if (x.empty() || x.front().empty()) { return std::vector<float>(); }
124 
125  long long int rows = x.size(), cols = x.front().size();
126 
127  tensorflow::Tensor _x(tensorflow::DT_FLOAT, tensorflow::TensorShape({ 1, rows, cols, 1 }));
128  auto input_map = _x.tensor<float, 4>();
129 
130  for (long long int r = 0; r < rows; ++r) {
131  const auto & row = x[r];
132  for (long long int c = 0; c < cols; ++c) {
133  input_map(0, r, c, 0) = row[c];
134  }
135  }
136 
137  auto result = run(_x);
138  if (!result.empty()) { return result.front(); }
139  else { return std::vector<float>(); }
140 }
141 // -------------------------------------------------------------------
142 
143 std::vector< std::vector<float> > tf::RegCNNGraph::run(
144  const std::vector< std::vector< std::vector< std::vector<float> > > > & x,
145  const unsigned int &ninputs,
146  long long int samples)
147 {
148  if (ninputs == 1) return run(x);
149 
150  if ((samples == 0) || x.empty() || x.front().empty() || x.front().front().empty() || x.front().front().front().empty())
151  return std::vector< std::vector<float> >();
152 
153  if ((samples == -1) || (samples > (long long int)x.size())) { samples = x.size(); }
154 
155  long long int
156  rows = x.front().size(),
157  cols = x.front().front().size(),
158  depth = x.front().front().front().size();
159 
160  // FIXIT
161  //std::cout << "====>" << rows << " " << cols << " " << depth << std::endl;
162 
163  std::vector< tensorflow::Tensor > _x;
164  for (unsigned int ii = 0; ii < ninputs; ++ii){
165  tensorflow::Tensor _xtemp(tensorflow::DT_FLOAT, tensorflow::TensorShape({ samples, rows, cols, 1 }));
166  _x.push_back(_xtemp);
167  }
168 
169  //auto input_map = _x[0].tensor<float, 4>();
170  // fill data into _x
171  for (long long int s = 0; s < samples; ++s) {
172  const auto & sample = x[s];
173  for (long long int r = 0; r < rows; ++r) {
174  const auto & row = sample[r];
175  for (long long int c = 0; c < cols; ++c) {
176  const auto & col = row[c];
177  for (long long int d = 0; d < depth; ++d) {
178  //input_map(s, r, c, d) = col[d];
179  _x[d].tensor<float, 4>()(s, r, c, 0) = col[d];
180  }
181  }
182  }
183  }
184 
185  return run(_x);
186 
187 }
188 
189 std::vector< std::vector<float> > tf::RegCNNGraph::run(
190  const std::vector< std::vector< std::vector< std::vector<float> > > > & x,
191  const std::vector<float> cm,
192  const unsigned int &ninputs,
193  long long int samples)
194 {
195  // this is for the vertex reconstruction
196  if (ninputs == 1) return run(x);
197 
198  if ((samples == 0) || x.empty() || x.front().empty() || x.front().front().empty() || x.front().front().front().empty())
199  return std::vector< std::vector<float> >();
200 
201  if ((samples == -1) || (samples > (long long int)x.size())) { samples = x.size(); }
202 
203  long long int
204  rows = x.front().size(),
205  cols = x.front().front().size(),
206  depth = x.front().front().front().size();
207 
208  //std::cout << "====>" << rows << " " << cols << " " << depth << std::endl;
209 
210  std::vector< tensorflow::Tensor > _x;
211  //for (unsigned int ii = 0; ii < ninputs; ++ii){
212  for (unsigned int ii = 0; ii < 3; ++ii){
213  tensorflow::Tensor _xtemp(tensorflow::DT_FLOAT, tensorflow::TensorShape({ samples, rows, cols, 1 }));
214  _x.push_back(_xtemp);
215  }
216  // for center of mass input
217  tensorflow::Tensor _xtemp(tensorflow::DT_FLOAT, tensorflow::TensorShape({ samples, (unsigned int)cm.size() }));
218  _x.push_back(_xtemp);
219 
220  //auto input_map = _x[0].tensor<float, 4>();
221  // fill data into _x
222  for (long long int s = 0; s < samples; ++s) {
223  const auto & sample = x[s];
224  for (long long int r = 0; r < rows; ++r) {
225  const auto & row = sample[r];
226  for (long long int c = 0; c < cols; ++c) {
227  const auto & col = row[c];
228  for (long long int d = 0; d < depth; ++d) {
229  //input_map(s, r, c, d) = col[d];
230  _x[d].tensor<float, 4>()(s, r, c, 0) = col[d];
231  }
232  }
233  }
234  for (unsigned int icm = 0; icm < (unsigned int)cm.size(); ++icm){
235  _x[depth].tensor<float, 2>()(s, icm) = cm[icm];
236  }
237  }
238  // for center of mass input
239 
240  return run(_x);
241 
242 }
243 
244 
245 std::vector< std::vector<float> > tf::RegCNNGraph::run(
246  const std::vector< std::vector< std::vector< std::vector<float> > > > & x,
247  long long int samples)
248 {
249  if ((samples == 0) || x.empty() || x.front().empty() || x.front().front().empty() || x.front().front().front().empty())
250  return std::vector< std::vector<float> >();
251 
252  if ((samples == -1) || (samples > (long long int)x.size())) { samples = x.size(); }
253 
254  long long int
255  rows = x.front().size(),
256  cols = x.front().front().size(),
257  depth = x.front().front().front().size();
258 
259 
260  tensorflow::Tensor _x(tensorflow::DT_FLOAT, tensorflow::TensorShape({ samples, rows, cols, depth }));
261  auto input_map = _x.tensor<float, 4>();
262  for (long long int s = 0; s < samples; ++s) {
263  const auto & sample = x[s];
264  for (long long int r = 0; r < rows; ++r) {
265  const auto & row = sample[r];
266  for (long long int c = 0; c < cols; ++c) {
267  const auto & col = row[c];
268  for (long long int d = 0; d < depth; ++d) {
269  input_map(s, r, c, d) = col[d];
270  }
271  }
272  }
273  }
274 
275  return run(_x);
276 }
277 // -------------------------------------------------------------------
278 
279 std::vector< std::vector< float > > tf::RegCNNGraph::run(
280  const tensorflow::Tensor & x)
281 {
282 
283  std::vector< std::pair<std::string, tensorflow::Tensor> > inputs = {
284  { fInputNames[0], x }
285  };
286 
287  //std::cout << "run session" << std::endl;
288 
289  std::vector<tensorflow::Tensor> outputs;
290  auto status = fSession->Run(inputs, fOutputNames, {}, &outputs);
291 
292  //std::cout << "out size " << outputs.size() << std::endl;
293 
294  if (status.ok())
295  {
296  size_t samples = 0, nouts = 0;
297  for (size_t o = 0; o < outputs.size(); ++o)
298  {
299  if (o == 0) { samples = outputs[o].dim_size(0); }
300  else if ((int)samples != outputs[o].dim_size(0))
301  {
302  throw std::string("TF outputs size inconsistent.");
303  }
304  nouts += outputs[o].dim_size(1);
305  }
306  //std::cout << "samples " << samples << " nouts " << nouts << std::endl;
307 
308  std::vector< std::vector< float > > result;
309  result.resize(samples, std::vector< float >(nouts));
310 
311  size_t idx0 = 0;
312  for (size_t o = 0; o < outputs.size(); ++o)
313  {
314  auto output_map = outputs[o].tensor<float, 2>();
315 
316  size_t n = outputs[o].dim_size(1);
317  for (size_t s = 0; s < samples; ++s) {
318  std::vector< float > & vs = result[s];
319  for (size_t i = 0; i < n; ++i) {
320  vs[idx0 + i] = output_map(s, i);
321  }
322  }
323  idx0 += n;
324  }
325  return result;
326  }
327  else
328  {
329  std::cout << status.ToString() << std::endl;
330  return std::vector< std::vector< float > >();
331  }
332 }
333 
334 std::vector< std::vector< float > > tf::RegCNNGraph::run(
335  const std::vector< tensorflow::Tensor >& x)
336 {
337 
338  // make inputs to feed into the model
339  std::vector< std::pair<std::string, tensorflow::Tensor> > inputs;
340  for (size_t ii = 0; ii < x.size(); ++ii){
341  inputs.push_back(std::make_pair(fInputNames[ii], x[ii]));
342  }
343 
344  //std::cout << "run session" << std::endl;
345 
346  std::vector<tensorflow::Tensor> outputs;
347  auto status = fSession->Run(inputs, fOutputNames, {}, &outputs);
348 
349  //std::cout << "out size " << outputs.size() << std::endl;
350 
351  if (status.ok())
352  {
353  size_t samples = 0, nouts = 0;
354  for (size_t o = 0; o < outputs.size(); ++o)
355  {
356  if (o == 0) { samples = outputs[o].dim_size(0); }
357  else if ((int)samples != outputs[o].dim_size(0))
358  {
359  throw std::string("TF outputs size inconsistent.");
360  }
361  nouts += outputs[o].dim_size(1);
362  }
363  //std::cout << "samples " << samples << " nouts " << nouts << std::endl;
364 
365  std::vector< std::vector< float > > result;
366  result.resize(samples, std::vector< float >(nouts));
367 
368  size_t idx0 = 0;
369  for (size_t o = 0; o < outputs.size(); ++o)
370  {
371  auto output_map = outputs[o].tensor<float, 2>();
372 
373  size_t n = outputs[o].dim_size(1);
374  for (size_t s = 0; s < samples; ++s) {
375  std::vector< float > & vs = result[s];
376  for (size_t i = 0; i < n; ++i) {
377  vs[idx0 + i] = output_map(s, i);
378  }
379  }
380  idx0 += n;
381  }
382  return result;
383  }
384  else
385  {
386  std::cout << status.ToString() << std::endl;
387  return std::vector< std::vector< float > >();
388  }
389 }
390 
391 // -------------------------------------------------------------------
392 
static constexpr double cm
Definition: Units.h:68
static QCString name
Definition: declinfo.cpp:673
static QCString result
std::string string
Definition: nybbler.cc:12
std::vector< float > run(const std::vector< std::vector< float > > &x)
struct vector vector
std::void_t< T > n
std::vector< std::string > fInputNames
static Entry * current
std::vector< std::string > fOutputNames
list x
Definition: train.py:276
tensorflow::Session * fSession
RegCNNGraph(const char *graph_file_name, const unsigned int &ninputs, const std::vector< std::string > &outputs, bool &success)
Not-throwing constructor.
static QCString * s
Definition: config.cpp:1042
QTextStream & endl(QTextStream &s)