blob: dad68324c1c60132466944b48185c0b3de07de97 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
2 * Copyright (c) 2017 ARM Limited.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#ifndef __ARM_COMPUTE_TEST_MODEL_OBJECTS_ALEXNET_H__
25#define __ARM_COMPUTE_TEST_MODEL_OBJECTS_ALEXNET_H__
26
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +010027#include "tests/AssetsLibrary.h"
Moritz Pflanzer94450f12017-06-30 12:48:43 +010028#include "tests/Globals.h"
Moritz Pflanzer94450f12017-06-30 12:48:43 +010029#include "tests/Utils.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010030
31#include <memory>
32
33using namespace arm_compute;
34using namespace arm_compute::test;
35
36namespace arm_compute
37{
38namespace test
39{
40namespace model_objects
41{
42/** AlexNet model object */
43template <typename ITensorType,
44 typename TensorType,
45 typename SubTensorType,
46 typename Accessor,
47 typename ActivationLayerFunction,
48 typename ConvolutionLayerFunction,
49 typename FullyConnectedLayerFunction,
50 typename NormalizationLayerFunction,
51 typename PoolingLayerFunction,
52 typename SoftmaxLayerFunction,
53 DataType dt = DataType::F32,
54 int fixed_point_position = 4>
55class AlexNet
56{
57public:
58 AlexNet()
59 : _batches(1), _reshaped_weights(false)
60 {
61 }
62
63 void init_weights(unsigned int batches, bool reshaped_weights = false)
64 {
65 _batches = batches;
66 _reshaped_weights = reshaped_weights;
67
68 // Initialize weights and biases
69 if(!_reshaped_weights)
70 {
71 for(auto &wi : w)
72 {
73 wi = std::unique_ptr<TensorType>(new TensorType());
74 }
75 for(auto &bi : b)
76 {
77 bi = std::unique_ptr<TensorType>(new TensorType());
78 }
79 w[0]->allocator()->init(TensorInfo(TensorShape(11U, 11U, 3U, 96U), 1, dt, fixed_point_position));
80 b[0]->allocator()->init(TensorInfo(TensorShape(96U), 1, dt, fixed_point_position));
81 w[1]->allocator()->init(TensorInfo(TensorShape(5U, 5U, 48U, 256U), 1, dt, fixed_point_position));
82 b[1]->allocator()->init(TensorInfo(TensorShape(256U), 1, dt, fixed_point_position));
83 w[2]->allocator()->init(TensorInfo(TensorShape(3U, 3U, 256U, 384U), 1, dt, fixed_point_position));
84 b[2]->allocator()->init(TensorInfo(TensorShape(384U), 1, dt, fixed_point_position));
85 w[3]->allocator()->init(TensorInfo(TensorShape(3U, 3U, 192U, 384U), 1, dt, fixed_point_position));
86 b[3]->allocator()->init(TensorInfo(TensorShape(384U), 1, dt, fixed_point_position));
87 w[4]->allocator()->init(TensorInfo(TensorShape(3U, 3U, 192U, 256U), 1, dt, fixed_point_position));
88 b[4]->allocator()->init(TensorInfo(TensorShape(256U), 1, dt, fixed_point_position));
89 w[5]->allocator()->init(TensorInfo(TensorShape(9216U, 4096U), 1, dt, fixed_point_position));
90 b[5]->allocator()->init(TensorInfo(TensorShape(4096U), 1, dt, fixed_point_position));
91 w[6]->allocator()->init(TensorInfo(TensorShape(4096U, 4096U), 1, dt, fixed_point_position));
92 b[6]->allocator()->init(TensorInfo(TensorShape(4096U), 1, dt, fixed_point_position));
93 w[7]->allocator()->init(TensorInfo(TensorShape(4096U, 1000U), 1, dt, fixed_point_position));
94 b[7]->allocator()->init(TensorInfo(TensorShape(1000U), 1, dt, fixed_point_position));
95
96 w21 = std::unique_ptr<SubTensorType>(new SubTensorType(w[1].get(), TensorShape(5U, 5U, 48U, 128U), Coordinates()));
97 w22 = std::unique_ptr<SubTensorType>(new SubTensorType(w[1].get(), TensorShape(5U, 5U, 48U, 128U), Coordinates(0, 0, 0, 128)));
98 b21 = std::unique_ptr<SubTensorType>(new SubTensorType(b[1].get(), TensorShape(128U), Coordinates()));
99 b22 = std::unique_ptr<SubTensorType>(new SubTensorType(b[1].get(), TensorShape(128U), Coordinates(128)));
100
101 w41 = std::unique_ptr<SubTensorType>(new SubTensorType(w[3].get(), TensorShape(3U, 3U, 192U, 192U), Coordinates()));
102 w42 = std::unique_ptr<SubTensorType>(new SubTensorType(w[3].get(), TensorShape(3U, 3U, 192U, 192U), Coordinates(0, 0, 0, 192)));
103 b41 = std::unique_ptr<SubTensorType>(new SubTensorType(b[3].get(), TensorShape(192U), Coordinates()));
104 b42 = std::unique_ptr<SubTensorType>(new SubTensorType(b[3].get(), TensorShape(192U), Coordinates(192)));
105
106 w51 = std::unique_ptr<SubTensorType>(new SubTensorType(w[4].get(), TensorShape(3U, 3U, 192U, 128U), Coordinates()));
107 w52 = std::unique_ptr<SubTensorType>(new SubTensorType(w[4].get(), TensorShape(3U, 3U, 192U, 128U), Coordinates(0, 0, 0, 128)));
108 b51 = std::unique_ptr<SubTensorType>(new SubTensorType(b[4].get(), TensorShape(128U), Coordinates()));
109 b52 = std::unique_ptr<SubTensorType>(new SubTensorType(b[4].get(), TensorShape(128U), Coordinates(128)));
110 }
111 else
112 {
113 const unsigned int dt_size = 16 / arm_compute::data_size_from_type(dt);
114
115 // Create tensor for the reshaped weights
116 w[0] = std::unique_ptr<TensorType>(new TensorType());
117 auto w21_tensor = std::unique_ptr<TensorType>(new TensorType());
118 auto w22_tensor = std::unique_ptr<TensorType>(new TensorType());
119 w[2] = std::unique_ptr<TensorType>(new TensorType());
120 auto w41_tensor = std::unique_ptr<TensorType>(new TensorType());
121 auto w42_tensor = std::unique_ptr<TensorType>(new TensorType());
122 auto w51_tensor = std::unique_ptr<TensorType>(new TensorType());
123 auto w52_tensor = std::unique_ptr<TensorType>(new TensorType());
124
125 w[0]->allocator()->init(TensorInfo(TensorShape(366U * dt_size, 96U / dt_size), 1, dt, fixed_point_position));
126 w21_tensor->allocator()->init(TensorInfo(TensorShape(1248U * dt_size, 128U / dt_size), 1, dt, fixed_point_position));
127 w22_tensor->allocator()->init(TensorInfo(TensorShape(1248U * dt_size, 128U / dt_size), 1, dt, fixed_point_position));
128 w[2]->allocator()->init(TensorInfo(TensorShape(2560U * dt_size, 384U / dt_size), 1, dt, fixed_point_position));
129 w41_tensor->allocator()->init(TensorInfo(TensorShape(1920U * dt_size, 192U / dt_size), 1, dt, fixed_point_position));
130 w42_tensor->allocator()->init(TensorInfo(TensorShape(1920U * dt_size, 192U / dt_size), 1, dt, fixed_point_position));
131 w51_tensor->allocator()->init(TensorInfo(TensorShape(1920U * dt_size, 128U / dt_size), 1, dt, fixed_point_position));
132 w52_tensor->allocator()->init(TensorInfo(TensorShape(1920U * dt_size, 128U / dt_size), 1, dt, fixed_point_position));
133
134 w21 = std::move(w21_tensor);
135 w22 = std::move(w22_tensor);
136 w41 = std::move(w41_tensor);
137 w42 = std::move(w42_tensor);
138 w51 = std::move(w51_tensor);
139 w52 = std::move(w52_tensor);
140
141 w[5] = std::unique_ptr<TensorType>(new TensorType());
142 w[6] = std::unique_ptr<TensorType>(new TensorType());
143 w[7] = std::unique_ptr<TensorType>(new TensorType());
144 b[5] = std::unique_ptr<TensorType>(new TensorType());
145 b[6] = std::unique_ptr<TensorType>(new TensorType());
146 b[7] = std::unique_ptr<TensorType>(new TensorType());
147
148 b[5]->allocator()->init(TensorInfo(TensorShape(4096U), 1, dt, fixed_point_position));
149 b[6]->allocator()->init(TensorInfo(TensorShape(4096U), 1, dt, fixed_point_position));
150 b[7]->allocator()->init(TensorInfo(TensorShape(1000U), 1, dt, fixed_point_position));
151
152 if(_batches > 1)
153 {
154 w[5]->allocator()->init(TensorInfo(TensorShape(9216U * dt_size, 4096U / dt_size), 1, dt, fixed_point_position));
155 w[6]->allocator()->init(TensorInfo(TensorShape(4096U * dt_size, 4096U / dt_size), 1, dt, fixed_point_position));
156 w[7]->allocator()->init(TensorInfo(TensorShape(4096U * dt_size, 1000U / dt_size), 1, dt, fixed_point_position));
157 }
158 else
159 {
160 w[5]->allocator()->init(TensorInfo(TensorShape(4096U, 9216U), 1, dt, fixed_point_position));
161 w[6]->allocator()->init(TensorInfo(TensorShape(4096U, 4096U), 1, dt, fixed_point_position));
162 w[7]->allocator()->init(TensorInfo(TensorShape(1000U, 4096U), 1, dt, fixed_point_position));
163 }
164 }
165 }
166
167 void build()
168 {
169 input.allocator()->init(TensorInfo(TensorShape(227U, 227U, 3U, _batches), 1, dt, fixed_point_position));
170 output.allocator()->init(TensorInfo(TensorShape(1000U, _batches), 1, dt, fixed_point_position));
171
172 // Initialize intermediate tensors
173 // Layer 1
174 conv1_out.allocator()->init(TensorInfo(TensorShape(55U, 55U, 96U, _batches), 1, dt, fixed_point_position));
175 act1_out.allocator()->init(TensorInfo(TensorShape(55U, 55U, 96U, _batches), 1, dt, fixed_point_position));
176 norm1_out.allocator()->init(TensorInfo(TensorShape(55U, 55U, 96U, _batches), 1, dt, fixed_point_position));
177 pool1_out.allocator()->init(TensorInfo(TensorShape(27U, 27U, 96U, _batches), 1, dt, fixed_point_position));
178 pool11_out = std::unique_ptr<SubTensorType>(new SubTensorType(&pool1_out, TensorShape(27U, 27U, 48U, _batches), Coordinates()));
179 pool12_out = std::unique_ptr<SubTensorType>(new SubTensorType(&pool1_out, TensorShape(27U, 27U, 48U, _batches), Coordinates(0, 0, 48)));
180 // Layer 2
181 conv2_out.allocator()->init(TensorInfo(TensorShape(27U, 27U, 256U, _batches), 1, dt, fixed_point_position));
182 conv21_out = std::unique_ptr<SubTensorType>(new SubTensorType(&conv2_out, TensorShape(27U, 27U, 128U, _batches), Coordinates()));
183 conv22_out = std::unique_ptr<SubTensorType>(new SubTensorType(&conv2_out, TensorShape(27U, 27U, 128U, _batches), Coordinates(0, 0, 128)));
184 act2_out.allocator()->init(TensorInfo(TensorShape(27U, 27U, 256U, _batches), 1, dt, fixed_point_position));
185 norm2_out.allocator()->init(TensorInfo(TensorShape(27U, 27U, 256U, _batches), 1, dt, fixed_point_position));
186 pool2_out.allocator()->init(TensorInfo(TensorShape(13U, 13U, 256U, _batches), 1, dt, fixed_point_position));
187 // Layer 3
188 conv3_out.allocator()->init(TensorInfo(TensorShape(13U, 13U, 384U, _batches), 1, dt, fixed_point_position));
189 act3_out.allocator()->init(TensorInfo(TensorShape(13U, 13U, 384U, _batches), 1, dt, fixed_point_position));
190 act31_out = std::unique_ptr<SubTensorType>(new SubTensorType(&act3_out, TensorShape(13U, 13U, 192U, _batches), Coordinates()));
191 act32_out = std::unique_ptr<SubTensorType>(new SubTensorType(&act3_out, TensorShape(13U, 13U, 192U, _batches), Coordinates(0, 0, 192)));
192 // Layer 4
193 conv4_out.allocator()->init(TensorInfo(TensorShape(13U, 13U, 384U, _batches), 1, dt, fixed_point_position));
194 conv41_out = std::unique_ptr<SubTensorType>(new SubTensorType(&conv4_out, TensorShape(13U, 13U, 192U, _batches), Coordinates()));
195 conv42_out = std::unique_ptr<SubTensorType>(new SubTensorType(&conv4_out, TensorShape(13U, 13U, 192U, _batches), Coordinates(0, 0, 192)));
196 act4_out.allocator()->init(TensorInfo(TensorShape(13U, 13U, 384U, _batches), 1, dt, fixed_point_position));
197 act41_out = std::unique_ptr<SubTensorType>(new SubTensorType(&act4_out, TensorShape(13U, 13U, 192U, _batches), Coordinates()));
198 act42_out = std::unique_ptr<SubTensorType>(new SubTensorType(&act4_out, TensorShape(13U, 13U, 192U, _batches), Coordinates(0, 0, 192)));
199 // Layer 5
200 conv5_out.allocator()->init(TensorInfo(TensorShape(13U, 13U, 256U, _batches), 1, dt, fixed_point_position));
201 conv51_out = std::unique_ptr<SubTensorType>(new SubTensorType(&conv5_out, TensorShape(13U, 13U, 128U, _batches), Coordinates()));
202 conv52_out = std::unique_ptr<SubTensorType>(new SubTensorType(&conv5_out, TensorShape(13U, 13U, 128U, _batches), Coordinates(0, 0, 128)));
203 act5_out.allocator()->init(TensorInfo(TensorShape(13U, 13U, 256U, _batches), 1, dt, fixed_point_position));
204 pool5_out.allocator()->init(TensorInfo(TensorShape(6U, 6U, 256U, _batches), 1, dt, fixed_point_position));
205 // Layer 6
206 fc6_out.allocator()->init(TensorInfo(TensorShape(4096U, _batches), 1, dt, fixed_point_position));
207 act6_out.allocator()->init(TensorInfo(TensorShape(4096U, _batches), 1, dt, fixed_point_position));
208 // Layer 7
209 fc7_out.allocator()->init(TensorInfo(TensorShape(4096U, _batches), 1, dt, fixed_point_position));
210 act7_out.allocator()->init(TensorInfo(TensorShape(4096U, _batches), 1, dt, fixed_point_position));
211 // Layer 8
212 fc8_out.allocator()->init(TensorInfo(TensorShape(1000U, _batches), 1, dt, fixed_point_position));
213
214 // Allocate layers
215 {
216 // Layer 1
217 conv1 = std::unique_ptr<ConvolutionLayerFunction>(new ConvolutionLayerFunction());
218 act1 = std::unique_ptr<ActivationLayerFunction>(new ActivationLayerFunction());
219 norm1 = std::unique_ptr<NormalizationLayerFunction>(new NormalizationLayerFunction());
220 pool1 = std::unique_ptr<PoolingLayerFunction>(new PoolingLayerFunction());
221 // Layer 2
222 conv21 = std::unique_ptr<ConvolutionLayerFunction>(new ConvolutionLayerFunction());
223 conv22 = std::unique_ptr<ConvolutionLayerFunction>(new ConvolutionLayerFunction());
224 act2 = std::unique_ptr<ActivationLayerFunction>(new ActivationLayerFunction());
225 norm2 = std::unique_ptr<NormalizationLayerFunction>(new NormalizationLayerFunction());
226 pool2 = std::unique_ptr<PoolingLayerFunction>(new PoolingLayerFunction());
227 // Layer 3
228 conv3 = std::unique_ptr<ConvolutionLayerFunction>(new ConvolutionLayerFunction());
229 act3 = std::unique_ptr<ActivationLayerFunction>(new ActivationLayerFunction());
230 // Layer 4
231 conv41 = std::unique_ptr<ConvolutionLayerFunction>(new ConvolutionLayerFunction());
232 conv42 = std::unique_ptr<ConvolutionLayerFunction>(new ConvolutionLayerFunction());
233 act4 = std::unique_ptr<ActivationLayerFunction>(new ActivationLayerFunction());
234 // Layer 5
235 conv51 = std::unique_ptr<ConvolutionLayerFunction>(new ConvolutionLayerFunction());
236 conv52 = std::unique_ptr<ConvolutionLayerFunction>(new ConvolutionLayerFunction());
237 act5 = std::unique_ptr<ActivationLayerFunction>(new ActivationLayerFunction());
238 pool5 = std::unique_ptr<PoolingLayerFunction>(new PoolingLayerFunction());
239 // Layer 6
240 fc6 = std::unique_ptr<FullyConnectedLayerFunction>(new FullyConnectedLayerFunction());
241 act6 = std::unique_ptr<ActivationLayerFunction>(new ActivationLayerFunction());
242 // Layer 7
243 fc7 = std::unique_ptr<FullyConnectedLayerFunction>(new FullyConnectedLayerFunction());
244 act7 = std::unique_ptr<ActivationLayerFunction>(new ActivationLayerFunction());
245 // Layer 8
246 fc8 = std::unique_ptr<FullyConnectedLayerFunction>(new FullyConnectedLayerFunction());
247 // Softmax
248 smx = std::unique_ptr<SoftmaxLayerFunction>(new SoftmaxLayerFunction());
249 }
250
251 // Configure Layers
252 {
253 // Layer 1
Gian Marco Iodice4e288692017-06-27 11:41:59 +0100254 conv1->configure(&input, w[0].get(), b[0].get(), &conv1_out, PadStrideInfo(4, 4, 0, 0), WeightsInfo(_reshaped_weights, 11U, 11U));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100255 act1->configure(&conv1_out, &act1_out, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
256 norm1->configure(&act1_out, &norm1_out, NormalizationLayerInfo(NormType::CROSS_MAP, 5, 0.0001f, 0.75f));
257 pool1->configure(&norm1_out, &pool1_out, PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0)));
258 // Layer 2
Gian Marco Iodice4e288692017-06-27 11:41:59 +0100259 conv21->configure(pool11_out.get(), w21.get(), b21.get(), conv21_out.get(), PadStrideInfo(1, 1, 2, 2), WeightsInfo(_reshaped_weights, 5U, 5U));
260 conv22->configure(pool12_out.get(), w22.get(), b22.get(), conv22_out.get(), PadStrideInfo(1, 1, 2, 2), WeightsInfo(_reshaped_weights, 5U, 5U));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100261 act2->configure(&conv2_out, &act2_out, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
262 norm2->configure(&act2_out, &norm2_out, NormalizationLayerInfo(NormType::CROSS_MAP, 5, 0.0001f, 0.75f));
263 pool2->configure(&norm2_out, &pool2_out, PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0)));
264 // Layer 3
Gian Marco Iodice4e288692017-06-27 11:41:59 +0100265 conv3->configure(&pool2_out, w[2].get(), b[2].get(), &conv3_out, PadStrideInfo(1, 1, 1, 1), WeightsInfo(_reshaped_weights, 3U, 3U));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100266 act3->configure(&conv3_out, &act3_out, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
267 // Layer 4
Gian Marco Iodice4e288692017-06-27 11:41:59 +0100268 conv41->configure(act31_out.get(), w41.get(), b41.get(), conv41_out.get(), PadStrideInfo(1, 1, 1, 1), WeightsInfo(_reshaped_weights, 3U, 3U));
269 conv42->configure(act32_out.get(), w42.get(), b42.get(), conv42_out.get(), PadStrideInfo(1, 1, 1, 1), WeightsInfo(_reshaped_weights, 3U, 3U));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100270 act4->configure(&conv4_out, &act4_out, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
271 // Layer 5
Gian Marco Iodice4e288692017-06-27 11:41:59 +0100272 conv51->configure(act41_out.get(), w51.get(), b51.get(), conv51_out.get(), PadStrideInfo(1, 1, 1, 1), WeightsInfo(_reshaped_weights, 3U, 3U));
273 conv52->configure(act42_out.get(), w52.get(), b52.get(), conv52_out.get(), PadStrideInfo(1, 1, 1, 1), WeightsInfo(_reshaped_weights, 3U, 3U));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100274 act5->configure(&conv5_out, &act5_out, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
275 pool5->configure(&act5_out, &pool5_out, PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0)));
276 // Layer 6
277 fc6->configure(&pool5_out, w[5].get(), b[5].get(), &fc6_out, true, _reshaped_weights);
278 act6->configure(&fc6_out, &act6_out, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
279 // Layer 7
280 fc7->configure(&act6_out, w[6].get(), b[6].get(), &fc7_out, true, _reshaped_weights);
281 act7->configure(&fc7_out, &act7_out, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
282 // Layer 8
283 fc8->configure(&act7_out, w[7].get(), b[7].get(), &fc8_out, true, _reshaped_weights);
284 // Softmax
285 smx->configure(&fc8_out, &output);
286 }
287 }
288
289 void allocate()
290 {
291 input.allocator()->allocate();
292 output.allocator()->allocate();
293 for(auto &wi : w)
294 {
295 if(wi.get())
296 {
297 wi->allocator()->allocate();
298 }
299 }
300 for(auto &bi : b)
301 {
302 if(bi.get())
303 {
304 bi->allocator()->allocate();
305 }
306 }
307 if(_reshaped_weights)
308 {
309 dynamic_cast<TensorType *>(w21.get())->allocator()->allocate();
310 dynamic_cast<TensorType *>(w22.get())->allocator()->allocate();
311 dynamic_cast<TensorType *>(w41.get())->allocator()->allocate();
312 dynamic_cast<TensorType *>(w42.get())->allocator()->allocate();
313 dynamic_cast<TensorType *>(w51.get())->allocator()->allocate();
314 dynamic_cast<TensorType *>(w52.get())->allocator()->allocate();
315 }
316 conv1_out.allocator()->allocate();
317 act1_out.allocator()->allocate();
318 norm1_out.allocator()->allocate();
319 pool1_out.allocator()->allocate();
320 conv2_out.allocator()->allocate();
321 act2_out.allocator()->allocate();
322 norm2_out.allocator()->allocate();
323 pool2_out.allocator()->allocate();
324 conv3_out.allocator()->allocate();
325 act3_out.allocator()->allocate();
326 conv4_out.allocator()->allocate();
327 act4_out.allocator()->allocate();
328 conv5_out.allocator()->allocate();
329 act5_out.allocator()->allocate();
330 pool5_out.allocator()->allocate();
331 fc6_out.allocator()->allocate();
332 act6_out.allocator()->allocate();
333 fc7_out.allocator()->allocate();
334 act7_out.allocator()->allocate();
335 fc8_out.allocator()->allocate();
336 }
337
338 /** Fills the trainable parameters and input with random data. */
339 void fill_random()
340 {
341 library->fill_tensor_uniform(Accessor(input), 0);
342 if(!_reshaped_weights)
343 {
344 for(unsigned int i = 0; i < w.size(); ++i)
345 {
346 library->fill_tensor_uniform(Accessor(*w[i]), i + 1);
347 library->fill_tensor_uniform(Accessor(*b[i]), i + 10);
348 }
349 }
350 else
351 {
352 library->fill_tensor_uniform(Accessor(*w[0]), 1);
353 library->fill_tensor_uniform(Accessor(*w[2]), 2);
354
355 library->fill_tensor_uniform(Accessor(*w[5]), 3);
356 library->fill_tensor_uniform(Accessor(*b[5]), 4);
357 library->fill_tensor_uniform(Accessor(*w[6]), 5);
358 library->fill_tensor_uniform(Accessor(*b[6]), 6);
359 library->fill_tensor_uniform(Accessor(*w[7]), 7);
360 library->fill_tensor_uniform(Accessor(*b[7]), 8);
361
362 library->fill_tensor_uniform(Accessor(*dynamic_cast<TensorType *>(w21.get())), 9);
363 library->fill_tensor_uniform(Accessor(*dynamic_cast<TensorType *>(w22.get())), 10);
364 library->fill_tensor_uniform(Accessor(*dynamic_cast<TensorType *>(w41.get())), 11);
365 library->fill_tensor_uniform(Accessor(*dynamic_cast<TensorType *>(w42.get())), 12);
366 library->fill_tensor_uniform(Accessor(*dynamic_cast<TensorType *>(w51.get())), 13);
367 library->fill_tensor_uniform(Accessor(*dynamic_cast<TensorType *>(w52.get())), 14);
368 }
369 }
370
371#ifdef INTERNAL_ONLY
372 /** Fills the trainable parameters from binary files
373 *
374 * @param weights Files names containing the weights data
375 * @param biases Files names containing the bias data
376 */
377 void fill(std::vector<std::string> weights, std::vector<std::string> biases)
378 {
379 ARM_COMPUTE_ERROR_ON(weights.size() != w.size());
380 ARM_COMPUTE_ERROR_ON(biases.size() != b.size());
381 ARM_COMPUTE_ERROR_ON(_reshaped_weights);
382
383 for(unsigned int i = 0; i < weights.size(); ++i)
384 {
385 library->fill_layer_data(Accessor(*w[i]), weights[i]);
386 library->fill_layer_data(Accessor(*b[i]), biases[i]);
387 }
388 }
389
390 /** Feed input to network from file.
391 *
392 * @param name File name of containing the input data.
393 */
394 void feed(std::string name)
395 {
396 library->fill_layer_data(Accessor(input), name);
397 }
398#endif /* INTERNAL_ONLY */
399
400 /** Get the classification results.
401 *
402 * @return Vector containing the classified labels
403 */
404 std::vector<unsigned int> get_classifications()
405 {
406 std::vector<unsigned int> classified_labels;
407 Accessor output_accessor(output);
408
409 Window window;
410 window.set(Window::DimX, Window::Dimension(0, 1, 1));
411 for(unsigned int d = 1; d < output_accessor.shape().num_dimensions(); ++d)
412 {
413 window.set(d, Window::Dimension(0, output_accessor.shape()[d], 1));
414 }
415
416 execute_window_loop(window, [&](const Coordinates & id)
417 {
418 int max_idx = 0;
419 float val = 0;
420 const void *const out_ptr = output_accessor(id);
421 for(unsigned int l = 0; l < output_accessor.shape().x(); ++l)
422 {
423 float curr_val = reinterpret_cast<const float *>(out_ptr)[l];
424 if(curr_val > val)
425 {
426 max_idx = l;
427 val = curr_val;
428 }
429 }
430 classified_labels.push_back(max_idx);
431 });
432 return classified_labels;
433 }
434
435 /** Clear all allocated memory from the tensor objects */
436 void clear()
437 {
438 conv1.reset();
439 act1.reset();
440 norm1.reset();
441 pool1.reset();
442 conv21.reset();
443 conv22.reset();
444 act2.reset();
445 norm2.reset();
446 pool2.reset();
447 conv3.reset();
448 act3.reset();
449 conv41.reset();
450 conv42.reset();
451 act4.reset();
452 conv51.reset();
453 conv52.reset();
454 act5.reset();
455 pool5.reset();
456 fc6.reset();
457 act6.reset();
458 fc7.reset();
459 act7.reset();
460 fc8.reset();
461 smx.reset();
462
463 // Free allocations
464 input.allocator()->free();
465 output.allocator()->free();
466 for(auto &wi : w)
467 {
468 wi.reset();
469 }
470 for(auto &bi : b)
471 {
472 bi.reset();
473 }
474
475 w21.reset();
476 w22.reset();
477 b21.reset();
478 b21.reset();
479 w41.reset();
480 w42.reset();
481 b41.reset();
482 b42.reset();
483 w51.reset();
484 w52.reset();
485 b51.reset();
486 b52.reset();
487
488 conv1_out.allocator()->free();
489 act1_out.allocator()->free();
490 norm1_out.allocator()->free();
491 pool1_out.allocator()->free();
492 conv2_out.allocator()->free();
493 act2_out.allocator()->free();
494 norm2_out.allocator()->free();
495 pool2_out.allocator()->free();
496 conv3_out.allocator()->free();
497 act3_out.allocator()->free();
498 conv4_out.allocator()->free();
499 act4_out.allocator()->free();
500 conv5_out.allocator()->free();
501 act5_out.allocator()->free();
502 pool5_out.allocator()->free();
503 fc6_out.allocator()->free();
504 act6_out.allocator()->free();
505 fc7_out.allocator()->free();
506 act7_out.allocator()->free();
507 fc8_out.allocator()->free();
508 }
509
510 /** Runs the model */
511 void run()
512 {
513 // Layer 1
514 conv1->run();
515 act1->run();
516 norm1->run();
517 pool1->run();
518 // Layer 2
519 conv21->run();
520 conv22->run();
521 act2->run();
522 norm2->run();
523 pool2->run();
524 // Layer 3
525 conv3->run();
526 act3->run();
527 // Layer 4
528 conv41->run();
529 conv42->run();
530 act4->run();
531 // Layer 5
532 conv51->run();
533 conv52->run();
534 act5->run();
535 pool5->run();
536 // Layer 6
537 fc6->run();
538 act6->run();
539 // Layer 7
540 fc7->run();
541 act7->run();
542 // Layer 8
543 fc8->run();
544 // Softmax
545 smx->run();
546 }
547
548private:
549 unsigned int _batches;
550 bool _reshaped_weights;
551
552 std::unique_ptr<ActivationLayerFunction> act1{ nullptr }, act2{ nullptr }, act3{ nullptr }, act4{ nullptr }, act5{ nullptr }, act6{ nullptr }, act7{ nullptr };
553 std::unique_ptr<ConvolutionLayerFunction> conv1{ nullptr }, conv21{ nullptr }, conv22{ nullptr }, conv3{ nullptr }, conv41{ nullptr }, conv42{ nullptr }, conv51{ nullptr }, conv52{ nullptr };
554 std::unique_ptr<FullyConnectedLayerFunction> fc6{ nullptr }, fc7{ nullptr }, fc8{};
555 std::unique_ptr<NormalizationLayerFunction> norm1{ nullptr }, norm2{ nullptr };
556 std::unique_ptr<PoolingLayerFunction> pool1{ nullptr }, pool2{ nullptr }, pool5{ nullptr };
557 std::unique_ptr<SoftmaxLayerFunction> smx{ nullptr };
558
559 TensorType input{}, output{};
560 std::array<std::unique_ptr<TensorType>, 8> w{}, b{};
561 std::unique_ptr<ITensorType> w21{ nullptr }, w22{ nullptr }, b21{ nullptr }, b22{ nullptr };
562 std::unique_ptr<ITensorType> w41{ nullptr }, w42{ nullptr }, b41{ nullptr }, b42{ nullptr };
563 std::unique_ptr<ITensorType> w51{ nullptr }, w52{ nullptr }, b51{ nullptr }, b52{ nullptr };
564
565 TensorType conv1_out{}, act1_out{}, norm1_out{}, pool1_out{};
566 TensorType conv2_out{}, act2_out{}, pool2_out{}, norm2_out{};
567 TensorType conv3_out{}, act3_out{};
568 TensorType conv4_out{}, act4_out{};
569 TensorType conv5_out{}, act5_out{}, pool5_out{};
570 TensorType fc6_out{}, act6_out{};
571 TensorType fc7_out{}, act7_out{};
572 TensorType fc8_out{};
573
574 std::unique_ptr<SubTensorType> pool11_out{ nullptr }, pool12_out{ nullptr };
575 std::unique_ptr<SubTensorType> conv21_out{ nullptr }, conv22_out{ nullptr };
576 std::unique_ptr<SubTensorType> act31_out{ nullptr }, act32_out{ nullptr };
577 std::unique_ptr<SubTensorType> conv41_out{ nullptr }, conv42_out{ nullptr }, act41_out{ nullptr }, act42_out{ nullptr };
578 std::unique_ptr<SubTensorType> conv51_out{ nullptr }, conv52_out{ nullptr };
579};
580} // namespace model_objects
581} // namespace test
582} // namespace arm_compute
583#endif //__ARM_COMPUTE_TEST_MODEL_OBJECTS_ALEXNET_H__