MyCaffe  1.12.2.41
Deep learning software for Windows C# programmers.
ArgMaxLayer.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{
25 public class ArgMaxLayer<T> : Layer<T>
26 {
27 bool m_bOutMaxVal;
28 int m_nTopK;
29 int? m_nAxis = null;
30
48 : base(cuda, log, p)
49 {
51 }
52
56 public override int ExactNumBottomBlobs
57 {
58 get { return 1; }
59 }
60
64 public override int ExactNumTopBlobs
65 {
66 get { return 1; }
67 }
68
74 public override void LayerSetUp(BlobCollection<T> colBottom, BlobCollection<T> colTop)
75 {
77 m_bOutMaxVal = p.out_max_val;
78 m_nTopK = (int)p.top_k;
79 m_nAxis = null;
80
81 m_log.CHECK_GE(m_nTopK, 1, "Top k must not be less than 1.");
82
83 if (p.axis.HasValue)
84 {
85 m_nAxis = colBottom[0].CanonicalAxisIndex(p.axis.Value);
86 m_log.CHECK_GE(m_nAxis.Value, 0, "axis must not be less than zero.");
87 m_log.CHECK_LE(m_nAxis.Value, colBottom[0].num_axes, "axis must be less tahn or equal to the dimension of the axis.");
88 m_log.CHECK_LE(m_nTopK, colBottom[0].shape(m_nAxis.Value), "top_k must be less than or equal to the dimension of the axis.");
89 }
90 else
91 {
92 m_log.CHECK_LE(m_nTopK, colBottom[0].count(1), "top_k must be less than or equal to the dimension of the flattened bottom blob per instance.");
93 }
94 }
95
101 public override void Reshape(BlobCollection<T> colBottom, BlobCollection<T> colTop)
102 {
103 int nNumTopAxes = colBottom[0].num_axes;
104
105 if (nNumTopAxes < 3)
106 nNumTopAxes = 3;
107
108 List<int> rgShape = Utility.Create<int>(nNumTopAxes, 1);
109
110 if (m_nAxis.HasValue)
111 {
112 // Produces max_ind or max_val per axis
113 rgShape = Utility.Clone<int>(colBottom[0].shape());
114 rgShape[m_nAxis.Value] = m_nTopK;
115 }
116 else
117 {
118 rgShape[0] = colBottom[0].shape(0);
119 // Produces max_ind
120 rgShape[2] = m_nTopK;
121
122 if (m_bOutMaxVal)
123 {
124 // Produces max_ind and max_val
125 rgShape[1] = 2;
126 }
127 }
128
129 colTop[0].Reshape(rgShape);
130 }
131
148 protected override void forward(BlobCollection<T> colBottom, BlobCollection<T> colTop)
149 {
151 forward_gpu(colBottom, colTop);
152 else
153 forward_cpu(colBottom, colTop);
154 }
155
156 private void forward_gpu(BlobCollection<T> colBottom, BlobCollection<T> colTop)
157 {
158 int nAxis = m_nAxis.GetValueOrDefault(1);
159 int nOuterNum = colBottom[0].count(0, nAxis);
160 int nChannels = colBottom[0].count(nAxis);
161 int nInnerNum = 1;
162
163 if (m_nTopK > 1)
164 m_log.WriteLine("WARNING: The gpu implementation of argmax only supports TopK = 1.");
165
166 if (m_bOutMaxVal)
167 m_log.WriteLine("WARNING: Currently the gpu implementation of argmax does now support output of the max values.");
168
170 m_cuda.channel_max(colBottom[0].count(), nOuterNum, nChannels, nInnerNum, colBottom[0].gpu_data, colTop[0].mutable_gpu_data, true);
171 else
172 m_cuda.channel_min(colBottom[0].count(), nOuterNum, nChannels, nInnerNum, colBottom[0].gpu_data, colTop[0].mutable_gpu_data, true);
173 }
174
175 private void forward_cpu(BlobCollection<T> colBottom, BlobCollection<T> colTop)
176 {
177 double[] rgBottomData = convertD(colBottom[0].update_cpu_data());
178 double[] rgTopData = convertD(colTop[0].mutable_cpu_data);
179 int nDim;
180 int nAxisDist;
181
182 if (m_nAxis.HasValue)
183 {
184 nDim = colBottom[0].shape(m_nAxis.Value);
185 // Distance between values of axis in blob.
186 nAxisDist = colBottom[0].count(m_nAxis.Value) / nDim;
187 }
188 else
189 {
190 nDim = colBottom[0].count(1);
191 nAxisDist = 1;
192 }
193
194 int nNum = colBottom[0].count() / nDim;
195
196 for (int i = 0; i < nNum; i++)
197 {
198 List<KeyValuePair<double, int>> rgBottomDataPair = new List<KeyValuePair<double, int>>();
199
200 for (int j = 0; j < nDim; j++)
201 {
202 int nIdx = (i / nAxisDist * nDim + j) * nAxisDist + i % nAxisDist;
203 rgBottomDataPair.Add(new KeyValuePair<double, int>(rgBottomData[nIdx], j));
204 }
205
207 rgBottomDataPair.Sort(new Comparison<KeyValuePair<double, int>>(sortDataItemsDescending));
208 else
209 rgBottomDataPair.Sort(new Comparison<KeyValuePair<double, int>>(sortDataItemsAscending));
210
211 for (int j = 0; j < m_nTopK; j++)
212 {
213 if (m_bOutMaxVal)
214 {
215 if (m_nAxis.HasValue)
216 {
217 // Produces max_val per axis
218 int nIdx = (i / nAxisDist * m_nTopK + j) * nAxisDist + i % nAxisDist;
219 rgTopData[nAxisDist] = rgBottomDataPair[j].Key;
220 }
221 else
222 {
223 // Produces max_ind and max_val
224 int nIdx1 = 2 * i * m_nTopK + j;
225 rgTopData[nIdx1] = rgBottomDataPair[j].Value;
226 int nIdx2 = 2 * i * m_nTopK + m_nTopK + j;
227 rgTopData[nIdx2] = rgBottomDataPair[j].Key;
228 }
229 }
230 else
231 {
232 // Produces max_ind per axis.
233 int nIdx = (i / nAxisDist * m_nTopK + j) * nAxisDist + i % nAxisDist;
234 rgTopData[nIdx] = rgBottomDataPair[j].Value;
235 }
236 }
237 }
238
239 colTop[0].mutable_cpu_data = convert(rgTopData);
240 }
241
242 private int sortDataItemsAscending(KeyValuePair<double, int> a, KeyValuePair<double, int> b)
243 {
244 if (a.Key < b.Key)
245 return 1;
246
247 if (a.Key > b.Key)
248 return -1;
249
250 return 0;
251 }
252
253 private int sortDataItemsDescending(KeyValuePair<double, int> a, KeyValuePair<double, int> b)
254 {
255 if (a.Key < b.Key)
256 return -1;
257
258 if (a.Key > b.Key)
259 return 1;
260
261 return 0;
262 }
263
265 protected override void backward(BlobCollection<T> colTop, List<bool> rgbPropagateDown, BlobCollection<T> colBottom)
266 {
267 new NotImplementedException();
268 }
269 }
270}
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_LE(double df1, double df2, string str)
Test whether one number is less than or equal to another.
Definition: Log.cs:263
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 Utility class provides general utility funtions.
Definition: Utility.cs:35
static List< int > Create(int nCount, int nStart, int nInc)
Create a new List and fill it with values starting with start and incrementing by inc.
Definition: Utility.cs:721
The BlobCollection contains a list of Blobs.
void Add(Blob< T > b)
Add a new Blob to the collection.
void Reshape(int[] rgShape)
Reshapes all blobs in the collection to the given shape.
The CudaDnn object is the main interface to the Low-Level Cuda C++ DLL.
Definition: CudaDnn.cs:969
The ArgMaxLayer computes the index of the K max values for each datum across all dimensions ....
Definition: ArgMaxLayer.cs:26
override void Reshape(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Reshape the bottom (input) and top (output) blobs.
Definition: ArgMaxLayer.cs:101
override void forward(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Forward computation. When 'enable_cuda_impl' = true (default = false) the GPU version is run.
Definition: ArgMaxLayer.cs:148
override int ExactNumTopBlobs
Returns the exact number of top blobs required: argmax
Definition: ArgMaxLayer.cs:65
override void LayerSetUp(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Setup the layer.
Definition: ArgMaxLayer.cs:74
override int ExactNumBottomBlobs
Returns the exact number of bottom blobs required: input
Definition: ArgMaxLayer.cs:57
override void backward(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Not implemented.
Definition: ArgMaxLayer.cs:265
ArgMaxLayer(CudaDnn< T > cuda, Log log, LayerParameter p)
Constructor.
Definition: ArgMaxLayer.cs:47
An interface for the units of computation which can be composed into a Net.
Definition: Layer.cs:31
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
void convert(BlobCollection< T > col)
Convert a collection of blobs from / to half size.
Definition: Layer.cs:535
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
Specifies the parameters for the ArgMaxLayer
bool enable_cuda_impl
Specifies to use the low-level full cuda implementation of LayerNorm (default = false).
uint top_k
When computing accuracy, count as correct by comparing the true label to the top_k scoring classes....
COMPARE_OPERATOR operation
Specifies the operation to use (default = MAX).
bool out_max_val
If true produce pairs (argmax, maxval)
COMPARE_OPERATOR
Defines the compare operator to use (max or min, default = max).
int? axis
The axis along which to maximize – may be negative to index from the end (e.g., -1 for the last axis)...
Specifies the base parameter for all layers.
ArgMaxParameter argmax_param
Returns the parameter set when initialized with LayerType.ARGMAX
LayerType
Specifies the layer type.
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