2using System.Collections.Generic;
42 T[] m_rgMatches =
null;
44 int m_nCentroidNotification = 10;
63 m_blobDiff =
new Blob<T>(cuda, log,
false);
65 m_blobDistSq =
new Blob<T>(cuda, log,
false);
67 m_blobDiffSq =
new Blob<T>(cuda, log,
false);
69 m_blobSummerVec =
new Blob<T>(cuda, log,
false);
71 m_blobSimilar =
new Blob<T>(cuda, log,
false);
73 m_blobDistScale =
new Blob<T>(cuda, log,
false);
75 m_blobPrimary =
new Blob<T>(cuda, log,
false);
84 if (m_blobDiff !=
null)
90 if (m_blobDistSq !=
null)
96 if (m_blobDiffSq !=
null)
102 if (m_blobSummerVec !=
null)
105 m_blobSummerVec =
null;
108 if (m_blobSimilar !=
null)
111 m_blobSimilar =
null;
114 if (m_blobDistScale !=
null)
117 m_blobDistScale =
null;
120 if (m_blobPrimary !=
null)
123 m_blobPrimary =
null;
198 base.LayerSetUp(colBottom, colTop);
202 m_log.
CHECK_EQ(colBottom[0].channels, colBottom[1].channels,
"the bottom[0] and bottom[1] should have equal channel values.");
203 m_log.
CHECK_EQ(1, colBottom[0].height,
"The bottom[0] should have height = 1.");
204 m_log.
CHECK_EQ(1, colBottom[0].width,
"The bottom[0] should have width = 1.");
205 m_log.
CHECK_EQ(1, colBottom[1].height,
"The bottom[1] should have height = 1.");
206 m_log.
CHECK_EQ(1, colBottom[1].width,
"The bottom[1] should have width = 1.");
207 m_log.
CHECK_GE(colBottom[2].channels, 1,
"The bottom[2] should have channels >= 1.");
208 m_log.
CHECK_LE(colBottom[2].channels, 3,
"The bottom[2] should have channels <= 3.");
209 m_log.
CHECK_EQ(1, colBottom[2].height,
"The bottom[2] should have height = 1.");
210 m_log.
CHECK_EQ(1, colBottom[2].width,
"The bottom[2] should have width = 1.");
211 m_nCentroidNotification = 10;
221 base.Reshape(colBottom, colTop);
223 m_blobDiff.Reshape(colBottom[0].num, colBottom[0].channels, 1, 1);
224 m_blobDiffSq.
Reshape(colBottom[0].num, colBottom[0].channels, 1, 1);
225 m_blobDistSq.
Reshape(colBottom[0].num, 1, 1, 1);
227 m_blobSummerVec.
Reshape(colBottom[0].channels, 1, 1, 1);
233 if (m_rgMatches ==
null || m_rgMatches.Length != colBottom[0].num)
234 m_rgMatches =
new T[colBottom[0].num];
236 colTop[1].
Reshape(colBottom[0].num, 1, 1, 1);
239 m_blobSimilar.
Reshape(colBottom[0].num, 1, 1, 1);
240 m_blobDistScale.
Reshape(colBottom[0].num, 1, 1, 1);
267 int nCount = colBottom[0].count();
270 if (colBottom[2].channels > 1)
273 m_cuda.channel_compare(colBottom[2].count(), colBottom[2].num, colBottom[2].channels, 1, colBottom[2].gpu_data, m_blobSimilar.
mutable_gpu_data);
283 bool bCentroidLearningEnabled =
false;
284 bool bUseCentroidLearning =
false;
287 bCentroidLearningEnabled =
true;
288 T fAsum = colBottom[3].asum_data();
291 bUseCentroidLearning =
true;
294 if (bUseCentroidLearning)
296 m_log.
CHECK_EQ(colBottom.
Count, 4,
"When using centroid learning, a fourth bottom is required that contains the class centroids (calculated by the DecodeLayer).");
297 m_log.
CHECK_EQ(colBottom[3].channels, colBottom[0].channels,
"Each centroid should have the same size as each encoding.");
298 m_log.
CHECK_EQ(colBottom[3].height, 1,
"The centroids should have a height = 1.");
299 m_log.
CHECK_EQ(colBottom[3].width, 1,
"The centroids should have a width = 1.");
300 m_log.
CHECK_EQ(colBottom[2].channels, 2,
"The colBottom[2] must contain labels, not a similarity value - make sure the data layer has 'output_all_labels' = True.");
303 int nEncodingDim = m_blobPrimary.
count(1);
304 int nLabelDim = colBottom[2].count(1);
307 m_cuda.channel_fill(m_blobPrimary.
count(), m_blobPrimary.
num, nEncodingDim, 1, colBottom[3].gpu_data, nLabelDim, colBottom[2].gpu_data, m_blobPrimary.
mutable_gpu_data);
317 if (m_nCentroidNotification > 0)
320 m_nCentroidNotification--;
332 float[] rgDist =
null;
338 bLegacyVersion =
true;
340 Blob<T> blobAbsDiff = m_blobDiffSq;
341 Blob<T> blobDist = m_blobDistSq;
345 colBottom[1].gpu_data,
346 m_blobDiff.mutable_gpu_data);
374 colBottom[1].gpu_data,
375 m_blobDiff.mutable_gpu_data);
378 m_blobDiff.mutable_gpu_data,
401 for (
int i = 0; i < colBottom[0].num; i++)
403 double dfDist = (bLegacyVersion) ? dfMargin - rgDist[i] : dfMargin - Math.Sqrt(rgDist[i]);
404 bool bSimilar = (rgSimPairs[i] == 0) ?
false :
true;
408 if (m_rgMatches !=
null)
420 if (m_rgMatches !=
null)
428 dfDist = Math.Max(dfDist, 0);
433 dfLoss += dfDist * dfDist;
437 dfLoss = dfLoss / (double)colBottom[0].num / 2.0;
440 if (colTop.
Count > 1 && m_rgMatches !=
null)
441 colTop[1].mutable_cpu_data = m_rgMatches;
478 if (!rgbPropagateDown[0] && !rgbPropagateDown[1])
481 double dfTopDiff =
convertD(colTop[0].GetDiff(0)) / colBottom[0].num;
483 m_log.
CHECK_GT(m_blobSimilar.
gpu_data, 0,
"The similar data is not initialized - you must first run the forward pass under the Phase = TRAIN.");
485 for (
int i = 0; i < 2; i++)
487 if (rgbPropagateDown[i])
489 int nCount = colBottom[0].count();
490 int nChannels = colBottom[0].channels;
493 double dfSign = (i == 0) ? 1 : -1;
494 double dfAlpha = dfSign * dfTopDiff;
504 colBottom[i].mutable_gpu_diff);
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_GT(double df1, double df2, string str)
Test whether one number is greater than another.
void CHECK_LE(double df1, double df2, string str)
Test whether one number is less than or 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.
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 Blob is the main holder of data that moves through the Layers of the Net.
int channels
DEPRECIATED; legacy shape accessor channels: use shape(1) instead.
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[] update_cpu_data()
Update the CPU data by transferring the GPU data over to the Host.
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).
int num
DEPRECIATED; legacy shape accessor num: use shape(0) instead.
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.
The ContrastiveLossLayer computes the contrastive loss where . This layer is initialized with the My...
override int MinBottomBlobs
Returns the minumum number of bottom blobs: featA, featB, label
override int MaxTopBlobs
Specifies the maximum number of required top (output) Blobs: loss, matches
override int MinTopBlobs
Specifies the minimum number of required top (output) Blobs: loss
override bool AllowForceBackward(int nBottomIdx)
Unlike most loss layers, in the ContrastiveLossLayer we can backpropagate to the first two inputs.
override void Reshape(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Reshape the bottom (input) and top (output) blobs.
override void dispose()
Releases all GPU and host resources used by the Layer.
override int ExactNumBottomBlobs
Returns -1 specifying a variable number of bottoms
ContrastiveLossLayer(CudaDnn< T > cuda, Log log, LayerParameter p)
The ContrastiveLossLayer constructor.
override int ExactNumTopBlobs
Returns -1 specifying a variable number of tops.
override void LayerSetUp(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Setup the layer.
override void forward(BlobCollection< T > colBottom, BlobCollection< T > colTop)
The forward computation.
override int MaxBottomBlobs
Returns the minumum number of bottom blobs: featA, featB, label, centroids
override void backward(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Computes the infogain loss error gradient w.r.t the inputs.
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.
double convertD(T df)
Converts a generic to a double value.
Phase m_phase
Specifies the Phase under which the Layer is run.
CudaDnn< T > m_cuda
Specifies the CudaDnn connection to Cuda.
LayerParameter.LayerType m_type
Specifies the Layer type.
The LossLayer provides an interface for Layer's that take two blobs as input – usually (1) prediction...
Specifies the parameters for the ContrastiveLossLayer.
bool output_matches
Optionally, specifies to output match information (default = false).
bool legacy_version
The first implementation of this cost did not exactly match the cost of Hadsell et al 2006 – using (m...
double matching_distance_scale
Optionally, specifies the scale applied to the matching distance when calculating the loss (default =...
CENTROID_LEARNING centroid_learning
Optionally, specifies to use centroid learning as soon as the centroids (from the DecodeLayer) are re...
double margin
Margin for dissimilar pair.
DISTANCE_CALCULATION distance_calculation
Optionally, specifies the distance calculation to use when calculating the distance between encoding ...
DISTANCE_CALCULATION
Defines the distance calculation to use.
CENTROID_LEARNING
Defines the type of centroid learning to use.
Specifies the base parameter for all layers.
string name
Specifies the name of this LayerParameter.
ContrastiveLossParameter contrastive_loss_param
Returns the parameter set when initialized with LayerType.CONTRASTIVE_LOSS
LayerType
Specifies the layer type.
The MyCaffe.basecode contains all generic types used throughout MyCaffe.
Phase
Defines the Phase under which to run a Net.
The MyCaffe.common namespace contains common MyCaffe classes.
The MyCaffe.layers namespace contains all layers that have a solidified code base,...
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-...