MyCaffe  1.12.2.41
Deep learning software for Windows C# programmers.
HingeLossLayer.cs
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using MyCaffe.basecode;
6using MyCaffe.common;
7using MyCaffe.param;
8
9namespace MyCaffe.layers
10{
20 public class HingeLossLayer<T> : LossLayer<T>
21 {
35 : base(cuda, log, p)
36 {
37 m_type = LayerParameter.LayerType.HINGE_LOSS;
38 }
39
41 protected override void dispose()
42 {
43 base.dispose();
44 }
45
90 protected override void forward(BlobCollection<T> colBottom, BlobCollection<T> colTop)
91 {
92 long hBottomData = colBottom[0].gpu_data;
93 long hBottomDiff = colBottom[0].mutable_gpu_diff;
94 int nNum = colBottom[0].num;
95 int nCount = colBottom[0].count();
96 int nDim = nCount / nNum;
97
98 m_cuda.copy(nCount, hBottomData, hBottomDiff);
99
100 T[] rgBottomDiff = colBottom[0].mutable_cpu_diff;
101 T[] rgLabel = colBottom[1].update_cpu_data();
102
103 if (typeof(T) == typeof(double))
104 {
105 double[] rgBottomDiffD = (double[])Convert.ChangeType(rgBottomDiff, typeof(double[]));
106 double[] rgLabelD = (double[])Convert.ChangeType(rgLabel, typeof(double[]));
107
108 for (int i = 0; i < nNum; i++)
109 {
110 rgBottomDiffD[i * nDim + (int)rgLabelD[i]] *= -1;
111 }
112 for (int i = 0; i < nNum; i++)
113 {
114 for (int j = 0; j < nDim; j++)
115 {
116 int nIdx = i * nDim + j;
117 double dfDiff = rgBottomDiffD[nIdx];
118 rgBottomDiffD[nIdx] = Math.Max(0.0, 1.0 + dfDiff);
119 }
120 }
121 }
122 else
123 {
124 float[] rgBottomDiffF = (float[])Convert.ChangeType(rgBottomDiff, typeof(float[]));
125 float[] rgLabelF = (float[])Convert.ChangeType(rgLabel, typeof(float[]));
126
127 for (int i = 0; i < nNum; i++)
128 {
129 rgBottomDiffF[i * nDim + (int)rgLabelF[i]] *= -1;
130 }
131 for (int i = 0; i < nNum; i++)
132 {
133 for (int j = 0; j < nDim; j++)
134 {
135 int nIdx = i * nDim + j;
136 float fDiff = rgBottomDiffF[nIdx];
137 rgBottomDiffF[nIdx] = Math.Max(0.0f, 1.0f + fDiff);
138 }
139 }
140 }
141
142 colBottom[0].mutable_cpu_diff = rgBottomDiff;
143
144 double dfLoss = 0;
146 {
147 case HingeLossParameter.Norm.L1:
148 dfLoss = convertD(m_cuda.asum(nCount, hBottomDiff)) / nNum;
149 break;
150
151 case HingeLossParameter.Norm.L2:
152 dfLoss = convertD(m_cuda.dot(nCount, hBottomDiff, hBottomDiff)) / nNum;
153 break;
154
155 default:
156 m_log.FAIL("Unknown norm in HingeLoss!");
157 break;
158 }
159
160 colTop[0].SetData(dfLoss, 0);
161 }
162
191 protected override void backward(BlobCollection<T> colTop, List<bool> rgbPropagateDown, BlobCollection<T> colBottom)
192 {
193 if (rgbPropagateDown[1])
194 m_log.FAIL(type.ToString() + " Layer cannot backpropagate to label inputs.");
195
196 if (rgbPropagateDown[0])
197 {
198 long hBottomDiff = colBottom[0].mutable_gpu_diff;
199 int nNum = colBottom[0].num;
200 int nCount = colBottom[0].count();
201 int nDim = nCount / nNum;
202
203 T[] rgBottomDiff = colBottom[0].mutable_cpu_diff;
204 T[] rgLabel = colBottom[1].update_cpu_data();
205
206 if (typeof(T) == typeof(double))
207 {
208 double[] rgBottomDiffD = (double[])Convert.ChangeType(rgBottomDiff, typeof(double[]));
209 double[] rgLabelD = (double[])Convert.ChangeType(rgLabel, typeof(double[]));
210
211 for (int i = 0; i < nNum; i++)
212 {
213 rgBottomDiffD[i * nDim + (int)rgLabelD[i]] *= -1;
214 }
215 }
216 else
217 {
218 float[] rgBottomDiffF = (float[])Convert.ChangeType(rgBottomDiff, typeof(float[]));
219 float[] rgLabelF = (float[])Convert.ChangeType(rgLabel, typeof(float[]));
220
221 for (int i = 0; i < nNum; i++)
222 {
223 rgBottomDiffF[i * nDim + (int)rgLabelF[i]] *= -1;
224 }
225 }
226
227 colBottom[0].mutable_cpu_diff = rgBottomDiff;
228
229 double dfLossWeight = convertD(colTop[0].GetDiff(0));
231 {
232 case HingeLossParameter.Norm.L1:
233 m_cuda.sign(nCount, hBottomDiff, hBottomDiff);
234 m_cuda.scal(nCount, dfLossWeight / nNum, hBottomDiff);
235 break;
236
237 case HingeLossParameter.Norm.L2:
238 m_cuda.scal(nCount, dfLossWeight * 2 / nNum, hBottomDiff);
239 break;
240
241 default:
242 m_log.FAIL("Unknown norm in HingeLoss!");
243 break;
244 }
245 }
246 }
247 }
248}
The Log class provides general output in text form.
Definition: Log.cs:13
void FAIL(string str)
Causes a failure which throws an exception with the desciptive text.
Definition: Log.cs:394
The BlobCollection contains a list of Blobs.
void SetData(double df)
Set all blob data to the value specified.
The CudaDnn object is the main interface to the Low-Level Cuda C++ DLL.
Definition: CudaDnn.cs:969
The HingeLossLayer computes the hinge loss for a one-of-many classification task. This layer is initi...
override void forward(BlobCollection< T > colBottom, BlobCollection< T > colTop)
The forward computation.
override void dispose()
Releases all GPU and host resources used by the Layer.
override void backward(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Computes the hinge loss error gradient w.r.t the predictions.
HingeLossLayer(CudaDnn< T > cuda, Log log, LayerParameter p)
The HingeLoss constructor.
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 type
Returns the LayerType of this Layer.
Definition: Layer.cs:927
double convertD(T df)
Converts a generic to a double value.
Definition: Layer.cs:1349
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
The LossLayer provides an interface for Layer's that take two blobs as input – usually (1) prediction...
Definition: LossLayer.cs:23
Specifies the parameters for the HingLossLayer.
Norm norm
Specify the Norm to use L1 or L2
Norm
Defines the type of normalization.
Specifies the base parameter for all layers.
HingeLossParameter hinge_loss_param
Returns the parameter set when initialized with LayerType.HINGE_LOSS
LayerType
Specifies the layer type.
override string ToString()
Returns a string representation of the LayerParameter.
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 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