33#include "tiny_dnn/util/util.h"
34#include "tiny_dnn/util/image.h"
35#include "tiny_dnn/layers/partial_connected_layer.h"
36#include "tiny_dnn/activations/activation_function.h"
41template <
typename Activation>
42void tiny_average_unpooling_kernel(
bool parallelize,
43 const std::vector<tensor_t*>& in_data,
44 std::vector<tensor_t*>& out_data,
45 const shape3d& out_dim,
47 std::vector<
typename partial_connected_layer<Activation>::wi_connections>& out2wi,
49 for (
size_t sample = 0; sample < in_data[0]->size(); sample++) {
50 const vec_t& in = (*in_data[0])[sample];
51 const vec_t& W = (*in_data[1])[0];
52 const vec_t& b = (*in_data[2])[0];
53 vec_t& out = (*out_data[0])[sample];
54 vec_t& a = (*out_data[1])[sample];
56 auto oarea = out_dim.area();
58 for (
size_t d = 0; d < out_dim.depth_; ++d) {
59 float_t weight = W[d];
61 for (
size_t i = 0; i < oarea; ++i, ++idx) {
62 const auto& connections = out2wi[idx];
63 float_t value = float_t(0);
64 for (
auto connection : connections)
65 value += in[connection.second];
72 assert(out.size() == out2wi.size());
73 for_i(parallelize, out2wi.size(), [&](
int i) {
80template<
typename Activation>
81void tiny_average_unpooling_back_kernel(
const std::vector<tensor_t*>& in_data,
82 const std::vector<tensor_t*>& out_data,
83 std::vector<tensor_t*>& out_grad,
84 std::vector<tensor_t*>& in_grad,
85 const shape3d& in_dim,
87 std::vector<
typename partial_connected_layer<Activation>::io_connections>& weight2io,
88 std::vector<
typename partial_connected_layer<Activation>::wo_connections>& in2wo,
89 std::vector<std::vector<serial_size_t>>& bias2out) {
91 for (
size_t sample = 0; sample < in_data[0]->size(); sample++) {
92 const vec_t& prev_out = (*in_data[0])[sample];
93 const vec_t& W = (*in_data[1])[0];
94 vec_t& dW = (*in_grad[1])[sample];
95 vec_t& db = (*in_grad[2])[sample];
96 vec_t& prev_delta = (*in_grad[0])[sample];
97 vec_t& curr_delta = (*out_grad[0])[sample];
99 auto inarea = in_dim.area();
101 for (
size_t i = 0; i < in_dim.depth_; ++i) {
102 float_t weight = W[i];
103 for (
size_t j = 0; j < inarea; ++j, ++idx) {
104 prev_delta[idx] = weight * curr_delta[in2wo[idx][0].second];
108 for (
size_t i = 0; i < weight2io.size(); ++i) {
109 const auto& connections = weight2io[i];
110 float_t diff = float_t(0);
112 for (
auto connection : connections)
113 diff += prev_out[connection.first] * curr_delta[connection.second];
118 for (
size_t i = 0; i < bias2out.size(); i++) {
119 const std::vector<serial_size_t>& outs = bias2out[i];
120 float_t diff = float_t(0);
123 diff += curr_delta[o];
133template<
typename Activation = activation::
identity>
137 CNN_USE_LAYER_MEMBERS;
185 std::vector<index3d<serial_size_t>>
in_shape()
const override {
189 std::vector<index3d<serial_size_t>>
out_shape()
const override {
190 return { out_, out_ };
193 std::string
layer_type()
const override {
return "ave-unpool"; }
196 std::vector<tensor_t*>&
out_data)
override {
210 const std::vector<tensor_t*>&
out_data,
212 std::vector<tensor_t*>&
in_grad)
override {
229 serial_size_t stride_;
234 static serial_size_t unpool_out_dim(serial_size_t
in_size,
240 void init_connection(serial_size_t pooling_size) {
241 for (serial_size_t c = 0; c < in_.depth_; ++c) {
242 for (serial_size_t y = 0; y < in_.height_; ++y) {
243 for (serial_size_t x = 0; x < in_.width_; ++x) {
244 connect_kernel(pooling_size, x, y, c);
249 for (serial_size_t c = 0; c < in_.depth_; ++c) {
250 for (serial_size_t y = 0; y < out_.height_; ++y) {
251 for (serial_size_t x = 0; x < out_.width_; ++x) {
252 this->connect_bias(c, out_.get_index(x, y, c));
258 void connect_kernel(serial_size_t pooling_size,
262 serial_size_t dymax = std::min(pooling_size, out_.height_ - y);
263 serial_size_t dxmax = std::min(pooling_size, out_.width_ - x);
264 serial_size_t dstx = x * stride_;
265 serial_size_t dsty = y * stride_;
266 serial_size_t inidx = in_.get_index(x, y, inc);
267 for (serial_size_t dy = 0; dy < dymax; ++dy) {
268 for (serial_size_t dx = 0; dx < dxmax; ++dx) {
269 this->connect_weight(
271 out_.get_index(dstx + dx, dsty + dy, inc),
average pooling with trainable weights
Definition average_unpooling_layer.h:134
std::vector< index3d< serial_size_t > > in_shape() const override
array of input shapes (width x height x depth)
Definition average_unpooling_layer.h:185
std::string layer_type() const override
name of layer, should be unique for each concrete class
Definition average_unpooling_layer.h:193
average_unpooling_layer(serial_size_t in_width, serial_size_t in_height, serial_size_t in_channels, serial_size_t pooling_size, serial_size_t stride)
Definition average_unpooling_layer.h:167
average_unpooling_layer(serial_size_t in_width, serial_size_t in_height, serial_size_t in_channels, serial_size_t pooling_size)
Definition average_unpooling_layer.h:145
std::vector< index3d< serial_size_t > > out_shape() const override
array of output shapes (width x height x depth)
Definition average_unpooling_layer.h:189
void forward_propagation(const std::vector< tensor_t * > &in_data, std::vector< tensor_t * > &out_data) override
Definition average_unpooling_layer.h:195
void back_propagation(const std::vector< tensor_t * > &in_data, const std::vector< tensor_t * > &out_data, std::vector< tensor_t * > &out_grad, std::vector< tensor_t * > &in_grad) override
return delta of previous layer (delta=\frac{dE}{da}, a=wx in fully-connected layer)
Definition average_unpooling_layer.h:209
Simple image utility class.
Definition image.h:94
serial_size_t in_size() const
!
Definition layer.h:176
bool parallelize_
Flag indicating whether the layer/node operations ara paralellized.
Definition layer.h:696
serial_size_t in_channels() const
number of outgoing edges in this layer
Definition layer.h:146
Definition partial_connected_layer.h:34