[model] Change the semantics for setting the batchsize
authorParichay Kapoor <pk.kapoor@samsung.com>
Fri, 7 Aug 2020 11:45:07 +0000 (20:45 +0900)
committerJijoong Moon <jijoong.moon@samsung.com>
Wed, 12 Aug 2020 01:09:58 +0000 (10:09 +0900)
Batchsize as a property was earlier set in input_shape for a layer
as well as for the model. However, this was conflicting and prone to errors.

This patch disables setting batch size while setting the input_shape.
If batch_size is more than 1 in the input_shape, a warning is issued.
And this value is later overriden by the batchsize set for the model.
This same batchsize is also used for the dataset as well.

Resolves #299

**Self evaluation:**
1. Build test: [x]Passed [ ]Failed [ ]Skipped
2. Run test: [x]Passed [ ]Failed [ ]Skipped

Signed-off-by: Parichay Kapoor <pk.kapoor@samsung.com>
35 files changed:
Applications/Classification/res/Classification.ini
Applications/Classification/res/Classification_func.ini
Applications/LogisticRegression/res/LogisticRegression.ini
Applications/ReinforcementLearning/DeepQ/jni/DeepQ.ini
Applications/Tizen_CAPI/Tizen_CAPI_config.ini
Applications/Tizen_CAPI/capi_file.c
Applications/Tizen_CAPI/capi_func.c
Applications/Training/res/Training.ini
Applications/mnist/res/mnist.ini
Applications/mnist/res/mnist_valid.ini
api/capi/include/nntrainer.h
api/capi/src/nntrainer.cpp
nntrainer/include/layer.h
nntrainer/include/neuralnet.h
nntrainer/include/parse_util.h
nntrainer/include/tensor_dim.h
nntrainer/src/activation_layer.cpp
nntrainer/src/bn_layer.cpp
nntrainer/src/conv2d_layer.cpp
nntrainer/src/databuffer.cpp
nntrainer/src/fc_layer.cpp
nntrainer/src/flatten_layer.cpp
nntrainer/src/input_layer.cpp
nntrainer/src/layer.cpp
nntrainer/src/neuralnet.cpp
nntrainer/src/parse_util.cpp
nntrainer/src/pooling2d_layer.cpp
nntrainer/src/tensor_dim.cpp
test/include/nntrainer_test_util.h
test/input_gen/genInput.py
test/tizen_capi/unittest_tizen_capi.cpp
test/tizen_capi/unittest_tizen_capi_layer.cpp
test/unittest/unittest_nntrainer_internal.cpp
test/unittest/unittest_nntrainer_layers.cpp
test/unittest/unittest_nntrainer_modelfile.cpp

index bf5558e..51432b9 100644 (file)
@@ -29,7 +29,7 @@ LabelData="label.dat"
 # Layer Section : Name
 [inputlayer]
 Type = input
-Input_Shape = 32:1:1:62720     # Input Layer Dimension
+Input_Shape = 1:1:62720        # Input Layer Dimension
 Bias_init_zero = true  # Zero Bias
 Normalization = true
 
index b569653..b802848 100644 (file)
@@ -18,7 +18,7 @@ epsilon = 1e-7        # epsilon for adam
 # Layer Section : Name
 [inputlayer]
 Type = input
-Input_Shape = 32:1:1:62720     # Input Layer Dimension
+Input_Shape = 1:1:62720        # Input Layer Dimension
 Bias_init_zero = true  # Zero Bias
 Normalization = true
 Activation = sigmoid   # activation : sigmoid, tanh
index 2f065bb..af6b975 100644 (file)
@@ -14,7 +14,7 @@ epsilon = 1e-5
 # Layer Section : Name
 [inputlayer]
 Type = input
-Input_Shape = 1:1:1:2
+Input_Shape = 1:1:2
 Bias_init_zero = true  # Zero Bias
 Activation = sigmoid
 
index 482f5ed..9aa9d71 100644 (file)
@@ -17,7 +17,7 @@ epsilon = 1e-8                # epsilon for adam
 # Layer Section : Name
 [inputlayer]
 Type = input
-Input_Shape = 32:1:1:4         # Input Layer Dimension
+Input_Shape = 1:1:4            # Input Layer Dimension
 Bias_init_zero = true  # Zero Bias
 Activation = tanh      # activation : sigmoid, tanh
 
index 9318a70..fc45603 100644 (file)
@@ -29,7 +29,7 @@ LabelData="label.dat"
 # Layer Section : Name
 [inputlayer]
 Type = input
-Input_Shape = 32:1:1:62720             # Input Layer Dimension
+Input_Shape = 1:1:62720                # Input Layer Dimension
 Bias_init_zero = true  # Zero Bias
 Normalization = true
 Activation = sigmoid   # activation : sigmoid, tanh
