Line data Source code
1 : /************************************************************************* 2 : * 3 : * Project 4 : * _____ _____ __ __ _____ 5 : * / ____| __ \| \/ | __ \ 6 : * ___ _ __ ___ _ __ | | __| |__) | \ / | |__) | 7 : * / _ \| '_ \ / _ \ '_ \| | |_ | ___/| |\/| | ___/ 8 : *| (_) | |_) | __/ | | | |__| | | | | | | | 9 : * \___/| .__/ \___|_| |_|\_____|_| |_| |_|_| 10 : * | | 11 : * |_| 12 : * 13 : * Copyright (C) Akiel Aries, <akiel@akiel.org>, et al. 14 : * 15 : * This software is licensed as described in the file LICENSE, which 16 : * you should have received as part of this distribution. The terms 17 : * among other details are referenced in the official documentation 18 : * seen here : https://akielaries.github.io/openGPMP/ along with 19 : * important files seen in this project. 20 : * 21 : * You may opt to use, copy, modify, merge, publish, distribute 22 : * and/or sell copies of the Software, and permit persons to whom 23 : * the Software is furnished to do so, under the terms of the 24 : * LICENSE file. As this is an Open Source effort, all implementations 25 : * must be of the same methodology. 26 : * 27 : * 28 : * 29 : * This software is distributed on an AS IS basis, WITHOUT 30 : * WARRANTY OF ANY KIND, either express or implied. 31 : * 32 : ************************************************************************/ 33 : #include <openGPMP/ml/activators.hpp> 34 : #include <vector> 35 : 36 0 : double gpmp::ml::Activation::sigmoid(double z) { 37 0 : return 1.0 / (1.0 + exp(-z)); 38 : } 39 : 40 0 : double gpmp::ml::Activation::sigmoid_derivative(double z) { 41 0 : double sig = sigmoid(z); 42 0 : return sig * (1.0 - sig); 43 : } 44 : 45 0 : double gpmp::ml::Activation::relu(double z) { 46 0 : return z > 0 ? z : 0; 47 : } 48 : 49 0 : double gpmp::ml::Activation::relu_derivative(double z) { 50 0 : return z > 0 ? 1 : 0; 51 : } 52 : 53 : std::vector<double> 54 0 : gpmp::ml::Activation::softmax(const std::vector<double> &inputs) { 55 0 : std::vector<double> result; 56 0 : double sum_exp = 0.0; 57 0 : for (double input : inputs) { 58 0 : sum_exp += exp(input); 59 : } 60 0 : for (double input : inputs) { 61 0 : result.push_back(exp(input) / sum_exp); 62 : } 63 0 : return result; 64 0 : } 65 : 66 : std::vector<std::vector<double>> 67 0 : gpmp::ml::Activation::softmax_derivative(const std::vector<double> &inputs) { 68 : std::vector<std::vector<double>> result( 69 : inputs.size(), 70 0 : std::vector<double>(inputs.size(), 0.0)); 71 0 : std::vector<double> softmax_values = softmax(inputs); 72 0 : for (size_t i = 0; i < inputs.size(); ++i) { 73 0 : for (size_t j = 0; j < inputs.size(); ++j) { 74 0 : if (i == j) { 75 0 : result[i][j] = softmax_values[i] * (1.0 - softmax_values[i]); 76 : } else { 77 0 : result[i][j] = -softmax_values[i] * softmax_values[j]; 78 : } 79 : } 80 : } 81 0 : return result; 82 0 : } 83 : 84 0 : double gpmp::ml::Activation::binary_step(double z) { 85 0 : return z >= 0 ? 1 : 0; 86 : } 87 : 88 0 : double gpmp::ml::Activation::tanh(double z) { 89 0 : return std::tanh(z); 90 : } 91 : 92 0 : double gpmp::ml::Activation::tanh_derivative(double z) { 93 0 : double tanh_z = std::tanh(z); 94 0 : return 1.0 - tanh_z * tanh_z; 95 : } 96 : 97 0 : double gpmp::ml::Activation::smht(double z) { 98 0 : return z / (1.0 + exp(-z)); 99 : } 100 : 101 0 : double gpmp::ml::Activation::smht_derivative(double z) { 102 0 : double smht_z = smht(z); 103 0 : return smht_z * (1.0 - smht_z); 104 : } 105 : 106 0 : double gpmp::ml::Activation::gelu(double z) { 107 0 : return 0.5 * z * 108 0 : (1.0 + tanh(sqrt(2.0 / M_PI) * (z + 0.044715 * z * z * z))); 109 : } 110 : 111 0 : double gpmp::ml::Activation::gelu_derivative(double z) { 112 : double cdf = 113 0 : 0.5 * (1.0 + tanh(sqrt(2.0 / M_PI) * (0.044715 * z * z * z + 3 * z))); 114 0 : double pdf = exp(-0.5 * z * z) / sqrt(2.0 * M_PI); 115 0 : return 0.5 * (1.0 + cdf + 116 0 : z * pdf * (1.0 / M_PI) * 117 0 : (0.5 * (1.0 + tanh(sqrt(2.0 / M_PI) * 118 0 : (0.044715 * z * z * z + 3 * z)))) + 119 0 : (1.0 / M_PI) * (1.0 - cdf * cdf)); 120 : } 121 : 122 0 : double gpmp::ml::Activation::softplus(double z) { 123 0 : return log(1.0 + exp(z)); 124 : } 125 : 126 0 : double gpmp::ml::Activation::elu(double z, double alpha) { 127 0 : return z >= 0 ? z : alpha * (exp(z) - 1); 128 : } 129 : 130 0 : double gpmp::ml::Activation::elu_derivative(double z, double alpha) { 131 0 : return z >= 0 ? 1 : elu(z, alpha) + alpha; 132 : } 133 : 134 0 : double gpmp::ml::Activation::selu(double z, double alpha, double scale) { 135 0 : return scale * (z >= 0 ? z : alpha * (exp(z) - 1)); 136 : } 137 : 138 : double 139 0 : gpmp::ml::Activation::selu_derivative(double z, double alpha, double scale) { 140 0 : return scale * (z >= 0 ? 1 : alpha * exp(z)); 141 : } 142 : 143 0 : double gpmp::ml::Activation::leaky_relu(double z, double alpha) { 144 0 : return z >= 0 ? z : alpha * z; 145 : } 146 : 147 0 : double gpmp::ml::Activation::leaky_relu_derivative(double z, double alpha) { 148 0 : return z >= 0 ? 1 : alpha; 149 : } 150 : 151 0 : double gpmp::ml::Activation::prelu(double z, double alpha) { 152 0 : return z >= 0 ? z : alpha * z; 153 : } 154 : 155 0 : double gpmp::ml::Activation::prelu_derivative(double z, double alpha) { 156 0 : return z >= 0 ? 1 : alpha; 157 : } 158 : 159 0 : double gpmp::ml::Activation::silu(double z) { 160 0 : return z / (1 + exp(-z)); 161 : } 162 : 163 0 : double gpmp::ml::Activation::silu_derivative(double z) { 164 0 : double sig_z = sigmoid(z); 165 0 : return sig_z + (1 - sig_z) * z * sig_z; 166 : }