@@ -142,6 +142,9 @@ class BaseConvolutionLayerImpl : public ConvolutionLayer
142
142
}
143
143
};
144
144
145
+
146
+ #define IS_POWER_LAYER (layer ) \
147
+ (!layer.empty() && !layer->type.compare(" Power" ))
145
148
// TODO: simultaneously convolution and bias addition for cache optimization
146
149
class ConvolutionLayerImpl : public BaseConvolutionLayerImpl
147
150
{
@@ -161,6 +164,7 @@ class ConvolutionLayerImpl : public BaseConvolutionLayerImpl
161
164
bool newWeightAndBias;
162
165
bool newActiv;
163
166
ocl4dnnFusedActiv_t activType;
167
+ float power;
164
168
#endif
165
169
ConvolutionLayerImpl ()
166
170
{
@@ -169,6 +173,7 @@ class ConvolutionLayerImpl : public BaseConvolutionLayerImpl
169
173
newWeightAndBias = false ;
170
174
newActiv = false ;
171
175
activType = OCL4DNN_CONV_FUSED_ACTIV_NONE;
176
+ power = 0 .f ;
172
177
#endif
173
178
}
174
179
@@ -225,6 +230,22 @@ class ConvolutionLayerImpl : public BaseConvolutionLayerImpl
225
230
#ifdef HAVE_OPENCL
226
231
newActiv = true ;
227
232
activType = OCL4DNN_CONV_FUSED_ACTIV_NONE;
233
+
234
+ if (preferableTarget == DNN_TARGET_OPENCL)
235
+ {
236
+ Ptr<PowerLayer> activ_power = activ.dynamicCast <PowerLayer>();
237
+ if (!activ_power.empty ())
238
+ {
239
+ if (activ_power->scale != 1 .f || activ_power->shift != 0 .f )
240
+ newWeightAndBias = true ;
241
+
242
+ if (activ_power->scale != 1 .f )
243
+ weightsMat.release ();
244
+
245
+ power = activ_power->power ;
246
+ activType = OCL4DNN_CONV_FUSED_ACTIV_POWER;
247
+ }
248
+ }
228
249
#endif
229
250
return !activ.empty ();
230
251
}
@@ -727,11 +748,12 @@ class ConvolutionLayerImpl : public BaseConvolutionLayerImpl
727
748
biasvec[k] = biasMat.at <float >(k);
728
749
}
729
750
730
- if ( !bnorm.empty () || !scaleLayer.empty () )
751
+ if ( !bnorm.empty () || !scaleLayer.empty () || IS_POWER_LAYER (activ) )
731
752
{
732
753
Mat scale, shift, scale2, shift2;
733
754
const float *scaleptr = 0 , *shiftptr = 0 ;
734
755
const float *scaleptr2 = 0 , *shiftptr2 = 0 ;
756
+ float a = 1 .f , b = 0 .f ;
735
757
736
758
if ( !bnorm.empty () )
737
759
{
@@ -758,7 +780,14 @@ class ConvolutionLayerImpl : public BaseConvolutionLayerImpl
758
780
}
759
781
}
760
782
761
- if (shiftptr || shiftptr2)
783
+ if ( IS_POWER_LAYER (activ) )
784
+ {
785
+ Ptr<PowerLayer> activ_power = activ.dynamicCast <PowerLayer>();
786
+ a = activ_power->scale ;
787
+ b = activ_power->shift ;
788
+ }
789
+
790
+ if (shiftptr || shiftptr2 || b != 0 .f )
762
791
fusedBias = true ;
763
792
764
793
for ( int i = 0 ; i < outCn; i++ )
@@ -771,9 +800,9 @@ class ConvolutionLayerImpl : public BaseConvolutionLayerImpl
771
800
int j, wcols = weightsMat.cols ;
772
801
773
802
for ( j = 0 ; j < wcols; j++ )
774
- w_i[j] *= (s1*s2);
803
+ w_i[j] *= (s1*s2*a );
775
804
776
- biasvec[i] = biasvec[i]*(s1*s2) + (delta1*s2 + delta2);
805
+ biasvec[i] = biasvec[i]*(s1*s2*a ) + (delta1*s2*a + delta2*a + b );
777
806
}
778
807
}
779
808
biasvec[outCn] = biasvec[outCn+1 ] = biasvec[outCn-1 ];
@@ -827,10 +856,15 @@ class ConvolutionLayerImpl : public BaseConvolutionLayerImpl
827
856
CV_Assert (!reluslope.empty ());
828
857
convolutionOp->setActivPReLU (true , reluslope);
829
858
}
859
+ else if ( activType == OCL4DNN_CONV_FUSED_ACTIV_POWER)
860
+ {
861
+ convolutionOp->setActivPower (true , power);
862
+ }
830
863
else
831
864
{
832
865
convolutionOp->setActivReLU (false , 0 );
833
866
convolutionOp->setActivPReLU (false , reluslope);
867
+ convolutionOp->setActivPower (false , 1 .f );
834
868
}
835
869
newActiv = false ;
836
870
}
@@ -840,6 +874,7 @@ class ConvolutionLayerImpl : public BaseConvolutionLayerImpl
840
874
int batch_size = inpMat.size [0 ];
841
875
842
876
return convolutionOp->Forward (inpMat,
877
+ inputs.size () == 2 ? inputs[1 ] : UMat (),
843
878
umat_blobs[0 ],
844
879
(hasBias () || fusedBias) ? umat_blobs[1 ] : UMat (),
845
880
outMat,
0 commit comments