tesseract  3.05.02
tesseract::NeuralNet Class Reference

#include <neural_net.h>

Classes

struct  Node
 
struct  WeightedNode
 

Public Member Functions

 NeuralNet ()
 
virtual ~NeuralNet ()
 
template<typename Type >
bool FeedForward (const Type *inputs, Type *outputs)
 
template<typename Type >
bool GetNetOutput (const Type *inputs, int output_id, Type *output)
 
int in_cnt () const
 
int out_cnt () const
 

Static Public Member Functions

static NeuralNetFromFile (const string file_name)
 
static NeuralNetFromInputBuffer (InputFileBuffer *ib)
 

Protected Member Functions

void Init ()
 
void Clear ()
 
template<class ReadBuffType >
bool ReadBinary (ReadBuffType *input_buff)
 
bool SetConnection (int from, int to)
 
bool CreateFastNet ()
 
float * AllocWgt (int wgt_cnt)
 
template<typename Type >
bool FastFeedForward (const Type *inputs, Type *outputs)
 
template<typename Type >
bool FastGetNetOutput (const Type *inputs, int output_id, Type *output)
 

Protected Attributes

bool read_only_
 
int in_cnt_
 
int out_cnt_
 
int neuron_cnt_
 
int wts_cnt_
 
Neuronneurons_
 
int alloc_wgt_cnt_
 
vector< vector< float > * > wts_vec_
 
bool auto_encoder_
 
vector< float > inputs_max_
 
vector< float > inputs_min_
 
vector< float > inputs_mean_
 
vector< float > inputs_std_dev_
 
vector< Nodefast_nodes_
 

Static Protected Attributes

static const int kWgtChunkSize = 0x10000
 
static const unsigned int kNetSignature = 0xFEFEABD0
 

Detailed Description

Definition at line 31 of file neural_net.h.

Constructor & Destructor Documentation

◆ NeuralNet()

tesseract::NeuralNet::NeuralNet ( )

Definition at line 24 of file neural_net.cpp.

24  {
25  Init();
26 }

◆ ~NeuralNet()

tesseract::NeuralNet::~NeuralNet ( )
virtual

Definition at line 28 of file neural_net.cpp.

28  {
29  // clean up the wts chunks vector
30  for (int vec = 0; vec < static_cast<int>(wts_vec_.size()); vec++) {
31  delete wts_vec_[vec];
32  }
33  // clean up neurons
34  delete []neurons_;
35  // clean up nodes
36  for (int node_idx = 0; node_idx < neuron_cnt_; node_idx++) {
37  delete []fast_nodes_[node_idx].inputs;
38  }
39 
40 }
vector< vector< float > * > wts_vec_
Definition: neural_net.h:92
vector< Node > fast_nodes_
Definition: neural_net.h:105

Member Function Documentation

◆ AllocWgt()

float * tesseract::NeuralNet::AllocWgt ( int  wgt_cnt)
protected

Definition at line 195 of file neural_net.cpp.

195  {
196  // see if need to allocate a new chunk of wts
197  if (wts_vec_.size() == 0 || (alloc_wgt_cnt_ + wgt_cnt) > kWgtChunkSize) {
198  // add the new chunck to the wts_chunks vector
199  wts_vec_.push_back(new vector<float> (kWgtChunkSize));
200  alloc_wgt_cnt_ = 0;
201  }
202  float *ret_ptr = &((*wts_vec_.back())[alloc_wgt_cnt_]);
203  // incr usage counts
204  alloc_wgt_cnt_ += wgt_cnt;
205  wts_cnt_ += wgt_cnt;
206  return ret_ptr;
207 }
vector< vector< float > * > wts_vec_
Definition: neural_net.h:92
static const int kWgtChunkSize
Definition: neural_net.h:85

◆ Clear()

void tesseract::NeuralNet::Clear ( )
inlineprotected

Definition at line 109 of file neural_net.h.

