MyCaffe  1.12.2.41
Deep learning software for Windows C# programmers.
PReLULayer.cs
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using MyCaffe.basecode;
6using MyCaffe.common;
7using MyCaffe.param;
8using MyCaffe.fillers;
9
10namespace MyCaffe.layers
11{
30 public class PReLULayer<T> : NeuronLayer<T>
31 {
32 bool m_bChannelShared;
33 Blob<T> m_blobMultiplier; // dot multiplier for backward computation of params.
34 Blob<T> m_blobBackwardBuff; // temporary buffer for backward computation.
35 Blob<T> m_blobBottomMemory; // memory for in-place computation.
36
37
50 : base(cuda, log, p)
51 {
53 m_blobMultiplier = new Blob<T>(cuda, log);
54 m_blobMultiplier.Name = m_param.name + " mult";
55 m_blobBackwardBuff = new Blob<T>(cuda, log);
56 m_blobBackwardBuff.Name = m_param.name + " backbuf";
57 m_blobBottomMemory = new Blob<T>(cuda, log);
58 m_blobBottomMemory.Name = m_param.name + " btmmem";
59 }
60
62 protected override void dispose()
63 {
64 m_blobBottomMemory.Dispose();
65 m_blobBackwardBuff.Dispose();
66 m_blobMultiplier.Dispose();
67
68 base.dispose();
69 }
70
72 protected override void setup_internal_blobs(BlobCollection<T> col)
73 {
74 if (col.Count > 0)
75 return;
76
77 col.Add(m_blobMultiplier);
78 col.Add(m_blobBackwardBuff);
79 col.Add(m_blobBottomMemory);
80 }
81
87 public override bool ReInitializeParameters(WEIGHT_TARGET target)
88 {
89 base.ReInitializeParameters(target);
90
91 if (target == WEIGHT_TARGET.BOTH || target == WEIGHT_TARGET.WEIGHTS)
92 {
94 if (fp == null)
95 fp = new FillerParameter("constant", 0.25);
96
97 Filler<T> filler = Filler<T>.Create(m_cuda, m_log, fp);
98 filler.Fill(m_colBlobs[0]);
99 }
100
101 return true;
102 }
103
109 public override void LayerSetUp(BlobCollection<T> colBottom, BlobCollection<T> colTop)
110 {
111 m_log.CHECK_GE(colBottom[0].num_axes, 2, "Number of axes of bottom must be >= 2");
113 int nChannels = colBottom[0].channels;
114
115 m_bChannelShared = p.channel_shared;
116
117 if (m_colBlobs.Count > 0)
118 {
119 m_log.WriteLine("Skipping parameter initialization.");
120 }
121 else
122 {
124
125 List<int> rgSlopeShape = new List<int>();
126 if (!m_bChannelShared)
127 rgSlopeShape.Add(nChannels);
128
129 Blob<T> blobSlope = new Blob<T>(m_cuda, m_log);
130 blobSlope.Name = m_param.name + " slope";
131 blobSlope.type = BLOB_TYPE.INTERNAL;
132
133 if (!shareParameter(blobSlope, rgSlopeShape))
134 {
135 blobSlope.Reshape(rgSlopeShape);
136 FillerParameter fp = p.filler;
137
138 if (fp == null)
139 fp = new FillerParameter("constant", 0.25);
140
141 Filler<T> filler = Filler<T>.Create(m_cuda, m_log, fp);
142 filler.Fill(blobSlope);
143 }
144 m_colBlobs.Add(blobSlope);
145 }
146
147 if (m_bChannelShared)
148 m_log.CHECK_EQ(m_colBlobs[0].count(), 1, "Negative slope size is inconsistent with prototxt config.");
149 else
150 m_log.CHECK_EQ(m_colBlobs[0].count(), nChannels, "Negative slope size is inconsistent with prototxt config.");
151
152 // Propagate gradients to the parameters (as directed by backward pass)
153 m_rgbParamPropagateDown = new DictionaryMap<bool>(m_colBlobs.Count, true);
154
155 List<int> rgShape = new List<int>() { colBottom[0].count(1) };
156
157 m_blobMultiplier.Reshape(rgShape);
158 m_blobBackwardBuff.Reshape(rgShape);
159 m_blobMultiplier.SetData(1.0);
160 }
161
167 public override void Reshape(BlobCollection<T> colBottom, BlobCollection<T> colTop)
168 {
169 if (!reshapeNeeded(colBottom, colTop))
170 return;
171
172 m_log.CHECK_GE(colBottom[0].num_axes, 2, "Number of axes of bottom blob must be >= 2.");
173 colTop[0].ReshapeLike(colBottom[0]);
174
175 if (colBottom[0] == colTop[0])
176 {
177 // For in-place computation.
178 m_blobBottomMemory.ReshapeLike(colBottom[0]);
179 }
180 }
181
196 protected override void forward(BlobCollection<T> colBottom, BlobCollection<T> colTop)
197 {
198 long hBottomData = colBottom[0].gpu_data;
199 long hTopData = colTop[0].mutable_gpu_data;
200 int nCount = colBottom[0].count();
201 int nDim = colBottom[0].count(2);
202 int nChannels = colBottom[0].channels;
203 long hSlopeData = m_colBlobs[0].gpu_data;
204 int nDivFactor = m_bChannelShared ? nChannels : 1;
205
206 if (colTop[0] == colBottom[0])
207 m_cuda.copy(nCount, hBottomData, m_blobBottomMemory.mutable_gpu_data);
208
209 m_cuda.prelu_fwd(nCount, nChannels, nDim, hBottomData, hTopData, hSlopeData, nDivFactor);
210 }
211
245 protected override void backward(BlobCollection<T> colTop, List<bool> rgbPropagateDown, BlobCollection<T> colBottom)
246 {
247 long hBottomData = colBottom[0].gpu_data;
248 long hTopDiff = colTop[0].gpu_diff;
249 int nCount = colBottom[0].count();
250 int nDim = colBottom[0].count(2);
251 int nChannels = colBottom[0].channels;
252
253 // for In-place computation
254 if (colTop[0] == colBottom[0])
255 hBottomData = m_blobBottomMemory.gpu_data;
256
257 // Propagate to param
258 // Since to write bottom diff will affect top diff if top and bottom blobs
259 // are identical (in-place computation), we first compute param backward to
260 // keep top_diff unchanged.
262 {
263 long hSlopeDiff = m_colBlobs[0].mutable_gpu_diff;
264 int nCDim = nChannels * nDim;
265
266 m_cuda.prelu_bwd_param(nCDim, colBottom[0].num, colTop[0].offset(1), hTopDiff, hBottomData, m_blobBackwardBuff.mutable_gpu_diff);
267
268 if (m_bChannelShared)
269 {
270 T dfSum = m_cuda.dot(nCDim, m_blobBackwardBuff.gpu_diff, m_blobMultiplier.gpu_data);
271 m_cuda.add_scalar(m_colBlobs[0].count(), dfSum, hSlopeDiff);
272 }
273 else
274 {
275 m_cuda.gemv(false, nChannels, nDim, m_tOne, m_blobBackwardBuff.gpu_diff, m_blobMultiplier.gpu_data, m_tOne, hSlopeDiff);
276 }
277 }
278
279 // Propagate to bottom
280 if (rgbPropagateDown[0])
281 {
282 long hBottomDiff = colBottom[0].mutable_gpu_diff;
283 long hSlopeData = m_colBlobs[0].gpu_data;
284 int nDivFactor = m_bChannelShared ? nChannels : 1;
285
286 m_cuda.prelu_bwd(nCount, nChannels, nDim, hTopDiff, hBottomData, hBottomDiff, hSlopeData, nDivFactor);
287 }
288 }
289 }
290}
The Log class provides general output in text form.
Definition: Log.cs:13
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_GE(double df1, double df2, string str)
Test whether one number is greater than or equal to another.
Definition: Log.cs:287
The BlobCollection contains a list of Blobs.
void Add(Blob< T > b)
Add a new Blob to the collection.
int Count
Returns the number of items in the collection.
void ReshapeLike(BlobCollection< T > src)
Reshapes all blobs in the collection to the sizes of the source.
The Blob is the main holder of data that moves through the Layers of the Net.
Definition: Blob.cs:25
void SetData(T[] rgData, int nCount=-1, bool bSetCount=true)
Sets a number of items within the Blob's data.
Definition: Blob.cs:1922
long mutable_gpu_diff
Returns the diff GPU handle used by the CudaDnn connection.
Definition: Blob.cs:1555
long mutable_gpu_data
Returns the data GPU handle used by the CudaDnn connection.
Definition: Blob.cs:1487
void Reshape(int nNum, int nChannels, int nHeight, int nWidth, bool? bUseHalfSize=null)
DEPRECIATED; use
Definition: Blob.cs:442
BLOB_TYPE type
Returns the BLOB_TYPE of the Blob.
Definition: Blob.cs:2761
void ReshapeLike(Blob< T > b, bool? bUseHalfSize=null)
Reshape this Blob to have the same shape as another Blob.
Definition: Blob.cs:648
string Name
Get/set the name of the Blob.
Definition: Blob.cs:2184
long gpu_diff
Returns the diff GPU handle used by the CudaDnn connection.
Definition: Blob.cs:1541
virtual void Dispose(bool bDisposing)
Releases all resources used by the Blob (including both GPU and Host).
Definition: Blob.cs:402
long gpu_data
Returns the data GPU handle used by the CudaDnn connection.
Definition: Blob.cs:1479
The CudaDnn object is the main interface to the Low-Level Cuda C++ DLL.
Definition: CudaDnn.cs:969
Abstract Filler class used to fill blobs with values.
Definition: Filler.cs:19
void Fill(Blob< T > b)
Fill the blob with values based on the actual filler used.
Definition: Filler.cs:50
static Filler< T > Create(CudaDnn< T > cuda, Log log, FillerParameter p)
Create a new Filler instance.
Definition: Filler.cs:79
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
T m_tOne
Specifies a generic type equal to 1.0.
Definition: Layer.cs:72
bool shareParameter(Blob< T > b, List< int > rgMinShape, bool bAllowEndsWithComparison=false)
Attempts to share a parameter Blob if another parameter Blob with the same name and accpetable size i...
Definition: Layer.cs:1152
virtual bool reshapeNeeded(BlobCollection< T > colBottom, BlobCollection< T > colTop, bool bReset=true)
Tests the shapes of both the bottom and top blobs and if they are the same as the previous sizing,...
Definition: Layer.cs:622
CudaDnn< T > m_cuda
Specifies the CudaDnn connection to Cuda.
Definition: Layer.cs:39
LayerParameter.LayerType m_type
Specifies the Layer type.
Definition: Layer.cs:35
BlobCollection< T > m_colBlobs
Specifies the learnable parameter Blobs of the Layer.
Definition: Layer.cs:55
DictionaryMap< bool > m_rgbParamPropagateDown
Specifies whether or not to compute the learnable diff of each parameter Blob.
Definition: Layer.cs:63
The NeuronLayer is an interface for layers that take one blob as input (x) and produce only equally-s...
Definition: NeuronLayer.cs:22
The PReLULayer computes the "Parameterized Rectified Linear Unit" non-linearity. This layer is initia...
Definition: PReLULayer.cs:31
override bool ReInitializeParameters(WEIGHT_TARGET target)
Re-initialize the parameters of the layer.
Definition: PReLULayer.cs:87
override void setup_internal_blobs(BlobCollection< T > col)
Derivative layers should add all internal blobws to the 'col' provided.
Definition: PReLULayer.cs:72
override void forward(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Forward operation
Definition: PReLULayer.cs:196
override void backward(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Computes the error gradient w.r.t. the PReLU inputs.
Definition: PReLULayer.cs:245
override void Reshape(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Reshape the bottom (input) and top (output) blobs.
Definition: PReLULayer.cs:167
override void LayerSetUp(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Setup the layer.
Definition: PReLULayer.cs:109
PReLULayer(CudaDnn< T > cuda, Log log, LayerParameter p)
The PReLULayer constructor.
Definition: PReLULayer.cs:49
override void dispose()
Releases all GPU and host resources used by the Layer.
Definition: PReLULayer.cs:62
Specifies the filler parameters used to create each Filler.
Specifies the base parameter for all layers.
string name
Specifies the name of this LayerParameter.
LayerType
Specifies the layer type.
PReLUParameter prelu_param
Returns the parameter set when initialized with LayerType.PRELU
Specifies the parameters for the PReLULayer.
bool channel_shared
Specifies whether or not slope parameters are shared across channels.
FillerParameter filler
Specifies initial value of . Default is for all i.
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
BLOB_TYPE
Defines the tpe of data held by a given Blob.
Definition: Interfaces.cs:62
WEIGHT_TARGET
Defines the type of weight to target in re-initializations.
Definition: Interfaces.cs:38
The MyCaffe.fillers namespace contains all fillers including the Filler class.
The MyCaffe.layers namespace contains all layers that have a solidified code base,...
Definition: LayerFactory.cs:15
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