2using System.Collections.Generic;
25 Blob<T> m_blobSumChannelMultiplier;
26 Blob<T> m_blobSumSpatialMultiplier;
30 bool m_bAcrossSpatial;
31 bool m_bChannelShared;
50 m_blobNorm =
new Blob<T>(cuda, log,
false);
52 m_blobSumChannelMultiplier =
new Blob<T>(cuda, log,
false);
54 m_blobSumSpatialMultiplier =
new Blob<T>(cuda, log,
false);
56 m_blobBuffer =
new Blob<T>(cuda, log,
false);
58 m_blobBufferChannel =
new Blob<T>(cuda, log,
false);
60 m_blobBufferSpatial =
new Blob<T>(cuda, log,
false);
68 m_blobSumChannelMultiplier.
Dispose();
69 m_blobSumSpatialMultiplier.
Dispose();
83 col.
Add(m_blobSumChannelMultiplier);
84 col.
Add(m_blobSumSpatialMultiplier);
85 col.
Add(m_blobBuffer);
86 col.
Add(m_blobBufferChannel);
87 col.
Add(m_blobBufferSpatial);
113 m_log.
CHECK_GE(colBottom[0].num_axes, 2,
"The bottom(0) must have >= 2 axes.");
114 m_blobBuffer.
Reshape(1, colBottom[0].channels, colBottom[0].height, colBottom[0].width);
115 m_blobBufferChannel.
Reshape(1, colBottom[0].channels, 1, 1);
116 m_blobBufferSpatial.
Reshape(1, 1, colBottom[0].height, colBottom[0].width);
121 if (m_bAcrossSpatial)
122 m_blobNorm.Reshape(colBottom[0].num, 1, 1, 1);
124 m_blobNorm.Reshape(colBottom[0].num, 1, colBottom[0].height, colBottom[0].width);
126 m_fEps = norm_param.
eps;
128 int nChannels = colBottom[0].channels;
129 int nSpatialDim = colBottom[0].width * colBottom[0].height;
131 m_blobSumChannelMultiplier.
Reshape(1, nChannels, 1, 1);
132 m_blobSumChannelMultiplier.
SetData(1);
134 m_blobSumSpatialMultiplier.
Reshape(1, 1, colBottom[0].height, colBottom[0].width);
135 m_blobSumSpatialMultiplier.
SetData(1);
147 List<int> rgShape =
new List<int>();
149 if (!m_bChannelShared)
150 rgShape.Add(nChannels);
154 filler.
Fill(blobScale);
159 if (m_bChannelShared)
174 m_log.
CHECK_GE(colBottom[0].num_axes, 2,
"Number of axes of bottom blob must be >= 2.");
176 m_blobBuffer.
Reshape(1, colBottom[0].channels, colBottom[0].height, colBottom[0].width);
178 if (!m_bAcrossSpatial)
179 m_blobNorm.Reshape(colBottom[0].num, 1, colBottom[0].height, colBottom[0].width);
181 int nSpatialDim = colBottom[0].height * colBottom[0].width;
183 if (nSpatialDim != m_blobSumSpatialMultiplier.
count())
185 m_blobSumSpatialMultiplier.
Reshape(1, 1, colBottom[0].height, colBottom[0].width);
186 m_blobSumSpatialMultiplier.
SetData(1);
187 m_blobBufferSpatial.
ReshapeLike(m_blobSumSpatialMultiplier);
200 long hBottomData = colBottom[0].gpu_data;
201 long hTopData = colTop[0].mutable_gpu_data;
204 long hSumChannelMultiplier = m_blobSumChannelMultiplier.
gpu_data;
206 T[] rgNormData =
null;
209 if (m_bAcrossSpatial)
212 rgNormData = m_blobNorm.mutable_cpu_data;
216 hNormData = m_blobNorm.mutable_gpu_data;
218 m_blobNorm.SetData(m_fEps);
221 if (m_bChannelShared)
226 int nNum = colBottom[0].num;
227 int nDim = colBottom[0].count() / nNum;
228 int nSpatialDim = colBottom[0].height * colBottom[0].width;
229 int nChannels = colBottom[0].channels;
230 int nNormDataOffset = 0;
231 int nBottomOffset = 0;
234 for (
int n = 0; n < nNum; n++)
236 m_cuda.powx(nDim, hBottomData, 2.0, hBufferData, nBottomOffset, 0);
238 if (m_bAcrossSpatial)
242 double dfNorm = Math.Pow(dfNormSqr, 0.5);
243 m_cuda.scale(nDim,
Utility.ConvertVal<T>(1.0 / dfNorm), hBottomData, hTopData, nBottomOffset, nTopOffset);
244 rgNormData[n] =
Utility.ConvertVal<T>(dfNorm);
249 m_cuda.gemv(
true, nChannels, nSpatialDim,
m_tOne, hBufferData, hSumChannelMultiplier,
m_tOne, hNormData, 0, 0, nNormDataOffset);
250 m_cuda.powx(nSpatialDim, hNormData, 0.5, hNormData, nNormDataOffset, nNormDataOffset);
253 m_cuda.divbsx(nDim, hBottomData, nBottomOffset, hNormData, nNormDataOffset, nChannels, nSpatialDim,
false, hTopData, nTopOffset);
254 nNormDataOffset += nSpatialDim;
258 if (m_bChannelShared)
260 m_cuda.scal(nDim, rgScale[0], hTopData, nTopOffset);
264 m_cuda.mulbsx(nDim, hTopData, nTopOffset, hScale, 0, nChannels, nSpatialDim,
true, hTopData, nTopOffset);
267 nBottomOffset += nDim;
271 if (rgNormData !=
null)
272 m_blobNorm.mutable_cpu_data = rgNormData;
285 long hTopDiff = colTop[0].gpu_diff;
286 long hTopData = colTop[0].gpu_data;
287 long hBottomData = colBottom[0].gpu_data;
288 long hBottomDiff = colBottom[0].mutable_gpu_diff;
293 long hSumChannelMultiplier = m_blobSumChannelMultiplier.
gpu_data;
294 long hSumSpatialMultiplier = m_blobSumSpatialMultiplier.
gpu_data;
297 double[] rgNormData =
null;
299 if (m_bAcrossSpatial)
306 hNormData = m_blobNorm.mutable_gpu_data;
309 if (m_bChannelShared)
314 int nCount = colTop[0].count();
315 int nNum = colTop[0].num;
316 int nDim = nCount / nNum;
317 int nSpatialDim = colTop[0].height * colTop[0].width;
318 int nChannels = colTop[0].channels;
323 if (m_bChannelShared)
326 double dfA =
Utility.ConvertVal<T>(
m_cuda.dot(nCount, hTopData, hTopDiff));
328 dfScaleDiff += (dfA / dfScale);
333 long hScaleDiff =
m_colBlobs[0].mutable_gpu_diff;
335 for (
int n = 0; n < nNum; n++)
338 m_cuda.mul(nDim, hTopData, hTopDiff, hBufferData, n * nDim, n * nDim, 0);
339 m_cuda.gemv(
false, nChannels, nSpatialDim,
m_tOne, hBufferData, hSumSpatialMultiplier,
m_tZero, hBufferChannel);
342 m_cuda.div(nChannels, hBufferChannel, hScale, hBufferChannel);
343 m_cuda.add(nChannels, hBufferChannel, hScaleDiff, hScaleDiff);
349 if (rgbPropagateDown[0])
351 int nBottomDataOffset = 0;
352 int nBottomDiffOffset = 0;
353 int nTopDiffOffset = 0;
354 int nNormDataOffset = 0;
356 for (
int n = 0; n < nNum; n++)
358 if (m_bAcrossSpatial)
360 double dfA =
Utility.ConvertVal<T>(
m_cuda.dot(nDim, hBottomData, hTopDiff, nBottomDataOffset, nTopDiffOffset));
361 double dfScale1 = dfA / rgNormData[n] / rgNormData[n];
362 m_cuda.scale(nDim,
Utility.ConvertVal<T>(dfScale1), hBottomData, hBottomDiff, nBottomDataOffset, nBottomDiffOffset);
363 m_cuda.sub(nDim, hTopDiff, hBottomDiff, hBottomDiff, nTopDiffOffset, nBottomDiffOffset, nBottomDiffOffset);
365 dfScale1 = 1.0 / rgNormData[n];
366 m_cuda.scale(nDim,
Utility.ConvertVal<T>(dfScale1), hBottomDiff, hBottomDiff, nBottomDiffOffset, nBottomDiffOffset);
371 m_cuda.mul(nDim, hBottomData, hTopDiff, hBufferData, nBottomDataOffset, nTopDiffOffset, 0);
372 m_cuda.gemv(
true, nChannels, nSpatialDim,
m_tOne, hBufferData, hSumChannelMultiplier,
m_tZero, hBufferSpatial);
375 m_cuda.mulbsx(nDim, hBottomData, nBottomDataOffset, hBufferSpatial, 0, nChannels, nSpatialDim,
false, hBottomDiff, nBottomDiffOffset);
378 m_cuda.powx(nSpatialDim, hNormData, 2.0, hBufferSpatial);
379 m_cuda.divbsx(nDim, hBottomDiff, nBottomDiffOffset, hBufferSpatial, 0, nChannels, nSpatialDim,
false, hBottomDiff, nBottomDiffOffset);
380 m_cuda.sub(nDim, hTopDiff, hBottomDiff, hBottomDiff, nTopDiffOffset, nBottomDiffOffset, nBottomDiffOffset);
383 m_cuda.divbsx(nDim, hBottomDiff, nBottomDiffOffset, hNormData, nNormDataOffset, nChannels, nSpatialDim,
false, hBottomDiff, nBottomDiffOffset);
384 nNormDataOffset += nSpatialDim;
388 if (m_bChannelShared)
389 m_cuda.scal(nDim, dfScale, hBottomDiff, nBottomDiffOffset);
391 m_cuda.mulbsx(nDim, hBottomDiff, nBottomDiffOffset, hScale, 0, nChannels, nSpatialDim,
true, hBottomDiff, nBottomDiffOffset);
393 nBottomDataOffset += nDim;
394 nBottomDiffOffset += nDim;
395 nTopDiffOffset += nDim;
The Log class provides general output in text form.
void WriteLine(string str, bool bOverrideEnabled=false, bool bHeader=false, bool bError=false, bool bDisable=false)
Write a line of output.
void CHECK_EQ(double df1, double df2, string str)
Test whether one number is equal to another.
void CHECK_GE(double df1, double df2, string str)
Test whether one number is greater than or equal to another.
The Utility class provides general utility funtions.
static double[] ConvertVec(float[] rgf)
Convert an array of float to an array of generics.
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.
void SetData(T[] rgData, int nCount=-1, bool bSetCount=true)
Sets a number of items within the Blob's data.
long mutable_gpu_data
Returns the data GPU handle used by the CudaDnn connection.
void Reshape(int nNum, int nChannels, int nHeight, int nWidth, bool? bUseHalfSize=null)
DEPRECIATED; use
T asum_data()
Compute the sum of absolute values (L1 norm) of the data.
int count()
Returns the total number of items in the Blob.
void ReshapeLike(Blob< T > b, bool? bUseHalfSize=null)
Reshape this Blob to have the same shape as another Blob.
string Name
Get/set the name of the Blob.
virtual void Dispose(bool bDisposing)
Releases all resources used by the Blob (including both GPU and Host).
long gpu_data
Returns the data GPU handle used by the CudaDnn connection.
The CudaDnn object is the main interface to the Low-Level Cuda C++ DLL.
Abstract Filler class used to fill blobs with values.
void Fill(Blob< T > b)
Fill the blob with values based on the actual filler used.
static Filler< T > Create(CudaDnn< T > cuda, Log log, FillerParameter p)
Create a new Filler instance.
An interface for the units of computation which can be composed into a Net.
Log m_log
Specifies the Log for output.
LayerParameter m_param
Specifies the LayerParameter describing the Layer.
T m_tZero
Specifies a generic type equal to 0.0.
T m_tOne
Specifies a generic type equal to 1.0.
CudaDnn< T > m_cuda
Specifies the CudaDnn connection to Cuda.
LayerParameter.LayerType m_type
Specifies the Layer type.
LayerParameter layer_param
Returns the LayerParameter for this Layer.
BlobCollection< T > m_colBlobs
Specifies the learnable parameter Blobs of the Layer.
DictionaryMap< bool > m_rgbParamPropagateDown
Specifies whether or not to compute the learnable diff of each parameter Blob.
The Normalization2Layer performs normalization used by the SSD algorithm. This layer is initialized w...
override void Reshape(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Reshape the bottom (input) and top (output) blobs.
override void LayerSetUp(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Setup the layer.
override void dispose()
Releases all GPU and host resources used by the Layer.
override int ExactNumBottomBlobs
Returns the exact number of required bottom (input) Blobs: data
override int ExactNumTopBlobs
Returns the exact number of required top (output) Blobs: norm
override void backward(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Computes the error gradient w.r.t the inputs.
override void forward(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Computes the forward calculation.
override void setup_internal_blobs(BlobCollection< T > col)
Derivative layers should add all internal blobws to the 'col' provided.
Normalization2Layer(CudaDnn< T > cuda, Log log, LayerParameter p)
The Normalization2Layer constructor.
Specifies the base parameter for all layers.
Normalization2Parameter normalization2_param
Returns the parameter set when initialized with LayerType.NORMALIZATION2
string name
Specifies the name of this LayerParameter.
LayerType
Specifies the layer type.
Specifies the parameters for the Normalization2Layer used in SSD.
float eps
Specifies the epsilon for not dividing by zero while normalizing variance.
FillerParameter scale_filler
Specifies the filler for the initial value of scale, default is 1.0 for all.
bool channel_shared
Specifies whether or not the scale parameters are shared across channels.
bool across_spatial
Specifies to normalize across the spatial dimensions.
The MyCaffe.basecode contains all generic types used throughout MyCaffe.
The MyCaffe.common namespace contains common MyCaffe classes.
The MyCaffe.fillers namespace contains all fillers including the Filler class.
The MyCaffe.layers.ssd namespace contains all Single-Shot MultiBox (SSD) related layers.
The MyCaffe.param.ssd namespace contains all SSD related parameter objects that correspond to the nat...
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-...