Coverage Report

Created: 2024-08-18 16:21

/home/liu/actions-runner/_work/ccv/ccv/test/unit/nnc/dropout.tests.c
Line
Count
Source (jump to first uncovered line)
1
#include "case.h"
2
#include "ccv_case.h"
3
#include "ccv_nnc_case.h"
4
#include <ccv.h>
5
#include <nnc/ccv_nnc.h>
6
#include <nnc/ccv_nnc_easy.h>
7
8
TEST_SETUP()
9
{
10
  ccv_nnc_init();
11
}
12
13
TEST_CASE("dropout 40% of a 20x50 matrix")
14
1
{
15
1
  ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 20, 50), 0);
16
1
  ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 20, 50), 0);
17
1
  int i;
18
1.00k
  for (i = 0; i < 20 * 50; 
i++1.00k
)
19
1.00k
    a->data.f32[i] = (i + 1) * 0.01;
20
1
  ccv_nnc_tensor_param_t output_info[2];
21
1
  ccv_nnc_hint_tensor_auto(CMD_DROPOUT_FORWARD(0.4), &a->info, 1, ccv_nnc_no_hint, output_info, 2);
22
1
  ccv_nnc_tensor_t* const c = ccv_nnc_tensor_new(0, output_info[1], 0);
23
1
  ccv_nnc_cmd_exec(CMD_DROPOUT_FORWARD(0.4), ccv_nnc_no_hint, 0, TENSOR_LIST(a), TENSOR_LIST(b, c), 0);
24
1
  int zero_count = 0;
25
1.00k
  for (i = 0; i < 20 * 50; 
i++1.00k
)
26
1.00k
    if (b->data.f32[i] == 0)
27
409
      ++zero_count;
28
591
    else {
29
591
      REQUIRE_EQ_WITH_TOLERANCE(a->data.f32[i] / 0.6, b->data.f32[i], 1e-5, "should be scaled up by 1 / 0.6");
30
591
    }
31
1
  REQUIRE_EQ_WITH_TOLERANCE((float)zero_count / (20 * 50), 0.4, 5 * 1e-2, "should be within 2%% of error");
32
1
  ccv_nnc_tensor_free(a);
33
1
  ccv_nnc_tensor_free(b);
34
1
  ccv_nnc_tensor_free(c);
35
1
}
36
37
TEST_CASE("dropout gradient for 40% of a 20x30 matrix")
38
1
{
39
1
  ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 20, 50), 0);
40
1
  ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 20, 50), 0);
41
1
  int i;
42
1.00k
  for (i = 0; i < 20 * 50; 
i++1.00k
)
43
1.00k
    a->data.f32[i] = (i + 1) * 0.01;
44
1
  ccv_nnc_tensor_param_t output_info[2];
45
1
  ccv_nnc_hint_tensor_auto(CMD_DROPOUT_FORWARD(0.4), &a->info, 1, ccv_nnc_no_hint, output_info, 2);
46
1
  ccv_nnc_tensor_t* const c = ccv_nnc_tensor_new(0, output_info[1], 0);
47
1
  ccv_nnc_cmd_exec(CMD_DROPOUT_FORWARD(0.4), ccv_nnc_no_hint, 0, TENSOR_LIST(a), TENSOR_LIST(b, c), 0);
48
1
  ccv_nnc_tensor_t* const g = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 20, 50), 0);
49
1.00k
  for (i = 0; i < 20 * 50; 
i++1.00k
)
50
1.00k
    g->data.f32[i] = i + 1;
51
1
  ccv_nnc_tensor_t* const h = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 20, 50), 0);
52
1
  ccv_nnc_cmd_exec(CMD_DROPOUT_BACKWARD(0.4), ccv_nnc_no_hint, 0, TENSOR_LIST(g, 0, 0, 0, c), TENSOR_LIST(h), 0);
53
1
  int zero_count = 0;
54
1.00k
  for (i = 0; i < 20 * 50; 
i++1.00k
)
55
1.00k
    if (h->data.f32[i] == 0)
56
391
      ++zero_count;
57
1
  REQUIRE_EQ_WITH_TOLERANCE((float)zero_count / (20 * 50), 0.4, 5 * 1e-2, "should be within 2%% of error");
58
1
  ccv_nnc_tensor_t* const ht = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 20, 50), 0);
59
1
  ccv_nnc_tensor_zero(ht);
60
1.00k
  for (i = 0; i < 20 * 50; 
i++1.00k
)
61
1.00k
    if (b->data.f32[i] != 0)
62
609
      ht->data.f32[i] = (i + 1) / 0.6;
