151 m_imageHeight = imageShape[0];
152 m_imageWidth = imageShape[1];
153 m_numChannels = imageShape[2];
154 m_numFilters = filterShape[0];
155 m_filterHeight = filterShape[1];
156 m_filterWidth = filterShape[2];
157 m_filters.resize(m_filterHeight * m_filterWidth * m_numFilters * m_numChannels);
158 m_offset.resize(m_numFilters);
159 updateBackpropFilters();
171 outputs.resize(inputs.size1(),
outputShape().numElements());
175 std::size_t paddingHeight = (m_type !=
Padding::Valid) ? m_filterHeight - 1: 0;
176 std::size_t paddingWidth = (m_type !=
Padding::Valid) ? m_filterWidth - 1: 0;
178 blas::kernels::conv2d(inputs, m_filters, outputs,
179 m_numChannels, m_numFilters,
180 m_imageHeight, m_imageWidth,
181 m_filterHeight, m_filterWidth,
182 paddingHeight, paddingWidth
185 auto reshapedOutputs = to_matrix(to_vector(outputs), outputsForFilter * inputs.size1(), m_numFilters);
186 noalias(reshapedOutputs ) += blas::repeat(m_offset,outputsForFilter * inputs.size1());
187 m_activation.evalInPlace(outputs, state.
toState<
typename ActivationFunction::State>());
199 SIZE_CHECK(coefficients.size1()==inputs.size1());
200 std::size_t n = inputs.size1();
204 m_activation.multiplyDerivative(outputs,delta, state.
toState<
typename ActivationFunction::State>());
207 auto weightGradient = subrange(gradient,0,m_filters.size());
208 auto offsetGradient = subrange(gradient, m_filters.size(),gradient.size());
210 std::size_t paddingHeight = (m_type !=
Padding::Valid) ? m_filterHeight - 1: 0;
211 std::size_t paddingWidth = (m_type !=
Padding::Valid) ? m_filterWidth - 1: 0;
215 auto delta_pixels = to_matrix(to_vector(delta), coefficients.size1() * coefficients.size2()/m_numFilters, m_numFilters);
216 noalias(offsetGradient) = sum(as_columns(delta_pixels));
225 BatchOutputType delta_CHWN(m_numFilters, outputHeight * outputWidth * n);
227 image::reorder<value_type, device_type>(
228 to_vector(delta), to_vector(delta_CHWN),
229 {n, outputHeight, outputWidth, m_numFilters},
232 image::reorder<value_type, device_type>(
233 to_vector(inputs), to_vector(inputs_CHWN),
234 {n, m_imageHeight, m_imageWidth, m_numChannels},
237 BatchInputType responses_CHWN(m_numChannels, m_filters.size() / m_numChannels);
238 blas::kernels::conv2d(inputs_CHWN, to_vector(delta_CHWN), responses_CHWN,
240 m_imageHeight, m_imageWidth,
241 outputHeight, outputWidth,
242 paddingHeight, paddingWidth
244 image::reorder<value_type, device_type>(
245 to_vector(responses_CHWN), weightGradient,
246 {m_numChannels, m_filterHeight, m_filterWidth, m_numFilters},
259 SIZE_CHECK(coefficients.size1() == inputs.size1());
262 m_activation.multiplyDerivative(outputs,delta, state.
toState<
typename ActivationFunction::State>());
264 std::size_t paddingHeight = m_filterHeight - 1;
265 std::size_t paddingWidth = m_filterWidth - 1;
270 derivatives.resize(inputs.size1(),
inputShape().numElements());
272 blas::kernels::conv2d(delta, m_backpropFilters, derivatives,
273 m_numFilters, m_numChannels,
275 m_filterHeight, m_filterWidth,
276 paddingHeight, paddingWidth
323 to_matrix(m_filters, m_numFilters, filterSize),
324 0, m_numFilters, c * filterImSize, (c+1) * filterImSize