MyCaffe  1.12.2.41
Deep learning software for Windows C# programmers.
UnPoolingLayer1.cs
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using MyCaffe.common;
6using MyCaffe.param;
7using MyCaffe.basecode;
8using System.Drawing;
9using MyCaffe.param.beta;
10
11namespace MyCaffe.layers.beta
12{
28 public class UnPoolingLayer1<T> : Layer<T>
29 {
30 int m_nKernelH;
31 int m_nKernelW;
32 int m_nStrideH;
33 int m_nStrideW;
34 int m_nPadH;
35 int m_nPadW;
36 int m_nChannels;
37 int m_nHeight;
38 int m_nWidth;
39 int m_nUnPooledHeight;
40 int m_nUnPooledWidth;
41 bool m_bGlobalPooling;
42
72 : base(cuda, log, p)
73 {
74 m_type = LayerParameter.LayerType.UNPOOLING1;
75 }
76
77
79 protected override void dispose()
80 {
81 base.dispose();
82 }
83
87 public override int MinBottomBlobs
88 {
89 get { return 1; }
90 }
91
95 public override int MaxBottomBlobs
96 {
97 get { return (m_param.unpooling_param.pool == PoolingParameter.PoolingMethod.MAX) ? 2 : 1; }
98 }
99
103 public override int ExactNumTopBlobs
104 {
105 get { return 1; }
106 }
107
113 public override void LayerSetUp(BlobCollection<T> colBottom, BlobCollection<T> colTop)
114 {
116
117 if (p.global_pooling)
118 {
119 m_log.CHECK(!(p.kernel_size.Count > 0 || p.kernel_h.HasValue || p.kernel_w.HasValue), "With global pooling = true, Filter size cannot be specified.");
120 }
121 else
122 {
123 m_log.CHECK(!(p.kernel_size.Count > 0) != !(p.kernel_h.HasValue && p.kernel_w.HasValue), "Filter size is kernel_size OR kernel_h and kernel_w; not both.");
124 m_log.CHECK(p.kernel_size.Count > 0 || (p.kernel_h.HasValue && p.kernel_w.HasValue), "For non-square filters, both kernel_h and kernel_w are required.");
125 }
126
127 m_log.CHECK(((p.pad.Count > 0) && p.pad_h.HasValue && p.pad_w.HasValue) || (!p.pad_h.HasValue && !p.pad_w.HasValue), "Pad is pad or pad_h and pad_w are required.");
128 m_log.CHECK(((p.stride.Count > 0) && p.stride_h.HasValue && p.stride_w.HasValue) || (!p.stride_h.HasValue && !p.stride_w.HasValue), "Stride is stride or stride_h and stride_w are required.");
129 m_bGlobalPooling = p.global_pooling;
130
131
132 //---- Kernel Size ----
133
134 if (m_bGlobalPooling)
135 {
136 m_nKernelH = colBottom[0].height;
137 m_nKernelW = colBottom[0].width;
138 }
139 else
140 {
141 if (p.kernel_size.Count > 0)
142 {
143 m_nKernelH = (int)p.kernel_size[0];
144 m_nKernelW = (int)p.kernel_size[0];
145 }
146 else
147 {
148 m_nKernelH = (int)p.kernel_h.Value;
149 m_nKernelW = (int)p.kernel_w.Value;
150 }
151 }
152
153 m_log.CHECK_GT(m_nKernelH, 0, "Filter dimensions cannot be zero.");
154 m_log.CHECK_GT(m_nKernelW, 0, "Filter dimensions cannot be zero.");
155
156
157 //---- Pad ----
158
159 if (p.pad.Count > 0)
160 {
161 m_nPadH = (int)p.pad[0];
162 m_nPadW = (int)p.pad[0];
163 }
164 else
165 {
166 m_nPadH = (p.pad_h.HasValue) ? (int)p.pad_h.Value : 0;
167 m_nPadW = (p.pad_w.HasValue) ? (int)p.pad_w.Value : 0;
168 }
169
170
171 //---- Stride ----
172
173 if (p.stride.Count > 0)
174 {
175 m_nStrideH = (int)p.stride[0];
176 m_nStrideW = (int)p.stride[0];
177 }
178 else
179 {
180 m_nStrideH = (p.stride_h.HasValue) ? (int)p.stride_h.Value : 1;
181 m_nStrideW = (p.stride_w.HasValue) ? (int)p.stride_w.Value : 1;
182 }
183
184 if (m_bGlobalPooling)
185 m_log.CHECK(m_nPadH == 0 && m_nPadW == 0 && m_nStrideH == 1 && m_nStrideW == 1, "With global pooling = true, only pad = 0 and stride = 1 allowed.");
186
187 if (m_nPadH != 0 || m_nPadW != 0)
188 {
190 m_param.unpooling_param.pool == PoolingParameter.PoolingMethod.MAX, "Padding implemented for AVE and MAX pooling only.");
191 m_log.CHECK_LT(m_nPadH, m_nKernelH, "The pad_h must be <= kernel_h.");
192 m_log.CHECK_LT(m_nPadW, m_nKernelW, "The pad_w must be <= kernel_w.");
193 }
194 }
195
201 public override void Reshape(BlobCollection<T> colBottom, BlobCollection<T> colTop)
202 {
203 m_log.CHECK_EQ(4, colBottom[0].num_axes, "Input must have 4 axes, corresponding to (num, channels, height, width)");
204
205 m_nChannels = colBottom[0].channels;
206 m_nHeight = colBottom[0].height;
207 m_nWidth = colBottom[0].width;
208
209 if (m_bGlobalPooling)
210 {
211 m_nKernelH = colBottom[0].height;
212 m_nKernelW = colBottom[0].width;
213 }
214
215 // Given the original pooling calculation:
216 // (int)Math.Ceiling((double)((nOriginalHeight + 2 * m_nPadH - m_nKernelH) / (double)m_nStrideH)) + 1;
217 // we do not know whether or not the ceiling kicks in for at the unpooling
218 // stage, we do not know the original height. For this reason, the unpooled
219 // height will always be >= the original height.
220 // Using the sizing method from HyeonwooNoh at
221 // https://github.com/HyeonwooNoh/caffe/blob/master/src/caffe/layers/unpooling_layer.cpp
222 m_nUnPooledHeight = Math.Max((m_nHeight - 1) * m_nStrideH + m_nKernelH - 2 * m_nPadH,
223 m_nHeight * m_nStrideH - m_nPadH + 1);
224 m_nUnPooledWidth = Math.Max((m_nWidth - 1) * m_nStrideW + m_nKernelW - 2 * m_nPadW,
225 m_nWidth * m_nStrideW - m_nPadW + 1);
226
227 if (m_nUnPooledHeight <= 0)
228 {
229 m_nUnPooledHeight = 1;
230 m_log.WriteLine("WARNING: unpooling height was 0, setting to 1.");
231 }
232
233 if (m_nUnPooledWidth <= 0)
234 {
235 m_nUnPooledWidth = 1;
236 m_log.WriteLine("WARNING: unpooling width was 0, setting to 1.");
237 }
238
239 colTop[0].Reshape(colBottom[0].num, m_nChannels, m_nUnPooledHeight, m_nUnPooledWidth);
240 }
241
247 protected override void forward(BlobCollection<T> colBottom, BlobCollection<T> colTop)
248 {
249 // Init the top blob to be all zeros since only special places
250 // wouldn't be zero then.
251 colTop[0].SetData(0);
252
253 T[] bottom_data = colBottom[0].update_cpu_data();
254 T[] mask = null;
255
256 if (colBottom.Count > 1)
257 mask = colBottom[1].update_cpu_data();
258
259 T[] top_data = colTop[0].mutable_cpu_data;
260 int nBottomDataOffset = 0;
261 int nTopDataOffset = 0;
262 int nMaskOffset = 0;
263
265 {
267 // Currently only the CPU version is supported
268 for (int n = 0; n < colBottom[0].num; n++)
269 {
270 for (int c = 0; c < m_nChannels; c++)
271 {
272 for (int ph = 0; ph < m_nHeight; ph++)
273 {
274 for (int pw = 0; pw < m_nWidth; pw++)
275 {
276 int nIdx = ph * m_nWidth + pw;
277 int nTopIdx = nIdx;
278
279#warning TODO: Bug - nMaskOffset + nIdx exceed length on last row of mask.
280 if (mask != null && nMaskOffset + nIdx < mask.Length)
281 nTopIdx = (int)Convert.ChangeType(mask[nMaskOffset + nIdx], typeof(int));
282
283#warning TODO: Bug - nTopDataOffset + nTopIdx exceed length on last row of data.
284 if (nTopDataOffset + nTopIdx < top_data.Length)
285 top_data[nTopDataOffset + nTopIdx] = bottom_data[nBottomDataOffset + nIdx];
286 }
287 }
288
289 // switch to the next channel.
290 nTopDataOffset += colTop[0].offset(0, 1);
291 nBottomDataOffset += colBottom[0].offset(0, 1);
292 nMaskOffset += colBottom[0].offset(0, 1);
293 }
294 }
295 colTop[0].mutable_cpu_data = top_data;
296 break;
297
299 throw new NotImplementedException("Unpooling is only supported on the MAX type of pooling.");
300
301 case PoolingParameter.PoolingMethod.STOCHASTIC:
302 throw new NotImplementedException("Unpooling is only supported on the MAX type of pooling.");
303 }
304 }
305
307 protected override void backward(BlobCollection<T> colTop, List<bool> rgbPropagateDown, BlobCollection<T> colBottom)
308 {
309 throw new NotImplementedException("UnPooling does not support the backward operation.");
310 }
311 }
312}
The Log class provides general output in text form.
Definition: Log.cs:13
void CHECK(bool b, string str)
Test a flag for true.
Definition: Log.cs:227
void WriteLine(string str, bool bOverrideEnabled=false, bool bHeader=false, bool bError=false, bool bDisable=false)
Write a line of output.
Definition: Log.cs:80
void CHECK_EQ(double df1, double df2, string str)
Test whether one number is equal to another.
Definition: Log.cs:239
void CHECK_GT(double df1, double df2, string str)
Test whether one number is greater than another.
Definition: Log.cs:299
void CHECK_LT(double df1, double df2, string str)
Test whether one number is less than another.
Definition: Log.cs:275
The BlobCollection contains a list of Blobs.
void SetData(double df)
Set all blob data to the value specified.
int Count
Returns the number of items in the collection.
void Reshape(int[] rgShape)
Reshapes all blobs in the collection to the given shape.
The CudaDnn object is the main interface to the Low-Level Cuda C++ DLL.
Definition: CudaDnn.cs:969
An interface for the units of computation which can be composed into a Net.
Definition: Layer.cs:31
Log m_log
Specifies the Log for output.
Definition: Layer.cs:43
LayerParameter m_param
Specifies the LayerParameter describing the Layer.
Definition: Layer.cs:47
LayerParameter.LayerType m_type
Specifies the Layer type.
Definition: Layer.cs:35
override int ExactNumTopBlobs
Returns the required number of top (output) Blobs: input
override int MinBottomBlobs
Returns the minimum number of required bottom (input) Blobs: input
override void dispose()
Releases all GPU and host resources used by the Layer.
UnPoolingLayer1(CudaDnn< T > cuda, Log log, LayerParameter p)
The UnPoolingLayer1 constructor.
override void LayerSetUp(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Setup the layer for use with both Engine.CAFFE and Engine.CUDNN modes.
override void forward(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Run the Forward computation using the Engine.CAFFE mode only.
override int? MaxBottomBlobs
Returns the maximum number of required bottom (input) Blobs: input, mask (only when using MAX)
override void Reshape(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Reshape the bottom (input) and top (output) blobs.
override void backward(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Currently, not implemented.
uint? stride_h
The stride height (2D only)
List< uint > kernel_size
Kernel size is given as a single value for equal dimensions in all spatial dimensions,...
uint? stride_w
The stride width (2D only)
uint? pad_h
The padding height (2D only)
uint? kernel_h
The kernel height (2D only)
List< uint > stride
Stride is given as a single value for equal dimensions in all spatial dimensions, or once per spatial...
uint? kernel_w
The kernel width (2D only)
uint? pad_w
The padding width (2D only)
List< uint > pad
Pad is given as a single value for equal dimensions in all spatial dimensions, or once per spatial di...
Specifies the base parameter for all layers.
UnPoolingParameter unpooling_param
Returns the parameter set when initialized with LayerType.UNPOOLING
LayerType
Specifies the layer type.
Specifies the parameters for the PoolingLayer.
PoolingMethod
Defines the pooling method.
PoolingMethod pool
Specifies the pooling method.
bool global_pooling
Specifies whether or not to enable global pooling.
Specifies the parameters for the UnPoolingLayer.
The MyCaffe.basecode contains all generic types used throughout MyCaffe.
Definition: Annotation.cs:12
The MyCaffe.common namespace contains common MyCaffe classes.
Definition: BatchInput.cs:8
The MyCaffe.layers.beta namespace contains all beta stage layers.
Definition: LayerFactory.cs:9
The MyCaffe.param.beta parameters are used by the MyCaffe.layer.beta layers.
The MyCaffe.param namespace contains parameters used to create models.
The MyCaffe namespace contains the main body of MyCaffe code that closesly tracks the C++ Caffe open-...
Definition: Annotation.cs:12