mirror of
https://github.com/opencv/opencv.git
synced 2025-01-18 22:44:02 +08:00
Port Swish and Mish layers
This commit is contained in:
parent
f5b9705c70
commit
8a18d132fc
@ -462,6 +462,18 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
|
||||
static Ptr<TanHLayer> create(const LayerParams ¶ms);
|
||||
};
|
||||
|
||||
class CV_EXPORTS SwishLayer : public ActivationLayer
|
||||
{
|
||||
public:
|
||||
static Ptr<SwishLayer> create(const LayerParams ¶ms);
|
||||
};
|
||||
|
||||
class CV_EXPORTS MishLayer : public ActivationLayer
|
||||
{
|
||||
public:
|
||||
static Ptr<MishLayer> create(const LayerParams ¶ms);
|
||||
};
|
||||
|
||||
class CV_EXPORTS SigmoidLayer : public ActivationLayer
|
||||
{
|
||||
public:
|
||||
|
@ -103,6 +103,8 @@ void initializeLayerFactory()
|
||||
CV_DNN_REGISTER_LAYER_CLASS(PReLU, ChannelsPReLULayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Sigmoid, SigmoidLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(TanH, TanHLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Swish, SwishLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(Mish, MishLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(ELU, ELULayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(BNLL, BNLLLayer);
|
||||
CV_DNN_REGISTER_LAYER_CLASS(AbsVal, AbsLayer);
|
||||
|
@ -534,6 +534,152 @@ struct TanHFunctor
|
||||
int64 getFLOPSPerElement() const { return 1; }
|
||||
};
|
||||
|
||||
struct SwishFunctor
|
||||
{
|
||||
typedef SwishLayer Layer;
|
||||
|
||||
bool supportBackend(int backendId, int)
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_HALIDE;
|
||||
}
|
||||
|
||||
void apply(const float* srcptr, float* dstptr, int len, size_t planeSize, int cn0, int cn1) const
|
||||
{
|
||||
for( int cn = cn0; cn < cn1; cn++, srcptr += planeSize, dstptr += planeSize )
|
||||
{
|
||||
for( int i = 0; i < len; i++ )
|
||||
{
|
||||
float x = srcptr[i];
|
||||
dstptr[i] = x / (1.0f + exp(-x));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
bool applyOCL(InputArrayOfArrays inps, OutputArrayOfArrays outs, OutputArrayOfArrays internals)
|
||||
{
|
||||
std::vector<UMat> inputs;
|
||||
std::vector<UMat> outputs;
|
||||
|
||||
inps.getUMatVector(inputs);
|
||||
outs.getUMatVector(outputs);
|
||||
String buildopt = oclGetTMacro(inputs[0]);
|
||||
|
||||
for (size_t i = 0; i < inputs.size(); i++)
|
||||
{
|
||||
UMat& src = inputs[i];
|
||||
UMat& dst = outputs[i];
|
||||
|
||||
ocl::Kernel kernel("SwishForward", ocl::dnn::activations_oclsrc, buildopt);
|
||||
kernel.set(0, (int)src.total());
|
||||
kernel.set(1, ocl::KernelArg::PtrReadOnly(src));
|
||||
kernel.set(2, ocl::KernelArg::PtrWriteOnly(dst));
|
||||
|
||||
size_t gSize = src.total();
|
||||
CV_Assert(kernel.run(1, &gSize, NULL, false));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
top(x, y, c, n) = input / (1.0f + exp(-input));
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
InferenceEngine::Builder::Layer initInfEngineBuilderAPI()
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "");
|
||||
}
|
||||
#endif // HAVE_INF_ENGINE
|
||||
|
||||
bool tryFuse(Ptr<dnn::Layer>&) { return false; }
|
||||
|
||||
void getScaleShift(Mat&, Mat&) const {}
|
||||
|
||||
int64 getFLOPSPerElement() const { return 3; }
|
||||
|
||||
};
|
||||
|
||||
struct MishFunctor
|
||||
{
|
||||
typedef MishLayer Layer;
|
||||
|
||||
bool supportBackend(int backendId, int)
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_HALIDE;
|
||||
}
|
||||
|
||||
void apply(const float* srcptr, float* dstptr, int len, size_t planeSize, int cn0, int cn1) const
|
||||
{
|
||||
for( int cn = cn0; cn < cn1; cn++, srcptr += planeSize, dstptr += planeSize )
|
||||
{
|
||||
for( int i = 0; i < len; i++ )
|
||||
{
|
||||
float x = srcptr[i];
|
||||
dstptr[i] = x * tanh(log(1.0f + exp(x)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
bool applyOCL(InputArrayOfArrays inps, OutputArrayOfArrays outs, OutputArrayOfArrays internals)
|
||||
{
|
||||
std::vector<UMat> inputs;
|
||||
std::vector<UMat> outputs;
|
||||
|
||||
inps.getUMatVector(inputs);
|
||||
outs.getUMatVector(outputs);
|
||||
String buildopt = oclGetTMacro(inputs[0]);
|
||||
|
||||
for (size_t i = 0; i < inputs.size(); i++)
|
||||
{
|
||||
UMat& src = inputs[i];
|
||||
UMat& dst = outputs[i];
|
||||
|
||||
ocl::Kernel kernel("MishForward", ocl::dnn::activations_oclsrc, buildopt);
|
||||
kernel.set(0, (int)src.total());
|
||||
kernel.set(1, ocl::KernelArg::PtrReadOnly(src));
|
||||
kernel.set(2, ocl::KernelArg::PtrWriteOnly(dst));
|
||||
|
||||
size_t gSize = src.total();
|
||||
CV_Assert(kernel.run(1, &gSize, NULL, false));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
top(x, y, c, n) = input * tanh(log(1.0f + exp(input)));
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
InferenceEngine::Builder::Layer initInfEngineBuilderAPI()
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "");
|
||||
}
|
||||
#endif // HAVE_INF_ENGINE
|
||||
|
||||
bool tryFuse(Ptr<dnn::Layer>&) { return false; }
|
||||
|
||||
void getScaleShift(Mat&, Mat&) const {}
|
||||
|
||||
int64 getFLOPSPerElement() const { return 3; }
|
||||
|
||||
};
|
||||
|
||||
struct SigmoidFunctor
|
||||
{
|
||||
typedef SigmoidLayer Layer;
|
||||
@ -1111,6 +1257,22 @@ Ptr<TanHLayer> TanHLayer::create(const LayerParams& params)
|
||||
return l;
|
||||
}
|
||||
|
||||
Ptr<SwishLayer> SwishLayer::create(const LayerParams& params)
|
||||
{
|
||||
Ptr<SwishLayer> l(new ElementWiseLayer<SwishFunctor>());
|
||||
l->setParamsFrom(params);
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
Ptr<MishLayer> MishLayer::create(const LayerParams& params)
|
||||
{
|
||||
Ptr<MishLayer> l(new ElementWiseLayer<MishFunctor>());
|
||||
l->setParamsFrom(params);
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
Ptr<SigmoidLayer> SigmoidLayer::create(const LayerParams& params)
|
||||
{
|
||||
Ptr<SigmoidLayer> l(new ElementWiseLayer<SigmoidFunctor>());
|
||||
|
@ -95,6 +95,18 @@ __kernel void SigmoidForward(const int count, __global const T* in, __global T*
|
||||
out[index] = 1.0f / (1.0f + exp(-in[index]));
|
||||
}
|
||||
|
||||
__kernel void SwishForward(const int count, __global const T* in, __global T* out) {
|
||||
int index = get_global_id(0);
|
||||
if(index < count)
|
||||
out[index] = in[index] / (1.0f + exp(-in[index]));
|
||||
}
|
||||
|
||||
__kernel void MishForward(const int count, __global const T* in, __global T* out) {
|
||||
int index = get_global_id(0);
|
||||
if(index < count)
|
||||
out[index] = in[index] * tanh(log(1.0f + exp(in[index])));
|
||||
}
|
||||
|
||||
__kernel void BNLLForward(const int n, __global const T* in, __global T* out) {
|
||||
int index = get_global_id(0);
|
||||
if (index < n) {
|
||||
|
@ -583,7 +583,7 @@ TEST_P(NoParamActivation, Accuracy)
|
||||
testInPlaceActivation(lp, backendId, targetId);
|
||||
}
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, NoParamActivation, Combine(
|
||||
/*type*/ Values("TanH", "Sigmoid", "AbsVal", "BNLL"),
|
||||
/*type*/ Values("TanH", "Sigmoid", "AbsVal", "BNLL", "Swish", "Mish"),
|
||||
dnnBackendsAndTargetsWithHalide()
|
||||
));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user