109  {
110  for (int node = 0; node < neuron_cnt_; node++) {
111  neurons_[node].Clear();
112  }
113  }
void Clear()
Definition: neuron.h:46

◆ CreateFastNet()

bool tesseract::NeuralNet::CreateFastNet ( )
protected

Definition at line 133 of file neural_net.cpp.

133  {
134  fast_nodes_.resize(neuron_cnt_);
135  // build the node structures
136  int wts_cnt = 0;
137  for (int node_idx = 0; node_idx < neuron_cnt_; node_idx++) {
138  Node *node = &fast_nodes_[node_idx];
139  if (neurons_[node_idx].node_type() == Neuron::Input) {
140  // Input neurons have no fan-in
141  node->fan_in_cnt = 0;
142  node->inputs = NULL;
143  // Input bias is the normalization offset computed from
144  // training input stats
145  if (fabs(inputs_max_[node_idx] - inputs_min_[node_idx]) <
146  kMinInputRange) {
147  // if the range approaches zero, the stdev is not defined,
148  // this indicates that this input does not change.
149  // Set the bias to zero
150  node->bias = 0.0f;
151  } else {
152  node->bias = inputs_min_[node_idx] + (inputs_mean_[node_idx] *
153  (inputs_max_[node_idx] - inputs_min_[node_idx]));
154  }
155  } else {
156  node->bias = neurons_[node_idx].bias();
157  node->fan_in_cnt = neurons_[node_idx].fan_in_cnt();
158  // allocate memory for fan-in nodes
159  node->inputs = new WeightedNode[node->fan_in_cnt];
160  for (int fan_in = 0; fan_in < node->fan_in_cnt; fan_in++) {
161  // identify fan-in neuron
162  const int id = neurons_[node_idx].fan_in(fan_in)->id();
163  // Feedback connections are not allowed and should never happen
164  if (id >= node_idx) {
165  return false;
166  }
167  // add the the fan-in neuron and its wgt
168  node->inputs[fan_in].input_node = &fast_nodes_[id];
169  float wgt_val = neurons_[node_idx].fan_in_wts(fan_in);
170  // for input neurons normalize the wgt by the input scaling
171  // values to save time during feedforward
172  if (neurons_[node_idx].fan_in(fan_in)->node_type() == Neuron::Input) {
173  // if the range approaches zero, the stdev is not defined,
174  // this indicates that this input does not change.
175  // Set the weight to zero
176  if (fabs(inputs_max_[id] - inputs_min_[id]) < kMinInputRange) {
177  wgt_val = 0.0f;
178  } else {
179  wgt_val /= ((inputs_max_[id] - inputs_min_[id]) *
180  inputs_std_dev_[id]);
181  }
182  }
183  node->inputs[fan_in].input_weight = wgt_val;
184  }
185  // incr wgt count to validate against at the end
186  wts_cnt += node->fan_in_cnt;
187  }
188  }
189  // sanity check
190  return wts_cnt_ == wts_cnt;
191 }
int fan_in_cnt() const
Definition: neuron.h:111
Neuron * fan_in(int idx) const
Definition: neuron.h:114
vector< float > inputs_max_
Definition: neural_net.h:96
float fan_in_wts(int idx) const
Definition: neuron.h:117
vector< float > inputs_min_
Definition: neural_net.h:98
vector< float > inputs_std_dev_
Definition: neural_net.h:102
float bias() const
Definition: neuron.h:123
int id() const
Definition: neuron.h:108
vector< float > inputs_mean_
Definition: neural_net.h:100
vector< Node > fast_nodes_
Definition: neural_net.h:105

◆ FastFeedForward()

template<typename Type >
template bool tesseract::NeuralNet::FastFeedForward ( const Type *  inputs,
Type *  outputs 
)
protected

Definition at line 61 of file neural_net.cpp.

