'Builds a network with input prev_layer from a VGSLSpecs description.
Args:
prev_layer: The input tensor.
model_str:  Model definition similar to Tesseract as follows:
============ FUNCTIONAL OPS ============
C(s|t|r|l|m)[{name}]<y>,<x>,<d> Convolves using a y,x window, with no
shrinkage, SAME infill, d outputs, with s|t|r|l|m non-linear layer.
(s|t|r|l|m) specifies the type of non-linearity:
s = sigmoid
t = tanh
r = relu
l = linear (i.e., None)
m = softmax
F(s|t|r|l|m)[{name}]<d> Fully-connected with s|t|r|l|m non-linearity and
d outputs. Reduces height, width to 1. Input height and width must be
constant.
L(f|r|b)(x|y)[s][{name}]<n> LSTM cell with n outputs.
f runs the LSTM forward only.
r runs the LSTM reversed only.
b runs the LSTM bidirectionally.
x runs the LSTM in the x-dimension (on data with or without the
y-dimension).
y runs the LSTM in the y-dimension (data must have a y dimension).
s (optional) summarizes the output in the requested dimension,
outputting only the final step, collapsing the dimension to a
single element.
Examples:
Lfx128 runs a forward-only LSTM in the x-dimension with 128
outputs, treating any y dimension independently.
Lfys64 runs a forward-only LSTM in the y-dimension with 64 outputs
and collapses the y-dimension to 1 element.
NOTE that Lbxsn is implemented as (LfxsnLrxsn) since the summaries
need to be taken from opposite ends of the output
Do[{name}] Insert a dropout layer.
============ PLUMBING OPS ============
[...] Execute ... networks in series (layers).
(...) Execute ... networks in parallel, with their output concatenated
in depth.
S[{name}]<d>(<a>x<b>)<e>,<f> Splits one dimension, moves one part to
another dimension.
Splits input dimension d into a x b, sending the high part (a) to the
high side of dimension e, and the low part (b) to the high side of
dimension f. Exception: if d=e=f, then then dimension d is internally
transposed to bxa.
Either a or b can be zero, meaning whatever is left after taking out
the other, allowing dimensions to be of variable size.
Eg. S3(3x50)2,3 will split the 150-element depth into 3x50, with the 3
going to the most significant part of the width, and the 50 part
staying in depth.
This will rearrange a 3x50 output parallel operation to spread the 3
output sets over width.
Mp[{name}]<y>,<x> Maxpool the input, reducing the (y,x) rectangle to a
single vector value.
Returns:
Output tensor'

def Build(self, prev_layer, model_str):

    self.model_str = model_str
    (final_layer, _) = self.BuildFromString(prev_layer, 0)
    return final_layer
