tesseract  4.00.00dev
convolve.cpp
Go to the documentation of this file.
1 // File: convolve.cpp
3 // Description: Convolutional layer that stacks the inputs over its rectangle
4 // and pulls in random data to fill out-of-input inputs.
5 // Output is therefore same size as its input, but deeper.
6 // Author: Ray Smith
7 // Created: Tue Mar 18 16:56:06 PST 2014
8 //
9 // (C) Copyright 2014, Google Inc.
10 // Licensed under the Apache License, Version 2.0 (the "License");
11 // you may not use this file except in compliance with the License.
12 // You may obtain a copy of the License at
13 // http://www.apache.org/licenses/LICENSE-2.0
14 // Unless required by applicable law or agreed to in writing, software
15 // distributed under the License is distributed on an "AS IS" BASIS,
16 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 // See the License for the specific language governing permissions and
18 // limitations under the License.
20 
21 #include "convolve.h"
22 
23 #include "networkscratch.h"
24 #include "serialis.h"
25 
26 namespace tesseract {
27 
28 Convolve::Convolve(const STRING& name, int ni, int half_x, int half_y)
29  : Network(NT_CONVOLVE, name, ni, ni * (2*half_x + 1) * (2*half_y + 1)),
30  half_x_(half_x), half_y_(half_y) {
31 }
32 
34 }
35 
36 // Writes to the given file. Returns false in case of error.
37 bool Convolve::Serialize(TFile* fp) const {
38  if (!Network::Serialize(fp)) return false;
39  if (fp->FWrite(&half_x_, sizeof(half_x_), 1) != 1) return false;
40  if (fp->FWrite(&half_y_, sizeof(half_y_), 1) != 1) return false;
41  return true;
42 }
43 
44 // Reads from the given file. Returns false in case of error.
46  if (fp->FReadEndian(&half_x_, sizeof(half_x_), 1) != 1) return false;
47  if (fp->FReadEndian(&half_y_, sizeof(half_y_), 1) != 1) return false;
48  no_ = ni_ * (2*half_x_ + 1) * (2*half_y_ + 1);
49  return true;
50 }
51 
52 // Runs forward propagation of activations on the input line.
53 // See NetworkCpp for a detailed discussion of the arguments.
54 void Convolve::Forward(bool debug, const NetworkIO& input,
55  const TransposedArray* input_transpose,
56  NetworkScratch* scratch, NetworkIO* output) {
57  output->Resize(input, no_);
58  int y_scale = 2 * half_y_ + 1;
59  StrideMap::Index dest_index(output->stride_map());
60  do {
61  // Stack x_scale groups of y_scale * ni_ inputs together.
62  int t = dest_index.t();
63  int out_ix = 0;
64  for (int x = -half_x_; x <= half_x_; ++x, out_ix += y_scale * ni_) {
65  StrideMap::Index x_index(dest_index);
66  if (!x_index.AddOffset(x, FD_WIDTH)) {
67  // This x is outside the image.
68  output->Randomize(t, out_ix, y_scale * ni_, randomizer_);
69  } else {
70  int out_iy = out_ix;
71  for (int y = -half_y_; y <= half_y_; ++y, out_iy += ni_) {
72  StrideMap::Index y_index(x_index);
73  if (!y_index.AddOffset(y, FD_HEIGHT)) {
74  // This y is outside the image.
75  output->Randomize(t, out_iy, ni_, randomizer_);
76  } else {
77  output->CopyTimeStepGeneral(t, out_iy, ni_, input, y_index.t(), 0);
78  }
79  }
80  }
81  }
82  } while (dest_index.Increment());
83  if (debug) DisplayForward(*output);
84 }
85 
86 // Runs backward propagation of errors on the deltas line.
87 // See NetworkCpp for a detailed discussion of the arguments.
88 bool Convolve::Backward(bool debug, const NetworkIO& fwd_deltas,
89  NetworkScratch* scratch,
90  NetworkIO* back_deltas) {
91  back_deltas->Resize(fwd_deltas, ni_);
92  NetworkScratch::IO delta_sum;
93  delta_sum.ResizeFloat(fwd_deltas, ni_, scratch);
94  delta_sum->Zero();
95  int y_scale = 2 * half_y_ + 1;
96  StrideMap::Index src_index(fwd_deltas.stride_map());
97  do {
98  // Stack x_scale groups of y_scale * ni_ inputs together.
99  int t = src_index.t();
100  int out_ix = 0;
101  for (int x = -half_x_; x <= half_x_; ++x, out_ix += y_scale * ni_) {
102  StrideMap::Index x_index(src_index);
103  if (x_index.AddOffset(x, FD_WIDTH)) {
104  int out_iy = out_ix;
105  for (int y = -half_y_; y <= half_y_; ++y, out_iy += ni_) {
106  StrideMap::Index y_index(x_index);
107  if (y_index.AddOffset(y, FD_HEIGHT)) {
108  fwd_deltas.AddTimeStepPart(t, out_iy, ni_,
109  delta_sum->f(y_index.t()));
110  }
111  }
112  }
113  }
114  } while (src_index.Increment());
115  back_deltas->CopyWithNormalization(*delta_sum, fwd_deltas);
116  return true;
117 }
118 
119 } // namespace tesseract.
bool AddOffset(int offset, FlexDimensions dimension)
Definition: stridemap.cpp:62
virtual void Forward(bool debug, const NetworkIO &input, const TransposedArray *input_transpose, NetworkScratch *scratch, NetworkIO *output)
Definition: convolve.cpp:54
float * f(int t)
Definition: networkio.h:115
void DisplayForward(const NetworkIO &matrix)
Definition: network.cpp:285
void Resize(const NetworkIO &src, int num_features)
Definition: networkio.h:45
int FReadEndian(void *buffer, int size, int count)
Definition: serialis.cpp:97
virtual ~Convolve()
Definition: convolve.cpp:33
TRand * randomizer_
Definition: network.h:297
virtual bool Serialize(TFile *fp) const
Definition: convolve.cpp:37
void ResizeFloat(const NetworkIO &src, int num_features, NetworkScratch *scratch)
virtual bool DeSerialize(TFile *fp)
Definition: convolve.cpp:45
Definition: strngs.h:45
void CopyTimeStepGeneral(int dest_t, int dest_offset, int num_features, const NetworkIO &src, int src_t, int src_offset)
Definition: networkio.cpp:393
int FWrite(const void *buffer, int size, int count)
Definition: serialis.cpp:148
void CopyWithNormalization(const NetworkIO &src, const NetworkIO &scale)
Definition: networkio.cpp:831
void AddTimeStepPart(int t, int offset, int num_features, float *inout) const
Definition: networkio.cpp:629
const StrideMap & stride_map() const
Definition: networkio.h:133
void Randomize(int t, int offset, int num_features, TRand *randomizer)
Definition: networkio.cpp:416
virtual bool Backward(bool debug, const NetworkIO &fwd_deltas, NetworkScratch *scratch, NetworkIO *back_deltas)
Definition: convolve.cpp:88
virtual bool Serialize(TFile *fp) const
Definition: network.cpp:153
Convolve(const STRING &name, int ni, int half_x, int half_y)
Definition: convolve.cpp:28