62  {
63  int node_idx = 0;
64  Node *node = &fast_nodes_[0];
65  // feed inputs in and offset them by the pre-computed bias
66  for (node_idx = 0; node_idx < in_cnt_; node_idx++, node++) {
67  node->out = inputs[node_idx] - node->bias;
68  }
69  // compute nodes activations and outputs
70  for (;node_idx < neuron_cnt_; node_idx++, node++) {
71  double activation = -node->bias;
72  for (int fan_in_idx = 0; fan_in_idx < node->fan_in_cnt; fan_in_idx++) {
73  activation += (node->inputs[fan_in_idx].input_weight *
74  node->inputs[fan_in_idx].input_node->out);
75  }
76  node->out = Neuron::Sigmoid(activation);
77  }
78  // copy the outputs to the output buffers
79  node = &fast_nodes_[neuron_cnt_ - out_cnt_];
80  for (node_idx = 0; node_idx < out_cnt_; node_idx++, node++) {
81  outputs[node_idx] = node->out;
82  }
83  return true;
84 }
static float Sigmoid(float activation)
Definition: neuron.cpp:94
vector< Node > fast_nodes_
Definition: neural_net.h:105

◆ FastGetNetOutput()

template<typename Type >
template bool tesseract::NeuralNet::FastGetNetOutput ( const Type *  inputs,
int  output_id,
Type *  output 
)
protected

Definition at line 234 of file neural_net.cpp.

236  {
237  // feed inputs in and offset them by the pre-computed bias
238  int node_idx = 0;
239  Node *node = &fast_nodes_[0];
240  for (node_idx = 0; node_idx < in_cnt_; node_idx++, node++) {
241  node->out = inputs[node_idx] - node->bias;
242  }
243 
244  // compute nodes' activations and outputs for hidden nodes if any
245  int hidden_node_cnt = neuron_cnt_ - out_cnt_;
246  for (;node_idx < hidden_node_cnt; node_idx++, node++) {
247  double activation = -node->bias;
248  for (int fan_in_idx = 0; fan_in_idx < node->fan_in_cnt; fan_in_idx++) {
249  activation += (node->inputs[fan_in_idx].input_weight *
250  node->inputs[fan_in_idx].input_node->out);
251  }
252  node->out = Neuron::Sigmoid(activation);
253  }
254 
255  // compute the output of the required output node
256  node += output_id;
257  double activation = -node->bias;
258  for (int fan_in_idx = 0; fan_in_idx < node->fan_in_cnt; fan_in_idx++) {
259  activation += (node->inputs[fan_in_idx].input_weight *
260  node->inputs[fan_in_idx].input_node->out);
261  }
262  (*output) = Neuron::Sigmoid(activation);
263  return true;
264 }
static float Sigmoid(float activation)
Definition: neuron.cpp:94
vector< Node > fast_nodes_
Definition: neural_net.h:105

◆ FeedForward()

template<typename Type >
template bool tesseract::NeuralNet::FeedForward ( const Type *  inputs,
Type *  outputs 
)

Definition at line 88 of file neural_net.cpp.

89  {
90  // call the fast version in case of readonly nets
91  if (read_only_) {
92  return FastFeedForward(inputs, outputs);
93  }
94  // clear all neurons
95  Clear();
96  // for auto encoders, apply no input normalization
97  if (auto_encoder_) {
98  for (int in = 0; in < in_cnt_; in++) {
99  neurons_[in].set_output(inputs[in]);
100  }
101  } else {
102  // Input normalization : subtract mean and divide by stddev
103  for (int in = 0; in < in_cnt_; in++) {
104  neurons_[in].set_output((inputs[in] - inputs_min_[in]) /
105  (inputs_max_[in] - inputs_min_[in]));
106  neurons_[in].set_output((neurons_[in].output() - inputs_mean_[in]) /
107  inputs_std_dev_[in]);
108  }
109  }
110  // compute the net outputs: follow a pull model each output pulls the
111  // outputs of its input nodes and so on
112  for (int out = neuron_cnt_ - out_cnt_; out < neuron_cnt_; out++) {
113  neurons_[out].FeedForward();
114  // copy the values to the output buffer
115  outputs[out] = neurons_[out].output();
116  }
117  return true;
118 }
vector< float > inputs_max_
Definition: neural_net.h:96
float output() const
Definition: neuron.h:102
bool FastFeedForward(const Type *inputs, Type *outputs)
Definition: neural_net.cpp:61
void FeedForward()
Definition: neuron.cpp:48
vector< float > inputs_min_
Definition: neural_net.h:98
vector< float > inputs_std_dev_
Definition: neural_net.h:102
void set_output(float out_val)
Definition: neuron.h:105
vector< float > inputs_mean_
Definition: neural_net.h:100