index 0c7dbe8..72766c3 100644 (file)
@@ -52,7 +52,7 @@ int main(int argc, char *argv[]) {
   NN_RETURN_STATUS();
 
   /* set property for input layer */
-  status = ml_train_layer_set_property(layers[0], "input_shape= 32:1:1:62720",
+  status = ml_train_layer_set_property(layers[0], "input_shape=1:1:62720",
                                        "normalization=true",
                                        "bias_init_zero=true", NULL);
   NN_RETURN_STATUS();
index 3b7ac93..6e64726 100644 (file)
@@ -308,7 +308,7 @@ int main(int argc, char *argv[]) {
   NN_RETURN_STATUS();
 
   /* set property for input layer */
-  status = ml_train_layer_set_property(layers[0], "input_shape= 32:1:1:62720",
+  status = ml_train_layer_set_property(layers[0], "input_shape=1:1:62720",
                                        "normalization=true",
                                        "bias_init_zero=true", NULL);
   NN_RETURN_STATUS();
index 8b02b78..469dafd 100644 (file)
@@ -16,7 +16,7 @@ minibatch = 1         # mini batch size
 # Layer Section : Name
 [inputlayer]
 Type = input
-Input_Shape = 1:1:1:128        # Input Layer Dimension
+Input_Shape = 1:1:128  # Input Layer Dimension
 Bias_init_zero = true  # Zero Bias
 Activation = sigmoid
 
index dd3896c..98706a6 100644 (file)
@@ -16,7 +16,7 @@ epsilon = 1e-7        # epsilon for adam
 # Layer Section : Name
 [inputlayer]
 Type = input
-Input_Shape = 32:1:28:28
+Input_Shape = 1:28:28
 
 # Layer Section : Name
 [conv2d_c1_layer]
index cbf433f..6c37a1f 100644 (file)
@@ -16,7 +16,7 @@ epsilon = 1e-7        # epsilon for adam
 # Layer Section : Name
 [inputlayer]
 Type = input
-Input_Shape = 2:1:28:28
+Input_Shape = 1:28:28
 
 #Layer Section : Name
 [conv2d_c1_layer]
index 496b75c..b9207b0 100644 (file)
@@ -297,7 +297,7 @@ int ml_train_layer_destroy(ml_train_layer_h layer);
  * }
  *
  * // Many of these hyperparmeters are optional
- * status = ml_train_layer_set_property(handle, "input_shape=32:1:1:6270",
+ * status = ml_train_layer_set_property(handle, "input_shape=1:1:6270",
  *      "unit=10", "bias_init_zero=true", "activation=sigmoid",
  *      "weight_decay=l2_norm", "weight_ini=he_uniform", NULL);
  * if (status != ML_ERROR_NONE) {
index c0395ac..888c246 100644 (file)
@@ -73,6 +73,9 @@ template <typename F> static int nntrainer_exception_boundary(F &&func) {
   } catch (std::out_of_range &e) {
     ml_loge("%s %s", typeid(e).name(), e.what());
     return ML_ERROR_INVALID_PARAMETER;
+  } catch (std::logic_error &e) {
+    ml_loge("%s %s", typeid(e).name(), e.what());
+    return ML_ERROR_INVALID_PARAMETER;
   } catch (std::bad_alloc &e) {
     ml_loge("%s %s", typeid(e).name(), e.what());
     return ML_ERROR_OUT_OF_MEMORY;
index 613ff91..f972787 100644 (file)
@@ -235,6 +235,7 @@ public:
    *            17. name : string (type)
    *            18. num_inputs : unsigned int (minimum 1)
    *            19. num_outputs : unsigned int (minimum 1)
+   *            20. batch_size : unsigned int (minimum 1)
    */
   enum class PropertyType {
     input_shape = 0,
@@ -257,7 +258,8 @@ public:
     name = 17,
     num_inputs = 18,
     num_outputs = 19,
-    unknown = 20
+    batch_size = 20,
+    unknown = 21
   };
 
   /**
@@ -327,12 +329,6 @@ public:
   void setWeightDecay(WeightDecayParam w) { weight_decay = w; }
 
   /**
-   * @brief  get Tensor Dimension
-   * @retval TensorDim Tensor Dimension
-   */
-  TensorDim &getTensorDim() { return dim; }
-
-  /**
    * @brief  set if this is last layer of Network
    * @param[in] last true/false
    */
@@ -366,13 +362,36 @@ public:
   Tensor initializeWeight(TensorDim w_dim, WeightIniType init_type,
                           int &status);
 
+  /**
+   * @brief Set the input dimension
+   * @param[in] d dimension to be set
+   */
   void setInputDimension(TensorDim d) { input_dim = d; }
 
+  /**
+   * @brief Get the output dimension
+   * @return TensorDim dimension of the output
+   */
   TensorDim getOutputDimension() { return output_dim; }
 
+  /**
+   * @brief Get the input dimension
+   * @return TensorDim dimension of the input
+   */
   TensorDim getInputDimension() { return input_dim; }
 
   /**
+   * @brief Set the batch for the layer
+   * @param batch Batch value to be set
+   * @note This denotes the maximum batch size of input. The actual batchsize
+   * of the data can be smaller in case of validation or testing
+   */
+  void setBatch(unsigned int batch) {
+    input_dim.setTensorDim(0, batch);
+    output_dim.setTensorDim(0, batch);
+  }
+
+  /**
    * @brief  get the loss value added by this layer
    * @retval loss value
    */
@@ -468,11 +487,6 @@ protected:
   bool last_layer;
 
   /**
-   * @brief     Dimension of this layer
-   */
-  TensorDim dim;
-
-  /**
    * @brief     Dimension of input activation
    */
   TensorDim input_dim;
index 6cf5ab5..4287f50 100644 (file)
@@ -311,7 +311,7 @@ public:
   void print(std::ostream &out, unsigned int flags = 0);
 
 private:
-  int batch_size; /**< batch size */
+  unsigned int batch_size; /**< batch size */
 
   unsigned int epoch; /**< Maximum Epoch */
 
index 6928f6e..9fb43c8 100644 (file)
@@ -124,13 +124,13 @@ unsigned int parseNetProperty(std::string property);
 unsigned int parseDataProperty(std::string property);
 
 /**
- * @brief     check str to be int and assign
+ * @brief     check str to be unsigned int and assign to variable to type T
  * @param[out] val assign variable
  * @param[in] str input string
  * @retval #ML_ERROR_NONE Successful.
  * @retval #ML_ERROR_INVALID_PARAMETER invalid parameter.
  */
-int setInt(int &val, std::string str);
+int setUint(unsigned int &val, const std::string &str);
 
 /**
  * @brief     check str to be float and assign
index 5e5045f..19537f7 100644 (file)
@@ -84,6 +84,7 @@ public:
   const unsigned int *getDim() const { return dim; }
   unsigned int getNumDim() const { return MAXDIM; }
 
+  unsigned int getTensorDim(unsigned int idx);
   void setTensorDim(unsigned int idx, unsigned int value);
   int setTensorDim(std::string input_shape);
 
index 0486877..fa71857 100644 (file)
@@ -46,8 +46,7 @@ int ActivationLayer::initialize(bool last) {
 
   this->last_layer = last;
 
-  dim = input_dim;
-  output_dim = dim;
+  output_dim = input_dim;
 
   return ML_ERROR_NONE;
 }
index 917db61..8ecf84a 100644 (file)
@@ -38,9 +38,9 @@ enum class BNParams { mu, var, gamma, beta };
 int BatchNormalizationLayer::initialize(bool last) {
   int status = ML_ERROR_NONE;
 
-  dim = input_dim;
-  dim.batch(1);
   output_dim = input_dim;
+  TensorDim dim = input_dim;
+  dim.batch(1);
 
   Tensor mu = Tensor(dim);
   Tensor var = Tensor(dim);
@@ -130,7 +130,7 @@ BatchNormalizationLayer::backwarding(sharedConstTensor derivative,
   Tensor dx;
   Tensor deriv = *derivative;
 
-  int batch = deriv.batch();
+  int batch = input_dim.batch();
 
   dgamma = x_normalized.multiply(deriv).sum(0);
   dbeta = deriv.sum(0);
@@ -159,7 +159,6 @@ void BatchNormalizationLayer::copy(std::shared_ptr<Layer> l) {
     std::static_pointer_cast<BatchNormalizationLayer>(l);
   this->opt = from->opt;
   this->last_layer = from->last_layer;
-  this->dim = from->dim;
   this->input_dim = from->input_dim;
   this->output_dim = from->output_dim;
   this->input.copy(from->input);
index cce0183..d113602 100644 (file)
@@ -31,7 +31,8 @@ int Conv2DLayer::initialize(bool last) {
   }
 
   this->last_layer = last;
-  dim = TensorDim(1, input_dim.channel(), kernel_size[0], kernel_size[1]);
+  TensorDim dim =
+    TensorDim(1, input_dim.channel(), kernel_size[0], kernel_size[1]);
   TensorDim bias_dim = TensorDim(1, 1, 1, 1);
 
   std::string kernelPrefix = "Conv2d:filter";
@@ -91,8 +92,9 @@ sharedConstTensor Conv2DLayer::forwarding(sharedConstTensor in) {
     input = input.standardization();
   }
 
-  hidden = Tensor(input.batch(), output_dim.channel(), output_dim.height(),
-                  output_dim.width());
+  TensorDim hidden_dim = output_dim;
+  hidden_dim.batch(in->batch());
+  hidden = Tensor(hidden_dim);
   hidden.setZero();
 
   std::vector<float> output(output_dim.width() * output_dim.height());
@@ -232,7 +234,6 @@ void Conv2DLayer::copy(std::shared_ptr<Layer> l) {
 
   this->input.copy(from->input);
   this->hidden.copy(from->hidden);
-  this->dim = from->dim;
   this->input_dim = from->input_dim;
   this->output_dim = from->output_dim;
   this->last_layer = from->last_layer;
@@ -281,10 +282,8 @@ void Conv2DLayer::setProperty(const PropertyType type,
   switch (type) {
   case PropertyType::filter: {
     if (!value.empty()) {
-      int size;
-      status = setInt(size, value);
+      status = setUint(filter_size, value);
       throw_status(status);
-      filter_size = size;
     }
   } break;
   case PropertyType::kernel_size:
index a17cc81..930acf7 100644 (file)
@@ -428,11 +428,11 @@ int DataBuffer::setProperty(std::vector<std::string> values) {
 
 int DataBuffer::setProperty(const PropertyType type, std::string &value) {
   int status = ML_ERROR_NONE;
+  unsigned int size = 0;
 
   switch (type) {
   case PropertyType::buffer_size:
-    int size;
-    status = setInt(size, value);
+    status = setUint(size, value);
     NN_RETURN_STATUS();
     status = this->setBufSize(size);
     NN_RETURN_STATUS();
index 5f27b76..bb874dc 100644 (file)
@@ -38,17 +38,16 @@ int FullyConnectedLayer::initialize(bool last) {
 
   this->last_layer = last;
 
+  output_dim = input_dim;
+  output_dim.width(unit);
+
   Tensor bias = Tensor(1, unit);
-  dim = input_dim;
-  dim.width(unit);
+  TensorDim dim = output_dim;
   dim.height(input_dim.width());
   dim.batch(1);
   Tensor weight = initializeWeight(dim, weight_ini_type, status);
   NN_RETURN_STATUS();
 
-  output_dim = input_dim;
-  output_dim.width(unit);
-
   if (bias_init_zero) {
     bias.setZero();
   } else {
@@ -68,10 +67,8 @@ void FullyConnectedLayer::setProperty(const PropertyType type,
   switch (type) {
   case PropertyType::unit: {
     if (!value.empty()) {
-      int width;
-      status = setInt(width, value);
+      status = setUint(unit, value);
       throw_status(status);
-      unit = width;
       output_dim.width(unit);
     }
   } break;
@@ -112,7 +109,6 @@ void FullyConnectedLayer::copy(std::shared_ptr<Layer> l) {
     std::static_pointer_cast<FullyConnectedLayer>(l);
   this->opt = from->opt;
   this->last_layer = from->last_layer;
-  this->dim = from->dim;
   this->unit = from->unit;
   this->input_dim = from->input_dim;
   this->output_dim = from->output_dim;
index 0f195fb..1894824 100644 (file)
@@ -65,7 +65,6 @@ void FlattenLayer::copy(std::shared_ptr<Layer> l) {
     std::static_pointer_cast<FlattenLayer>(l);
   this->input.copy(from->input);
   this->hidden.copy(from->hidden);
-  this->dim = from->dim;
   this->input_dim = from->input_dim;
   this->output_dim = from->output_dim;
   this->last_layer = from->last_layer;
index 6d6e17d..1da1c5c 100644 (file)
@@ -55,7 +55,6 @@ void InputLayer::copy(std::shared_ptr<Layer> l) {
   std::shared_ptr<InputLayer> from = std::static_pointer_cast<InputLayer>(l);
   this->opt = from->opt;
   this->last_layer = from->last_layer;
-  this->dim = from->dim;
   this->input_dim = from->input_dim;
   this->output_dim = from->output_dim;
   this->input.copy(from->input);
@@ -78,8 +77,7 @@ sharedConstTensor InputLayer::backwarding(sharedConstTensor in, int iteration) {
 
 int InputLayer::initialize(bool last) {
   int status = ML_ERROR_NONE;
-  dim = input_dim;
-  output_dim = dim;
+  output_dim = input_dim;
 
   return status;
 }
index 850a10f..a899acb 100644 (file)
@@ -94,25 +94,25 @@ Tensor Layer::initializeWeight(TensorDim w_dim, WeightIniType init_type,
 
   switch (init_type) {
   case WEIGHT_LECUN_NORMAL:
-    w.setRandNormal(0.0f, sqrt(1.0f / dim.height()));
+    w.setRandNormal(0.0f, sqrt(1.0f / w_dim.height()));
     break;
   case WEIGHT_XAVIER_NORMAL:
-    w.setRandNormal(0.0f, sqrt(2.0f / (dim.width() + dim.height())));
+    w.setRandNormal(0.0f, sqrt(2.0f / (w_dim.width() + w_dim.height())));
     break;
   case WEIGHT_HE_NORMAL:
-    w.setRandNormal(0.0f, sqrt(2.0f / (dim.height())));
+    w.setRandNormal(0.0f, sqrt(2.0f / (w_dim.height())));
     break;
   case WEIGHT_LECUN_UNIFORM:
-    w.setRandUniform(-1.0f * sqrt(1.0f / dim.height()),
-                     sqrt(1.0f / dim.height()));
+    w.setRandUniform(-1.0f * sqrt(1.0f / w_dim.height()),
+                     sqrt(1.0f / w_dim.height()));
     break;
   case WEIGHT_XAVIER_UNIFORM:
-    w.setRandUniform(-1.0f * sqrt(6.0f / (dim.height() + dim.width())),
-                     sqrt(6.0 / (dim.height() + dim.width())));
+    w.setRandUniform(-1.0f * sqrt(6.0f / (w_dim.height() + w_dim.width())),
+                     sqrt(6.0 / (w_dim.height() + w_dim.width())));
     break;
   case WEIGHT_HE_UNIFORM:
-    w.setRandUniform(-1.0f * sqrt(6.0f / (dim.height())),
-                     sqrt(6.0 / (dim.height())));
+    w.setRandUniform(-1.0f * sqrt(6.0f / (w_dim.height())),
+                     sqrt(6.0 / (w_dim.height())));
     break;
   default:
     break;
@@ -158,8 +158,29 @@ void Layer::setProperty(const PropertyType type, const std::string &value) {
     break;
   case PropertyType::input_shape:
     if (!value.empty()) {
+      unsigned int cache_batch_size = 1;
+      /** cache original value of batch size */
+      if (input_dim.batch()) {
+        cache_batch_size = input_dim.batch();
+        input_dim.batch(1);
+      }
       status = input_dim.setTensorDim(value.c_str());
+      if (input_dim.batch() > 1) {
+        ml_logw("Batch size set with input dimension %d is ignored."
+                "Set batchsize property for the model to update batchsize.",
+                input_dim.batch());
+      }
+      /** set back to cache value of dimension */
+      input_dim.batch(cache_batch_size);
+      throw_status(status);
+    }
+    break;
+  case PropertyType::batch_size:
+    if (!value.empty()) {
+      unsigned int batch_size;
+      status = setUint(batch_size, value);
       throw_status(status);
+      input_dim.batch(batch_size);
     }
     break;
   case PropertyType::bias_init_zero:
@@ -228,7 +249,10 @@ void Layer::printIfValid(std::ostream &out, const PropertyType type,
 }
 
 void Layer::printShapeInfo(std::ostream &out) {
-  out << "input " << input_dim << "inner " << dim << "output " << output_dim;
+  out << "input " << input_dim;
+  for (unsigned int i = 0; i < param_size; i++)
+    out << "inner" << i << " " << paramsAt(i).weight.getDim();
+  out << "output " << output_dim;
 }
 
 void Layer::printPropertiesMeta(std::ostream &out) {
index 199491f..c6ec0dd 100644 (file)
@@ -160,6 +160,9 @@ int NeuralNetwork::loadDatasetConfig(void *_ini) {
   status = data_buffer->setBufSize(bufsize);
   NN_INI_RETURN_STATUS();
 
+  status = data_buffer->setMiniBatch(batch_size);
+  NN_INI_RETURN_STATUS();
+
   ml_logd("parsing dataset done");
   return status;
 }
@@ -387,16 +390,8 @@ int NeuralNetwork::setProperty(std::vector<std::string> values) {
 
     switch (static_cast<PropertyType>(type)) {
     case PropertyType::batch_size: {
-      status = setInt(batch_size, value);
+      status = setUint(batch_size, value);
       NN_RETURN_STATUS();
-      for (unsigned int i = 0; i < layers.size(); ++i) {
-        if (layers[i]->getTensorDim().batch() !=
-            static_cast<unsigned int>(batch_size)) {
-          ml_logw("Warning: Batch Size is changing!! : %d -> %d",
-                  layers[i]->getTensorDim().batch(), batch_size);
-          layers[i]->getTensorDim().batch(batch_size);
-        }
-      }
     } break;
     case PropertyType::cost:
     case PropertyType::loss: {
@@ -425,10 +420,8 @@ int NeuralNetwork::setTrainConfig(std::vector<std::string> values) {
 
     switch (static_cast<PropertyType>(type)) {
     case PropertyType::epochs: {
-      int e;
-      status = setInt(e, value);
+      status = setUint(epoch, value);
       NN_RETURN_STATUS();
-      epoch = e;
     } break;
     case PropertyType::model_file: {
       model = value;
@@ -476,6 +469,7 @@ int NeuralNetwork::init() {
       }
     }
 
+    layers[i]->setBatch(batch_size);
     status = layers[i]->initialize(last);
 
     switch (l.getType()) {
@@ -549,6 +543,9 @@ sharedConstTensor NeuralNetwork::forwarding(sharedConstTensor input,
                                             sharedConstTensor label) {
   sharedConstTensor X;
 
+  if (input->getDim().batch() > batch_size)
+    throw std::logic_error("Error: mismatch in batchsize for data and model.");
+
   X = forwarding(input);
   X = std::static_pointer_cast<LossLayer>(layers[layers.size() - 1])
         ->forwarding(X, label);
@@ -643,11 +640,12 @@ int NeuralNetwork::train(std::vector<std::string> values) {
     return ML_ERROR_INVALID_PARAMETER;
   }
 
-  status = data_buffer->setMiniBatch(layers[0]->getInputDimension().batch());
+  /** Setup data buffer properties */
+  status = data_buffer->setMiniBatch(batch_size);
   NN_RETURN_STATUS();
 
-  status = data_buffer->setClassNum(
-    layers[layers.size() - 1]->getOutputDimension().width());
+  status =
+    data_buffer->setClassNum(layers.back()->getOutputDimension().width());
   NN_RETURN_STATUS();
 
   status = data_buffer->setFeatureSize(layers[0]->getInputDimension());
@@ -726,7 +724,7 @@ int NeuralNetwork::train_run() {
       while (true) {
         vec_4d in, label;
         if (data_buffer->getDataFromBuffer(nntrainer::BUF_VAL, in, label)) {
-          for (int i = 0; i < batch_size; ++i) {
+          for (unsigned int i = 0; i < batch_size; ++i) {
             sharedTensor X = MAKE_SHARED_TENSOR(Tensor({in[i]}));
             sharedTensor Y2 = MAKE_SHARED_TENSOR(Tensor({label[i]}));
             sharedConstTensor Y = forwarding(X, Y2);
index cf0c486..db604e0 100644 (file)
@@ -264,6 +264,9 @@ unsigned int parseType(std::string ll, InputType t) {
  * pooling = 15
  * flatten = 16
  * name = 17
+ * num_inputs = 18
+ * num_outputs = 19
+ * batch_size = 20
  *
  * InputLayer has 0, 1, 2, 3 properties.
  * FullyConnectedLayer has 1, 4, 6, 7, 8, 9 properties.
@@ -271,12 +274,13 @@ unsigned int parseType(std::string ll, InputType t) {
  * Pooling2DLayer has 12, 13, 14, 15 properties.
  * BatchNormalizationLayer has 0, 1, 5, 6, 7 properties.
  */
-static std::array<std::string, 19> property_string = {
+static std::array<std::string, 22> property_string = {
   "input_shape", "bias_init_zero", "normalization", "standardization",
   "activation",  "epsilon",        "weight_decay",  "weight_decay_lambda",
   "unit",        "weight_ini",     "filter",        "kernel_size",
   "stride",      "padding",        "pooling_size",  "pooling",
-  "flatten",     "name",           "unknown"};
+  "flatten",     "name",           "num_inputs",    "num_outputs",
+  "batch_size",  "unknown"};
 
 unsigned int parseLayerProperty(std::string property) {
   unsigned int i;
@@ -380,10 +384,10 @@ unsigned int parseDataProperty(std::string property) {
   return (unsigned int)DataBuffer::PropertyType::unknown;
 }
 
-int setInt(int &val, std::string str) {
+int setUint(unsigned int &val, const std::string &str) {
   int status = ML_ERROR_NONE;
   try {
-    val = std::stoi(str.c_str());
+    val = (unsigned int)std::stoul(str.c_str());
   } catch (...) {
     ml_loge("Error: Wrong Type. Must be int");
     status = ML_ERROR_INVALID_PARAMETER;
index cafede9..3337851 100644 (file)
@@ -55,8 +55,9 @@ int Pooling2DLayer::initialize(bool last) {
 sharedConstTensor Pooling2DLayer::forwarding(sharedConstTensor in) {
   input = *in;
 
-  hidden = Tensor(input.batch(), output_dim.channel(), output_dim.height(),
-                  output_dim.width());
+  TensorDim hidden_dim = output_dim;
+  hidden_dim.batch(in->batch());
+  hidden = Tensor(hidden_dim);
   hidden.setZero();
 
   for (unsigned int b = 0; b < input.batch(); ++b) {
@@ -175,7 +176,6 @@ void Pooling2DLayer::copy(std::shared_ptr<Layer> l) {
 
   this->input.copy(from->input);
   this->hidden.copy(from->hidden);
-  this->dim = from->dim;
   this->input_dim = from->input_dim;
   this->output_dim = from->output_dim;
   this->last_layer = from->last_layer;
index ffda4c2..28811fc 100644 (file)
@@ -45,11 +45,21 @@ void TensorDim::resetLen() {
   len = dim[0] * feature_len;
 }
 
+unsigned int TensorDim::getTensorDim(unsigned int idx) {
+  if (idx < 0 || idx > MAXDIM)
+    throw std::invalid_argument(
+      "[TensorDim] Tensor Dimension index should be between 0 and 4");
+
+  return dim[idx];
+}
+
 void TensorDim::setTensorDim(unsigned int idx, unsigned int value) {
-  if (value == 0) {
+  if (idx < 0 || idx > MAXDIM)
+    throw std::out_of_range(
+      "[TensorDim] Tensor Dimension index should be between 0 and 4");
+  if (value <= 0)
     throw std::invalid_argument(
-      "[TensorDim] Trying to assign value of 0 to tensor dim");
-  }
+      "[TensorDim] Trying to assign value <=0 to tensor dim");
 
   if (len == 0) {
     for (int i = 0; i < MAXDIM; ++i) {
@@ -68,25 +78,15 @@ int TensorDim::setTensorDim(std::string input_shape) {
     std::sregex_iterator(input_shape.begin(), input_shape.end(), words_regex);
   auto words_end = std::sregex_iterator();
   int cur_dim = std::distance(words_begin, words_end);
-  if (cur_dim > MAXDIM) {
-    ml_loge("Tensor Dimension should be less than 4");
+  if (cur_dim <= 0 || cur_dim > MAXDIM) {
+    ml_loge("Tensor Dimension should be between 1 and 4");
     return ML_ERROR_INVALID_PARAMETER;
   }
   int cn = 0;
-  for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
-    if ((MAXDIM - cur_dim + cn) > 3 || (MAXDIM - cur_dim + cn) < 0) {
-      ml_loge("Tensor Dimension Setting Error");
-      return ML_ERROR_INVALID_PARAMETER;
-    }
-    setTensorDim(MAXDIM - cur_dim + cn, std::stoi((*i).str()));
-    if (dim[MAXDIM - cur_dim + cn] <= 0) {
-      ml_loge("Tensor Dimension should be greater than 0");
-      return ML_ERROR_INVALID_PARAMETER;
-    }
-    cn++;
+  for (std::sregex_iterator i = words_begin; i != words_end; ++i, ++cn) {
+    setTensorDim(MAXDIM - cur_dim + cn, std::stoul((*i).str()));
   }
-  feature_len = dim[1] * dim[2] * dim[3];
-  len = dim[0] * feature_len;
+
   return status;
 }
 
index a71e011..b9ad74f 100644 (file)
@@ -216,7 +216,7 @@ const std::string config_str = "[Network]"
                                "\n"
                                "Type = input"
                                "\n"
-                               "Input_Shape = 32:1:1:62720"
+                               "Input_Shape = 1:1:62720"
                                "\n"
                                "bias_init_zero = true"
                                "\n"
@@ -279,7 +279,7 @@ const std::string config_str2 = "[Network]"
                                 "\n"
                                 "Type = conv2d"
                                 "\n"
-                                "Input_Shape = 32:3:28:28"
+                                "Input_Shape = 3:28:28"
                                 "\n"
                                 "bias_init_zero = true"
                                 "\n"
index 5b6b61e..bf0c7a5 100755 (executable)
@@ -449,7 +449,7 @@ def gen_test_case_fc(input_shape, kernel_shape, base_name):
     save(base_name + "_goldenFCGradientDxSoftmaxCrossAdam.out", golden_fc[2][0])
     save(base_name + "_goldenFCGradientsSoftmaxCrossAdam.out", golden_fc[2][1], golden_fc[2][2])
     save(base_name + "_goldenFCUpdatedWeightsSoftmaxCrossAdam.out", golden_fc[3][0], golden_fc[3][1])
-    
+
 def gen_test_case_bn(input_shape, base_name, training=True):
     input_data = gen_input(base_name + "_BNLayerInput.in", input_shape)
 
index aa55b6b..6f4349c 100644 (file)
@@ -92,8 +92,8 @@ TEST(nntrainer_capi_nnmodel, construct_conf_02_n) {
   int status = ML_ERROR_NONE;
   std::string config_file = "./test_compile_03_n.ini";
   RESET_CONFIG(config_file.c_str());
-  replaceString("Input_Shape = 32:1:1:62720", "Input_Shape= 32:1:1:0",
-                config_file, config_str);
+  replaceString("Input_Shape = 1:1:62720", "Input_Shape=1:1:0", config_file,
+                config_str);
   status = ml_train_model_construct_with_conf(config_file.c_str(), &handle);
   EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
 }
@@ -125,7 +125,7 @@ TEST(nntrainer_capi_nnmodel, compile_05_p) {
   status = ml_train_layer_create(&layers[0], ML_TRAIN_LAYER_TYPE_INPUT);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
-  status = ml_train_layer_set_property(layers[0], "input_shape= 32:1:1:62720",
+  status = ml_train_layer_set_property(layers[0], "input_shape=1:1:62720",
                                        "normalization=true",
                                        "bias_init_zero=true", NULL);
   EXPECT_EQ(status, ML_ERROR_NONE);
@@ -166,7 +166,7 @@ TEST(nntrainer_capi_nnmodel, compile_05_p) {
   status = ml_train_model_set_optimizer(model, optimizer);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
-  status = ml_train_model_compile(model, "loss=cross", NULL);
+  status = ml_train_model_compile(model, "loss=cross", "batch_size=32", NULL);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
   status = ml_train_model_destroy(model);
@@ -189,7 +189,7 @@ TEST(nntrainer_capi_nnmodel, compile_06_n) {
   status = ml_train_layer_create(&layers[0], ML_TRAIN_LAYER_TYPE_INPUT);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
-  status = ml_train_layer_set_property(layers[0], "input_shape= 32:1:1:62720",
+  status = ml_train_layer_set_property(layers[0], "input_shape=1:1:62720",
                                        "normalization=true",
                                        "bias_init_zero=true", NULL);
   EXPECT_EQ(status, ML_ERROR_NONE);
@@ -260,8 +260,8 @@ TEST(nntrainer_capi_nnmodel, train_01_p) {
   int status = ML_ERROR_NONE;
   std::string config_file = "./test_train_01_p.ini";
   RESET_CONFIG(config_file.c_str());
-  replaceString("Input_Shape = 32:1:1:62720", "Input_Shape=16:1:1:62720",
-                config_file, config_str);
+  replaceString("Input_Shape = 1:1:62720", "Input_Shape=1:1:62720", config_file,
+                config_str);
   replaceString("minibatch = 32", "minibatch = 16", config_file, config_str);
   replaceString("BufferSize=100", "", config_file, config_str);
   status = ml_train_model_construct_with_conf(config_file.c_str(), &handle);
@@ -291,8 +291,6 @@ TEST(nntrainer_capi_nnmodel, train_03_n) {
   int status = ML_ERROR_NONE;
   std::string config_file = "./test_train_01_p.ini";
   RESET_CONFIG(config_file.c_str());
-  replaceString("Input_Shape = 32:1:1:62720", "input_shape=32:1:1:62720",
-                config_file, config_str);
   replaceString("minibatch = 32", "minibatch = 16", config_file, config_str);
   replaceString("BufferSize=100", "", config_file, config_str);
   status = ml_train_model_construct_with_conf(config_file.c_str(), &handle);
@@ -320,7 +318,7 @@ TEST(nntrainer_capi_nnmodel, addLayer_01_p) {
   status = ml_train_layer_create(&layer, ML_TRAIN_LAYER_TYPE_INPUT);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
-  status = ml_train_layer_set_property(layer, "input_shape= 32:1:1:6270", NULL);
+  status = ml_train_layer_set_property(layer, "input_shape=1:1:6270", NULL);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
   status = ml_train_layer_set_property(layer, "normalization = true", NULL);
@@ -351,7 +349,7 @@ TEST(nntrainer_capi_nnmodel, addLayer_02_p) {
   status = ml_train_layer_create(&layer, ML_TRAIN_LAYER_TYPE_INPUT);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
-  status = ml_train_layer_set_property(layer, "input_shape= 32:1:1:6270",
+  status = ml_train_layer_set_property(layer, "input_shape=1:1:6270",
                                        "normalization=true", NULL);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
@@ -377,7 +375,7 @@ TEST(nntrainer_capi_nnmodel, addLayer_03_p) {
   status = ml_train_layer_create(&layer, ML_TRAIN_LAYER_TYPE_INPUT);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
-  status = ml_train_layer_set_property(layer, "input_shape= 32:1:1:62720",
+  status = ml_train_layer_set_property(layer, "input_shape=1:1:62720",
                                        "activation=sigmoid", NULL);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
@@ -403,7 +401,7 @@ TEST(nntrainer_capi_nnmodel, addLayer_04_p) {
   status = ml_train_layer_create(&layers[0], ML_TRAIN_LAYER_TYPE_INPUT);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
-  status = ml_train_layer_set_property(layers[0], "input_shape= 32:1:1:62720",
+  status = ml_train_layer_set_property(layers[0], "input_shape=1:1:62720",
                                        "normalization=true",
                                        "bias_init_zero=true", NULL);
   EXPECT_EQ(status, ML_ERROR_NONE);
@@ -513,7 +511,7 @@ TEST(nntrainer_capi_nnmodel, create_optimizer_02_p) {
   status = ml_train_layer_create(&layers[0], ML_TRAIN_LAYER_TYPE_INPUT);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
-  status = ml_train_layer_set_property(layers[0], "input_shape= 32:1:1:62720",
+  status = ml_train_layer_set_property(layers[0], "input_shape=1:1:62720",
                                        "normalization=true",
                                        "bias_init_zero=true", NULL);
   EXPECT_EQ(status, ML_ERROR_NONE);
@@ -563,7 +561,7 @@ TEST(nntrainer_capi_nnmodel, create_optimizer_03_p) {
   status = ml_train_layer_create(&layers[0], ML_TRAIN_LAYER_TYPE_INPUT);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
-  status = ml_train_layer_set_property(layers[0], "input_shape= 32:1:1:62720",
+  status = ml_train_layer_set_property(layers[0], "input_shape=1:1:62720",
                                        "normalization=true",
                                        "bias_init_zero=true", NULL);
   EXPECT_EQ(status, ML_ERROR_NONE);
@@ -617,7 +615,7 @@ TEST(nntrainer_capi_nnmodel, train_with_file_01_p) {
   status = ml_train_layer_create(&layers[0], ML_TRAIN_LAYER_TYPE_INPUT);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
-  status = ml_train_layer_set_property(layers[0], "input_shape= 16:1:1:62720",
+  status = ml_train_layer_set_property(layers[0], "input_shape=1:1:62720",
                                        "normalization=true",
                                        "bias_init_zero=true", NULL);
   EXPECT_EQ(status, ML_ERROR_NONE);
@@ -686,7 +684,7 @@ TEST(nntrainer_capi_nnmodel, train_with_generator_01_p) {
   status = ml_train_layer_create(&layers[0], ML_TRAIN_LAYER_TYPE_INPUT);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
-  status = ml_train_layer_set_property(layers[0], "input_shape= 16:1:1:62720",
+  status = ml_train_layer_set_property(layers[0], "input_shape=1:1:62720",
                                        "normalization=true",
                                        "bias_init_zero=true", NULL);
   EXPECT_EQ(status, ML_ERROR_NONE);
index bf73ce5..83cadbb 100644 (file)
@@ -66,7 +66,7 @@ TEST(nntrainer_capi_nnlayer, setproperty_01_p) {
   int status;
   status = ml_train_layer_create(&handle, ML_TRAIN_LAYER_TYPE_INPUT);
   EXPECT_EQ(status, ML_ERROR_NONE);
-  status = ml_train_layer_set_property(handle, "input_shape=32:1:1:6270", NULL);
+  status = ml_train_layer_set_property(handle, "input_shape=1:1:6270", NULL);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
   status = ml_train_layer_set_property(handle, "normalization=true", NULL);
@@ -120,7 +120,7 @@ TEST(nntrainer_capi_nnlayer, setproperty_04_n) {
   int status;
   status = ml_train_layer_create(&handle, ML_TRAIN_LAYER_TYPE_INPUT);
   EXPECT_EQ(status, ML_ERROR_NONE);
-  status = ml_train_layer_set_property(handle, "input_shape=0:0:0:1", NULL);
+  status = ml_train_layer_set_property(handle, "input_shape=0:0:1", NULL);
   EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
   status = ml_train_layer_destroy(handle);
   EXPECT_EQ(status, ML_ERROR_NONE);
index 69f777c..9ace2a4 100644 (file)
@@ -100,8 +100,8 @@ TEST(nntrainer_NeuralNetwork, load_config_02_n) {
  */
 TEST(nntrainer_NeuralNetwork, load_config_03_n) {
   RESET_CONFIG("./test.ini");
-  replaceString("Input_Shape = 32:1:1:62720", "Input_Shape = 32:1:1:0",
-                "./test.ini", config_str);
+  replaceString("Input_Shape = 1:1:62720", "Input_Shape = 1:1:0", "./test.ini",
+                config_str);
   nntrainer::NeuralNetwork NN;
   NN.setConfig("./test.ini");
 
@@ -117,7 +117,7 @@ TEST(nntrainer_NeuralNetwork, load_config_03_n) {
 TEST(nntrainer_NeuralNetwork, load_config_04_p) {
   int status = ML_ERROR_NONE;
   RESET_CONFIG("./test.ini");
-  replaceString("Input_Shape = 32:1:1:62720", "", "./test.ini", config_str);
+  replaceString("Input_Shape = 1:1:62720", "", "./test.ini", config_str);
   nntrainer::NeuralNetwork NN;
   NN.setConfig("./test.ini");
 
index 314c440..e45f78e 100644 (file)
@@ -23,6 +23,7 @@
 #include <nntrainer_test_util.h>
 #include <optimizer.h>
 #include <pooling2d_layer.h>
+#include <tensor_dim.h>
 #include <util_func.h>
 
 using nntrainer::sharedConstTensor;
@@ -170,7 +171,10 @@ protected:
 class nntrainer_InputLayer
   : public nntrainer_abstractLayer<nntrainer::InputLayer> {
 protected:
-  virtual void prepareLayer() { setInputDim("32:3:28:28"); }
+  virtual void prepareLayer() {
+    setInputDim("3:28:28");
+    setProperty("batch_size=1");
+  }
 };
 
 /**
@@ -181,6 +185,83 @@ TEST_F(nntrainer_InputLayer, initialize_01_p) {
   EXPECT_EQ(status, ML_ERROR_NONE);
 }
 
+TEST_F(nntrainer_InputLayer, set_property_01_n) {
+  EXPECT_THROW(
+    layer.setProperty(nntrainer::Layer::PropertyType::input_shape, "0:3:2:1"),
+    std::invalid_argument);
+}
+
+TEST_F(nntrainer_InputLayer, set_property_02_p) {
+  nntrainer::TensorDim dim;
+  int status = setProperty("input_shape=3:2:1");
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  dim = layer.getInputDimension();
+  EXPECT_EQ(dim.getTensorDim(0), 1);
+  EXPECT_EQ(dim.getTensorDim(1), 3);
+  EXPECT_EQ(dim.getTensorDim(2), 2);
+  EXPECT_EQ(dim.getTensorDim(3), 1);
+}
+
+TEST_F(nntrainer_InputLayer, set_property_03_p) {
+  nntrainer::TensorDim dim;
+  int status = setProperty("input_shape=1:3:2:1");
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  dim = layer.getInputDimension();
+  EXPECT_EQ(dim.getTensorDim(0), 1);
+  EXPECT_EQ(dim.getTensorDim(1), 3);
+  EXPECT_EQ(dim.getTensorDim(2), 2);
+  EXPECT_EQ(dim.getTensorDim(3), 1);
+}
+
+TEST_F(nntrainer_InputLayer, set_property_04_p) {
+  nntrainer::TensorDim dim;
+  int status = setProperty("input_shape=4:3:2:1");
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  /** Set input shape ignores batch size */
+  dim = layer.getInputDimension();
+  EXPECT_EQ(dim.getTensorDim(0), 1);
+  EXPECT_EQ(dim.getTensorDim(1), 3);
+  EXPECT_EQ(dim.getTensorDim(2), 2);
+  EXPECT_EQ(dim.getTensorDim(3), 1);
+}
+
+TEST_F(nntrainer_InputLayer, set_property_05_p) {
+  nntrainer::TensorDim dim;
+  int status = ML_ERROR_NONE;
+
+  status = setProperty("batch_size=5");
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  dim = layer.getInputDimension();
+  EXPECT_EQ(dim.getTensorDim(0), 5);
+  EXPECT_EQ(dim.getTensorDim(1), 3);
+  EXPECT_EQ(dim.getTensorDim(2), 28);
+  EXPECT_EQ(dim.getTensorDim(3), 28);
+
+  /** Original batch size is retained */
+  status = setProperty("input_shape=1:3:2:1");
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  dim = layer.getInputDimension();
+  EXPECT_EQ(dim.getTensorDim(0), 5);
+  EXPECT_EQ(dim.getTensorDim(1), 3);
+  EXPECT_EQ(dim.getTensorDim(2), 2);
+  EXPECT_EQ(dim.getTensorDim(3), 1);
+
+  /** Original batch size is retained */
+  status = setProperty("input_shape=4:3:2:1");
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  dim = layer.getInputDimension();
+  EXPECT_EQ(dim.getTensorDim(0), 5);
+  EXPECT_EQ(dim.getTensorDim(1), 3);
+  EXPECT_EQ(dim.getTensorDim(2), 2);
+  EXPECT_EQ(dim.getTensorDim(3), 1);
+}
+
 /**
  * @brief Input Layer
  */
@@ -224,7 +305,8 @@ class nntrainer_FullyConnectedLayer
   : public nntrainer_abstractLayer<nntrainer::FullyConnectedLayer> {
 protected:
   virtual void prepareLayer() {
-    setInputDim("32:1:28:28");
+    setInputDim("1:28:28");
+    setProperty("batch_size=32");
     setProperty("unit=1");
   }
 };
@@ -447,7 +529,8 @@ protected:
   }
 
   virtual void prepareLayer() {
-    setInputDim("3:1:1:12");
+    setInputDim("1:1:12");
+    setProperty("batch_size=3");
     setProperty("unit=15");
     setProperty("bias_init_zero=true");
     last_layer = true;
@@ -699,7 +782,7 @@ protected:
   }
 
   virtual void prepareLayer() {
-    setProperty("input_shape=3:1:4:5 | epsilon=0.001");
+    setProperty("input_shape=1:4:5 | epsilon=0.001");
     setOptimizer(nntrainer::OptType::sgd, "learning_rate=1");
   }
 };
@@ -775,7 +858,7 @@ protected:
 
   virtual void prepareLayer() {
     int status =
-      setProperty("input_shape=32:3:28:28 |"
+      setProperty("input_shape=3:28:28 | batch_size=32 |"
                   "bias_init_zero=true |"
                   "activation=sigmoid |"
                   "weight_decay=l2norm |"
@@ -842,7 +925,7 @@ TEST_F(nntrainer_Conv2DLayer, save_read_01_p) {
  * @brief Convolution 2D Layer
  */
 TEST_F(nntrainer_Conv2DLayer, forwarding_01_p) {
-  reinitialize("input_shape=1:3:7:7 |"
+  reinitialize("input_shape=3:7:7 | batch_size=1 |"
                "bias_init_zero = true |"
                "weight_ini=xavier_uniform |"
                "filter=2 | kernel_size=3,3 | stride=1, 1 | padding=0,0",
@@ -863,7 +946,7 @@ TEST_F(nntrainer_Conv2DLayer, forwarding_01_p) {
  */
 
 TEST_F(nntrainer_Conv2DLayer, forwarding_02_p) {
-  reinitialize("input_shape=2:3:7:7 |"
+  reinitialize("input_shape=3:7:7 | batch_size=2 |"
                "bias_init_zero = true |"
                "weight_ini=xavier_uniform |"
                "filter=3 | kernel_size=3,3 | stride=1, 1 | padding=0,0",
@@ -880,7 +963,7 @@ TEST_F(nntrainer_Conv2DLayer, forwarding_02_p) {
 }
 
 TEST_F(nntrainer_Conv2DLayer, backwarding_01_p) {
-  status = reinitialize("input_shape=1:3:7:7 |"
+  status = reinitialize("input_shape=3:7:7 | batch_size=1 |"
                         "bias_init_zero=true |"
                         "weight_ini=xavier_uniform |"
                         "filter=2 |"
@@ -934,7 +1017,7 @@ TEST_F(nntrainer_Conv2DLayer, backwarding_01_p) {
 }
 
 TEST_F(nntrainer_Conv2DLayer, backwarding_02_p) {
-  status = reinitialize("input_shape=2:3:7:7 |"
+  status = reinitialize("input_shape=3:7:7 | batch_size=2 |"
                         "bias_init_zero=true |"
                         "weight_ini=xavier_uniform |"
                         "filter=3 |"
@@ -1005,10 +1088,14 @@ protected:
 };
 
 TEST_F(nntrainer_Pooling2DLayer, setProperty_01_p) {
+  setInputDim("3:5:5");
+  setProperty("batch_size=2");
   setProperty("pooling_size=2,2 | stride=1,1 | padding=0,0 | pooling=average");
 }
 
 TEST_F(nntrainer_Pooling2DLayer, setProperty_02_n) {
+  setInputDim("3:5:5");
+  setProperty("batch_size=2");
   int status = layer.setProperty({"pooling_size="});
   EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
 }
@@ -1016,7 +1103,7 @@ TEST_F(nntrainer_Pooling2DLayer, setProperty_02_n) {
 TEST_F(nntrainer_Pooling2DLayer, initialize_01_p) { reinitialize(); }
 
 TEST_F(nntrainer_Pooling2DLayer, forwarding_01_p) {
-  setInputDim("1:2:5:5");
+  setInputDim("2:5:5");
   setProperty("pooling_size=2,2 | stride=1,1 | padding=0,0 | pooling=max");
 
   reinitialize();
@@ -1029,7 +1116,7 @@ TEST_F(nntrainer_Pooling2DLayer, forwarding_01_p) {
 }
 
 TEST_F(nntrainer_Pooling2DLayer, forwarding_02_p) {
-  setInputDim("1:2:5:5");
+  setInputDim("2:5:5");
   setProperty("pooling_size=2,2 | stride=1,1 | padding=0,0 | pooling=average");
 
   reinitialize();
@@ -1043,7 +1130,7 @@ TEST_F(nntrainer_Pooling2DLayer, forwarding_02_p) {
 
 TEST_F(nntrainer_Pooling2DLayer, forwarding_03_p) {
   resetLayer();
-  setInputDim("1:2:5:5");
+  setInputDim("2:5:5");
   setProperty("pooling=global_max");
   reinitialize();
 
@@ -1056,7 +1143,7 @@ TEST_F(nntrainer_Pooling2DLayer, forwarding_03_p) {
 
 TEST_F(nntrainer_Pooling2DLayer, forwarding_04_p) {
   resetLayer();
-  setInputDim("1:2:5:5");
+  setInputDim("2:5:5");
   setProperty("pooling=global_average");
   reinitialize();
 
@@ -1069,7 +1156,8 @@ TEST_F(nntrainer_Pooling2DLayer, forwarding_04_p) {
 
 TEST_F(nntrainer_Pooling2DLayer, forwarding_05_p) {
   resetLayer();
-  setInputDim("2:2:5:5");
+  setInputDim("2:5:5");
+  setProperty("batch_size=2");
   setProperty("pooling=global_max");
   reinitialize();
 
@@ -1080,7 +1168,8 @@ TEST_F(nntrainer_Pooling2DLayer, forwarding_05_p) {
 
 TEST_F(nntrainer_Pooling2DLayer, forwarding_06_p) {
   resetLayer();
-  setInputDim("2:2:5:5");
+  setInputDim("2:5:5");
+  setProperty("batch_size=2");
   setProperty("pooling=global_average");
   reinitialize();
 
@@ -1092,7 +1181,7 @@ TEST_F(nntrainer_Pooling2DLayer, forwarding_06_p) {
 
 TEST_F(nntrainer_Pooling2DLayer, backwarding_01_p) {
   resetLayer();
-  setInputDim("1:2:5:5");
+  setInputDim("2:5:5");
   setProperty("pooling_size=2,2 | stride=1,1 | padding=0,0 | pooling=max");
 
   reinitialize();
@@ -1113,7 +1202,7 @@ TEST_F(nntrainer_Pooling2DLayer, backwarding_01_p) {
 
 TEST_F(nntrainer_Pooling2DLayer, backwarding_02_p) {
   resetLayer();
-  setInputDim("1:2:5:5");
+  setInputDim("2:5:5");
   setProperty("pooling_size=2,2 | stride=1,1 | padding=0,0 | pooling=average");
   reinitialize();
   loadFile("tc_pooling2d_1.in", in);
@@ -1133,7 +1222,7 @@ TEST_F(nntrainer_Pooling2DLayer, backwarding_02_p) {
 
 TEST_F(nntrainer_Pooling2DLayer, backwarding_03_p) {
   resetLayer();
-  setInputDim("1:2:5:5");
+  setInputDim("2:5:5");
   setProperty(
     "pooling_size=2,2 | stride=1,1 | padding=0,0 | pooling=global_max");
   reinitialize();
@@ -1154,7 +1243,7 @@ TEST_F(nntrainer_Pooling2DLayer, backwarding_03_p) {
 }
 
 TEST_F(nntrainer_Pooling2DLayer, backwarding_04_p) {
-  setInputDim("1:2:5:5");
+  setInputDim("2:5:5");
   setProperty(
     "pooling_size=2,2 | stride=1,1 | padding=0,0 | pooling=global_average");
   reinitialize();
@@ -1176,7 +1265,10 @@ TEST_F(nntrainer_Pooling2DLayer, backwarding_04_p) {
 class nntrainer_FlattenLayer
   : public nntrainer_abstractLayer<nntrainer::FlattenLayer> {
 protected:
-  virtual void prepareLayer() { setInputDim("1:2:4:4"); }
+  virtual void prepareLayer() {
+    setInputDim("2:4:4");
+    layer.setBatch(1);
+  }
 };
 
 /**
@@ -1198,7 +1290,8 @@ TEST_F(nntrainer_FlattenLayer, forwarding_01_p) {
  * @brief Flatten Layer
  */
 TEST_F(nntrainer_FlattenLayer, forwarding_02_p) {
-  setInputDim("2:2:4:4");
+  setInputDim("2:4:4");
+  layer.setBatch(2);
   reinitialize(false);
 
   EXPECT_EQ(out.getDim(), nntrainer::TensorDim(2, 1, 1, 32));
@@ -1230,7 +1323,8 @@ TEST_F(nntrainer_FlattenLayer, backwarding_01_p) {
  * @brief Flatten Layer
  */
 TEST_F(nntrainer_FlattenLayer, backwarding_02_p) {
-  setInputDim("2:2:4:4");
+  setInputDim("2:4:4");
+  layer.setBatch(2);
   reinitialize(false);
 
   EXPECT_EQ(out.getDim(), nntrainer::TensorDim(2, 1, 1, 32));
index 27708f5..a02c6e1 100644 (file)
@@ -111,7 +111,7 @@ static IniSection batch_normal("bn", "Type = batch_normalization | "
 static IniSection flatten("flat", "Type = flatten");
 
 static IniSection input("inputlayer", "Type = input |"
-                                      "Input_Shape = 32:1:1:62720 |"
+                                      "Input_Shape = 1:1:62720 |"
                                       "bias_init_zero = true |"
                                       "Normalization = true |"
                                       "Activation = sigmoid");
@@ -156,7 +156,7 @@ INSTANTIATE_TEST_CASE_P(
     mkIniTc("basic_dataset_p", {nw_adam, dataset, input, out}, SUCCESS),
     mkIniTc("basic_dataset2_p", {nw_sgd, input, out, dataset}, SUCCESS),
     mkIniTc("basic_dataset3_p", {dataset, nw_sgd, input, out}, SUCCESS),
-    mkIniTc("basic_conv2d_p", {nw_adam, conv2d + "input_shape = 32:1:1:62720"}, SUCCESS),
+    mkIniTc("basic_conv2d_p", {nw_adam, conv2d + "input_shape = 1:1:62720"}, SUCCESS),
     mkIniTc("no_testSet_p", {nw_adam, dataset + "-TestData", input, out}, SUCCESS),
     mkIniTc("no_validSet_p", {nw_adam, dataset + "-ValidData", input, out}, SUCCESS),
     mkIniTc("no_bufferSize_p", {nw_adam, dataset + "-BufferSize", input, out}, SUCCESS),