ResizeLayer.h
Go to the documentation of this file.
1/*!
2 *
3 *
4 * \brief Implements a model applying a convolution to an image
5 *
6 *
7 *
8 * \author
9 * \date 2017
10 *
11 *
12 * \par Copyright 1995-2017 Shark Development Team
13 *
14 * <BR><HR>
15 * This file is part of Shark.
16 * <https://shark-ml.github.io/Shark/>
17 *
18 * Shark is free software: you can redistribute it and/or modify
19 * it under the terms of the GNU Lesser General Public License as published
20 * by the Free Software Foundation, either version 3 of the License, or
21 * (at your option) any later version.
22 *
23 * Shark is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU Lesser General Public License for more details.
27 *
28 * You should have received a copy of the GNU Lesser General Public License
29 * along with Shark. If not, see <http://www.gnu.org/licenses/>.
30 *
31 */
32#ifndef SHARK_MODELS_RESIZE_LAYER_H
33#define SHARK_MODELS_RESIZE_LAYER_H
34
38namespace shark {
39
40
41
42
43
44
45///
46/// \brief Resizes an input image to a given size
47///
48/// \par
49/// The image is resized using an interpolation algorithm which can be chosen by the user. Right now,
50/// only spline interpolation is supported. This will slightly smooth input images
51/// over a 4x4 grid. This also means that resizing to the same size is not an identity operation
52///
53/// The derivative of the model wrt its input images is available.
54///
55/// \ingroup models
56template <class VectorType = RealVector>
57class ResizeLayer : public AbstractModel<VectorType,VectorType,VectorType>{
58private:
59 typedef typename VectorType::value_type value_type;
60 typedef typename VectorType::device_type device_type;
61 typedef blas::matrix<value_type, blas::row_major, device_type> MatrixType;
63 static_assert(!std::is_same<typename VectorType::storage_type::storage_tag, blas::dense_tag>::value, "Resizing not supported for sparse inputs");
64public:
68
69 /// Default Constructor; use setStructure later.
74
75 ///\brief Configures the model.
76 ///
77 /// \arg inputShape Shape of the image imHeight x imWidth x channel
78 /// \arg outputShape Shape of the resized output imHeight x imWidth
79 /// \arg type Type of interpolation to perform, default is Spline-Interpolation
87
88 std::string name() const
89 { return "ResizeLayer"; }
90
91 ///\brief Returns the expected shape of the input
93 return m_inputShape;
94 }
95 ///\brief Returns the shape of the output
97 return m_outputShape;
98 }
99
100 /// \brief Obtain the parameter vector.
104
105 /// \brief Set the new parameters of the model.
106 void setParameterVector(ParameterVectorType const& newParameters){}
107
108 /// \brief Return the number of parameters.
109 size_t numberOfParameters() const{
110 return 0;
111 }
112
113 ///\brief Configures the model.
114 ///
115 /// \arg inputShape Shape of the image imHeight x imWidth x channel
116 /// \arg outputShape Shape of the resized output imHeight x imWidth
117 /// \arg type Type of interpolation to perform, default is Spline-Interpolation
120 ){
121 m_type = type;
122 m_inputShape = inputShape;
123 m_outputShape = {outputShape[0], outputShape[1], inputShape[2]};
124 //compute pixel coordinates by evenly spreading them out on the image
125 blas::matrix<value_type> points(outputShape[0] * outputShape[1], 2);
126 for(std::size_t i = 0; i != outputShape[1]; ++i){
127 for(std::size_t j = 0; j != outputShape[0]; ++j){
128 points(i * outputShape[0] +j, 0) = value_type(i) / outputShape[1];
129 points(i * outputShape[0] +j, 1) = value_type(j) / outputShape[0];
130 }
131 }
132
133 m_points = copy_to_device(points, device_type());
134 }
135
136 boost::shared_ptr<State> createState()const{
137 return boost::shared_ptr<State>(new EmptyState());
138 }
139
140 using base_type::eval;
141
142 /// Evaluate the model
143 void eval(BatchInputType const& inputs, BatchOutputType& outputs, State&)const{
144 SIZE_CHECK(inputs.size2() == m_inputShape.numElements());
145 outputs.resize(inputs.size1(), m_outputShape.numElements());
146 imageInterpolate2D<value_type, device_type>(
147 inputs, m_inputShape, m_type,
148 m_points, m_points.size1(),
149 outputs
150 );
151 }
152
153 ///\brief Calculates the first derivative w.r.t the parameters and summing them up over all inputs of the last computed batch
155 BatchInputType const& inputs,
156 BatchOutputType const& outputs,
157 BatchOutputType const& coefficients,
158 State const& state,
159 ParameterVectorType& gradient
160 )const{}
161 ///\brief Calculates the first derivative w.r.t the inputs and summs them up over all inputs of the last computed batch
163 BatchInputType const & inputs,
164 BatchOutputType const& outputs,
165 BatchOutputType const & coefficients,
166 State const& state,
167 BatchInputType& derivatives
168 )const{
169 SIZE_CHECK(inputs.size2() == m_inputShape.numElements());
170 SIZE_CHECK(outputs.size2() == m_outputShape.numElements());
171 SIZE_CHECK(coefficients.size2() == outputs.size2());
172 SIZE_CHECK(coefficients.size1() == inputs.size1());
173 SIZE_CHECK(outputs.size1() == inputs.size1());
174
175 derivatives.resize(inputs.size1(), m_inputShape.numElements());
176 weightedImageInterpolate2DDerivative<value_type, device_type>(
177 inputs, m_inputShape, m_type,
178 coefficients,
179 m_points, m_points.size1(),
180 derivatives
181 );
182 }
183
184 /// From ISerializable
185 void read(InArchive& archive){
186 archive >> m_points;
187 archive >> (int&)m_type;
188 archive >> m_inputShape;
189 archive >> m_outputShape;
190 }
191 /// From ISerializable
192 void write(OutArchive& archive) const{
193 archive << m_points;
194 archive << (int&)m_type;
195 archive << m_inputShape;
196 archive << m_outputShape;
197 }
198
199private:
200 Interpolation m_type;
201 MatrixType m_points;
202 Shape m_inputShape;
203 Shape m_outputShape;
204};
205
206
207}
208#endif