MyCaffe  1.12.2.41
Deep learning software for Windows C# programmers.
TVLossLayer.cs
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using MyCaffe.basecode;
6using MyCaffe.common;
7using MyCaffe.layers;
8using MyCaffe.param;
9
10namespace MyCaffe.layers.nt
11{
21 public class TVLossLayer<T> : LossLayer<T>
22 {
23 Blob<T> m_blobTmp;
24 Blob<T> m_blobYDiff;
25 Blob<T> m_blobXDiff;
26 Blob<T> m_blobMask;
27 Blob<T> m_blobGradNorm;
28 T m_tMinusOne;
29
37 : base(cuda, log, p)
38 {
40
41 m_tMinusOne = (T)Convert.ChangeType(-1, typeof(T));
42 m_blobTmp = new Blob<T>(cuda, log, false);
43 m_blobTmp.Name = p.name + " tmp";
44 m_blobYDiff = new Blob<T>(cuda, log, false);
45 m_blobYDiff.Name = p.name + " y diff";
46 m_blobXDiff = new Blob<T>(cuda, log, false);
47 m_blobXDiff.Name = p.name + " x diff";
48 m_blobMask = new Blob<T>(cuda, log, false);
49 m_blobMask.Name = p.name + " mask";
50 m_blobGradNorm = new Blob<T>(cuda, log, false);
51 m_blobGradNorm.Name = p.name + " grad norm";
52 }
53
57 public override int ExactNumBottomBlobs
58 {
59 get { return 1; }
60 }
61
65 public override int ExactNumTopBlobs
66 {
67 get { return 1; }
68 }
69
75 public override void LayerSetUp(BlobCollection<T> colBottom, BlobCollection<T> colTop)
76 {
77 }
78
79 private void create_mask(int nCount, int nH, int nW, Blob<T> mask)
80 {
81 float[] rgMask = convertF(mask.mutable_cpu_data);
82 int nSize = nH * nW;
83
84 for (int i = 0; i < nCount; i++)
85 {
86 int nUnitPos = i % nSize;
87
88 if (nUnitPos % nW == nW - 1 || nUnitPos / nW == nH - 1)
89 rgMask[i] = 0;
90 else
91 rgMask[i] = 1;
92 }
93
94 mask.mutable_cpu_data = convert(rgMask);
95 }
96
102 public override void Reshape(BlobCollection<T> colBottom, BlobCollection<T> colTop)
103 {
104 m_blobTmp.ReshapeLike(colBottom[0]);
105 m_blobXDiff.ReshapeLike(colBottom[0]);
106 m_blobYDiff.ReshapeLike(colBottom[0]);
107 m_blobGradNorm.ReshapeLike(colBottom[0]);
108
109 m_blobMask.ReshapeLike(colBottom[0]);
110 create_mask(colBottom[0].count(), colBottom[0].shape(-2), colBottom[0].shape(-1), m_blobMask);
111
112 // Loss layers output a scalar; 0 axes.
113 List<int> rgLossShape = new List<int>();
114 colTop[0].Reshape(rgLossShape);
115 }
116
126 protected override void forward(BlobCollection<T> colBottom, BlobCollection<T> colTop)
127 {
128 int nW = colBottom[0].shape(-1);
129 int nCount = colBottom[0].count();
130 long hBottomData = colBottom[0].gpu_data;
131
132 m_cuda.sub(nCount - 1, hBottomData, hBottomData, m_blobXDiff.mutable_gpu_data, 0, 1, 0);
133 m_cuda.mul(nCount, m_blobXDiff.gpu_data, m_blobMask.gpu_data, m_blobXDiff.mutable_gpu_data);
134
135 m_cuda.sub(nCount - nW, hBottomData, hBottomData, m_blobYDiff.mutable_gpu_data, 0, nW, 0);
136 m_cuda.mul(nCount, m_blobYDiff.gpu_data, m_blobMask.gpu_data, m_blobYDiff.mutable_gpu_data);
137
138 m_cuda.mul(nCount, m_blobXDiff.gpu_data, m_blobXDiff.gpu_data, m_blobGradNorm.mutable_gpu_data); // X_diff^2
139 m_cuda.mul(nCount, m_blobYDiff.gpu_data, m_blobYDiff.gpu_data, m_blobTmp.mutable_gpu_data); // Y_diff^2
140
141 m_cuda.add(nCount, m_blobTmp.gpu_data, m_blobGradNorm.gpu_data, m_blobGradNorm.mutable_gpu_data); // X_diff^2 + Y_diff^2
142 m_cuda.powx(nCount, m_blobGradNorm.gpu_data, m_param.tv_loss_param.beta / 2, m_blobTmp.mutable_gpu_data); // (X_diff^2 + Y_diff^2)^(beta/2)
143
144 double dfAsum = convertD(m_blobTmp.asum_data());
145 colTop[0].SetData(dfAsum, 0);
146 }
147
156 protected override void backward(BlobCollection<T> colTop, List<bool> rgbPropagateDown, BlobCollection<T> colBottom)
157 {
158 if (!rgbPropagateDown[0])
159 return;
160
161 int nW = colBottom[0].shape(-1);
162 int nCount = colBottom[0].count();
163 long hBottomDiff = colBottom[0].mutable_gpu_diff;
164
165 m_cuda.powx(nCount, m_blobGradNorm.gpu_data, m_param.tv_loss_param.beta / 2 - 1, m_blobGradNorm.mutable_gpu_data);
166 m_cuda.scal(nCount, m_param.tv_loss_param.beta / 2, m_blobGradNorm.mutable_gpu_data);
167
168 m_cuda.mul(nCount, m_blobXDiff.gpu_data, m_blobGradNorm.gpu_data, m_blobXDiff.mutable_gpu_data);
169 m_cuda.scal(nCount, 2.0, m_blobXDiff.mutable_gpu_data); // dX_diff
170
171 m_cuda.mul(nCount, m_blobYDiff.gpu_data, m_blobGradNorm.gpu_data, m_blobYDiff.mutable_gpu_data);
172 m_cuda.scal(nCount, 2.0, m_blobYDiff.mutable_gpu_data); // dY_diff
173
174 m_cuda.axpy(nCount, 1.0, m_blobXDiff.gpu_data, hBottomDiff);
175 m_cuda.axpy(nCount, 1.0, m_blobYDiff.gpu_data, hBottomDiff);
176 m_cuda.axpy(nCount - 1, m_tMinusOne, m_blobXDiff.gpu_data, hBottomDiff, 0, 1);
177 m_cuda.axpy(nCount - nW, m_tMinusOne, m_blobYDiff.gpu_data, hBottomDiff, 0, nW);
178
179 double dfTopDiff = convertD(colTop[0].GetDiff(0));
180 m_cuda.scal(nCount, dfTopDiff, hBottomDiff);
181 }
182 }
183}
The Log class provides general output in text form.
Definition: Log.cs:13
The BlobCollection contains a list of Blobs.
void SetData(double df)
Set all blob data to the value specified.
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.
Definition: Blob.cs:25
long mutable_gpu_data
Returns the data GPU handle used by the CudaDnn connection.
Definition: Blob.cs:1487
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...
Definition: Blob.cs:1461
void ReshapeLike(Blob< T > b, bool? bUseHalfSize=null)
Reshape this Blob to have the same shape as another Blob.
Definition: Blob.cs:648
string Name
Get/set the name of the Blob.
Definition: Blob.cs:2184
long gpu_data
Returns the data GPU handle used by the CudaDnn connection.
Definition: Blob.cs:1479
The CudaDnn object is the main interface to the Low-Level Cuda C++ DLL.
Definition: CudaDnn.cs:969
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
float convertF(T df)
Converts a generic to a float value.
Definition: Layer.cs:1359
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
The TVLossLayer computes total variation loss as described by 'Mahendran' et al., and used in Neural ...
Definition: TVLossLayer.cs:22
override int ExactNumTopBlobs
Returns the exact number of bottom blobs (e.g. 1)
Definition: TVLossLayer.cs:66
override void Reshape(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Reshape the bottom (input) and top (output) blobs.
Definition: TVLossLayer.cs:102
override void forward(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Computes the Gram matrix values.
Definition: TVLossLayer.cs:126
override void backward(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Computes the error gradient w.r.t. the absolute value inputs.
Definition: TVLossLayer.cs:156
override int ExactNumBottomBlobs
Returns the exact number of bottom blobs (e.g. 1)
Definition: TVLossLayer.cs:58
TVLossLayer(CudaDnn< T > cuda, Log log, LayerParameter p)
The TVLossLayer constructor.
Definition: TVLossLayer.cs:36
override void LayerSetUp(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Setup the layer.
Definition: TVLossLayer.cs:75
Specifies the base parameter for all layers.
string name
Specifies the name of this LayerParameter.
TVLossParameter tv_loss_param
Returns the parameter set when initialized with LayerType.TV_LOSS
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.nt namespace contains all Neural Transfer related layers.
Definition: LayerFactory.cs:19
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