-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPoolLayers.cpp
154 lines (134 loc) · 4.84 KB
/
PoolLayers.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//
// PoolLayers.cpp
// ConvNet
//
// Created by Márton Szemenyei on 2017. 09. 28..
// Copyright © 2017. Márton Szemenyei. All rights reserved.
//
#include "PoolLayers.h"
#include "Utils.h"
#include "BLAS.h"
#include <cfloat>
MaxPoolLayer::MaxPoolLayer(int32_t _h, int32_t _w, int32_t _outCh, Tuple _size, Tuple _stride, ACTIVATION _activation)
{
// Setup parameters
type = MAXPOOL;
inH = _h;
inW = _w;
inCh = _outCh;
stride = _stride;
size = _size;
outW = inW/stride.x;
outH = inH/stride.y;
outCh = _outCh;
outputs = new float [outH*outW*outCh];
activation = _activation;
cropRows = 0;
}
MaxPoolLayer::~MaxPoolLayer()
{
delete [] outputs;
}
void MaxPoolLayer::forward()
{
if (inputs)
{
int32_t currInH = inH - cropRows;
int32_t currOutH = outH - getNextCropRows();
int32_t w_offset = 0;
int32_t h_offset = 0;
// Go through all output elements
for(int32_t k = 0; k < outCh; ++k){
for(int32_t i = 0; i < currOutH; ++i){
for(int32_t j = 0; j < outW; ++j){
// Get the max value amongts the input pixels
int32_t out_index = j + outW*(i + currOutH*k);
float max = -FLT_MAX;
for(int32_t n = 0; n < size.y; ++n){
for(int32_t m = 0; m < size.x; ++m){
int32_t cur_h = h_offset + i*stride.y + n;
int32_t cur_w = w_offset + j*stride.x + m;
int32_t index = cur_w + inW*(cur_h + currInH*k);
bool valid = (cur_h < currInH && cur_w < inW);
float val = valid ? inputs[index] : -FLT_MAX;
max = (val > max) ? val : max;
}
}
outputs[out_index] = max;
}
}
}
// Activate output
activate(outputs, currOutH*outW*outCh, activation);
}
}
void MaxPoolLayer::print()
{
#ifndef NN_SILENT
// Print layer parameters aligned
std::cout << "Max Pooling:" << std::setw(8) << "(" << std::setw(3) << inCh << " x " << std::setw(3) << inW << " x " << std::setw(3) << inH << ")->(" << std::setw(3) << outCh << " x " << std::setw(3) << outW << " x " << std::setw(3) << outH << ") Size: (" << size.x << "x" << size.y << ")" << std::setw(8) << " -> " << act2string(activation) << std::endl;
#endif
}
AvgPoolLayer::AvgPoolLayer(int32_t _h, int32_t _w, int32_t _outCh, Tuple _size, Tuple _stride, ACTIVATION _activation)
{
// Setup parameters
type = AVGPOOL;
inH = _h;
inW = _w;
inCh = _outCh;
stride = _stride;
size = _size;
outW = inW/stride.x;
outH = inH/stride.y;
outCh = _outCh;
outputs = new float [outH*outW*outCh];
activation = _activation;
cropRows = 0;
}
AvgPoolLayer::~AvgPoolLayer()
{
delete [] outputs;
}
void AvgPoolLayer::forward()
{
if (inputs)
{
int32_t currInH = inH - cropRows;
int32_t currOutH = outH - getNextCropRows();
int32_t w_offset = 0;
int32_t h_offset = 0;
// Compute averaging denominator
float denum = 1.f/(size.x*size.y);
// Fill output with 0
fill(getN(), 0.f, outputs);
// Go through all output elements
for(int32_t k = 0; k < outCh; ++k){
for(int32_t i = 0; i < currOutH; ++i){
for(int32_t j = 0; j < outW; ++j){
// Sum input elements
int32_t out_index = j + outW*(i + currOutH*k);
for(int32_t n = 0; n < size.y; ++n){
for(int32_t m = 0; m < size.x; ++m){
int32_t cur_h = h_offset + i*stride.y + n;
int32_t cur_w = w_offset + j*stride.x + m;
int32_t index = cur_w + inW*(cur_h + currInH*k);
if (cur_h < currInH && cur_w < inW)
outputs[out_index] += inputs[index];
}
}
// Get average
outputs[out_index] *= denum;
}
}
}
// Activate output
activate(outputs, currOutH*outW*outCh, activation);
}
}
void AvgPoolLayer::print()
{
#ifndef NN_SILENT
// Print layer parameters aligned
std::cout << "Avg Pooling:" << std::setw(8) << "(" << std::setw(3) << inCh << " x " << std::setw(3) << inW << " x " << std::setw(3) << inH << ")->(" << std::setw(3) << outCh << " x " << std::setw(3) << outW << " x " << std::setw(3) << outH << ") Size: (" << size.x << "x" << size.y << ")" << std::setw(8) << " -> " << act2string(activation) << std::endl;
#endif
}