◆ FromFile()

NeuralNet * tesseract::NeuralNet::FromFile ( const string  file_name)
static

Definition at line 210 of file neural_net.cpp.

210  {
211  // open the file
212  InputFileBuffer input_buff(file_name);
213  // create a new net object using input buffer
214  NeuralNet *net_obj = FromInputBuffer(&input_buff);
215  return net_obj;
216 }
static NeuralNet * FromInputBuffer(InputFileBuffer *ib)
Definition: neural_net.cpp:219

◆ FromInputBuffer()

NeuralNet * tesseract::NeuralNet::FromInputBuffer ( InputFileBuffer ib)
static

Definition at line 219 of file neural_net.cpp.

219  {
220  // create a new net object
221  NeuralNet *net_obj = new NeuralNet();
222  // load the net
223  if (!net_obj->ReadBinary(ib)) {
224  delete net_obj;
225  net_obj = NULL;
226  }
227  return net_obj;
228 }

◆ GetNetOutput()

template<typename Type >
template bool tesseract::NeuralNet::GetNetOutput ( const Type *  inputs,
int  output_id,
Type *  output 
)

Definition at line 268 of file neural_net.cpp.

270  {
271  // validate output id
272  if (output_id < 0 || output_id >= out_cnt_) {
273  return false;
274  }
275 
276  // call the fast version in case of readonly nets
277  if (read_only_) {
278  return FastGetNetOutput(inputs, output_id, output);
279  }
280 
281  // For the slow version, we'll just call FeedForward and return the
282  // appropriate output
283  vector<Type> outputs(out_cnt_);
284  if (!FeedForward(inputs, &outputs[0])) {
285  return false;
286  }
287  (*output) = outputs[output_id];
288 
289  return true;
290 }
bool FeedForward(const Type *inputs, Type *outputs)
Definition: neural_net.cpp:88
bool FastGetNetOutput(const Type *inputs, int output_id, Type *output)
Definition: neural_net.cpp:234

◆ in_cnt()

int tesseract::NeuralNet::in_cnt ( ) const
inline

Definition at line 49 of file neural_net.h.

49 { return in_cnt_; }

◆ Init()

void tesseract::NeuralNet::Init ( )
protected

Definition at line 43 of file neural_net.cpp.

43  {
44  read_only_ = true;
45  auto_encoder_ = false;
46  alloc_wgt_cnt_ = 0;
47  wts_cnt_ = 0;
48  neuron_cnt_ = 0;
49  in_cnt_ = 0;
50  out_cnt_ = 0;
51  wts_vec_.clear();
52  neurons_ = NULL;
53  inputs_mean_.clear();
54  inputs_std_dev_.clear();
55  inputs_min_.clear();
56  inputs_max_.clear();
57 }
vector< float > inputs_max_
Definition: neural_net.h:96
vector< vector< float > * > wts_vec_
Definition: neural_net.h:92
vector< float > inputs_min_
Definition: neural_net.h:98
vector< float > inputs_std_dev_
Definition: neural_net.h:102
vector< float > inputs_mean_
Definition: neural_net.h:100

◆ out_cnt()

int tesseract::NeuralNet::out_cnt ( ) const
inline

Definition at line 50 of file neural_net.h.

50 { return out_cnt_; }

◆ ReadBinary()

