@@ -66,7 +66,10 @@ void verify(const nntrainer::Tensor &actual, const nntrainer::Tensor &expected,
6666 std::cout << " \033 [1;33mdifference\033 [0m " << diff;
6767 std::cout << " number of data: " << diff.size () << std::endl;
6868 std::cout << " \033 [4;33mMAX DIFF: "
69- << *std::max_element (diff_data, diff_data + diff.size ())
69+ << *std::max_element (diff_data, diff_data + diff.size (),
70+ [](auto v1, auto v2) {
71+ return std::fabs (v1) < std::fabs (v2);
72+ })
7073 << " \033 [0m\n " ;
7174 }
7275 std::stringstream ss;
@@ -199,12 +202,19 @@ class NodeWatcher {
199202 *
200203 * @return LayerType
201204 */
202- std::string getNodeType () { return node->getType (); }
205+ std::string getType () { return node->getType (); }
206+
207+ /* *
208+ * @brief get Node type
209+ *
210+ * @return LayerType
211+ */
212+ std::string getName () { return node->getName (); }
203213
204214 /* *
205215 * @brief is loss type
206216 *
207- * @return true if loss type node, else false\
217+ * @return true if loss type node, else false
208218 */
209219 bool isLossType () { return node->requireLabel (); }
210220
@@ -275,28 +285,28 @@ void NodeWatcher::verifyGrad(const std::string &error_msg) {
275285
276286void NodeWatcher::forward (int iteration, bool verify_forward) {
277287 std::stringstream ss;
278- ss << " forward failed at " << node->getName () << " at iteration "
279- << iteration;
288+ ss << " forward failed at " << node->getName () << " , " << node-> getType ()
289+ << " at iteration " << iteration;
280290 std::string err_msg = ss.str ();
281291
282292 std::vector<nntrainer::Tensor> out;
283293 for (unsigned int idx = 0 ; idx < node->getNumOutputs (); idx++) {
284294 out.push_back (node->getOutput (idx));
285295 }
286296
287- if (verify_forward && getNodeType () != nntrainer::MultiOutLayer::type)
297+ if (verify_forward && getType () != nntrainer::MultiOutLayer::type)
288298 verify (out, expected_output, err_msg + " at output" );
289299}
290300
291301void NodeWatcher::backward (int iteration, bool verify_deriv, bool verify_grad) {
292302
293- if (getNodeType () == nntrainer::MultiOutLayer::type) {
303+ if (getType () == nntrainer::MultiOutLayer::type) {
294304 return ;
295305 }
296306
297307 std::stringstream ss;
298- ss << " backward failed at " << node->getName () << " at iteration "
299- << iteration;
308+ ss << " backward failed at " << node->getName () << " , " << node-> getType ()
309+ << " at iteration " << iteration;
300310 std::string err_msg = ss.str ();
301311
302312 std::vector<nntrainer::Tensor> out;
@@ -510,7 +520,7 @@ GraphWatcher::prepareData(std::ifstream &f,
510520
511521void GraphWatcher::readIteration (std::ifstream &f) {
512522 for (auto &i : nodes) {
513- if (i.getNodeType () == nntrainer::MultiOutLayer::type) {
523+ if (i.getType () == nntrainer::MultiOutLayer::type) {
514524 continue ;
515525 }
516526
@@ -534,8 +544,7 @@ typedef enum {
534544 COMPARE = 1 << 0 , /* *< Set this to compare the numbers */
535545 SAVE_AND_LOAD_INI = 1 << 1 , /* *< Set this to check if saving and constructing
536546 a new model works okay (without weights) */
537-
538- MINIMUM = 0 , /* *< Minimum */
547+ NO_THROW_RUN = 0 , /* *< no comparison, only validate execution without throw */
539548 ALL = COMPARE | SAVE_AND_LOAD_INI /* *< Set every option */
540549} ModelTestOption;
541550
@@ -557,7 +566,7 @@ class nntrainerModelTest
557566 nntrainerModelTest () :
558567 iteration (0 ),
559568 name (" " ),
560- options (ModelTestOption::MINIMUM ) {}
569+ options (ModelTestOption::NO_THROW_RUN ) {}
561570 virtual void SetUp () {
562571 auto param = GetParam ();
563572
@@ -580,7 +589,9 @@ class nntrainerModelTest
580589 int getIteration () { return iteration; };
581590 nntrainer::TensorDim getLabelDim () { return label_dim; }
582591
583- bool shouldCompare () { return options & ModelTestOption::COMPARE; }
592+ bool shouldCompare () {
593+ return (options & ModelTestOption::COMPARE) == ModelTestOption::COMPARE;
594+ }
584595 bool shouldSaveLoadIniTest () {
585596 return options & ModelTestOption::SAVE_AND_LOAD_INI;
586597 }
@@ -1411,6 +1422,93 @@ INI multiple_output_model(
14111422 }
14121423);
14131424
1425+ /* *
1426+ * @brief helper function to make model testcase
1427+ *
1428+ * @param nntrainer::TensorDim label dimension
1429+ * @param int Iteration
1430+ * @param options options
1431+ */
1432+ auto mkResNet18Tc (const unsigned int iteration,
1433+ ModelTestOption options = ModelTestOption::ALL) {
1434+ unsigned int batch_size = 2 ;
1435+ unsigned int num_class = 100 ;
1436+ unsigned int count = 0 ;
1437+ nntrainer::IniWrapper::Sections layers;
1438+
1439+ /* * get unique name for a layer */
1440+ auto getName = [&count]() -> std::string {
1441+ if (count == 21 )
1442+ std::cout << " mimatch" << std::endl;
1443+ return " layer" + std::to_string (++count);
1444+ };
1445+ auto getPreviousName = [&count]() -> std::string { return " layer" + std::to_string (count); };
1446+
1447+ /* * add blocks */
1448+ auto addBlock = [&count, &layers, &getName, &getPreviousName] (
1449+ unsigned int filters, unsigned int kernel_size, bool downsample) {
1450+ std::string filter_str = " filters=" + std::to_string (filters);
1451+ std::string kernel_str = " kernel_size=" + std::to_string (kernel_size) + " ," + std::to_string (kernel_size);
1452+ std::string kernel1_str = " kernel_size=1,1" ;
1453+ std::string stride1_str = " stride=1,1" ;
1454+ std::string stride2_str = " stride=2,2" ;
1455+ std::string padding_str = " padding=same" ;
1456+ std::string input_name = getPreviousName ();
1457+ std::string in_layer_str = " input_layers=" + input_name;
1458+ std::string stride_str = stride1_str;
1459+ if (downsample)
1460+ stride_str = stride2_str;
1461+
1462+ /* * skip connection */
1463+ std::string b1_name = input_name;
1464+ if (downsample) {
1465+ b1_name = getName ();
1466+ layers.push_back (I (b1_name) + conv_base + filter_str +
1467+ kernel1_str + stride_str + padding_str + in_layer_str);
1468+ }
1469+
1470+ /* * main connection */
1471+ layers.push_back (I (getName ()) + conv_base + filter_str +
1472+ kernel_str + stride_str + padding_str + in_layer_str);
1473+ layers.push_back (I (getName ()) + bn_base);
1474+ layers.push_back (I (getName ()) + relu_base);
1475+ std::string a1_name = getName ();
1476+ layers.push_back (I (a1_name) + conv_base + filter_str +
1477+ kernel_str + stride1_str + padding_str);
1478+
1479+ /* * add the two connections */
1480+ layers.push_back (I (getName ()) + " type=addition" + (" input_layers=" + b1_name + " ," + a1_name));
1481+ layers.push_back (I (getName ()) + bn_base);
1482+ layers.push_back (I (getName ()) + relu_base);
1483+ };
1484+
1485+ layers.push_back (nn_base + (" loss=cross | batch_size = " + std::to_string (batch_size)));
1486+ layers.push_back (sgd_base + " learning_rate = 0.1" );
1487+ /* * prefix for resnet model */
1488+ layers.push_back (I (getName ()) + input_base + " input_shape = 3:32:32" );
1489+ layers.push_back (I (getName ()) + conv_base + " kernel_size=3,3 | filters=64 | padding=same" );
1490+ layers.push_back (I (getName ()) + bn_base);
1491+ layers.push_back (I (getName ()) + relu_base);
1492+ /* * add all the blocks */
1493+ addBlock (64 , 3 , false );
1494+ addBlock (64 , 3 , false );
1495+ addBlock (128 , 3 , true );
1496+ addBlock (128 , 3 , false );
1497+ addBlock (256 , 3 , true );
1498+ addBlock (256 , 3 , false );
1499+ addBlock (512 , 3 , true );
1500+ addBlock (512 , 3 , false );
1501+ /* * add suffix for resnet model */
1502+ layers.push_back (I (getName ()) + pooling_base + " pooling = average | pool_size=4,4" );
1503+ layers.push_back (I (getName ()) + " type=flatten" );
1504+ layers.push_back (I (getName ()) + fc_base + " unit=100" );
1505+ layers.push_back (I (getName ()) + softmax_base);
1506+
1507+ return std::tuple<const nntrainer::IniWrapper, const nntrainer::TensorDim,
1508+ const unsigned int , ModelTestOption>(
1509+ nntrainer::IniWrapper (" ResNet18" , layers), nntrainer::TensorDim ({batch_size, 1 ,1 , num_class}), iteration, options);
1510+ }
1511+
14141512INSTANTIATE_TEST_CASE_P (
14151513 nntrainerModelAutoTests, nntrainerModelTest, ::testing::ValuesIn(
14161514 {
@@ -1435,7 +1533,7 @@ INSTANTIATE_TEST_CASE_P(
14351533 mkModelTc (conv_uneven_strides3, " 3:1:1:10" , 10 , ModelTestOption::ALL),
14361534 mkModelTc (conv_bn, " 3:1:1:10" , 10 , ModelTestOption::ALL),
14371535 mkModelTc (conv_same_padding_multi_stride, " 3:1:1:10" , 10 , ModelTestOption::ALL),
1438- mkModelTc (conv_no_loss, " 3:1:1:10" , 1 , ModelTestOption::MINIMUM ),
1536+ mkModelTc (conv_no_loss, " 3:1:1:10" , 1 , ModelTestOption::NO_THROW_RUN ),
14391537
14401538 /* *< single pooling layer test */
14411539 mkModelTc (pooling_max_same_padding, " 3:1:1:10" , 10 , ModelTestOption::ALL),
@@ -1453,17 +1551,17 @@ INSTANTIATE_TEST_CASE_P(
14531551
14541552 /* *< augmentation layer */
14551553 #if defined(ENABLE_DATA_AUGMENTATION_OPENCV)
1456- mkModelTc (preprocess_translate, " 3:1:1:10" , 10 , ModelTestOption::MINIMUM ),
1554+ mkModelTc (preprocess_translate, " 3:1:1:10" , 10 , ModelTestOption::NO_THROW_RUN ),
14571555 #endif
1458- mkModelTc (preprocess_flip_validate, " 3:1:1:10" , 10 , ModelTestOption::MINIMUM ),
1556+ mkModelTc (preprocess_flip_validate, " 3:1:1:10" , 10 , ModelTestOption::NO_THROW_RUN ),
14591557
14601558 /* *< Addition test */
14611559 mkModelTc (addition_resnet_like, " 3:1:1:10" , 10 , ModelTestOption::COMPARE), // Todo: Enable option to ALL
14621560
14631561 // / #1192 time distribution inference bug
1464- mkModelTc (fc_softmax_mse_distribute, " 3:1:5:3" , 1 , ModelTestOption::MINIMUM ),
1465- mkModelTc (fc_softmax_cross_distribute, " 3:1:5:3" , 1 , ModelTestOption::MINIMUM ),
1466- mkModelTc (fc_sigmoid_cross_distribute, " 3:1:5:3" , 1 , ModelTestOption::MINIMUM ),
1562+ mkModelTc (fc_softmax_mse_distribute, " 3:1:5:3" , 1 , ModelTestOption::NO_THROW_RUN ),
1563+ mkModelTc (fc_softmax_cross_distribute, " 3:1:5:3" , 1 , ModelTestOption::NO_THROW_RUN ),
1564+ mkModelTc (fc_sigmoid_cross_distribute, " 3:1:5:3" , 1 , ModelTestOption::NO_THROW_RUN ),
14671565 mkModelTc (lstm_basic, " 1:1:1:1" , 10 , ModelTestOption::ALL),
14681566 mkModelTc (lstm_return_sequence, " 1:1:2:1" , 10 , ModelTestOption::ALL),
14691567 mkModelTc (lstm_return_sequence_with_batch, " 2:1:2:1" , 10 , ModelTestOption::ALL),
@@ -1482,6 +1580,9 @@ INSTANTIATE_TEST_CASE_P(
14821580
14831581 /* *< multi output test */
14841582 mkModelTc (multiple_output_model, " 3:1:1:10" , 10 , ModelTestOption::COMPARE) // Todo: Enable option to ALL
1583+ /* * resnet model */
1584+ // this must match training (verify only forwarding output values) for 2 iterations with tolerance 1.2e-4
1585+ // mkResNet18Tc(2, ModelTestOption::COMPARE)
14851586 }
14861587), [](const testing::TestParamInfo<nntrainerModelTest::ParamType>& info){
14871588 return std::get<0 >(info.param ).getName ();
0 commit comments