conv_2d_test.cc 6.7 KB
Newer Older
L
Liangliang He 已提交
1 2 3 4 5
//
// Copyright (c) 2017 XiaoMi All rights reserved.
//

#include "mace/ops/conv_2d.h"
L
Liangliang He 已提交
6
#include "mace/core/operator.h"
7
#include "mace/ops/ops_test_util.h"
L
Liangliang He 已提交
8 9 10 11 12 13 14

using namespace mace;

class Conv2dOpTest : public OpsTestBase {};

TEST_F(Conv2dOpTest, Simple_VALID) {
  // Construct graph
15
  auto& net = test_net();
L
Liangliang He 已提交
16
  OpDefBuilder("Conv2d", "Conv2dTest")
L
Liangliang He 已提交
17 18 19 20 21
      .Input("Input")
      .Input("Filter")
      .Input("Bias")
      .Output("Output")
      .Finalize(net.operator_def());
L
Liangliang He 已提交
22 23

  // Add args
24 25 26
  net.AddIntsArg("strides", {1, 1});
  net.AddIntArg("padding", Padding::VALID);
  net.AddIntsArg("dilations", {1, 1});
L
Liangliang He 已提交
27 28

  // Add input data
L
Liangliang He 已提交
29 30 31 32 33 34 35
  net.AddInputFromArray<float>(
      "Input", {1, 2, 3, 3},
      {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1});
  net.AddInputFromArray<float>(
      "Filter", {1, 2, 3, 3},
      {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
       1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f});
36
  net.AddInputFromArray<float>("Bias", {1}, {0.1f});
L
Liangliang He 已提交
37 38

  // Run
39
  net.RunOp();
L
Liangliang He 已提交
40 41

  // Check
李寅 已提交
42
  auto expected = CreateTensor<float>({1, 1, 1, 1}, {18.1f});
L
Liangliang He 已提交
43

李寅 已提交
44
  ExpectTensorNear<float>(*expected, *net.GetOutput("Output"), 0.001);
L
Liangliang He 已提交
45 46 47 48
}

TEST_F(Conv2dOpTest, Simple_SAME) {
  // Construct graph
49
  auto& net = test_net();
L
Liangliang He 已提交
50
  OpDefBuilder("Conv2d", "Conv2dTest")
L
Liangliang He 已提交
51 52 53 54 55
      .Input("Input")
      .Input("Filter")
      .Input("Bias")
      .Output("Output")
      .Finalize(net.operator_def());
L
Liangliang He 已提交
56 57

  // Add args
58 59 60
  net.AddIntsArg("strides", {1, 1});
  net.AddIntArg("padding", Padding::SAME);
  net.AddIntsArg("dilations", {1, 1});
L
Liangliang He 已提交
61 62

  // Add input data
L
Liangliang He 已提交
63 64 65 66 67 68 69
  net.AddInputFromArray<float>(
      "Input", {1, 2, 3, 3},
      {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1});
  net.AddInputFromArray<float>(
      "Filter", {1, 2, 3, 3},
      {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
       1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f});
70
  net.AddInputFromArray<float>("Bias", {1}, {0.1f});
L
Liangliang He 已提交
71 72

  // Run
73
  net.RunOp();
L
Liangliang He 已提交
74 75

  // Check
L
Liangliang He 已提交
76 77 78
  auto expected = CreateTensor<float>(
      {1, 1, 3, 3},
      {8.1f, 12.1f, 8.1f, 12.1f, 18.1f, 12.1f, 8.1f, 12.1f, 8.1f});
L
Liangliang He 已提交
79

李寅 已提交
80
  ExpectTensorNear<float>(*expected, *net.GetOutput("Output"), 0.001);
L
Liangliang He 已提交
81 82 83 84
}

TEST_F(Conv2dOpTest, Combined) {
  // Construct graph
85
  auto& net = test_net();
L
Liangliang He 已提交
86
  OpDefBuilder("Conv2d", "Conv2dTest")
L
Liangliang He 已提交
87 88 89 90 91
      .Input("Input")
      .Input("Filter")
      .Input("Bias")
      .Output("Output")
      .Finalize(net.operator_def());
L
Liangliang He 已提交
92 93

  // Add args
94 95 96
  net.AddIntsArg("strides", {2, 2});
  net.AddIntArg("padding", Padding::SAME);
  net.AddIntsArg("dilations", {1, 1});
L
Liangliang He 已提交
97 98

  // Add input data
L
Liangliang He 已提交
99 100 101 102 103 104 105 106 107
  net.AddInputFromArray<float>(
      "Input", {1, 2, 5, 5}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1});
  net.AddInputFromArray<float>(
      "Filter", {2, 2, 3, 3},
      {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
       1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
       0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f});
108
  net.AddInputFromArray<float>("Bias", {2}, {0.1f, 0.2f});
L
Liangliang He 已提交
109 110

  // Run
111
  net.RunOp();
L
Liangliang He 已提交
112 113

  // Check
L
Liangliang He 已提交
114 115 116
  auto expected = CreateTensor<float>(
      {1, 2, 3, 3}, {8.1f, 12.1f, 8.1f, 12.1f, 18.1f, 12.1f, 8.1f, 12.1f, 8.1f,
                     4.2f, 6.2f, 4.2f, 6.2f, 9.2f, 6.2f, 4.2f, 6.2f, 4.2f});
