aboutsummaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorGeorgios Pinitas <georgios.pinitas@arm.com>2018-02-16 11:42:38 +0000
committerAnthony Barbier <anthony.barbier@arm.com>2018-11-02 16:47:18 +0000
commit140fdc76e99c92b2f71865b679de0659a70b713f (patch)
treea8218bfd303772ed68f6c4d57e17d5ddd7b61ce0 /utils
parent72f39be2f372b9a810cb27320dba5d0722407549 (diff)
downloadComputeLibrary-140fdc76e99c92b2f71865b679de0659a70b713f.tar.gz
COMPMID-913: Fix preprocessing step for TF models.
Change-Id: If0fbb6bbe5384038124d3dc189274b8266f796ca Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/120771 Reviewed-by: Anthony Barbier <anthony.barbier@arm.com> Reviewed-by: Pablo Tello <pablo.tello@arm.com> Tested-by: Jenkins <bsgcomp@arm.com>
Diffstat (limited to 'utils')
-rw-r--r--utils/GraphUtils.cpp65
-rw-r--r--utils/GraphUtils.h81
2 files changed, 88 insertions, 58 deletions
diff --git a/utils/GraphUtils.cpp b/utils/GraphUtils.cpp
index a36cf8ea9f..448343a977 100644
--- a/utils/GraphUtils.cpp
+++ b/utils/GraphUtils.cpp
@@ -36,6 +36,41 @@
using namespace arm_compute::graph_utils;
+void TFPreproccessor::preprocess(ITensor &tensor)
+{
+ 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));
+ float res = value / 255.f; // Normalize to [0, 1]
+ res = (res - 0.5f) * 2.f; // Map to [-1, 1]
+ *reinterpret_cast<float *>(tensor.ptr_to_element(id)) = res;
+ });
+}
+
+CaffePreproccessor::CaffePreproccessor(std::array<float, 3> mean, bool bgr)
+ : _mean(mean), _bgr(bgr)
+{
+ if(_bgr)
+ {
+ std::swap(_mean[0], _mean[2]);
+ }
+}
+
+void CaffePreproccessor::preprocess(ITensor &tensor)
+{
+ 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;
+ });
+}
+
PPMWriter::PPMWriter(std::string name, unsigned int maximum)
: _name(std::move(name)), _iterator(0), _maximum(maximum)
{
@@ -76,28 +111,14 @@ bool DummyAccessor::access_tensor(ITensor &tensor)
return ret;
}
-PPMAccessor::PPMAccessor(std::string ppm_path, bool bgr,
- float mean_r, float mean_g, float mean_b,
- float std_r, float std_g, float std_b)
- : _ppm_path(std::move(ppm_path)), _bgr(bgr), _mean_r(mean_r), _mean_g(mean_g), _mean_b(mean_b), _std_r(std_r), _std_g(std_g), _std_b(std_b)
+PPMAccessor::PPMAccessor(std::string ppm_path, bool bgr, std::unique_ptr<IPreprocessor> preprocessor)
+ : _ppm_path(std::move(ppm_path)), _bgr(bgr), _preprocessor(std::move(preprocessor))
{
}
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
- };
- const float std[3] =
- {
- _bgr ? _std_b : _std_r,
- _std_g,
- _bgr ? _std_r : _std_b
- };
// Open PPM file
ppm.open(_ppm_path);
@@ -108,15 +129,11 @@ bool PPMAccessor::access_tensor(ITensor &tensor)
// 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)
+ // Preprocess tensor
+ if(_preprocessor)
{
- const float value = *reinterpret_cast<float *>(tensor.ptr_to_element(id)) - mean[id.z()];
- *reinterpret_cast<float *>(tensor.ptr_to_element(id)) = value / std[id.z()];
- });
+ _preprocessor->preprocess(tensor);
+ }
return true;
}
diff --git a/utils/GraphUtils.h b/utils/GraphUtils.h
index b48e5b563d..cc6f40417e 100644
--- a/utils/GraphUtils.h
+++ b/utils/GraphUtils.h
@@ -29,6 +29,7 @@
#include "arm_compute/graph/ITensorAccessor.h"
#include "arm_compute/graph/Types.h"
+#include <array>
#include <random>
#include <string>
#include <vector>
@@ -37,6 +38,38 @@ namespace arm_compute
{
namespace graph_utils
{
+/** Preprocessor interface **/
+class IPreprocessor
+{
+public:
+ virtual ~IPreprocessor() = default;
+ virtual void preprocess(ITensor &tensor) = 0;
+};
+
+/** Caffe preproccessor */
+class CaffePreproccessor : public IPreprocessor
+{
+public:
+ /** Default Constructor
+ *
+ * @param mean Mean array in RGB ordering
+ * @param bgr Boolean specifying if the preprocessing should assume BGR format
+ */
+ CaffePreproccessor(std::array<float, 3> mean = std::array<float, 3> { { 0, 0, 0 } }, bool bgr = true);
+ void preprocess(ITensor &tensor) override;
+
+private:
+ std::array<float, 3> _mean;
+ bool _bgr;
+};
+
+/** TF preproccessor */
+class TFPreproccessor : public IPreprocessor
+{
+public:
+ void preprocess(ITensor &tensor) override;
+};
+
/** PPM writer class */
class PPMWriter : public graph::ITensorAccessor
{
@@ -85,18 +118,11 @@ class PPMAccessor final : public graph::ITensorAccessor
public:
/** Constructor
*
- * @param[in] ppm_path Path to PPM file
- * @param[in] bgr (Optional) Fill the first plane with blue channel (default = false)
- * @param[in] mean_r (Optional) Red mean value to be subtracted from red channel
- * @param[in] mean_g (Optional) Green mean value to be subtracted from green channel
- * @param[in] mean_b (Optional) Blue mean value to be subtracted from blue channel
- * @param[in] std_r (Optional) Red standard deviation value to be divided from red channel
- * @param[in] std_g (Optional) Green standard deviation value to be divided from green channel
- * @param[in] std_b (Optional) Blue standard deviation value to be divided from blue channel
+ * @param[in] ppm_path Path to PPM file
+ * @param[in] bgr (Optional) Fill the first plane with blue channel (default = false)
+ * @param[in] preprocessor (Optional) PPM pre-processing object
*/
- PPMAccessor(std::string ppm_path, bool bgr = true,
- float mean_r = 0.0f, float mean_g = 0.0f, float mean_b = 0.0f,
- float std_r = 1.f, float std_g = 1.f, float std_b = 1.f);
+ PPMAccessor(std::string ppm_path, bool bgr = true, std::unique_ptr<IPreprocessor> preprocessor = nullptr);
/** Allow instances of this class to be move constructed */
PPMAccessor(PPMAccessor &&) = default;
@@ -104,14 +130,9 @@ public:
bool access_tensor(ITensor &tensor) override;
private:
- const std::string _ppm_path;
- const bool _bgr;
- const float _mean_r;
- const float _mean_g;
- const float _mean_b;
- const float _std_r;
- const float _std_g;
- const float _std_b;
+ const std::string _ppm_path;
+ const bool _bgr;
+ std::unique_ptr<IPreprocessor> _preprocessor;
};
/** Result accessor class */
@@ -226,21 +247,15 @@ inline std::unique_ptr<graph::ITensorAccessor> get_weights_accessor(const std::s
*
* @note If ppm_path is empty will generate a DummyAccessor else will generate a PPMAccessor
*
- * @param[in] ppm_path Path to PPM file
- * @param[in] mean_r Red mean value to be subtracted from red channel
- * @param[in] mean_g Green mean value to be subtracted from green channel
- * @param[in] mean_b Blue mean value to be subtracted from blue channel
- * @param[in] std_r (Optional) Red standard deviation value to be divided from red channel
- * @param[in] std_g (Optional) Green standard deviation value to be divided from green channel
- * @param[in] std_b (Optional) Blue standard deviation value to be divided from blue channel
- * @param[in] bgr (Optional) Fill the first plane with blue channel (default = true)
+ * @param[in] ppm_path Path to PPM file
+ * @param[in] preprocessor Preproccessor object
+ * @param[in] bgr (Optional) Fill the first plane with blue channel (default = true)
*
* @return An appropriate tensor accessor
*/
-inline std::unique_ptr<graph::ITensorAccessor> get_input_accessor(const std::string &ppm_path,
- float mean_r = 0.f, float mean_g = 0.f, float mean_b = 0.f,
- float std_r = 1.f, float std_g = 1.f, float std_b = 1.f,
- bool bgr = true)
+inline std::unique_ptr<graph::ITensorAccessor> get_input_accessor(const std::string &ppm_path,
+ std::unique_ptr<IPreprocessor> preprocessor = nullptr,
+ bool bgr = true)
{
if(ppm_path.empty())
{
@@ -248,9 +263,7 @@ inline std::unique_ptr<graph::ITensorAccessor> get_input_accessor(const std::str
}
else
{
- return arm_compute::support::cpp14::make_unique<PPMAccessor>(ppm_path, bgr,
- mean_r, mean_g, mean_b,
- std_r, std_g, std_b);
+ return arm_compute::support::cpp14::make_unique<PPMAccessor>(ppm_path, bgr, std::move(preprocessor));
}
}