template<class ReadBuffType >
template bool tesseract::NeuralNet::ReadBinary ( ReadBuffType *  input_buff)
inlineprotected

Definition at line 115 of file neural_net.h.

115  {
116  // Init vars
117  Init();
118  // is this an autoencoder
119  unsigned int read_val;
120  unsigned int auto_encode;
121  // read and verify signature
122  if (input_buff->Read(&read_val, sizeof(read_val)) != sizeof(read_val)) {
123  return false;
124  }
125  if (read_val != kNetSignature) {
126  return false;
127  }
128  if (input_buff->Read(&auto_encode, sizeof(auto_encode)) !=
129  sizeof(auto_encode)) {
130  return false;
131  }
132  auto_encoder_ = auto_encode;
133  // read and validate total # of nodes
134  if (input_buff->Read(&read_val, sizeof(read_val)) != sizeof(read_val)) {
135  return false;
136  }
137  neuron_cnt_ = read_val;
138  if (neuron_cnt_ <= 0) {
139  return false;
140  }
141  // set the size of the neurons vector
142  neurons_ = new Neuron[neuron_cnt_];
143  // read & validate inputs
144  if (input_buff->Read(&read_val, sizeof(read_val)) != sizeof(read_val)) {
145  return false;
146  }
147  in_cnt_ = read_val;
148  if (in_cnt_ <= 0) {
149  return false;
150  }
151  // read outputs
152  if (input_buff->Read(&read_val, sizeof(read_val)) != sizeof(read_val)) {
153  return false;
154  }
155  out_cnt_ = read_val;
156  if (out_cnt_ <= 0) {
157  return false;
158  }
159  // set neuron ids and types
160  for (int idx = 0; idx < neuron_cnt_; idx++) {
161  neurons_[idx].set_id(idx);
162  // input type
163  if (idx < in_cnt_) {
165  } else if (idx >= (neuron_cnt_ - out_cnt_)) {
167  } else {
169  }
170  }
171  // read the connections
172  for (int node_idx = 0; node_idx < neuron_cnt_; node_idx++) {
173  // read fanout
174  if (input_buff->Read(&read_val, sizeof(read_val)) != sizeof(read_val)) {
175  return false;
176  }
177  // read the neuron's info
178  int fan_out_cnt = read_val;
179  for (int fan_out_idx = 0; fan_out_idx < fan_out_cnt; fan_out_idx++) {
180  // read the neuron id
181  if (input_buff->Read(&read_val, sizeof(read_val)) != sizeof(read_val)) {
182  return false;
183  }
184  // create the connection
185  if (!SetConnection(node_idx, read_val)) {
186  return false;
187  }
188  }
189  }
190  // read all the neurons' fan-in connections
191  for (int node_idx = 0; node_idx < neuron_cnt_; node_idx++) {
192  // read
193  if (!neurons_[node_idx].ReadBinary(input_buff)) {
194  return false;
195  }
196  }
197  // size input stats vector to expected input size
198  inputs_mean_.resize(in_cnt_);
199  inputs_std_dev_.resize(in_cnt_);
200  inputs_min_.resize(in_cnt_);
201  inputs_max_.resize(in_cnt_);
202  // read stats
203  if (input_buff->Read(&(inputs_mean_.front()),
204  sizeof(inputs_mean_[0]) * in_cnt_) !=
205  sizeof(inputs_mean_[0]) * in_cnt_) {
206  return false;
207  }
208  if (input_buff->Read(&(inputs_std_dev_.front()),
209  sizeof(inputs_std_dev_[0]) * in_cnt_) !=
210  sizeof(inputs_std_dev_[0]) * in_cnt_) {
211  return false;
212  }
213  if (input_buff->Read(&(inputs_min_.front()),
214  sizeof(inputs_min_[0]) * in_cnt_) !=
215  sizeof(inputs_min_[0]) * in_cnt_) {
216  return false;
217  }
218  if (input_buff->Read(&(inputs_max_.front()),
219  sizeof(inputs_max_[0]) * in_cnt_) !=
220  sizeof(inputs_max_[0]) * in_cnt_) {
221  return false;
222  }
223  // create a readonly version for fast feedforward
224  if (read_only_) {
225  return CreateFastNet();
226  }
227  return true;
228  }
void set_node_type(NeuronTypes type)
Definition: neuron.cpp:71
bool SetConnection(int from, int to)
Definition: neural_net.cpp:121
vector< float > inputs_max_
Definition: neural_net.h:96
void set_id(int id)
Definition: neuron.h:120
vector< float > inputs_min_
Definition: neural_net.h:98
bool ReadBinary(ReadBuffType *input_buff)
Definition: neural_net.h:115
vector< float > inputs_std_dev_
Definition: neural_net.h:102
static const unsigned int kNetSignature
Definition: neural_net.h:88
vector< float > inputs_mean_
Definition: neural_net.h:100

