diff options
author | Anthony Barbier <anthony.barbier@arm.com> | 2017-10-23 18:55:17 +0100 |
---|---|---|
committer | Anthony Barbier <anthony.barbier@arm.com> | 2017-10-23 18:58:11 +0100 |
commit | 8a3da6f91f90c566b844d568f4ec43b946915af8 (patch) | |
tree | d8265ab6b77cdabaa856b623fc8c1ade64867c03 /utils/GraphUtils.cpp | |
parent | 2aab3165ae3104c8f3018157b62d4febdc94f2b7 (diff) | |
download | armcl-8a3da6f91f90c566b844d568f4ec43b946915af8.tar.gz armcl-8a3da6f91f90c566b844d568f4ec43b946915af8.tar.bz2 armcl-8a3da6f91f90c566b844d568f4ec43b946915af8.zip |
Update AlexNet example with accessors
Diffstat (limited to 'utils/GraphUtils.cpp')
-rw-r--r-- | utils/GraphUtils.cpp | 111 |
1 files changed, 100 insertions, 11 deletions
diff --git a/utils/GraphUtils.cpp b/utils/GraphUtils.cpp index bdd831075..bcfc0f799 100644 --- a/utils/GraphUtils.cpp +++ b/utils/GraphUtils.cpp @@ -34,8 +34,10 @@ #include "arm_compute/core/PixelValue.h" #include "libnpy/npy.hpp" +#include <algorithm> +#include <iomanip> +#include <ostream> #include <random> -#include <sstream> using namespace arm_compute::graph_utils; @@ -48,16 +50,8 @@ bool PPMWriter::access_tensor(ITensor &tensor) { std::stringstream ss; ss << _name << _iterator << ".ppm"; - if(dynamic_cast<Tensor *>(&tensor) != nullptr) - { - arm_compute::utils::save_to_ppm(dynamic_cast<Tensor &>(tensor), ss.str()); - } -#ifdef ARM_COMPUTE_CL - else if(dynamic_cast<CLTensor *>(&tensor) != nullptr) - { - arm_compute::utils::save_to_ppm(dynamic_cast<CLTensor &>(tensor), ss.str()); - } -#endif /* ARM_COMPUTE_CL */ + + arm_compute::utils::save_to_ppm(tensor, ss.str()); _iterator++; if(_maximum == 0) @@ -87,6 +81,101 @@ bool DummyAccessor::access_tensor(ITensor &tensor) return ret; } +PPMAccessor::PPMAccessor(const std::string &ppm_path, bool bgr, float mean_r, float mean_g, float mean_b) + : _ppm_path(ppm_path), _bgr(bgr), _mean_r(mean_r), _mean_g(mean_g), _mean_b(mean_b) +{ +} + +bool PPMAccessor::access_tensor(ITensor &tensor) +{ + utils::PPMLoader ppm; + const float mean[3] = + { + _bgr ? _mean_b : _mean_r, + _mean_g, + _bgr ? _mean_r : _mean_b + }; + + // Open PPM file + ppm.open(_ppm_path); + + // Fill the tensor with the PPM content (BGR) + ppm.fill_planar_tensor(tensor, _bgr); + + // Subtract the mean value from each channel + Window window; + window.use_tensor_dimensions(tensor.info()->tensor_shape()); + + execute_window_loop(window, [&](const Coordinates & id) + { + const float value = *reinterpret_cast<float *>(tensor.ptr_to_element(id)) - mean[id.z()]; + *reinterpret_cast<float *>(tensor.ptr_to_element(id)) = value; + }); + + return true; +} + +TopNPredictionsAccessor::TopNPredictionsAccessor(const std::string &labels_path, size_t top_n, std::ostream &output_stream) + : _labels(), _output_stream(output_stream), _top_n(top_n) +{ + _labels.clear(); + + std::ifstream ifs; + + try + { + ifs.exceptions(std::ifstream::badbit); + ifs.open(labels_path, std::ios::in | std::ios::binary); + + for(std::string line; !std::getline(ifs, line).fail();) + { + _labels.emplace_back(line); + } + } + catch(const std::ifstream::failure &e) + { + ARM_COMPUTE_ERROR("Accessing %s: %s", labels_path.c_str(), e.what()); + } +} + +bool TopNPredictionsAccessor::access_tensor(ITensor &tensor) +{ + ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&tensor, 1, DataType::F32); + ARM_COMPUTE_ERROR_ON(_labels.size() != tensor.info()->dimension(0)); + + // Get the predicted class + std::vector<float> classes_prob; + std::vector<size_t> index; + + const auto output_net = reinterpret_cast<float *>(tensor.buffer() + tensor.info()->offset_first_element_in_bytes()); + const size_t num_classes = tensor.info()->dimension(0); + + classes_prob.resize(num_classes); + index.resize(num_classes); + + std::copy(output_net, output_net + num_classes, classes_prob.begin()); + + // Sort results + std::iota(std::begin(index), std::end(index), static_cast<size_t>(0)); + std::sort(std::begin(index), std::end(index), + [&](size_t a, size_t b) + { + return classes_prob[a] > classes_prob[b]; + }); + + _output_stream << "---------- Top " << _top_n << " predictions ----------" << std::endl + << std::endl; + for(size_t i = 0; i < _top_n; ++i) + { + _output_stream << std::fixed << std::setprecision(4) + << classes_prob[index.at(i)] + << " - [id = " << index.at(i) << "]" + << ", " << _labels[index.at(i)] << std::endl; + } + + return false; +} + RandomAccessor::RandomAccessor(PixelValue lower, PixelValue upper, std::random_device::result_type seed) : _lower(lower), _upper(upper), _seed(seed) { |