-// Copyright (C) 2018 Intel Corporation
+// Copyright (C) 2018-2019 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
* @param def Default value of the parameter if not found
* @return An bool value for the specified parameter
*/
- bool GetParamsAsBool(const char *param, bool def) const {
+ bool GetParamAsBool(const char *param, bool def) const {
std::string val = GetParamAsString(param, std::to_string(def).c_str());
std::string loweredCaseValue;
std::transform(val.begin(), val.end(), std::back_inserter(loweredCaseValue), [](char value) {
if (!(std::istringstream(loweredCaseValue) >> std::boolalpha >> result)) {
// attempting parse using non alpha bool
- return static_cast<bool>(GetParamAsInt(param, def));
+ return (GetParamAsInt(param, def) != 0);
}
return result;
}
+ /**
+ * @deprecated Use GetParamAsBool function for that functionality
+ */
+ bool GetParamsAsBool(const char *param, bool def) const {
+ return GetParamAsBool(param, def);
+ }
/**
* @brief Returns a string value for the given parameter or returns the default one
*/
std::string GetParamAsString(const char *param, const char *def) const {
auto it = params.find(param);
- if (it == params.end()) {
+ if (it == params.end() || it->second.empty()) {
return def;
}
return (*it).second;
}
/**
+ * @brief Checks the param presence in the layer
+ * @param param Name of the layer parameter
+ * @return a bool depending param presence
+ */
+ bool CheckParamPresence(const char *param) const {
+ auto it = params.find(param);
+ if (it == params.end()) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
* @brief Returns a string value for the given parameter.
* Throws exception if parameter was not found.
* @param param Name of the layer parameter
return (*it).second;
}
+ std::vector<std::string> GetParamAsStrings(const char *param, std::vector<std::string> def) const {
+ std::string vals = GetParamAsString(param, "");
+ std::vector<std::string> result;
+ std::istringstream stream(vals);
+ std::string str;
+ if (vals.empty())
+ return def;
+ while (getline(stream, str, ',')) {
+ try {
+ result.push_back(str);
+ } catch (...) {
+ THROW_IE_EXCEPTION << "Cannot parse parameter " << param << " from IR for layer " << name << ".";
+ }
+ }
+ return result;
+ }
+
/**
* @brief Map of pairs: (parameter name, parameter value)
*/
std::map<std::string, std::string> params;
+
/**
* @brief Map of pairs: (name, weights/biases blob)
*/
PoolingLayer(PoolingLayer &&) = default;
};
+/**
+ * @brief This class represents a standard binary convolution layer
+ */
+class BinaryConvolutionLayer : public WeightableLayer {
+public:
+ /**
+ * @enum eBinaryConvolutionMode
+ * @brief Defines possible modes of binary convolution operation
+ */
+ enum eBinaryConvolutionMode {
+ xnor_popcount = 0
+ };
+
+ /**
+ * @brief Mode of binary convolution operation
+ */
+ eBinaryConvolutionMode _mode = xnor_popcount;
+
+ /**
+ * @brief A number of input feature maps (size) generating the 3'rd input dimension
+ */
+ unsigned int _in_depth = 0u;
+
+ /**
+ * @brief A pad value which is used to fill pad area
+ */
+ float _pad_value = -1.0f;
+
+ /**
+ * @brief A convolution kernel array [X, Y, Z, ...]
+ */
+ DEFINE_PROP(_kernel);
+ /**
+ * @brief A convolution paddings begin array [X, Y, Z, ...]
+ */
+ DEFINE_PROP(_padding);
+ /**
+ * @brief A convolution paddings end array [X, Y, Z, ...]
+ */
+ PropertyVector<unsigned int> _pads_end;
+ /**
+ * @brief A convolution strides array [X, Y, Z, ...]
+ */
+ DEFINE_PROP(_stride);
+ /**
+ * @brief A convolution dilations array [X, Y, Z, ...]
+ */
+ DEFINE_PROP(_dilation);
+ /**
+ * @brief A number of output feature maps (size) generating the 3'rd output dimension
+ */
+ unsigned int _out_depth = 0u;
+ /**
+ * @brief Number of groups
+ */
+ unsigned int _group = 1u;
+ /**
+ * @brief Auto padding type
+ */
+ std::string _auto_pad;
+
+ /**
+ * @brief Creates a new BinaryConvolutionLayer instance.
+ */
+ explicit BinaryConvolutionLayer(const LayerParams &p) : WeightableLayer(p),
+ _kernel(2, 0u), _padding(2, 0u), _stride(2, 1u), _dilation(2, 1u) {}
+ /**
+ * @brief assignment operator
+ */
+ BinaryConvolutionLayer & operator = (const BinaryConvolutionLayer & that) {
+ if (&that != this) {
+ WeightableLayer::operator=(that);
+ _kernel = that._kernel;
+ _padding = that._padding;
+ _pads_end = that._pads_end;
+ _stride = that._stride;
+ _dilation = that._dilation;
+ _out_depth = that._out_depth;
+ _group = that._group;
+ _mode = that._mode;
+ _in_depth = that._in_depth;
+ _pad_value = that._pad_value;
+ }
+ return *this;
+ }
+ /**
+ * @brief move assignment operator
+ */
+ BinaryConvolutionLayer& operator = (BinaryConvolutionLayer &&) = default;
+ /**
+ * @brief copy constructor
+ */
+ BinaryConvolutionLayer(const BinaryConvolutionLayer & that) : WeightableLayer(that) {
+ operator = (that);
+ }
+ /**
+ * @brief move constructor
+ */
+ BinaryConvolutionLayer(BinaryConvolutionLayer &&) = default;
+};
+
#undef DEFINE_PROP
/**
using CNNLayer::CNNLayer;
};
+
+/**
+ * @brief This class represents a ReLU6 activation layer
+ * Clamps all tensor elements into the range [0, 6.0]
+ */
+class ReLU6Layer : public ClampLayer {
+public:
+ explicit ReLU6Layer(const LayerParams &prms) : ClampLayer(prms) {
+ max_value = 6.0f;
+ }
+
+ using ClampLayer::ClampLayer;
+};
+
+
/**
* @brief This class represents an element wise operation layer
*/
* @brief Defines possible operations that can be used
*/
enum eOperation {
- Sum = 0, Prod, Max
+ Sum = 0, Prod, Max, Sub, Min, Div, Squared_diff, Floor_mod, Pow,
+ Equal, Not_equal, Less, Less_equal, Greater, Greater_equal,
+ Logical_AND, Logical_OR, Logical_XOR
};
/**
};
/**
-* @class PReLULayer
-* @brief This class represents a Layer which performs Scale and Shift
-*/
+ * @brief Base class for recurrent cell layers
+ */
+class RNNCellBase : public WeightableLayer {
+public:
+ using WeightableLayer::WeightableLayer;
+
+ /**
+ * @brief Direct type of recurrent cell (including subtypes)
+ * Description of particular cell semantics is in LSTMCell, GRUCell, RNNCell.
+ */
+ enum CellType {
+ LSTM, /**< Original LSTM cell */
+ GRU, /**< Original GRU cell */
+ RNN, /**< Original RNN cell */
+ GRU_LBR, /**< GRU cell modification. "Linear before reset" */
+ };
+
+ /** @copybrief CellType */
+ CellType cellType = LSTM;
+
+ /**
+ * @brief Size of hidden state data
+ *
+ * In case of batch output state tensor will have shape [N, hidden_size]
+ */
+ int hidden_size = 0;
+
+ /**
+ * @brief Clip data into range [-clip, clip] on input of activations
+ *
+ * clip==0.0f means no clipping
+ */
+ float clip = 0.0f;
+ /**
+ * @brief Activations used inside recurrent cell
+ *
+ * Valid values: sigmoid, tanh, relu
+ */
+ std::vector<std::string> activations;
+
+ /**
+ * @brief Alpha parameters of activations
+ *
+ * Respective to activation list.
+ */
+ std::vector<float> activation_alpha;
+
+ /**
+ * @brief Beta parameters of activations
+ *
+ * Respective to activation list.
+ */
+ std::vector<float> activation_beta;
+};
+
+/**
+ * @brief LSTM Cell layer
+ *
+ * G - number of gates (=4)
+ * N - batch size
+ * S - state size (=hidden_size)
+ *
+ * Inputs:
+ * [N,D] Xt - input data
+ * [N,S] Ht-1 - initial hidden state
+ * [N,S] Ct-1 - initial cell state
+ *
+ * Outputs:
+ * [N,S] Ht - out hidden state
+ * [N,S] Ct - out cell state
+ *
+ * Weights:
+ * - weights [G,S,D+S]
+ * - biases [G,S]
+ * NB! gates order is FICO {forget, input, candidate, output}
+ *
+ * activations is {_f, _g, _h}
+ * default: {_f=sigm, _g=tanh, _h=tanh}
+ *
+ * Equations:
+ *
+ * * - matrix mult
+ * (.) - eltwise mult
+ * [,] - concatenation
+ *
+ * - ft = _f(Wf*[Ht-1, Xt] + Bf)
+ * - it = _f(Wi*[Ht-1, Xt] + Bi)
+ * - ct = _g(Wc*[Ht-1, Xt] + Bc)
+ * - ot = _f(Wo*[Ht-1, Xt] + Bo)
+ * - Ct = ft (.) Ct-1 + it (.) ct
+ * - Ht = ot (.) _h(Ct)
+ */
+using LSTMCell = RNNCellBase;
+
+/**
+ * @brief GRU Cell layer
+ *
+ * G - number of gates (=3)
+ * N - batch size
+ * S - state size (=hidden_size)
+ *
+ * Inputs:
+ * [N,D] Xt - input data
+ * [N,S] Ht-1 - initial hidden state
+ *
+ * Outputs:
+ * [N,S] Ht - out hidden state
+ *
+ * Weights:
+ * - weights [G,S,D+S]
+ * - biases [G,S]
+ * NB! gates order is ZRH {update, reset, output}
+ *
+ * activations is {_f, _g}
+ * default: {_f=sigm, _g=tanh}
+ *
+ * Equations:
+ *
+ * * - matrix mult
+ * (.) - eltwise mult
+ * [,] - concatenation
+ *
+ * - zt = _f(Wz*[Ht-1, Xt] + Bz)
+ * - rt = _f(Wr*[Ht-1, Xt] + Br)
+ * - ht = _g(Wh*[rt (.) Ht-1, Xt] + Bh)
+ * - Ht = (1 - zt) (.) ht + zt (.) Ht-1
+ */
+using GRUCell = RNNCellBase;
+
+/**
+ * @brief RNN Cell layer
+ *
+ * G - number of gates (=1)
+ * N - batch size
+ * S - state size (=hidden_size)
+ *
+ * Inputs:
+ * [N,D] Xt - input data
+ * [N,S] Ht-1 - initial hidden state
+ *
+ * Outputs:
+ * [N,S] Ht - out hidden state
+ *
+ * Weights:
+ * - weights [G,S,D+S]
+ * - biases [G,S]
+ *
+ * activations is {_f}
+ * default: {_f=tanh}
+ *
+ * Equations:
+ *
+ * * - matrix mult
+ * [,] - concatenation
+ *
+ * - Ht = _f(Wi*[Ht-1, Xt] + Bi)
+ */
+using RNNCell = RNNCellBase;
+
+/**
+ * @brief Sequence of recurrent cells
+ *
+ * N - batch size
+ * T - sequence size
+ * S - state size (=hidden_size)
+ * NS - num of state tensors (LSTM=2, GRU/RNN=1)
+ * ND - num of direction (BDR=2, WFD/BWD=1)
+ *
+ * Inputs:
+ * [N,T,D] Xt - input data
+ * [ND,N,S] Ht-1 - initial hidden state
+ * [ND,N,S] Ct-1 - initial cell state // if NS==2
+ *
+ * Outputs:
+ * [ND,N,T,S] Xt - input data
+ * [ND,N,S] Ht-1 - initial hidden state
+ * [ND,N,S] Ct-1 - initial cell state // if NS==2
+ *
+ * NB! if axis==0 batch and sequense dimensions are swapped (N <-> T) for input and output tensors
+ *
+ * Weights:
+ * - weights [ND,G,S,D+S]
+ * - biases [ND,G,S]
+ * NB! if ND==2 weights are concatenated cell weights [forward_cell_weights, backward_cell_weights]
+ *
+ */
+class RNNSequenceLayer : public RNNCellBase {
+public:
+ using RNNCellBase::RNNCellBase;
+
+ /**
+ * @brief An axis by which iteration is performed
+ * axis=0 means first input/output data blob dimension is sequence
+ * axis=1 means first input/output data blob dimension is batch
+ */
+ unsigned int axis = 1;
+
+ /**
+ * @brief Direction of iteration through sequence dimension
+ */
+ enum Direction {
+ FWD, /**< Forward mode. Iterate starts from index 0 with step 1. */
+ BWD, /**< Backward mode. Iterate starts from last index with step -1. */
+ BDR /**< Bidirectional mode. First is forward pass, second is backward. */
+ };
+
+ /** @copybrief Direction */
+ Direction direction = FWD;
+};
+
+/**
+ * @brief This class represents a Layer which performs Scale and Shift
+ */
class PReLULayer : public WeightableLayer {
public:
/**
public:
/**
- * @brief A default constructor. Creates a new PReLULayer instance and initializes layer parameters with the given values.
- * @param prms Initial layer parameters
- */
+ * @brief A default constructor. Creates a new PReLULayer instance and initializes layer parameters with the given values.
+ * @param prms Initial layer parameters
+ */
explicit PReLULayer(const LayerParams &prms) : WeightableLayer(prms), _channel_shared(false) {}
};
*/
using CNNLayer::CNNLayer;
};
+
+/**
+ * @brief This class represents a standard Strided Slice layer
+ * Strided Slice picks from input tensor according parameters
+ */
+class StridedSliceLayer : public CNNLayer {
+public:
+ /**
+ * @brief The begin_mask is a bitmask where bit i being 0 means
+ * to ignore the begin value and instead use the default value
+ */
+ std::string begin_mask;
+ /**
+ * @brief Analogous to begin_mask
+ */
+ std::string end_mask;
+ /**
+ * @brief The ellipsis_mask is a bitmask where bit i being 1 means
+ * the i-th is actually an ellipsis
+ */
+ std::string ellipsis_mask;
+ /**
+ * @brief The new_axis_mask_ is a bitmask where bit i being 1 means
+ * the i-th position creates a new 1 dimension shape
+ */
+ std::string new_axis_mask;
+ /**
+ * @brief The shrink_axis_mask is a bitmask where bit i being 1 means
+ * the i-th position shrinks the dimensionality
+ */
+ std::string shrink_axis_mask;
+
+ /**
+ * @brief Creates a new StridedSliceLayer instance.
+ */
+ using CNNLayer::CNNLayer;
+};
+
+/**
+* @brief This class represents a standard Shuffle Channels layer
+* Shuffle Channels picks from input tensor according parameters
+*/
+class ShuffleChannelsLayer : public CNNLayer {
+public:
+ /**
+ * @brief The axis in tensor to shuffle channels
+ */
+ int axis = 1;
+
+ /**
+ * @brief The group of output shuffled channels
+ */
+ unsigned int group = 1;
+
+ /**
+ * @brief Creates a new ShuffleChannelsLayer instance.
+ */
+ using CNNLayer::CNNLayer;
+};
+
+
+/**
+* @brief This class represents a standard Depth To Space layer
+* Depth To Space picks from input tensor according parameters
+*/
+class DepthToSpaceLayer : public CNNLayer {
+public:
+ /**
+ * @brief The group of output shuffled channels
+ */
+ unsigned int block_size = 1;
+
+ /**
+ * @brief Creates a new DepthToSpaceLayer instance.
+ */
+ using CNNLayer::CNNLayer;
+};
+
+
+/**
+* @brief This class represents a standard Space To Depth layer
+* Depth To Space picks from input tensor according parameters
+*/
+class SpaceToDepthLayer : public CNNLayer {
+public:
+ /**
+ * @brief The group of output Space To Depth
+ */
+ unsigned int block_size = 1;
+
+ /**
+ * @brief Creates a new SpaceToDepthLayer instance.
+ */
+ using CNNLayer::CNNLayer;
+};
+
+
+/**
+* @brief This class represents a standard Reverse Sequence layer
+* Reverse Sequence modifies input tensor according parameters
+*/
+class ReverseSequenceLayer : public CNNLayer {
+public:
+ /**
+ * @brief The seq_axis dimension in tensor which is partially reversed
+ */
+ int seq_axis = 1;
+
+ /**
+ * @brief The batch_axis dimension in tensor along which reversal is performed
+ */
+ int batch_axis = 0;
+
+ /**
+ * @brief Creates a new ReverseSequence instance.
+ */
+ using CNNLayer::CNNLayer;
+};
+
+
+/**
+* @brief This class represents a standard Squeeze layer
+* Squeeze modifies input tensor dimensions according parameters
+*/
+class SqueezeLayer : public CNNLayer {
+public:
+ /**
+ * @brief Creates a new Squeeze instance.
+ */
+ using CNNLayer::CNNLayer;
+};
+
+
+/**
+* @brief This class represents a standard Unsqueeze layer
+* Unsqueeze modifies input tensor dimensions according parameters
+*/
+class UnsqueezeLayer : public CNNLayer {
+public:
+ /**
+ * @brief Creates a new Unsqueeze instance.
+ */
+ using CNNLayer::CNNLayer;
+};
+
+
+/**
+* @brief This class represents a standard RangeLayer layer
+* RangeLayer modifies input tensor dimensions according parameters
+*/
+class RangeLayer : public CNNLayer {
+public:
+ /**
+ * @brief Creates a new RangeLayer instance.
+ */
+ using CNNLayer::CNNLayer;
+};
+
+
+/**
+* @brief This class represents a standard Fill layer
+* RFill modifies input tensor according parameters
+*/
+class FillLayer : public CNNLayer {
+public:
+ /**
+ * @brief Creates a new Fill instance.
+ */
+ using CNNLayer::CNNLayer;
+};
+
+
+/**
+* @brief This class represents a standard Expand layer
+* Expand modifies input tensor dimensions according parameters
+*/
+class ExpandLayer : public CNNLayer {
+public:
+ /**
+ * @brief Creates a new Expand instance.
+ */
+ using CNNLayer::CNNLayer;
+};
+
+/**
+ * @brief This class represents a quantization operation layer
+ * Element-wise linear quantization of floating point input values into a descrete set of floating point values
+ */
+class QuantizeLayer : public CNNLayer {
+public:
+ /**
+ * @brief The number of quantization levels
+ */
+ int levels = 1;
+
+ /**
+ * @brief Creates a new QuantizeLayer instance.
+ */
+ using CNNLayer::CNNLayer;
+};
+
} // namespace InferenceEngine