[capi] add unittest for learning rate scheduler
authorhyeonseok lee <hs89.lee@samsung.com>
Thu, 13 Apr 2023 08:29:25 +0000 (17:29 +0900)
committerJijoong Moon <jijoong.moon@samsung.com>
Tue, 18 Apr 2023 04:49:44 +0000 (13:49 +0900)
 - Added learning rate scheduler related unittest

Signed-off-by: hyeonseok lee <hs89.lee@samsung.com>
test/tizen_capi/meson.build
test/tizen_capi/unittest_tizen_capi.cpp
test/tizen_capi/unittest_tizen_capi_lr_scheduler.cpp [new file with mode: 0644]
test/tizen_capi/unittest_tizen_capi_optimizer.cpp

index 707243a..9132efe 100644 (file)
@@ -3,7 +3,7 @@ unittest_tizen_deps = [
   nntrainer_test_deps,
 ]
 
-unittest_name_list = ['', '_layer', '_optimizer', '_dataset']
+unittest_name_list = ['', '_layer', '_optimizer', '_lr_scheduler', '_dataset']
 unittest_prefix = 'unittest_tizen_capi'
 
 foreach test_name : unittest_name_list
index 24c2aeb..9768e23 100644 (file)
@@ -168,6 +168,7 @@ TEST(nntrainer_capi_nnmodel, compile_03_p) {
   ml_train_layer_h layers[2];
   ml_train_layer_h get_layer;
   ml_train_optimizer_h optimizer;
+  ml_train_lr_scheduler_h lr_scheduler;
 
   status = ml_train_model_construct(&model);
   EXPECT_EQ(status, ML_ERROR_NONE);
@@ -208,9 +209,20 @@ TEST(nntrainer_capi_nnmodel, compile_03_p) {
   status = ml_train_optimizer_create(&optimizer, ML_TRAIN_OPTIMIZER_TYPE_ADAM);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
-  status = ml_train_optimizer_set_property(
-    optimizer, "learning_rate=0.0001", "decay_rate=0.96", "decay_steps=1000",
-    "beta1=0.002", "beta2=0.001", "epsilon=1e-7", NULL);
+  status = ml_train_optimizer_set_property(optimizer, "beta1=0.002",
+                                           "beta2=0.001", "epsilon=1e-7", NULL);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  status = ml_train_lr_scheduler_create(&lr_scheduler,
+                                        ML_TRAIN_LR_SCHEDULER_TYPE_EXPONENTIAL);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  status = ml_train_lr_scheduler_set_property(
+    lr_scheduler, "learning_rate=0.0001", "decay_rate=0.96", "decay_steps=1000",
+    NULL);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  status = ml_train_optimizer_set_lr_scheduler(optimizer, lr_scheduler);
   EXPECT_EQ(status, ML_ERROR_NONE);
 
   status = ml_train_model_set_optimizer(model, optimizer);
diff --git a/test/tizen_capi/unittest_tizen_capi_lr_scheduler.cpp b/test/tizen_capi/unittest_tizen_capi_lr_scheduler.cpp
new file mode 100644 (file)
index 0000000..4dfe75d
--- /dev/null
@@ -0,0 +1,376 @@
+/**
+ * Copyright (C) 2023 Samsung Electronics Co., Ltd. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file        unittest_tizen_capi_lr_scheduler.cpp
+ * @date        13 April 2023
+ * @brief       Unit test utility for learning rate scheduler.
+ * @see         https://github.com/nnstreamer/nntrainer
+ * @author      Hyeonseok Lee <hs89.lee@samsung.com>
+ * @bug         No known bugs
+ */
+#include <gtest/gtest.h>
+
+#include <nntrainer.h>
+#include <nntrainer_internal.h>
+#include <nntrainer_test_util.h>
+
+/**
+ * @brief Learning rate scheduler Create / Destruct Test (positive test)
+ */
+TEST(nntrainer_capi_lr_scheduler, create_destruct_01_p) {
+  ml_train_lr_scheduler_h handle;
+  int status;
+  status =
+    ml_train_lr_scheduler_create(&handle, ML_TRAIN_LR_SCHEDULER_TYPE_CONSTANT);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_destroy(handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Learning rate scheduler Create / Destruct Test (positive test)
+ */
+TEST(nntrainer_capi_lr_scheduler, create_destruct_02_p) {
+  ml_train_lr_scheduler_h handle;
+  int status;
+  status = ml_train_lr_scheduler_create(&handle,
+                                        ML_TRAIN_LR_SCHEDULER_TYPE_EXPONENTIAL);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_destroy(handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Learning rate scheduler Create / Destruct Test (positive test)
+ */
+TEST(nntrainer_capi_lr_scheduler, create_destruct_03_p) {
+  ml_train_lr_scheduler_h handle;
+  int status;
+  status =
+    ml_train_lr_scheduler_create(&handle, ML_TRAIN_LR_SCHEDULER_TYPE_STEP);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_destroy(handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Learning rate scheduler Create / Destruct Test (negative test)
+ */
+TEST(nntrainer_capi_lr_scheduler, create_destruct_04_n) {
+  ml_train_lr_scheduler_h handle = NULL;
+  int status;
+  status = ml_train_lr_scheduler_destroy(&handle);
+  EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
+}
+
+/**
+ * @brief Learning rate scheduler Create / Destruct Test (negative test)
+ */
+TEST(nntrainer_capi_lr_scheduler, create_destruct_05_n) {
+  ml_train_lr_scheduler_h handle;
+  int status;
+  status =
+    ml_train_lr_scheduler_create(&handle, ML_TRAIN_LR_SCHEDULER_TYPE_UNKNOWN);
+  EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
+}
+
+/**
+ * @brief Learning rate scheduler Create / Destruct Test (negative test)
+ */
+TEST(nntrainer_capi_lr_scheduler, create_destruct_06_n) {
+  ml_train_optimizer_h opt_handle;
+  ml_train_lr_scheduler_h lr_sched_handle;
+  int status;
+  status = ml_train_optimizer_create(&opt_handle, ML_TRAIN_OPTIMIZER_TYPE_SGD);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  status = ml_train_lr_scheduler_create(&lr_sched_handle,
+                                        ML_TRAIN_LR_SCHEDULER_TYPE_CONSTANT);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  status = ml_train_optimizer_set_lr_scheduler(opt_handle, lr_sched_handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  status = ml_train_lr_scheduler_destroy(lr_sched_handle);
+  EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
+
+  status = ml_train_optimizer_destroy(opt_handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Learning rate scheduler Create / Destruct Test (negative test)
+ */
+TEST(nntrainer_capi_lr_scheduler, create_destruct_07_n) {
+  int status = ML_ERROR_NONE;
+
+  ml_train_model_h model;
+  ml_train_optimizer_h optimizer;
+  ml_train_lr_scheduler_h lr_scheduler;
+
+  status = ml_train_model_construct(&model);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  status = ml_train_optimizer_create(&optimizer, ML_TRAIN_OPTIMIZER_TYPE_ADAM);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  status = ml_train_optimizer_set_property(optimizer, "beta1=0.002",
+                                           "beta2=0.001", "epsilon=1e-7", NULL);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  status = ml_train_lr_scheduler_create(&lr_scheduler,
+                                        ML_TRAIN_LR_SCHEDULER_TYPE_EXPONENTIAL);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  status = ml_train_lr_scheduler_set_property(
+    lr_scheduler, "learning_rate=0.0001", "decay_rate=0.96", "decay_steps=1000",
+    NULL);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  status = ml_train_model_set_optimizer(model, optimizer);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  status = ml_train_optimizer_set_lr_scheduler(optimizer, lr_scheduler);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  status = ml_train_lr_scheduler_destroy(lr_scheduler);
+  EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
+
+  status = ml_train_model_destroy(model);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Learning rate scheduler set Property Test (positive test)
+ */
+TEST(nntrainer_capi_lr_scheduler, setProperty_01_p) {
+  ml_train_lr_scheduler_h handle;
+  int status;
+  status =
+    ml_train_lr_scheduler_create(&handle, ML_TRAIN_LR_SCHEDULER_TYPE_CONSTANT);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status =
+    ml_train_lr_scheduler_set_property(handle, "learning_rate=0.001", NULL);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_destroy(handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Learning rate scheduler set Property Test (positive test)
+ */
+TEST(nntrainer_capi_lr_scheduler, setProperty_02_p) {
+  ml_train_lr_scheduler_h handle;
+  int status;
+  status = ml_train_lr_scheduler_create(&handle,
+                                        ML_TRAIN_LR_SCHEDULER_TYPE_EXPONENTIAL);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_set_property(
+    handle, "learning_rate=0.001", "decay_rate=0.9", "decay_steps=2", NULL);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_destroy(handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Learning rate scheduler set Property Test (positive test)
+ */
+TEST(nntrainer_capi_lr_scheduler, setProperty_03_p) {
+  ml_train_lr_scheduler_h handle;
+  int status;
+  status =
+    ml_train_lr_scheduler_create(&handle, ML_TRAIN_LR_SCHEDULER_TYPE_STEP);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_set_property(
+    handle, "learning_rate=0.01, 0.001", "iteration=100", NULL);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_destroy(handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Learning rate scheduler set Property Test (negative test)
+ */
+TEST(nntrainer_capi_lr_scheduler, setProperty_04_n) {
+  ml_train_lr_scheduler_h handle;
+  int status;
+  status =
+    ml_train_lr_scheduler_create(&handle, ML_TRAIN_LR_SCHEDULER_TYPE_CONSTANT);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_set_property(handle, "learning_rate=0.001",
+                                              "iteration=10", NULL);
+  EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
+  status = ml_train_lr_scheduler_destroy(handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Learning rate scheduler set Property Test (negative test)
+ */
+TEST(nntrainer_capi_lr_scheduler, setProperty_05_n) {
+  ml_train_lr_scheduler_h handle;
+  int status;
+  status =
+    ml_train_lr_scheduler_create(&handle, ML_TRAIN_LR_SCHEDULER_TYPE_CONSTANT);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_set_property(handle, "learning_rate=0.001",
+                                              "decay_rate=0.9", NULL);
+  EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
+  status = ml_train_lr_scheduler_destroy(handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Learning rate scheduler set Property Test (negative test)
+ */
+TEST(nntrainer_capi_lr_scheduler, setProperty_06_n) {
+  ml_train_lr_scheduler_h handle;
+  int status;
+  status =
+    ml_train_lr_scheduler_create(&handle, ML_TRAIN_LR_SCHEDULER_TYPE_CONSTANT);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_set_property(handle, "learning_rate=0.001",
+                                              "decay_steps=2", NULL);
+  EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
+  status = ml_train_lr_scheduler_destroy(handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Learning rate scheduler set Property Test (negative test)
+ */
+TEST(nntrainer_capi_lr_scheduler, setProperty_07_n) {
+  ml_train_lr_scheduler_h handle;
+  int status;
+  status = ml_train_lr_scheduler_create(&handle,
+                                        ML_TRAIN_LR_SCHEDULER_TYPE_EXPONENTIAL);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_set_property(handle, "learning_rate=0.001",
+                                              "iteration=100", NULL);
+  EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
+  status = ml_train_lr_scheduler_destroy(handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Learning rate scheduler set Property Test (negative test)
+ */
+TEST(nntrainer_capi_lr_scheduler, setProperty_08_n) {
+  ml_train_lr_scheduler_h handle;
+  int status;
+  status =
+    ml_train_lr_scheduler_create(&handle, ML_TRAIN_LR_SCHEDULER_TYPE_STEP);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_set_property(handle, "learning_rate=0.001",
+                                              "decay_rate=0.9", NULL);
+  EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
+  status = ml_train_lr_scheduler_destroy(handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Learning rate scheduler set Property Test (negative test)
+ */
+TEST(nntrainer_capi_lr_scheduler, setProperty_09_n) {
+  ml_train_lr_scheduler_h handle;
+  int status;
+  status =
+    ml_train_lr_scheduler_create(&handle, ML_TRAIN_LR_SCHEDULER_TYPE_STEP);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_set_property(handle, "learning_rate=0.001",
+                                              "decay_steps=2", NULL);
+  EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
+  status = ml_train_lr_scheduler_destroy(handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Learning rate scheduler set Property Test (positive test)
+ */
+TEST(nntrainer_capi_lr_scheduler, setProperty_with_single_param_01_p) {
+  ml_train_lr_scheduler_h handle;
+  int status;
+  status = ml_train_lr_scheduler_create(&handle,
+                                        ML_TRAIN_LR_SCHEDULER_TYPE_EXPONENTIAL);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_set_property_with_single_param(
+    handle, "learning_rate=0.001 | decay_rate=0.9 | decay_steps=2");
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_destroy(handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Learning rate scheduler set Property Test (negative test)
+ */
+TEST(nntrainer_capi_lr_scheduler, setProperty_with_single_param_02_n) {
+  ml_train_lr_scheduler_h handle;
+  int status;
+  status = ml_train_lr_scheduler_create(&handle,
+                                        ML_TRAIN_LR_SCHEDULER_TYPE_EXPONENTIAL);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_set_property_with_single_param(
+    handle, "learning_rate=0.001, decay_rate=0.9, decay_steps=2");
+  EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
+  status = ml_train_lr_scheduler_destroy(handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Learning rate scheduler set Property Test (negative test)
+ */
+TEST(nntrainer_capi_lr_scheduler, setProperty_with_single_param_03_n) {
+  ml_train_lr_scheduler_h handle;
+  int status;
+  status = ml_train_lr_scheduler_create(&handle,
+                                        ML_TRAIN_LR_SCHEDULER_TYPE_EXPONENTIAL);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+  status = ml_train_lr_scheduler_set_property_with_single_param(
+    handle, "learning_rate=0.001 ! decay_rate=0.9 ! decay_steps=2");
+  EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
+  status = ml_train_lr_scheduler_destroy(handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
+ * @brief Main gtest
+ */
+int main(int argc, char **argv) {
+  int result = -1;
+
+  try {
+    testing::InitGoogleTest(&argc, argv);
+  } catch (...) {
+    std::cerr << "Error duing IniGoogleTest" << std::endl;
+    return 0;
+  }
+
+  /** ignore tizen feature check while running the testcases */
+  set_feature_state(ML_FEATURE, SUPPORTED);
+  set_feature_state(ML_FEATURE_INFERENCE, SUPPORTED);
+  set_feature_state(ML_FEATURE_TRAINING, SUPPORTED);
+
+  try {
+    result = RUN_ALL_TESTS();
+  } catch (...) {
+    std::cerr << "Error duing RUN_ALL_TSETS()" << std::endl;
+  }
+
+  /** reset tizen feature check state */
+  set_feature_state(ML_FEATURE, NOT_CHECKED_YET);
+  set_feature_state(ML_FEATURE_INFERENCE, NOT_CHECKED_YET);
+  set_feature_state(ML_FEATURE_TRAINING, NOT_CHECKED_YET);
+
+  return result;
+}
index f52da48..afa77f9 100644 (file)
@@ -186,6 +186,28 @@ TEST(nntrainer_capi_nnopt, setProperty_with_single_param_03_n) {
 }
 
 /**
+ * @brief Set learning rate scheduler to Neural Network Optimizer Test (positive
+ * test)
+ */
+TEST(nntrainer_capi_nnopt, set_lr_scheduler_01_p) {
+  ml_train_optimizer_h opt_handle;
+  ml_train_lr_scheduler_h lr_sched_handle;
+  int status;
+  status = ml_train_optimizer_create(&opt_handle, ML_TRAIN_OPTIMIZER_TYPE_SGD);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  status = ml_train_lr_scheduler_create(&lr_sched_handle,
+                                        ML_TRAIN_LR_SCHEDULER_TYPE_CONSTANT);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  status = ml_train_optimizer_set_lr_scheduler(opt_handle, lr_sched_handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+
+  status = ml_train_optimizer_destroy(opt_handle);
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
+/**
  * @brief Main gtest
  */
 int main(int argc, char **argv) {