63
1
  REQUIRE_TENSOR_EQ(h, ht, "propagated gradient should simply match the dropout");
64
1
  ccv_nnc_tensor_free(a);
65
1
  ccv_nnc_tensor_free(b);
66
1
  ccv_nnc_tensor_free(c);
67
1
  ccv_nnc_tensor_free(g);
68
1
  ccv_nnc_tensor_free(h);
69
1
  ccv_nnc_tensor_free(ht);
70
1
}
71
72
TEST_CASE("dropout entire matrix with 20% chance")
73
1
{
74
1
  ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 20, 50), 0);
75
1
  ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 20, 50), 0);
76
1
  int i;
77
1.00k
  for (i = 0; i < 20 * 50; 
i++1.00k
)
78
1.00k
    a->data.f32[i] = (i + 1) * 0.01;
79
1
  ccv_nnc_tensor_param_t output_info[2];
80
1
  ccv_nnc_hint_tensor_auto(CMD_DROPOUT_FORWARD(0.4), &a->info, 1, ccv_nnc_no_hint, output_info, 2);
81
1
  ccv_nnc_tensor_t* const c = ccv_nnc_tensor_new(0, output_info[1], 0);
82
1
  ccv_nnc_cmd_exec(CMD_DROPOUT_FORWARD(0.2, 1), ccv_nnc_no_hint, 0, TENSOR_LIST(a), TENSOR_LIST(b, c), 0);
83
1
  ccv_nnc_tensor_t* const d = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 20, 50), 0);
84
1
  if (b->data.f32[0] == 0)
85
0
    for (i = 0; i < 20 * 50; i++)
86
0
      d->data.f32[i] = 0;
87
1
  else
88
1.00k
    
for (i = 0; 1
i < 20 * 50;
i++1.00k
)
89
1.00k
      d->data.f32[i] = a->data.f32[i] / 0.8;
90
1
  REQUIRE_TENSOR_EQ(b, d, "dropout chance should be equal");
91
1
  ccv_nnc_tensor_free(a);
92
1
  ccv_nnc_tensor_free(b);
93
1
  ccv_nnc_tensor_free(c);
94
1
  ccv_nnc_tensor_free(d);
95
1
}
96
97
TEST_CASE("dropout gradient entire matrix with 20% chance")
98
1
{
99
1
  ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 20, 50), 0);
100
1
  ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 20, 50), 0);
101
1
  int i;
102
1.00k
  for (i = 0; i < 20 * 50; 
i++1.00k
)
103
1.00k
    a->data.f32[i] = (i + 1) * 0.01;
104
1
  ccv_nnc_tensor_param_t output_info[2];
105
1
  ccv_nnc_hint_tensor_auto(CMD_DROPOUT_FORWARD(0.4), &a->info, 1, ccv_nnc_no_hint, output_info, 2);
106
1
  ccv_nnc_tensor_t* const c = ccv_nnc_tensor_new(0, output_info[1], 0);
107
1
  ccv_nnc_cmd_exec(CMD_DROPOUT_FORWARD(0.2, 1), ccv_nnc_no_hint, 0, TENSOR_LIST(a), TENSOR_LIST(b, c), 0);
108
1
  ccv_nnc_tensor_t* const g = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 20, 50), 0);
109
1.00k
  for (i = 0; i < 20 * 50; 
i++1.00k
)
110
1.00k
    g->data.f32[i] = i + 1;
111
1
  ccv_nnc_tensor_t* const h = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 20, 50), 0);
112
1
  ccv_nnc_cmd_exec(CMD_DROPOUT_BACKWARD(0.2, 1), ccv_nnc_no_hint, 0, TENSOR_LIST(g, 0, 0, 0, c), TENSOR_LIST(h), 0);
113
1
  ccv_nnc_tensor_t* const d = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 20, 50), 0);
114
1
  if (b->data.f32[0] == 0)
115
0
    for (i = 0; i < 20 * 50; i++)
116
0
      d->data.f32[i] = 0;
117
1
  else
118
1.00k
    
for (i = 0; 1
i < 20 * 50;
i++1.00k
)
119
1.00k
      d->data.f32[i] = g->data.f32[i] / 0.8;
120
1
  REQUIRE_TENSOR_EQ(h, d, "dropout chance should be equal");
121
1
  ccv_nnc_tensor_free(a);
122
1
  ccv_nnc_tensor_free(b);
123
1
  ccv_nnc_tensor_free(c);
124
1
  ccv_nnc_tensor_free(g);
125
1
  ccv_nnc_tensor_free(h);
126
1
  ccv_nnc_tensor_free(d);
127
1
}
128
129
#include "case_main.h"