tesseract v5.3.3.20231005
convolve.cpp
Go to the documentation of this file.
1
2// 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//
8// (C) Copyright 2014, Google Inc.
9// Licensed under the Apache License, Version 2.0 (the "License");
10// you may not use this file except in compliance with the License.
11// You may obtain a copy of the License at
12// http://www.apache.org/licenses/LICENSE-2.0
13// Unless required by applicable law or agreed to in writing, software
14// distributed under the License is distributed on an "AS IS" BASIS,
15// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16// See the License for the specific language governing permissions and
17// limitations under the License.
19
20#ifdef HAVE_CONFIG_H
21# include "config_auto.h"
22#endif
23
24#include "convolve.h"
25
26#include "networkscratch.h"
27#include "serialis.h"
28
29namespace tesseract {
30
31Convolve::Convolve(const std::string &name, int ni, int half_x, int half_y)
32 : Network(NT_CONVOLVE, name, ni, ni * (2 * half_x + 1) * (2 * half_y + 1))
33 , half_x_(half_x)
34 , half_y_(half_y) {}
35
36// Writes to the given file. Returns false in case of error.
37bool Convolve::Serialize(TFile *fp) const {
38 return Network::Serialize(fp) && fp->Serialize(&half_x_) && fp->Serialize(&half_y_);
39}
40
41// Reads from the given file. Returns false in case of error.
43 if (!fp->DeSerialize(&half_x_)) {
44 return false;
45 }
46 if (!fp->DeSerialize(&half_y_)) {
47 return false;
48 }
49 no_ = ni_ * (2 * half_x_ + 1) * (2 * half_y_ + 1);
50 return true;
51}
52
53// Runs forward propagation of activations on the input line.
54// See NetworkCpp for a detailed discussion of the arguments.
55void Convolve::Forward(bool debug, const NetworkIO &input, 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#ifndef GRAPHICS_DISABLED
84 if (debug) {
86 }
87#endif
88}
89
90// Runs backward propagation of errors on the deltas line.
91// See NetworkCpp for a detailed discussion of the arguments.
92bool Convolve::Backward(bool debug, const NetworkIO &fwd_deltas, NetworkScratch *scratch,
93 NetworkIO *back_deltas) {
94 back_deltas->Resize(fwd_deltas, ni_);
95 NetworkScratch::IO delta_sum;
96 delta_sum.ResizeFloat(fwd_deltas, ni_, scratch);
97 delta_sum->Zero();
98 int y_scale = 2 * half_y_ + 1;
99 StrideMap::Index src_index(fwd_deltas.stride_map());
100 do {
101 // Stack x_scale groups of y_scale * ni_ inputs together.
102 int t = src_index.t();
103 int out_ix = 0;
104 for (int x = -half_x_; x <= half_x_; ++x, out_ix += y_scale * ni_) {
105 StrideMap::Index x_index(src_index);
106 if (x_index.AddOffset(x, FD_WIDTH)) {
107 int out_iy = out_ix;
108 for (int y = -half_y_; y <= half_y_; ++y, out_iy += ni_) {
109 StrideMap::Index y_index(x_index);
110 if (y_index.AddOffset(y, FD_HEIGHT)) {
111 fwd_deltas.AddTimeStepPart(t, out_iy, ni_, delta_sum->f(y_index.t()));
112 }
113 }
114 }
115 }
116 } while (src_index.Increment());
117 back_deltas->CopyAll(*delta_sum);
118 return true;
119}
120
121} // namespace tesseract.
const double y
@ NT_CONVOLVE
Definition: network.h:45
@ FD_WIDTH
Definition: stridemap.h:35
@ FD_HEIGHT
Definition: stridemap.h:34
bool DeSerialize(std::string &data)
Definition: serialis.cpp:94
bool Serialize(const std::string &data)
Definition: serialis.cpp:107
void Forward(bool debug, const NetworkIO &input, const TransposedArray *input_transpose, NetworkScratch *scratch, NetworkIO *output) override
Definition: convolve.cpp:55
bool Serialize(TFile *fp) const override
Definition: convolve.cpp:37
bool Backward(bool debug, const NetworkIO &fwd_deltas, NetworkScratch *scratch, NetworkIO *back_deltas) override
Definition: convolve.cpp:92
TESS_API Convolve(const std::string &name, int ni, int half_x, int half_y)
Definition: convolve.cpp:31
bool DeSerialize(TFile *fp) override
Definition: convolve.cpp:42
void DisplayForward(const NetworkIO &matrix)
Definition: network.cpp:333
virtual bool Serialize(TFile *fp) const
Definition: network.cpp:158
TRand * randomizer_
Definition: network.h:312
void Resize(const NetworkIO &src, int num_features)
Definition: networkio.h:44
void AddTimeStepPart(int t, int offset, int num_features, float *inout) const
Definition: networkio.cpp:641
float * f(int t)
Definition: networkio.h:110
const StrideMap & stride_map() const
Definition: networkio.h:128
void CopyAll(const NetworkIO &src)
Definition: networkio.cpp:825
void ResizeFloat(const NetworkIO &src, int num_features, NetworkScratch *scratch)
bool AddOffset(int offset, FlexDimensions dimension)
Definition: stridemap.cpp:67