blob: 51c4de0ec1d8b1ccc4b0dcd2e2af0992b4c36c3e [file] [log] [blame]
Georgios Pinitas37561862017-10-19 10:51:03 +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 */
Georgios Pinitas37561862017-10-19 10:51:03 +010024
Georgios Pinitas37561862017-10-19 10:51:03 +010025#include "arm_compute/graph/Graph.h"
26#include "arm_compute/graph/Nodes.h"
27#include "arm_compute/graph/SubGraph.h"
Georgios Pinitas37561862017-10-19 10:51:03 +010028#include "support/ToolchainSupport.h"
29#include "utils/GraphUtils.h"
30#include "utils/Utils.h"
31
32#include <cstdlib>
Georgios Pinitas37561862017-10-19 10:51:03 +010033#include <tuple>
34
35using namespace arm_compute::graph;
36using namespace arm_compute::graph_utils;
Isabella Gottardi4398bec2017-10-19 16:10:59 +010037using namespace arm_compute::logging;
Georgios Pinitas37561862017-10-19 10:51:03 +010038
Georgios Pinitas37561862017-10-19 10:51:03 +010039BranchLayer get_expand_fire_node(const std::string &data_path, std::string &&param_path, unsigned int expand1_filt, unsigned int expand3_filt)
40{
41 std::string total_path = "/cnn_data/squeezenet_v1.0_model/" + param_path + "_";
42 SubGraph i_a;
43 i_a << ConvolutionLayer(
44 1U, 1U, expand1_filt,
Isabella Gottardi97988a42017-11-03 14:39:44 +000045 get_weights_accessor(data_path, total_path + "expand1x1_w.npy"),
46 get_weights_accessor(data_path, total_path + "expand1x1_b.npy"),
Georgios Pinitas37561862017-10-19 10:51:03 +010047 PadStrideInfo(1, 1, 0, 0))
48 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
49
50 SubGraph i_b;
51 i_b << ConvolutionLayer(
52 3U, 3U, expand3_filt,
Isabella Gottardi97988a42017-11-03 14:39:44 +000053 get_weights_accessor(data_path, total_path + "expand3x3_w.npy"),
54 get_weights_accessor(data_path, total_path + "expand3x3_b.npy"),
Georgios Pinitas37561862017-10-19 10:51:03 +010055 PadStrideInfo(1, 1, 1, 1))
56 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU));
57
58 return BranchLayer(BranchMergeMethod::DEPTH_CONCATENATE, std::move(i_a), std::move(i_b));
59}
60
61/** Example demonstrating how to implement Squeezenet's network using the Compute Library's graph API
62 *
63 * @param[in] argc Number of arguments
Isabella Gottardi97988a42017-11-03 14:39:44 +000064 * @param[in] argv Arguments ( [optional] Path to the weights folder, [optional] image, [optional] labels )
Georgios Pinitas37561862017-10-19 10:51:03 +010065 */
66void main_graph_squeezenet(int argc, const char **argv)
67{
Isabella Gottardi97988a42017-11-03 14:39:44 +000068 std::string data_path; /* Path to the trainable data */
69 std::string image; /* Image data */
70 std::string label; /* Label data */
71
72 constexpr float mean_r = 122.68f; /* Mean value to subtract from red channel */
73 constexpr float mean_g = 116.67f; /* Mean value to subtract from green channel */
74 constexpr float mean_b = 104.01f; /* Mean value to subtract from blue channel */
Georgios Pinitas37561862017-10-19 10:51:03 +010075
76 // Parse arguments
77 if(argc < 2)
78 {
79 // Print help
Isabella Gottardi97988a42017-11-03 14:39:44 +000080 std::cout << "Usage: " << argv[0] << " [path_to_data] [image] [labels]\n\n";
Georgios Pinitas37561862017-10-19 10:51:03 +010081 std::cout << "No data folder provided: using random values\n\n";
82 }
83 else if(argc == 2)
84 {
85 //Do something with argv[1]
86 data_path = argv[1];
Isabella Gottardi97988a42017-11-03 14:39:44 +000087 std::cout << "Usage: " << argv[0] << " " << argv[1] << " [image] [labels]\n\n";
88 std::cout << "No image provided: using random values\n";
89 }
90 else if(argc == 3)
91 {
92 data_path = argv[1];
93 image = argv[2];
94 std::cout << "Usage: " << argv[0] << " " << argv[1] << " " << argv[2] << " [labels]\n\n";
95 std::cout << "No text file with labels provided: skipping output accessor\n";
Georgios Pinitas37561862017-10-19 10:51:03 +010096 }
97 else
98 {
Georgios Pinitas37561862017-10-19 10:51:03 +010099 data_path = argv[1];
Isabella Gottardi97988a42017-11-03 14:39:44 +0000100 image = argv[2];
101 label = argv[3];
Georgios Pinitas37561862017-10-19 10:51:03 +0100102 }
103
104 // Check if OpenCL is available and initialize the scheduler
Isabella Gottardib28f29d2017-11-09 17:05:07 +0000105 TargetHint hint = TargetHint::NEON;
106 if(Graph::opencl_is_available())
Georgios Pinitas37561862017-10-19 10:51:03 +0100107 {
Isabella Gottardib28f29d2017-11-09 17:05:07 +0000108 hint = TargetHint::OPENCL;
Georgios Pinitas37561862017-10-19 10:51:03 +0100109 }
110
111 Graph graph;
Georgios Pinitas37561862017-10-19 10:51:03 +0100112
Isabella Gottardib28f29d2017-11-09 17:05:07 +0000113 graph << hint
Isabella Gottardi97988a42017-11-03 14:39:44 +0000114 << Tensor(TensorInfo(TensorShape(224U, 224U, 3U, 1U), 1, DataType::F32),
115 get_input_accessor(image, mean_r, mean_g, mean_b))
Georgios Pinitas37561862017-10-19 10:51:03 +0100116 << ConvolutionLayer(
117 7U, 7U, 96U,
Isabella Gottardi97988a42017-11-03 14:39:44 +0000118 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/conv1_w.npy"),
119 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/conv1_b.npy"),
Georgios Pinitas37561862017-10-19 10:51:03 +0100120 PadStrideInfo(2, 2, 0, 0))
121 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
122 << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)))
123 << ConvolutionLayer(
124 1U, 1U, 16U,
Isabella Gottardi97988a42017-11-03 14:39:44 +0000125 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire2_squeeze1x1_w.npy"),
126 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire2_squeeze1x1_b.npy"),
Georgios Pinitas37561862017-10-19 10:51:03 +0100127 PadStrideInfo(1, 1, 0, 0))
128 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
129 << get_expand_fire_node(data_path, "fire2", 64U, 64U)
130 << ConvolutionLayer(
131 1U, 1U, 16U,
Isabella Gottardi97988a42017-11-03 14:39:44 +0000132 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire3_squeeze1x1_w.npy"),
133 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire3_squeeze1x1_b.npy"),
Georgios Pinitas37561862017-10-19 10:51:03 +0100134 PadStrideInfo(1, 1, 0, 0))
135 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
136 << get_expand_fire_node(data_path, "fire3", 64U, 64U)
137 << ConvolutionLayer(
138 1U, 1U, 32U,
Isabella Gottardi97988a42017-11-03 14:39:44 +0000139 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire4_squeeze1x1_w.npy"),
140 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire4_squeeze1x1_b.npy"),
Georgios Pinitas37561862017-10-19 10:51:03 +0100141 PadStrideInfo(1, 1, 0, 0))
142 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
143 << get_expand_fire_node(data_path, "fire4", 128U, 128U)
144 << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)))
145 << ConvolutionLayer(
146 1U, 1U, 32U,
Isabella Gottardi97988a42017-11-03 14:39:44 +0000147 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire5_squeeze1x1_w.npy"),
148 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire5_squeeze1x1_b.npy"),
Georgios Pinitas37561862017-10-19 10:51:03 +0100149 PadStrideInfo(1, 1, 0, 0))
150 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
151 << get_expand_fire_node(data_path, "fire5", 128U, 128U)
152 << ConvolutionLayer(
153 1U, 1U, 48U,
Isabella Gottardi97988a42017-11-03 14:39:44 +0000154 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire6_squeeze1x1_w.npy"),
155 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire6_squeeze1x1_b.npy"),
Georgios Pinitas37561862017-10-19 10:51:03 +0100156 PadStrideInfo(1, 1, 0, 0))
157 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
158 << get_expand_fire_node(data_path, "fire6", 192U, 192U)
159 << ConvolutionLayer(
160 1U, 1U, 48U,
Isabella Gottardi97988a42017-11-03 14:39:44 +0000161 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire7_squeeze1x1_w.npy"),
162 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire7_squeeze1x1_b.npy"),
Georgios Pinitas37561862017-10-19 10:51:03 +0100163 PadStrideInfo(1, 1, 0, 0))
164 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
165 << get_expand_fire_node(data_path, "fire7", 192U, 192U)
166 << ConvolutionLayer(
167 1U, 1U, 64U,
Isabella Gottardi97988a42017-11-03 14:39:44 +0000168 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire8_squeeze1x1_w.npy"),
169 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire8_squeeze1x1_b.npy"),
Georgios Pinitas37561862017-10-19 10:51:03 +0100170 PadStrideInfo(1, 1, 0, 0))
171 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
172 << get_expand_fire_node(data_path, "fire8", 256U, 256U)
173 << PoolingLayer(PoolingLayerInfo(PoolingType::MAX, 3, PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)))
174 << ConvolutionLayer(
175 1U, 1U, 64U,
Isabella Gottardi97988a42017-11-03 14:39:44 +0000176 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire9_squeeze1x1_w.npy"),
177 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/fire9_squeeze1x1_b.npy"),
Georgios Pinitas37561862017-10-19 10:51:03 +0100178 PadStrideInfo(1, 1, 0, 0))
179 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
180 << get_expand_fire_node(data_path, "fire9", 256U, 256U)
181 << ConvolutionLayer(
182 1U, 1U, 1000U,
Isabella Gottardi97988a42017-11-03 14:39:44 +0000183 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/conv10_w.npy"),
184 get_weights_accessor(data_path, "/cnn_data/squeezenet_v1.0_model/conv10_b.npy"),
Georgios Pinitas37561862017-10-19 10:51:03 +0100185 PadStrideInfo(1, 1, 0, 0))
186 << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU))
Georgios Pinitas4c2dd542017-11-13 12:58:41 +0000187 << PoolingLayer(PoolingLayerInfo(PoolingType::AVG))
Isabella Gottardi97988a42017-11-03 14:39:44 +0000188 << FlattenLayer()
Georgios Pinitas37561862017-10-19 10:51:03 +0100189 << SoftmaxLayer()
Isabella Gottardi97988a42017-11-03 14:39:44 +0000190 << Tensor(get_output_accessor(label, 5));
Georgios Pinitas37561862017-10-19 10:51:03 +0100191
192 graph.run();
193}
194
195/** Main program for Squeezenet v1.0
196 *
197 * @param[in] argc Number of arguments
Isabella Gottardi97988a42017-11-03 14:39:44 +0000198 * @param[in] argv Arguments ( [optional] Path to the weights folder, [optional] image, [optional] labels )
Georgios Pinitas37561862017-10-19 10:51:03 +0100199 */
200int main(int argc, const char **argv)
201{
202 return arm_compute::utils::run_example(argc, argv, main_graph_squeezenet);
Isabella Gottardi97988a42017-11-03 14:39:44 +0000203}