From 168af40fe9a3cc81c6ee16b3e81f154780c36bdb Mon Sep 17 00:00:00 2001
From: Scheaven <xuepengqiang>
Date: 星期四, 03 六月 2021 15:03:27 +0800
Subject: [PATCH] up new v4

---
 lib/detecter_tools/darknet/activations.c |  797 ++++++++++++++++++++++++++++++--------------------------
 1 files changed, 420 insertions(+), 377 deletions(-)

diff --git a/lib/detecter_tools/darknet/activations.c b/lib/detecter_tools/darknet/activations.c
index 5d12247..87ba1d9 100644
--- a/lib/detecter_tools/darknet/activations.c
+++ b/lib/detecter_tools/darknet/activations.c
@@ -1,377 +1,420 @@
-#include "activations.h"
-
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <float.h>
-
-char *get_activation_string(ACTIVATION a)
-{
-    switch(a){
-        case LOGISTIC:
-            return "logistic";
-        case LOGGY:
-            return "loggy";
-        case RELU:
-            return "relu";
-        case ELU:
-            return "elu";
-        case SELU:
-            return "selu";
-        case GELU:
-            return "gelu";
-        case RELIE:
-            return "relie";
-        case RAMP:
-            return "ramp";
-        case LINEAR:
-            return "linear";
-        case TANH:
-            return "tanh";
-        case PLSE:
-            return "plse";
-        case LEAKY:
-            return "leaky";
-        case STAIR:
-            return "stair";
-        case HARDTAN:
-            return "hardtan";
-        case LHTAN:
-            return "lhtan";
-        default:
-            break;
-    }
-    return "relu";
-}
-
-ACTIVATION get_activation(char *s)
-{
-    if (strcmp(s, "logistic")==0) return LOGISTIC;
-    if (strcmp(s, "swish") == 0) return SWISH;
-    if (strcmp(s, "mish") == 0) return MISH;
-    if (strcmp(s, "normalize_channels") == 0) return NORM_CHAN;
-    if (strcmp(s, "normalize_channels_softmax") == 0) return NORM_CHAN_SOFTMAX;
-    if (strcmp(s, "normalize_channels_softmax_maxval") == 0) return NORM_CHAN_SOFTMAX_MAXVAL;
-    if (strcmp(s, "loggy")==0) return LOGGY;
-    if (strcmp(s, "relu")==0) return RELU;
-    if (strcmp(s, "relu6") == 0) return RELU6;
-    if (strcmp(s, "elu")==0) return ELU;
-    if (strcmp(s, "selu") == 0) return SELU;
-    if (strcmp(s, "gelu") == 0) return GELU;
-    if (strcmp(s, "relie")==0) return RELIE;
-    if (strcmp(s, "plse")==0) return PLSE;
-    if (strcmp(s, "hardtan")==0) return HARDTAN;
-    if (strcmp(s, "lhtan")==0) return LHTAN;
-    if (strcmp(s, "linear")==0) return LINEAR;
-    if (strcmp(s, "ramp")==0) return RAMP;
-    if (strcmp(s, "leaky")==0) return LEAKY;
-    if (strcmp(s, "tanh")==0) return TANH;
-    if (strcmp(s, "stair")==0) return STAIR;
-    fprintf(stderr, "Couldn't find activation function %s, going with ReLU\n", s);
-    return RELU;
-}
-
-float activate(float x, ACTIVATION a)
-{
-    switch(a){
-        case LINEAR:
-            return linear_activate(x);
-        case LOGISTIC:
-            return logistic_activate(x);
-        case LOGGY:
-            return loggy_activate(x);
-        case RELU:
-            return relu_activate(x);
-        case ELU:
-            return elu_activate(x);
-        case SELU:
-            return selu_activate(x);
-        case GELU:
-            return gelu_activate(x);
-        case RELIE:
-            return relie_activate(x);
-        case RAMP:
-            return ramp_activate(x);
-        case LEAKY:
-            return leaky_activate(x);
-        case TANH:
-            return tanh_activate(x);
-        case PLSE:
-            return plse_activate(x);
-        case STAIR:
-            return stair_activate(x);
-        case HARDTAN:
-            return hardtan_activate(x);
-        case LHTAN:
-            return lhtan_activate(x);
-    }
-    return 0;
-}
-
-void activate_array(float *x, const int n, const ACTIVATION a)
-{
-    int i;
-    if (a == LINEAR) {}
-    else if (a == LEAKY) {
-        #pragma omp parallel for
-        for (i = 0; i < n; ++i) {
-            x[i] = leaky_activate(x[i]);
-        }
-    }
-    else if (a == LOGISTIC) {
-        #pragma omp parallel for
-        for (i = 0; i < n; ++i) {
-            x[i] = logistic_activate(x[i]);
-        }
-    }
-    else {
-        for (i = 0; i < n; ++i) {
-            x[i] = activate(x[i], a);
-        }
-    }
-}
-
-void activate_array_swish(float *x, const int n, float * output_sigmoid, float * output)
-{
-    int i;
-    #pragma omp parallel for
-    for (i = 0; i < n; ++i) {
-        float x_val = x[i];
-        float sigmoid = logistic_activate(x_val);
-        output_sigmoid[i] = sigmoid;
-        output[i] = x_val * sigmoid;
-    }
-}
-
-// https://github.com/digantamisra98/Mish
-void activate_array_mish(float *x, const int n, float * activation_input, float * output)
-{
-    const float MISH_THRESHOLD = 20;
-    int i;
-    #pragma omp parallel for
-    for (i = 0; i < n; ++i) {
-        float x_val = x[i];
-        activation_input[i] = x_val;    // store value before activation
-        output[i] = x_val * tanh_activate( softplus_activate(x_val, MISH_THRESHOLD) );
-    }
-}
-
-void activate_array_normalize_channels(float *x, const int n, int batch, int channels, int wh_step, float *output)
-{
-    int size = n / channels;
-
-    int i;
-    #pragma omp parallel for
-    for (i = 0; i < size; ++i) {
-        int wh_i = i % wh_step;
-        int b = i / wh_step;
-
-        const float eps = 0.0001;
-        if (i < size) {
-            float sum = eps;
-            int k;
-            for (k = 0; k < channels; ++k) {
-                float val = x[wh_i + k * wh_step + b*wh_step*channels];
-                if (val > 0) sum += val;
-            }
-            for (k = 0; k < channels; ++k) {
-                float val = x[wh_i + k * wh_step + b*wh_step*channels];
-                if (val > 0) val = val / sum;
-                else val = 0;
-                output[wh_i + k * wh_step + b*wh_step*channels] = val;
-            }
-        }
-    }
-}
-
-void activate_array_normalize_channels_softmax(float *x, const int n, int batch, int channels, int wh_step, float *output, int use_max_val)
-{
-    int size = n / channels;
-
-    int i;
-    #pragma omp parallel for
-    for (i = 0; i < size; ++i) {
-        int wh_i = i % wh_step;
-        int b = i / wh_step;
-
-        const float eps = 0.0001;
-        if (i < size) {
-            float sum = eps;
-            float max_val = -FLT_MAX;
-            int k;
-            if (use_max_val) {
-                for (k = 0; k < channels; ++k) {
-                    float val = x[wh_i + k * wh_step + b*wh_step*channels];
-                    if (val > max_val || k == 0) max_val = val;
-                }
-            }
-            else
-                max_val = 0;
-
-            for (k = 0; k < channels; ++k) {
-                float val = x[wh_i + k * wh_step + b*wh_step*channels];
-                sum += expf(val - max_val);
-            }
-            for (k = 0; k < channels; ++k) {
-                float val = x[wh_i + k * wh_step + b*wh_step*channels];
-                val = expf(val - max_val) / sum;
-                output[wh_i + k * wh_step + b*wh_step*channels] = val;
-            }
-        }
-    }
-}
-
-void gradient_array_normalize_channels_softmax(float *x, const int n, int batch, int channels, int wh_step, float *delta)
-{
-    int size = n / channels;
-
-    int i;
-    #pragma omp parallel for
-    for (i = 0; i < size; ++i) {
-        int wh_i = i % wh_step;
-        int b = i / wh_step;
-
-        if (i < size) {
-            float grad = 0;
-            int k;
-            for (k = 0; k < channels; ++k) {
-                const int index = wh_i + k * wh_step + b*wh_step*channels;
-                float out = x[index];
-                float d = delta[index];
-                grad += out*d;
-            }
-            for (k = 0; k < channels; ++k) {
-                const int index = wh_i + k * wh_step + b*wh_step*channels;
-                float d = delta[index];
-                d = d * grad;
-                delta[index] = d;
-            }
-        }
-    }
-}
-
-void gradient_array_normalize_channels(float *x, const int n, int batch, int channels, int wh_step, float *delta)
-{
-    int size = n / channels;
-
-    int i;
-    #pragma omp parallel for
-    for (i = 0; i < size; ++i) {
-        int wh_i = i % wh_step;
-        int b = i / wh_step;
-
-        if (i < size) {
-            float grad = 0;
-            int k;
-            for (k = 0; k < channels; ++k) {
-                const int index = wh_i + k * wh_step + b*wh_step*channels;
-                float out = x[index];
-                float d = delta[index];
-                grad += out*d;
-            }
-            for (k = 0; k < channels; ++k) {
-                const int index = wh_i + k * wh_step + b*wh_step*channels;
-                if (x[index] > 0) {
-                    float d = delta[index];
-                    d = d * grad;
-                    delta[index] = d;
-                }
-            }
-        }
-    }
-}
-
-float gradient(float x, ACTIVATION a)
-{
-    switch(a){
-        case LINEAR:
-            return linear_gradient(x);
-        case LOGISTIC:
-            return logistic_gradient(x);
-        case LOGGY:
-            return loggy_gradient(x);
-        case RELU:
-            return relu_gradient(x);
-        case RELU6:
-            return relu6_gradient(x);
-        case NORM_CHAN:
-            //return relu_gradient(x);
-        case NORM_CHAN_SOFTMAX_MAXVAL:
-            //...
-        case NORM_CHAN_SOFTMAX:
-            printf(" Error: should be used custom NORM_CHAN or NORM_CHAN_SOFTMAX-function for gradient \n");
-            exit(0);
-            return 0;
-        case ELU:
-            return elu_gradient(x);
-        case SELU:
-            return selu_gradient(x);
-        case GELU:
-            return gelu_gradient(x);
-        case RELIE:
-            return relie_gradient(x);
-        case RAMP:
-            return ramp_gradient(x);
-        case LEAKY:
-            return leaky_gradient(x);
-        case TANH:
-            return tanh_gradient(x);
-        case PLSE:
-            return plse_gradient(x);
-        case STAIR:
-            return stair_gradient(x);
-        case HARDTAN:
-            return hardtan_gradient(x);
-        case LHTAN:
-            return lhtan_gradient(x);
-    }
-    return 0;
-}
-
-void gradient_array(const float *x, const int n, const ACTIVATION a, float *delta)
-{
-    int i;
-    #pragma omp parallel for
-    for(i = 0; i < n; ++i){
-        delta[i] *= gradient(x[i], a);
-    }
-}
-
-// https://github.com/BVLC/caffe/blob/04ab089db018a292ae48d51732dd6c66766b36b6/src/caffe/layers/swish_layer.cpp#L54-L56
-void gradient_array_swish(const float *x, const int n, const float * sigmoid, float * delta)
-{
-    int i;
-    #pragma omp parallel for
-    for (i = 0; i < n; ++i) {
-        float swish = x[i];
-        delta[i] *= swish + sigmoid[i]*(1 - swish);
-    }
-}
-
-// https://github.com/digantamisra98/Mish
-void gradient_array_mish(const int n, const float * activation_input, float * delta)
-{
-    int i;
-    #pragma omp parallel for
-    for (i = 0; i < n; ++i) {
-        const float MISH_THRESHOLD = 20.0f;
-
-        // implementation from TensorFlow: https://github.com/tensorflow/addons/commit/093cdfa85d334cbe19a37624c33198f3140109ed
-        // implementation from Pytorch: https://github.com/thomasbrandon/mish-cuda/blob/master/csrc/mish.h#L26-L31
-        float inp = activation_input[i];
-        const float sp = softplus_activate(inp, MISH_THRESHOLD);
-        const float grad_sp = 1 - exp(-sp);
-        const float tsp = tanh(sp);
-        const float grad_tsp = (1 - tsp*tsp) * grad_sp;
-        const float grad = inp * grad_tsp + tsp;
-        delta[i] *= grad;
-
-
-        //float x = activation_input[i];
-        //float d = 2 * expf(x) + expf(2 * x) + 2;
-        //float w = 4 * (x + 1) + 4 * expf(2 * x) + expf(3 * x) + expf(x)*(4 * x + 6);
-        //float derivative = expf(x) * w / (d * d);
-        //delta[i] *= derivative;
-    }
-}
+#include "activations.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+
+char *get_activation_string(ACTIVATION a)
+{
+    switch(a){
+        case LOGISTIC:
+            return "logistic";
+        case LOGGY:
+            return "loggy";
+        case RELU:
+            return "relu";
+        case ELU:
+            return "elu";
+        case SELU:
+            return "selu";
+        case GELU:
+            return "gelu";
+        case RELIE:
+            return "relie";
+        case RAMP:
+            return "ramp";
+        case LINEAR:
+            return "linear";
+        case TANH:
+            return "tanh";
+        case PLSE:
+            return "plse";
+        case LEAKY:
+            return "leaky";
+        case STAIR:
+            return "stair";
+        case HARDTAN:
+            return "hardtan";
+        case LHTAN:
+            return "lhtan";
+        default:
+            break;
+    }
+    return "relu";
+}
+
+ACTIVATION get_activation(char *s)
+{
+    if (strcmp(s, "logistic")==0) return LOGISTIC;
+    if (strcmp(s, "swish") == 0) return SWISH;
+    if (strcmp(s, "mish") == 0) return MISH;
+    if (strcmp(s, "hard_mish") == 0) return HARD_MISH;
+    if (strcmp(s, "normalize_channels") == 0) return NORM_CHAN;
+    if (strcmp(s, "normalize_channels_softmax") == 0) return NORM_CHAN_SOFTMAX;
+    if (strcmp(s, "normalize_channels_softmax_maxval") == 0) return NORM_CHAN_SOFTMAX_MAXVAL;
+    if (strcmp(s, "loggy")==0) return LOGGY;
+    if (strcmp(s, "relu")==0) return RELU;
+    if (strcmp(s, "relu6") == 0) return RELU6;
+    if (strcmp(s, "elu")==0) return ELU;
+    if (strcmp(s, "selu") == 0) return SELU;
+    if (strcmp(s, "gelu") == 0) return GELU;
+    if (strcmp(s, "relie")==0) return RELIE;
+    if (strcmp(s, "plse")==0) return PLSE;
+    if (strcmp(s, "hardtan")==0) return HARDTAN;
+    if (strcmp(s, "lhtan")==0) return LHTAN;
+    if (strcmp(s, "linear")==0) return LINEAR;
+    if (strcmp(s, "ramp")==0) return RAMP;
+    if (strcmp(s, "revleaky") == 0) return REVLEAKY;
+    if (strcmp(s, "leaky")==0) return LEAKY;
+    if (strcmp(s, "tanh")==0) return TANH;
+    if (strcmp(s, "stair")==0) return STAIR;
+    fprintf(stderr, "Couldn't find activation function %s, going with ReLU\n", s);
+    return RELU;
+}
+
+float activate(float x, ACTIVATION a)
+{
+    switch(a){
+        case LINEAR:
+            return linear_activate(x);
+        case LOGISTIC:
+            return logistic_activate(x);
+        case LOGGY:
+            return loggy_activate(x);
+        case RELU:
+            return relu_activate(x);
+        case ELU:
+            return elu_activate(x);
+        case SELU:
+            return selu_activate(x);
+        case GELU:
+            return gelu_activate(x);
+        case RELIE:
+            return relie_activate(x);
+        case RAMP:
+            return ramp_activate(x);
+        case REVLEAKY:
+        case LEAKY:
+            return leaky_activate(x);
+        case TANH:
+            return tanh_activate(x);
+        case PLSE:
+            return plse_activate(x);
+        case STAIR:
+            return stair_activate(x);
+        case HARDTAN:
+            return hardtan_activate(x);
+        case LHTAN:
+            return lhtan_activate(x);
+    }
+    return 0;
+}
+
+void activate_array(float *x, const int n, const ACTIVATION a)
+{
+    int i;
+    if (a == LINEAR) {}
+    else if (a == LEAKY) {
+        #pragma omp parallel for
+        for (i = 0; i < n; ++i) {
+            x[i] = leaky_activate(x[i]);
+        }
+    }
+    else if (a == LOGISTIC) {
+        #pragma omp parallel for
+        for (i = 0; i < n; ++i) {
+            x[i] = logistic_activate(x[i]);
+        }
+    }
+    else {
+        for (i = 0; i < n; ++i) {
+            x[i] = activate(x[i], a);
+        }
+    }
+}
+
+void activate_array_swish(float *x, const int n, float * output_sigmoid, float * output)
+{
+    int i;
+    #pragma omp parallel for
+    for (i = 0; i < n; ++i) {
+        float x_val = x[i];
+        float sigmoid = logistic_activate(x_val);
+        output_sigmoid[i] = sigmoid;
+        output[i] = x_val * sigmoid;
+    }
+}
+
+// https://github.com/digantamisra98/Mish
+void activate_array_mish(float *x, const int n, float * activation_input, float * output)
+{
+    const float MISH_THRESHOLD = 20;
+    int i;
+    #pragma omp parallel for
+    for (i = 0; i < n; ++i) {
+        float x_val = x[i];
+        activation_input[i] = x_val;    // store value before activation
+        output[i] = x_val * tanh_activate( softplus_activate(x_val, MISH_THRESHOLD) );
+    }
+}
+
+static float hard_mish_yashas(float x)
+{
+    if (x > 0)
+        return x;
+    if (x > -2)
+        return x * x / 2 + x;
+    return 0;
+}
+
+void activate_array_hard_mish(float *x, const int n, float * activation_input, float * output)
+{
+    int i;
+    #pragma omp parallel for
+    for (i = 0; i < n; ++i) {
+        float x_val = x[i];
+        activation_input[i] = x_val;    // store value before activation
+        output[i] = hard_mish_yashas(x_val);
+    }
+}
+
+void activate_array_normalize_channels(float *x, const int n, int batch, int channels, int wh_step, float *output)
+{
+    int size = n / channels;
+
+    int i;
+    #pragma omp parallel for
+    for (i = 0; i < size; ++i) {
+        int wh_i = i % wh_step;
+        int b = i / wh_step;
+
+        const float eps = 0.0001;
+        if (i < size) {
+            float sum = eps;
+            int k;
+            for (k = 0; k < channels; ++k) {
+                float val = x[wh_i + k * wh_step + b*wh_step*channels];
+                if (val > 0) sum += val;
+            }
+            for (k = 0; k < channels; ++k) {
+                float val = x[wh_i + k * wh_step + b*wh_step*channels];
+                if (val > 0) val = val / sum;
+                else val = 0;
+                output[wh_i + k * wh_step + b*wh_step*channels] = val;
+            }
+        }
+    }
+}
+
+void activate_array_normalize_channels_softmax(float *x, const int n, int batch, int channels, int wh_step, float *output, int use_max_val)
+{
+    int size = n / channels;
+
+    int i;
+    #pragma omp parallel for
+    for (i = 0; i < size; ++i) {
+        int wh_i = i % wh_step;
+        int b = i / wh_step;
+
+        const float eps = 0.0001;
+        if (i < size) {
+            float sum = eps;
+            float max_val = -FLT_MAX;
+            int k;
+            if (use_max_val) {
+                for (k = 0; k < channels; ++k) {
+                    float val = x[wh_i + k * wh_step + b*wh_step*channels];
+                    if (val > max_val || k == 0) max_val = val;
+                }
+            }
+            else
+                max_val = 0;
+
+            for (k = 0; k < channels; ++k) {
+                float val = x[wh_i + k * wh_step + b*wh_step*channels];
+                sum += expf(val - max_val);
+            }
+            for (k = 0; k < channels; ++k) {
+                float val = x[wh_i + k * wh_step + b*wh_step*channels];
+                val = expf(val - max_val) / sum;
+                output[wh_i + k * wh_step + b*wh_step*channels] = val;
+            }
+        }
+    }
+}
+
+void gradient_array_normalize_channels_softmax(float *x, const int n, int batch, int channels, int wh_step, float *delta)
+{
+    int size = n / channels;
+
+    int i;
+    #pragma omp parallel for
+    for (i = 0; i < size; ++i) {
+        int wh_i = i % wh_step;
+        int b = i / wh_step;
+
+        if (i < size) {
+            float grad = 0;
+            int k;
+            for (k = 0; k < channels; ++k) {
+                const int index = wh_i + k * wh_step + b*wh_step*channels;
+                float out = x[index];
+                float d = delta[index];
+                grad += out*d;
+            }
+            for (k = 0; k < channels; ++k) {
+                const int index = wh_i + k * wh_step + b*wh_step*channels;
+                float d = delta[index];
+                d = d * grad;
+                delta[index] = d;
+            }
+        }
+    }
+}
+
+void gradient_array_normalize_channels(float *x, const int n, int batch, int channels, int wh_step, float *delta)
+{
+    int size = n / channels;
+
+    int i;
+    #pragma omp parallel for
+    for (i = 0; i < size; ++i) {
+        int wh_i = i % wh_step;
+        int b = i / wh_step;
+
+        if (i < size) {
+            float grad = 0;
+            int k;
+            for (k = 0; k < channels; ++k) {
+                const int index = wh_i + k * wh_step + b*wh_step*channels;
+                float out = x[index];
+                float d = delta[index];
+                grad += out*d;
+            }
+            for (k = 0; k < channels; ++k) {
+                const int index = wh_i + k * wh_step + b*wh_step*channels;
+                if (x[index] > 0) {
+                    float d = delta[index];
+                    d = d * grad;
+                    delta[index] = d;
+                }
+            }
+        }
+    }
+}
+
+float gradient(float x, ACTIVATION a)
+{
+    switch(a){
+        case LINEAR:
+            return linear_gradient(x);
+        case LOGISTIC:
+            return logistic_gradient(x);
+        case LOGGY:
+            return loggy_gradient(x);
+        case RELU:
+            return relu_gradient(x);
+        case RELU6:
+            return relu6_gradient(x);
+        case NORM_CHAN:
+            //return relu_gradient(x);
+        case NORM_CHAN_SOFTMAX_MAXVAL:
+            //...
+        case NORM_CHAN_SOFTMAX:
+            printf(" Error: should be used custom NORM_CHAN or NORM_CHAN_SOFTMAX-function for gradient \n");
+            exit(0);
+            return 0;
+        case ELU:
+            return elu_gradient(x);
+        case SELU:
+            return selu_gradient(x);
+        case GELU:
+            return gelu_gradient(x);
+        case RELIE:
+            return relie_gradient(x);
+        case RAMP:
+            return ramp_gradient(x);
+        case REVLEAKY:
+        case LEAKY:
+            return leaky_gradient(x);
+        case TANH:
+            return tanh_gradient(x);
+        case PLSE:
+            return plse_gradient(x);
+        case STAIR:
+            return stair_gradient(x);
+        case HARDTAN:
+            return hardtan_gradient(x);
+        case LHTAN:
+            return lhtan_gradient(x);
+    }
+    return 0;
+}
+
+void gradient_array(const float *x, const int n, const ACTIVATION a, float *delta)
+{
+    int i;
+    #pragma omp parallel for
+    for(i = 0; i < n; ++i){
+        delta[i] *= gradient(x[i], a);
+    }
+}
+
+// https://github.com/BVLC/caffe/blob/04ab089db018a292ae48d51732dd6c66766b36b6/src/caffe/layers/swish_layer.cpp#L54-L56
+void gradient_array_swish(const float *x, const int n, const float * sigmoid, float * delta)
+{
+    int i;
+    #pragma omp parallel for
+    for (i = 0; i < n; ++i) {
+        float swish = x[i];
+        delta[i] *= swish + sigmoid[i]*(1 - swish);
+    }
+}
+
+// https://github.com/digantamisra98/Mish
+void gradient_array_mish(const int n, const float * activation_input, float * delta)
+{
+    int i;
+    #pragma omp parallel for
+    for (i = 0; i < n; ++i) {
+        const float MISH_THRESHOLD = 20.0f;
+
+        // implementation from TensorFlow: https://github.com/tensorflow/addons/commit/093cdfa85d334cbe19a37624c33198f3140109ed
+        // implementation from Pytorch: https://github.com/thomasbrandon/mish-cuda/blob/master/csrc/mish.h#L26-L31
+        float inp = activation_input[i];
+        const float sp = softplus_activate(inp, MISH_THRESHOLD);
+        const float grad_sp = 1 - exp(-sp);
+        const float tsp = tanh(sp);
+        const float grad_tsp = (1 - tsp*tsp) * grad_sp;
+        const float grad = inp * grad_tsp + tsp;
+        delta[i] *= grad;
+
+
+        //float x = activation_input[i];
+        //float d = 2 * expf(x) + expf(2 * x) + 2;
+        //float w = 4 * (x + 1) + 4 * expf(2 * x) + expf(3 * x) + expf(x)*(4 * x + 6);
+        //float derivative = expf(x) * w / (d * d);
+        //delta[i] *= derivative;
+    }
+}
+
+static float hard_mish_yashas_grad(float x)
+{
+    if (x > 0)
+        return 1;
+    if (x > -2)
+        return x + 1;
+    return 0;
+}
+
+void gradient_array_hard_mish(const int n, const float * activation_input, float * delta)
+{
+    int i;
+    #pragma omp parallel for
+    for (i = 0; i < n; ++i) {
+        float inp = activation_input[i];
+        delta[i] *= hard_mish_yashas_grad(inp);
+    }
+}

--
Gitblit v1.8.0