MyCaffe  1.12.2.41
Deep learning software for Windows C# programmers.
QuantileAccuracyLayer.cs
1using System;
2using System.Collections.Generic;
3using System.Diagnostics;
4using System.Linq;
5using System.Reflection;
6using System.Text;
7using MyCaffe.basecode;
8using MyCaffe.common;
9using MyCaffe.param;
10
11namespace MyCaffe.layers.tft
12{
22 public class QuantileAccuracyLayer<T> : Layer<T>
23 {
24 float m_fLastAverage = 0;
25 Dictionary<float, List<float>> m_rgAccuracies = new Dictionary<float, List<float>>();
26 Dictionary<float, List<float>> m_rgAcccuracyAverages = new Dictionary<float, List<float>>();
27 Dictionary<float, int> m_rgWithinTargetCounts;
28
36 : base(cuda, log, p)
37 {
38 m_type = LayerParameter.LayerType.QUANTILE_ACCURACY;
39 }
40
42 protected override void dispose()
43 {
44 }
45
47 protected override void setup_internal_blobs(BlobCollection<T> col)
48 {
49 if (col.Count > 0)
50 return;
51 }
52
56 public override int ExactNumBottomBlobs
57 {
58 get { return 2; }
59 }
60
64 public override int ExactNumTopBlobs
65 {
66 get { return m_param.quantile_accuracy_param.accuracy_ranges.Count; }
67 }
68
74 public override void LayerSetUp(BlobCollection<T> colBottom, BlobCollection<T> colTop)
75 {
76 int nN = colBottom[0].num;
77 int nC = colBottom[0].channels;
78 m_log.CHECK_EQ(colBottom[0].height, 3, "Currently, the Quantile Accuracy Layer only supports 3 quantile predictions (upper, center, lower).");
79
80 m_rgWithinTargetCounts = new Dictionary<float, int>(nC);
81
82 foreach (float fRange in m_param.quantile_accuracy_param.accuracy_ranges)
83 {
84 m_rgAccuracies.Add(fRange, new List<float>(nN));
85 m_rgAcccuracyAverages.Add(fRange, new List<float>((int)m_param.quantile_accuracy_param.average_period));
86 m_rgWithinTargetCounts.Add(fRange, 0);
87 }
88 }
89
95 public override void Reshape(BlobCollection<T> colBottom, BlobCollection<T> colTop)
96 {
97 List<int> rgShape = new List<int>() { 1 };
98
99 foreach (Blob<T> blobTop in colTop)
100 {
101 blobTop.Reshape(rgShape);
102 }
103 }
104
116 protected override void forward(BlobCollection<T> colBottom, BlobCollection<T> colTop)
117 {
118 int nN = colBottom[0].num;
119 int nC = colBottom[0].channels;
120 int nQ = colBottom[0].height;
121 float[] rgX = convertF(colBottom[0].update_cpu_data());
122 float[] rgTgt = convertF(colBottom[1].update_cpu_data());
123
124 if (nQ != 3)
125 throw new Exception("There should only be 3 quantile predictions (upper, center, lower).");
126
127 foreach (KeyValuePair<float, List<float>> kv in m_rgAccuracies)
128 {
129 kv.Value.Clear();
130 }
131
132 for (int i = 0; i < nN; i++)
133 {
134 foreach (float fRange in m_param.quantile_accuracy_param.accuracy_ranges)
135 {
136 m_rgWithinTargetCounts[fRange] = 0;
137 }
138
139 for (int c = 0; c < nC; c++)
140 {
141 int nIdx = i * nC * nQ + c * nQ;
142 float fUpper = rgX[nIdx + 2];
143 float fCenter = rgX[nIdx + 1];
144 float fLower = rgX[nIdx];
145
146 float fUpperRange = Math.Abs(fUpper - fCenter);
147 float fLowerRange = Math.Abs(fCenter - fLower);
148
149 for (int r = 0; r < m_param.quantile_accuracy_param.accuracy_ranges.Count; r++)
150 {
151 float fUpperTarget = fCenter + fUpperRange * m_param.quantile_accuracy_param.accuracy_ranges[r];
152 float fLowerTarget = fCenter - fLowerRange * m_param.quantile_accuracy_param.accuracy_ranges[r];
153 float fTarget = rgTgt[i * nC + c];
154
155 if (fTarget <= fUpperTarget && fTarget >= fLowerTarget)
156 m_rgWithinTargetCounts[m_param.quantile_accuracy_param.accuracy_ranges[r]]++;
157 }
158 }
159
160 foreach (KeyValuePair<float, int> kvp in m_rgWithinTargetCounts)
161 {
162 float fAccuracy = (float)kvp.Value / nC;
163 m_rgAccuracies[kvp.Key].Add(fAccuracy);
164 }
165 }
166
167 int nIdx1 = 0;
168 foreach (KeyValuePair<float, List<float>> kvp in m_rgAccuracies)
169 {
170 float fAccuracy = kvp.Value.Average();
171
172 m_rgAcccuracyAverages[kvp.Key].Add(fAccuracy);
173 if (m_rgAcccuracyAverages[kvp.Key].Count > m_param.quantile_accuracy_param.average_period)
174 m_rgAcccuracyAverages[kvp.Key].RemoveAt(0);
175 }
176
177 foreach (KeyValuePair<float, List<float>> kvp in m_rgAcccuracyAverages)
178 {
179 float fAveAccuracy = average(kvp.Value, m_param.quantile_accuracy_param.average_period);
180 colTop[nIdx1].SetData(fAveAccuracy);
181 nIdx1++;
182 }
183 }
184
185 private float average(List<float> rg, uint nN)
186 {
187 if (rg.Count == 0)
188 m_fLastAverage = 0;
189 else if (rg.Count == 1)
190 m_fLastAverage = rg[0];
191 else if (rg.Count < nN)
192 {
193 m_fLastAverage = (((float)nN - 1) / (float)nN) * m_fLastAverage;
194 m_fLastAverage += (1.0f / (float)nN) * rg[rg.Count - 1];
195 }
196 else
197 {
198 m_fLastAverage = rg.Average();
199 }
200
201 return m_fLastAverage;
202 }
203
205 protected override void backward(BlobCollection<T> colTop, List<bool> rgbPropagateDown, BlobCollection<T> colBottom)
206 {
207 if (rgbPropagateDown[0])
208 throw new NotImplementedException();
209 }
210 }
211}
The Log class provides general output in text form.
Definition: Log.cs:13
void CHECK_EQ(double df1, double df2, string str)
Test whether one number is equal to another.
Definition: Log.cs:239
The BlobCollection contains a list of Blobs.
int Count
Returns the number of items in the collection.
The Blob is the main holder of data that moves through the Layers of the Net.
Definition: Blob.cs:25
void Reshape(int nNum, int nChannels, int nHeight, int nWidth, bool? bUseHalfSize=null)
DEPRECIATED; use
Definition: Blob.cs:442
The CudaDnn object is the main interface to the Low-Level Cuda C++ DLL.
Definition: CudaDnn.cs:969
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
float convertF(T df)
Converts a generic to a float value.
Definition: Layer.cs:1359
LayerParameter.LayerType m_type
Specifies the Layer type.
Definition: Layer.cs:35
The QuantileAccuracyLayer implements the Quantile Accuracy Layer used in TFT models.
override void forward(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Forward computation
override void Reshape(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Reshape the top (output) blobs.
override void setup_internal_blobs(BlobCollection< T > col)
Derivative layers should add all internal blobws to the 'col' provided.
override void backward(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Not implemented – AccuracyLayer cannot be used as a loss.
override int ExactNumBottomBlobs
Returns the exact number of required bottom (input) Blobs: x, target
override int ExactNumTopBlobs
Returns the exact number of required top (output) Blobs: one per accuracy range, each containing an a...
override void LayerSetUp(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Setup the layer.
QuantileAccuracyLayer(CudaDnn< T > cuda, Log log, LayerParameter p)
The constructor.
override void dispose()
Releases all GPU and host resources used by the Layer.
Specifies the base parameter for all layers.
QuantileAccuracyParameter quantile_accuracy_param
Returns the parameter set when initialized with LayerType.QUANTILE_ACCURACY
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.tft namespace contains all TFT related layers.
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