2using System.Collections.Generic;
37 Blob<T> m_blobSumRowsOfH =
null;
39 int? m_nIgnoreLabel =
null;
40 int m_nInfogainAxis = 0;
74 if (m_blobInfoGain !=
null)
77 m_blobInfoGain =
null;
80 if (m_blobProb !=
null)
86 if (m_blobSumRowsOfH !=
null)
89 m_blobSumRowsOfH =
null;
99 col.
Add(m_blobInfoGain);
101 col.
Add(m_blobSumRowsOfH);
161 m_log.
CHECK_EQ(blobH.
count(), m_nNumLabels * m_nNumLabels,
"H must be " + m_nNumLabels.ToString() +
" x " + m_nNumLabels.ToString());
165 for (
int row = 0; row < m_nNumLabels; row++)
169 for (
int col = 0; col < m_nNumLabels; col++)
171 rgSum[row] += rgInfogainMat[row * m_nNumLabels + col];
185 base.LayerSetUp(colBottom, colTop);
193 m_colSoftmaxBottomVec.
Clear();
194 m_colSoftmaxBottomVec.
Add(colBottom[0]);
195 m_colSoftmaxTopVec.
Clear();
196 m_colSoftmaxTopVec.
Add(m_blobProb);
197 m_softmaxLayer.Setup(m_colSoftmaxBottomVec, m_colSoftmaxTopVec);
203 if (colBottom.
Count < 3)
219 base.Reshape(colBottom, colTop);
221 m_softmaxLayer.Reshape(m_colSoftmaxBottomVec, m_colSoftmaxTopVec);
223 m_nOuterNum = colBottom[0].count(0, m_nInfogainAxis);
224 m_nInnerNum = colBottom[0].count(m_nInfogainAxis + 1);
226 m_log.
CHECK_EQ(
m_nOuterNum *
m_nInnerNum, colBottom[1].count(),
"Number of labels must match the number of predictions; e.g., if infogain_axis == 1 and predictions shape is (N, C, H, W), label count (number of labels) must be N*H*W, with integer values in {0, 1, ..., C-1}.");
227 m_nNumLabels = colBottom[0].shape(m_nInfogainAxis);
231 if (colBottom.
Count < 3)
232 blobInfoGain = m_blobInfoGain;
234 blobInfoGain = colBottom[2];
236 m_log.
CHECK_EQ(blobInfoGain.
count(), m_nNumLabels * m_nNumLabels,
"The infogain count must equal 'num_labels' * 'num_labels'.");
237 m_blobSumRowsOfH.
Reshape(
new List<int>() { m_nNumLabels });
238 if (colBottom.
Count == 2)
243 if (colTop.
Count >= 2)
283 m_softmaxLayer.Forward(m_colSoftmaxBottomVec, m_colSoftmaxTopVec);
285 Blob<T> blobInfoGain = (colBottom.
Count < 3) ? m_blobInfoGain : colBottom[2];
290 double dfProbLog = 0;
293 if (typeof(T) == typeof(
double))
295 double[] rgProbData = (
double[])Convert.ChangeType(m_blobProb.
update_cpu_data(), typeof(
double[]));
296 double[] rgBottomLabel = (
double[])Convert.ChangeType(colBottom[1].update_cpu_data(), typeof(
double[]));
297 double[] rgInfoGainMat = (
double[])Convert.ChangeType(blobInfoGain.
update_cpu_data(), typeof(
double[]));
304 if (m_nIgnoreLabel.HasValue && m_nIgnoreLabel.Value == nLabel)
307 m_log.
CHECK_GE(nLabel, 0,
"The label should be greater than or equal to 0.");
308 m_log.
CHECK_LT(nLabel, m_nNumLabels,
"The label should be less than the number of labels '" + m_nNumLabels.ToString() +
"'");
310 for (
int l = 0; l < m_nNumLabels; l++)
313 dfProbLog = Math.Log(dfProb);
314 dfVal = rgInfoGainMat[nLabel * m_nNumLabels + l] * dfProbLog;
324 float[] rgProbData = (
float[])Convert.ChangeType(m_blobProb.
update_cpu_data(), typeof(
float[]));
325 float[] rgBottomLabel = (
float[])Convert.ChangeType(colBottom[1].update_cpu_data(), typeof(
float[]));
326 float[] rgInfoGainMat = (
float[])Convert.ChangeType(blobInfoGain.
update_cpu_data(), typeof(
float[]));
333 if (m_nIgnoreLabel.HasValue && m_nIgnoreLabel.Value == nLabel)
336 m_log.
CHECK_GE(nLabel, 0,
"The label should be greater than or equal to 0.");
337 m_log.
CHECK_LT(nLabel, m_nNumLabels,
"The label should be less than the number of labels '" + m_nNumLabels.ToString() +
"'");
339 for (
int l = 0; l < m_nNumLabels; l++)
342 dfProbLog = Math.Log(dfProb);
343 dfVal = rgInfoGainMat[nLabel * m_nNumLabels + l] * dfProbLog;
353 double dfNormalizedLoss = dfLoss / dfNormalizer;
354 colTop[0].
SetData(dfNormalizedLoss, 0);
356 if (colTop.
Count == 2)
357 colTop[1].ShareData(m_blobProb);
395 if (rgbPropagateDown[1])
398 if (rgbPropagateDown.Count > 2 && rgbPropagateDown[2])
401 if (rgbPropagateDown[0])
403 Blob<T> blobInfoGainMat = m_blobInfoGain;
408 if (colBottom.
Count >= 3)
410 blobInfoGainMat = colBottom[2];
415 if (typeof(T) == typeof(
double))
417 double[] rgProbData = (
double[])Convert.ChangeType(m_blobProb.
update_cpu_data(), typeof(
double[]));
418 double[] rgBottomLabel = (
double[])Convert.ChangeType(colBottom[1].update_cpu_data(), typeof(
double[]));
419 double[] rgInfoGainMat = (
double[])Convert.ChangeType(blobInfoGainMat.
update_cpu_data(), typeof(
double[]));
420 double[] rgSumsRowsH = (
double[])Convert.ChangeType(m_blobSumRowsOfH.
update_cpu_data(), typeof(
double[]));
421 double[] rgBottomDiff = (
double[])Convert.ChangeType(colBottom[0].mutable_cpu_diff, typeof(
double[]));
427 nLabelValue = (int)rgBottomLabel[i *
m_nInnerNum + j];
429 m_log.
CHECK_GE(nLabelValue, 0,
"The label should be greater than or equal to 0.");
430 m_log.
CHECK_LT(nLabelValue, m_nNumLabels,
"The label should be less than the number of labels '" + m_nNumLabels.ToString() +
"'");
432 if (m_nIgnoreLabel.HasValue && m_nIgnoreLabel.Value == nLabelValue)
434 for (
int l = 0; l < m_nNumLabels; l++)
441 for (
int l = 0; l < m_nNumLabels; l++)
444 rgBottomDiff[nIdx] = rgProbData[nIdx] * rgSumsRowsH[nLabelValue] - rgInfoGainMat[nLabelValue * m_nNumLabels + l];
452 colBottom[0].mutable_cpu_diff =
convert(rgBottomDiff);
456 float[] rgProbData = (
float[])Convert.ChangeType(m_blobProb.
update_cpu_data(), typeof(
float[]));
457 float[] rgBottomLabel = (
float[])Convert.ChangeType(colBottom[1].update_cpu_data(), typeof(
float[]));
458 float[] rgInfoGainMat = (
float[])Convert.ChangeType(blobInfoGainMat.
update_cpu_data(), typeof(
float[]));
459 float[] rgSumsRowsH = (
float[])Convert.ChangeType(m_blobSumRowsOfH.
update_cpu_data(), typeof(
float[]));
460 float[] rgBottomDiff = (
float[])Convert.ChangeType(colBottom[0].mutable_cpu_diff, typeof(
float[]));
466 nLabelValue = (int)rgBottomLabel[i *
m_nInnerNum + j];
468 m_log.
CHECK_GE(nLabelValue, 0,
"The label should be greater than or equal to 0.");
469 m_log.
CHECK_LT(nLabelValue, m_nNumLabels,
"The label should be less than the number of labels '" + m_nNumLabels.ToString() +
"'");
471 if (m_nIgnoreLabel.HasValue && m_nIgnoreLabel.Value == nLabelValue)
473 for (
int l = 0; l < m_nNumLabels; l++)
480 for (
int l = 0; l < m_nNumLabels; l++)
483 rgBottomDiff[nIdx] = rgProbData[nIdx] * rgSumsRowsH[nLabelValue] - rgInfoGainMat[nLabelValue * m_nNumLabels + l];
491 colBottom[0].mutable_cpu_diff =
convert(rgBottomDiff);
496 double dfLossWeight =
convertD(colTop[0].GetDiff(0)) / dfNormalizer;
497 m_cuda.scal(colBottom[0].count(), dfLossWeight, colBottom[0].mutable_gpu_diff);
The Log class provides general output in text form.
void CHECK(bool b, string str)
Test a flag for true.
void FAIL(string str)
Causes a failure which throws an exception with the desciptive text.
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.
void CHECK_LT(double df1, double df2, string str)
Test whether one number is less than another.
The BlobCollection contains a list of Blobs.
void Add(Blob< T > b)
Add a new Blob to the collection.
void SetData(double df)
Set all blob data to the value specified.
int Count
Returns the number of items in the collection.
void Clear(bool bDispose=false)
Remove all items from 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.
T[] mutable_cpu_data
Get data from the GPU and bring it over to the host, or Set data from the Host and send it over to th...
void Reshape(int nNum, int nChannels, int nHeight, int nWidth, bool? bUseHalfSize=null)
DEPRECIATED; use
void FromProto(BlobProto bp, bool bReshape=true)
Create a new Blob from a given BlobProto.
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.
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).
The CudaDnn object is the main interface to the Low-Level Cuda C++ DLL.
The PersistCaffe class is used to load and save weight files in the .caffemodel format.
BlobProto LoadBlobProto(byte[] rg, int nFieldId)
The LoadBlobProto function loads a BlobProto from a proto buffer.
The InforgainLossLayer is a generalization of SoftmaxWithLossLayer that takes an 'information gain' (...
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)
Computes the infogain loss error gradient w.r.t the predictions.
override int ExactNumBottomBlobs
InfogainLossLayer takes 2-3 bottom blobs; if there are 3 the third should be the infogain matrix....
virtual void sum_rows_of_H(Blob< T > blobH)
Fill m_blobSumRowsOfH according to matrix H.
override void setup_internal_blobs(BlobCollection< T > col)
Derivative layers should add all internal blobws to the 'col' provided.
override int MaxBottomBlobs
Returns the maximum number of required bottom (intput) Blobs: pred, label, matrix
override int MaxTopBlobs
Returns the maximum number of requried top (output) Blobs: infogain, softmax
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 MinBottomBlobs
Returns the minimum number of required bottom (intput) Blobs: pred, label
override void forward(BlobCollection< T > colBottom, BlobCollection< T > colTop)
The forward computation.
override int MinTopBlobs
Returns the minimum number of required top (output) Blobs: infogain
InfogainLossLayer(CudaDnn< T > cuda, Log log, LayerParameter p)
The InfogainLossLayer constructor.
override int ExactNumTopBlobs
InfogainLossLayer computes softmax probability internally. optional second 'top' outputs the sofmax p...
Log m_log
Specifies the Log for output.
LayerParameter m_param
Specifies the LayerParameter describing the Layer.
void convert(BlobCollection< T > col)
Convert a collection of blobs from / to half size.
LayerParameter.LayerType type
Returns the LayerType of this Layer.
float convertF(T df)
Converts a generic to a float value.
double convertD(T df)
Converts a generic to a double value.
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...
const double kLOG_THRESHOLD
Specifies the minimum threshold for loss values.
int m_nOuterNum
Specifies the outer num, such as the batch count (e.g. count(0, axis)). Each derivative class must se...
int m_nInnerNum
Specifies the inner num, such as the channel + height + width (e.g. count(axis + 1))....
virtual double get_normalizer(LossParameter.NormalizationMode normalization_mode, int nValidCount)
Returns the normalizer used to normalize the loss.
LossParameter.NormalizationMode m_normalization
Specifies the normalization mode used to normalize the loss.
The SoftmaxLayer computes the softmax function. This layer is initialized with the MyCaffe....
The BlobProto contains the descripion of a blob.
string source
Specifies the infogain matrix source.
int axis
[optional, default = 1] Specifies the axis of the probability.
Specifies the base parameter for all layers.
string name
Specifies the name of this LayerParameter.
List< double > loss_weight
Specifies the loss weight.
SoftmaxParameter softmax_param
Returns the parameter set when initialized with LayerType.SOFTMAX
LayerType
Specifies the layer type.
override string ToString()
Returns a string representation of the LayerParameter.
InfogainLossParameter infogain_loss_param
Returns the parameter set when initialized with LayerType.INFOGAIN_LOSS
LossParameter loss_param
Returns the parameter set when initialized with LayerType.LOSS
int? ignore_label
If specified, the ignore instances with the given label.
int axis
The axis along which to perform the softmax – may be negative to index from the end (e....
The MyCaffe.basecode contains all generic types used throughout MyCaffe.
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-...