MyCaffe  1.12.2.41
Deep learning software for Windows C# programmers.
PowerLayer.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{
23 public class PowerLayer<T> : NeuronLayer<T>
24 {
25 double m_dfPower;
26 double m_dfScale;
27 double m_dfShift;
28 double m_dfDiffScale;
29
43 : base(cuda, log, p)
44 {
46 }
47
53 public override void LayerSetUp(BlobCollection<T> colBottom, BlobCollection<T> colTop)
54 {
55 base.LayerSetUp(colBottom, colTop);
56
57 m_dfPower = m_param.power_param.power;
58 m_dfScale = m_param.power_param.scale;
59 m_dfShift = m_param.power_param.shift;
60 m_dfDiffScale = m_dfPower * m_dfScale;
61 }
62
76 protected override void forward(BlobCollection<T> colBottom, BlobCollection<T> colTop)
77 {
78 // Special case where we can ignore the input: scale or power are 0.
79 if (m_dfDiffScale == 0)
80 {
81 colTop[0].SetData((m_dfPower == 0) ? 1.0 : Math.Pow(m_dfShift, m_dfPower));
82 return;
83 }
84
85 int nCount = colBottom[0].count();
86 long hTopData = colTop[0].mutable_gpu_data;
87 long hBottomData = colBottom[0].gpu_data;
88
89 m_cuda.copy(nCount, hBottomData, hTopData);
90
91 if (m_dfScale != 1.0)
92 m_cuda.scal(nCount, convert(m_dfScale), hTopData);
93
94 if (m_dfShift != 0)
95 m_cuda.add_scalar(nCount, convert(m_dfShift), hTopData);
96
97 if (m_dfPower != 1.0)
98 m_cuda.powx(nCount, hTopData, convert(m_dfPower), hTopData);
99 }
100
122 protected override void backward(BlobCollection<T> colTop, List<bool> rgbPropagateDown, BlobCollection<T> colBottom)
123 {
124 if (!rgbPropagateDown[0])
125 return;
126
127 int nCount = colBottom[0].count();
128 long hTopDiff = colTop[0].gpu_diff;
129 long hBottomDiff = colBottom[0].mutable_gpu_diff;
130
131 if (m_dfDiffScale == 0 || m_dfPower == 1)
132 {
133 colBottom[0].SetDiff(m_dfDiffScale);
134 }
135 else
136 {
137 long hBottomData = colBottom[0].gpu_data;
138
139 // Compute dx/dy = scale * power * (shift + scale * x)^(power - 1)
140 // = diff_scale * y / (shift + scale * x)
141 if (m_dfPower == 2)
142 {
143 // Special case for y = (shift + scale * x)^2
144 // -> dy/dx = 2 * scale * (shift + scale * x)
145 // = diff_scale * shift + diff_scale * scale * x
146 m_cuda.axpby(nCount, convert(m_dfDiffScale * m_dfScale), hBottomData, m_tZero, hBottomDiff);
147
148 if (m_dfShift != 0)
149 m_cuda.add_scalar(nCount, convert(m_dfDiffScale * m_dfShift), hBottomDiff);
150 }
151 else if (m_dfShift == 0)
152 {
153 // Special case for y = (scale * x)^power
154 // -> dy/dx = scale * power * (scale * x)^(power - 1)
155 // = scale * power * (scale * x)^{power} * (scale * x)^(-1)
156 // = power * y / x
157 long hTopData = colTop[0].gpu_data;
158 m_cuda.div(nCount, hTopData, hBottomData, hBottomDiff);
159 m_cuda.scal(nCount, convert(m_dfPower), hBottomDiff);
160 }
161 else
162 {
163 m_cuda.copy(nCount, hBottomData, hBottomDiff);
164
165 if (m_dfScale != 1.0)
166 m_cuda.scal(nCount, convert(m_dfScale), hBottomDiff);
167
168 if (m_dfShift != 0.0)
169 m_cuda.add_scalar(nCount, convert(m_dfShift), hBottomDiff);
170
171 long hTopData = colTop[0].gpu_data;
172 m_cuda.div(nCount, hTopData, hBottomDiff, hBottomDiff);
173
174 if (m_dfDiffScale != 1.0)
175 m_cuda.scal(nCount, convert(m_dfDiffScale), hBottomDiff);
176 }
177 }
178
179 m_cuda.mul(nCount, hTopDiff, hBottomDiff, hBottomDiff);
180 }
181 }
182}
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 SetDiff(double df)
Set all blob diff to the value specified.
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
T m_tZero
Specifies a generic type equal to 0.0.
Definition: Layer.cs:76
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 NeuronLayer is an interface for layers that take one blob as input (x) and produce only equally-s...
Definition: NeuronLayer.cs:22
The PowerLayer computes the power of the input. This layer is initialized with the MyCaffe....
Definition: PowerLayer.cs:24
override void backward(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Computes the error gradient w.r.t. the power inputs
Definition: PowerLayer.cs:122
override void LayerSetUp(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Setup the layer.
Definition: PowerLayer.cs:53
PowerLayer(CudaDnn< T > cuda, Log log, LayerParameter p)
The PowerLayer constructor.
Definition: PowerLayer.cs:42
override void forward(BlobCollection< T > colBottom, BlobCollection< T > colTop)
The forward computation.
Definition: PowerLayer.cs:76
Specifies the base parameter for all layers.
PowerParameter power_param
Returns the parameter set when initialized with LayerType.POWER
LayerType
Specifies the layer type.
double power
Specifies power value in the formula .
double scale
Specifies scale value in the formula .
double shift
Specifies shift value in the formula .
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