L
Liangliang He 已提交
117

李寅 已提交
118
  ExpectTensorNear<float>(*expected, *net.GetOutput("Output"), 0.001);
L
Liangliang He 已提交
119 120
}

L
Liangliang He 已提交
121 122
TEST_F(Conv2dOpTest, Conv1x1) {
  // Construct graph
123
  auto& net = test_net();
L
Liangliang He 已提交
124
  OpDefBuilder("Conv2d", "Conv2dTest")
L
Liangliang He 已提交
125 126 127 128 129
      .Input("Input")
      .Input("Filter")
      .Input("Bias")
      .Output("Output")
      .Finalize(net.operator_def());
L
Liangliang He 已提交
130 131

  // Add args
132 133 134
  net.AddIntsArg("strides", {1, 1});
  net.AddIntArg("padding", Padding::VALID);
  net.AddIntsArg("dilations", {1, 1});
L
Liangliang He 已提交
135 136

  // Add input data
L
Liangliang He 已提交
137 138 139 140 141 142 143 144 145 146 147 148
  net.AddInputFromArray<float>(
      "Input", {1, 5, 3, 10},
      {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1});
  net.AddInputFromArray<float>(
      "Filter", {2, 5, 1, 1},
      {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f});
149
  net.AddInputFromArray<float>("Bias", {2}, {0.1f, 0.2f});
L
Liangliang He 已提交
150 151

  // Run
152
  net.RunOp();
L
Liangliang He 已提交
153 154

  // Check
L
Liangliang He 已提交
155 156 157 158 159 160 161 162
  auto expected = CreateTensor<float>(
      {1, 2, 3, 10},
      {5.1f,  5.1f,  5.1f,  5.1f,  5.1f,  5.1f,  5.1f,  5.1f,  5.1f,  5.1f,
       5.1f,  5.1f,  5.1f,  5.1f,  5.1f,  5.1f,  5.1f,  5.1f,  5.1f,  5.1f,
       5.1f,  5.1f,  5.1f,  5.1f,  5.1f,  5.1f,  5.1f,  5.1f,  5.1f,  5.1f,
       10.2f, 10.2f, 10.2f, 10.2f, 10.2f, 10.2f, 10.2f, 10.2f, 10.2f, 10.2f,
       10.2f, 10.2f, 10.2f, 10.2f, 10.2f, 10.2f, 10.2f, 10.2f, 10.2f, 10.2f,
       10.2f, 10.2f, 10.2f, 10.2f, 10.2f, 10.2f, 10.2f, 10.2f, 10.2f, 10.2f});
L
Liangliang He 已提交
163

李寅 已提交
164
  ExpectTensorNear<float>(*expected, *net.GetOutput("Output"), 0.001);
L
Liangliang He 已提交
165 166
}

L
Liangliang He 已提交
167
// TODO we need more tests
168
TEST_F(Conv2dOpTest, ConvNxNS12) {
李寅 已提交
169
  testing::internal::LogToStderr();
L
Liangliang He 已提交
170
  auto func = [&](int kernel_h, int kernel_w, int stride_h, int stride_w,
171
                  Padding type) {
172 173 174
    srand(time(NULL));

    // generate random input
175
    index_t batch = 1 + rand() % 10;
176 177 178 179
    index_t input_channels = 1 + rand() % 10;
    index_t height = 107;
    index_t width = 113;
    index_t output_channels = 1 + rand() % 10;
180
    // Construct graph
L
Liangliang He 已提交
181
    auto& net = test_net();
182
    OpDefBuilder("Conv2d", "Conv2dTest")
李寅 已提交
183 184 185 186 187
        .Input("Input")
        .Input("Filter")
        .Input("Bias")
        .Output("Output")
        .Finalize(net.operator_def());
188 189

    // Add args
190
    net.AddIntsArg("strides", {stride_h, stride_w});
191 192 193 194 195
    net.AddIntArg("padding", type);
    net.AddIntsArg("dilations", {1, 1});

    // Add input data
    net.AddRandomInput<float>("Input", {batch, input_channels, height, width});
L
Liangliang He 已提交
196 197
    net.AddRandomInput<float>(
        "Filter", {output_channels, input_channels, kernel_h, kernel_w});
198 199 200 201 202
    net.AddRandomInput<float>("Bias", {output_channels});
    // run cpu
    net.RunOp();

    // Check
L
Liangliang He 已提交
203
    Tensor expected;
李寅 已提交
204
    expected.Copy(*net.GetOutput("Output"));
205 206 207

    // Run NEON
    net.RunOp(DeviceType::NEON);
李寅 已提交
208
    ExpectTensorNear<float>(expected, *net.GetOutput("Output"), 0.001);
209 210
  };

李寅 已提交
211
  for (int kernel_size : {1, 3, 5}) {
L
liuqi 已提交
212
    for (int stride : {1, 2}) {
213 214 215 216
      func(kernel_size, kernel_size, stride, stride, VALID);
      func(kernel_size, kernel_size, stride, stride, SAME);
    }
  }
217
}