[Resnet] Sync resnet app with validated model
authorJihoon Lee <jhoon.it.lee@samsung.com>
Mon, 12 Jul 2021 02:07:26 +0000 (11:07 +0900)
committerJijoong Moon <jijoong.moon@samsung.com>
Tue, 13 Jul 2021 01:31:43 +0000 (10:31 +0900)
This patch syncs resnet application with validated model.
Changes include:

1. s/setIteration/updateIteration
2. normalize input
3. fixed batchsize of 128 -> args received from the sysargs
4. output layer to copy
5. silent failed to read epoch idx and iteration

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

Signed-off-by: Jihoon Lee <jhoon.it.lee@samsung.com>
Applications/Resnet/jni/cifar_dataloader.cpp
Applications/Resnet/jni/main.cpp
nntrainer/layers/output_layer.cpp
nntrainer/models/neuralnet.cpp

index 5c0d32a402140de7d29c47311ebb4e80a85187f6..44aa502a28f84034ac0767353bddb9740be5eba8 100644 (file)
@@ -46,7 +46,8 @@ void fillLabel(float *data, unsigned int length, unsigned int label) {
  * @param iteration_per_epoch iteration per epoch
  * @return bool true if iteration has finished
  */
-bool setIteration(unsigned int &iteration, unsigned int iteration_per_epoch) {
+bool updateIteration(unsigned int &iteration,
+                     unsigned int iteration_per_epoch) {
   if (iteration++ == iteration_per_epoch) {
     iteration = 0;
     return true;
@@ -90,7 +91,7 @@ void RandomDataLoader::next(float **input, float **label, bool *last) {
     }
   };
 
-  if (setIteration(iteration, iteration_for_one_epoch)) {
+  if (updateIteration(iteration, iteration_for_one_epoch)) {
     *last = true;
     return;
   }
@@ -150,17 +151,19 @@ void Cifar100DataLoader::next(float **input, float **label, bool *last) {
     for (unsigned int i = 0; i < Cifar100DataLoader::ImageSize; ++i) {
       uint8_t data;
       file.read(reinterpret_cast<char *>(&data), sizeof(uint8_t));
-      *input_ = data;
+      *input_ = data / 255.f;
       input_++;
     }
   };
 
   unsigned int idx_pos = current_iteration * batch;
-  if (setIteration(current_iteration, iteration_per_epoch)) {
+  if (updateIteration(current_iteration, iteration_per_epoch)) {
     *last = true;
     std::shuffle(idxes.begin(), idxes.end(), rng);
     return;
   }
+
+  *last = false;
   unsigned int idx_pos_end =
     current_iteration * batch; // iteration increased by 1
 
index f275aa73c34f8048ebf459def1ccac0a22634599..773576f4aed9eaecb2847346a56e96ab85546987 100644 (file)
@@ -122,7 +122,7 @@ std::vector<LayerHandle> resnetBlock(const std::string &block_name,
                 {withKey("name", block_name), withKey("activation", "relu")});
 
   if (downsample) {
-    return {a1, a2, a3, b1, c1, c2};
+    return {b1, a1, a2, a3, c1, c2};
   } else {
     return {a1, a2, a3, c1, c2};
   }
@@ -162,8 +162,8 @@ std::vector<LayerHandle> createResnet18Graph() {
   blocks.push_back(resnetBlock("conv2_1", "conv2_0", 128, 3, false));
   blocks.push_back(resnetBlock("conv3_0", "conv2_1", 256, 3, true));
   blocks.push_back(resnetBlock("conv3_1", "conv3_0", 256, 3, false));
-  blocks.push_back(resnetBlock("conv4_0", "conv3_1", 256, 3, true));
-  blocks.push_back(resnetBlock("conv4_1", "conv4_0", 256, 3, false));
+  blocks.push_back(resnetBlock("conv4_0", "conv3_1", 512, 3, true));
+  blocks.push_back(resnetBlock("conv4_1", "conv4_0", 512, 3, false));
 
   for (auto &block : blocks) {
     layers.insert(layers.end(), block.begin(), block.end());
@@ -213,10 +213,11 @@ int validData_cb(float **input, float **label, bool *last, void *user_data) {
 void createAndRun(unsigned int epochs, unsigned int batch_size,
                   UserDataType *user_data) {
   ModelHandle model = createResnet18();
-  model->setProperty(
-    {withKey("batch_size", batch_size), withKey("epochs", epochs)});
+  model->setProperty({withKey("batch_size", batch_size),
+                      withKey("epochs", epochs),
+                      withKey("save_path", "resnet_full.bin")});
 
-  auto optimizer = ml::train::createOptimizer("adam");
+  auto optimizer = ml::train::createOptimizer("adam", {"learning_rate=0.001"});
   model->setOptimizer(std::move(optimizer));
 
   int status = model->compile();
@@ -310,7 +311,7 @@ int main(int argc, char *argv[]) {
   }
 
   try {
-    createAndRun(epoch, 128, &user_data);
+    createAndRun(epoch, batch_size, &user_data);
   } catch (std::exception &e) {
     std::cerr << "uncaught error while running! details: " << e.what() << '\n';
     return 1;
index 4dae92b9c9a647b051a7f94e7d181f661cd0bebd..3dbff6d391e5363ffde9a6dbb52f3c3dc0b012a2 100644 (file)
@@ -42,7 +42,7 @@ int OutputLayer::initialize(Manager &manager) {
 void OutputLayer::forwarding(bool training) {
   Tensor &input_ = net_input[0]->getVariableRef();
   for (unsigned int idx = 0; idx < getNumOutputs(); ++idx) {
-    net_hidden[idx]->getVariableRef() = input_;
+    net_hidden[idx]->getVariableRef().fill(input_);
   }
 }
 
index edd71f3b86b11edcfc9741e90dbec53319f39ad3..661dfb7bfd088601d684936b397de15d118aed9f 100644 (file)
@@ -430,10 +430,17 @@ void NeuralNetwork::readModel() {
     (*iter)->read(model_file);
   }
 
-  checkedRead(model_file, (char *)&tmp.epoch_idx, sizeof(epoch_idx),
-              "[NeuralNetwork::readModel] failed to read epoch_idx");
-  checkedRead(model_file, (char *)&tmp.iter, sizeof(iter),
-              "[NeuralNetwork::readModel] failed to read iteration");
+  try {
+    /// this is assuming that the failure is allowed at the end of the file
+    /// read. so, after this line, additional read shouldn't be called
+    checkedRead(model_file, (char *)&tmp.epoch_idx, sizeof(epoch_idx),
+                "[NeuralNetwork::readModel] failed to read epoch_idx");
+    checkedRead(model_file, (char *)&tmp.iter, sizeof(iter),
+                "[NeuralNetwork::readModel] failed to read iteration");
+  } catch (...) {
+    model_file.close();
+    std::cerr << "failed to read epoch idx, proceeding with default index\n";
+  }
 
   model_file.close();
   ml_logi("read modelfile: %s", save_path.c_str());
@@ -610,6 +617,7 @@ int NeuralNetwork::train_run() {
     int count = 0;
 
     while (true) {
+
       if (data_buffer->getDataFromBuffer(nntrainer::BufferType::BUF_TRAIN,
                                          in.getData(), label.getData())) {
         try {
@@ -843,8 +851,9 @@ void NeuralNetwork::print(std::ostream &out, unsigned int flags,
   /** print layer properties */
   // TODO: get sorted layers if initialized
   auto layers = model_graph.getLayerNodes();
-  for (auto &layer : layers)
+  for (auto &layer : layers) {
     layer->getObject()->printPreset(out, layerPrintPreset);
+  }
 
   /// @todo Add status to check neuralnet has been run. #290
 }