◆ SetConnection()

bool tesseract::NeuralNet::SetConnection ( int  from,
int  to 
)
protected

Definition at line 121 of file neural_net.cpp.

121  {
122  // allocate the wgt
123  float *wts = AllocWgt(1);
124  if (wts == NULL) {
125  return false;
126  }
127  // register the connection
128  neurons_[to].AddFromConnection(neurons_ + from, wts, 1);
129  return true;
130 }
void AddFromConnection(Neuron *neuron_vec, float *wts_offset, int from_cnt)
Definition: neuron.cpp:83
float * AllocWgt(int wgt_cnt)
Definition: neural_net.cpp:195

Member Data Documentation

◆ alloc_wgt_cnt_

int tesseract::NeuralNet::alloc_wgt_cnt_
protected

Definition at line 90 of file neural_net.h.

◆ auto_encoder_

bool tesseract::NeuralNet::auto_encoder_
protected

Definition at line 94 of file neural_net.h.

◆ fast_nodes_

vector<Node> tesseract::NeuralNet::fast_nodes_
protected

Definition at line 105 of file neural_net.h.

◆ in_cnt_

int tesseract::NeuralNet::in_cnt_
protected

Definition at line 72 of file neural_net.h.

◆ inputs_max_

vector<float> tesseract::NeuralNet::inputs_max_
protected

Definition at line 96 of file neural_net.h.

◆ inputs_mean_

vector<float> tesseract::NeuralNet::inputs_mean_
protected

Definition at line 100 of file neural_net.h.

◆ inputs_min_

vector<float> tesseract::NeuralNet::inputs_min_
protected

Definition at line 98 of file neural_net.h.

◆ inputs_std_dev_

vector<float> tesseract::NeuralNet::inputs_std_dev_
protected

Definition at line 102 of file neural_net.h.

◆ kNetSignature

const unsigned int tesseract::NeuralNet::kNetSignature = 0xFEFEABD0
staticprotected

Definition at line 88 of file neural_net.h.

◆ kWgtChunkSize

const int tesseract::NeuralNet::kWgtChunkSize = 0x10000
staticprotected

Definition at line 85 of file neural_net.h.

◆ neuron_cnt_

int tesseract::NeuralNet::neuron_cnt_
protected

Definition at line 76 of file neural_net.h.

◆ neurons_

Neuron* tesseract::NeuralNet::neurons_
protected

Definition at line 80 of file neural_net.h.

◆ out_cnt_

int tesseract::NeuralNet::out_cnt_
protected

Definition at line 74 of file neural_net.h.

◆ read_only_

bool tesseract::NeuralNet::read_only_
protected

Definition at line 70 of file neural_net.h.

◆ wts_cnt_

int tesseract::NeuralNet::wts_cnt_
protected

Definition at line 78 of file neural_net.h.

◆ wts_vec_

vector<vector<float> *> tesseract::NeuralNet::wts_vec_
protected

Definition at line 92 of file neural_net.h.


The documentation for this class was generated from the following files: