File indexing completed on 2023-03-17 11:13:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #ifndef NNET_ACTIVATION_H_
0021 #define NNET_ACTIVATION_H_
0022
0023 #include <cmath>
0024 #include "ap_fixed.h"
0025 #include "nnet_common.h"
0026
0027 namespace nnet {
0028
0029 struct activ_config {
0030
0031 static const unsigned n_in = 10;
0032
0033
0034 static const unsigned table_size = 1024;
0035
0036
0037 static const unsigned io_type = io_parallel;
0038 static const unsigned reuse_factor = 1;
0039
0040
0041
0042 typedef float table_t;
0043 };
0044
0045
0046
0047
0048 template <class data_T, class res_T, typename CONFIG_T>
0049 void linear(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in]) {
0050 for (unsigned ii = 0; ii < CONFIG_T::n_in; ii++) {
0051 res[ii] = data[ii];
0052 }
0053 }
0054
0055
0056
0057
0058 template <class data_T, class res_T, typename CONFIG_T>
0059 void relu(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in]) {
0060 data_T datareg;
0061 for (unsigned ii = 0; ii < CONFIG_T::n_in; ii++) {
0062 datareg = data[ii];
0063 if (datareg > 0)
0064 res[ii] = datareg;
0065 else
0066 res[ii] = 0;
0067 }
0068 }
0069
0070 template <class data_T, class res_T, int MAX_INT, typename CONFIG_T>
0071 void relu_max(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in]) {
0072 data_T datareg;
0073 for (unsigned ii = 0; ii < CONFIG_T::n_in; ii++) {
0074 datareg = data[ii];
0075 if (datareg < 0)
0076 res[ii] = 0;
0077 else if (datareg > MAX_INT)
0078 res[ii] = MAX_INT;
0079 else
0080 res[ii] = datareg;
0081 }
0082 }
0083
0084 template <class data_T, class res_T, typename CONFIG_T>
0085 void relu6(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in]) {
0086 relu_max<data_T, res_T, 6, CONFIG_T>(data, res);
0087 }
0088
0089
0090
0091
0092 template <class out_T>
0093 inline out_T sigmoid_fcn_float(float input) {
0094 return 1.0 / (1 + exp(-input));
0095 }
0096
0097 template <class res_T, typename CONFIG_T, int N_TABLE>
0098 void init_sigmoid_table(res_T table_out[N_TABLE]) {
0099
0100
0101 for (unsigned ii = 0; ii < N_TABLE; ii++) {
0102
0103 float in_val = 2 * 8.0 * (ii - float(N_TABLE) / 2.0) / float(N_TABLE);
0104
0105 res_T real_val = sigmoid_fcn_float<res_T>(in_val);
0106
0107 table_out[ii] = (res_T)real_val;
0108 }
0109 }
0110
0111 template <class data_T, class res_T, typename CONFIG_T>
0112 void sigmoid(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in]) {
0113
0114 res_T sigmoid_table[CONFIG_T::table_size];
0115 init_sigmoid_table<res_T, CONFIG_T, CONFIG_T::table_size>(sigmoid_table);
0116
0117
0118 int data_round;
0119 unsigned index;
0120 for (unsigned ii = 0; ii < CONFIG_T::n_in; ii++) {
0121 data_round = data[ii] * CONFIG_T::table_size / 16;
0122 index = data_round + 8 * CONFIG_T::table_size / 16;
0123
0124
0125 if (index > CONFIG_T::table_size - 1)
0126 index = CONFIG_T::table_size - 1;
0127 res[ii] = (res_T)sigmoid_table[index];
0128 }
0129 }
0130
0131
0132
0133
0134 inline float exp_fcn_float(float input) { return exp(input); }
0135
0136 template <typename CONFIG_T, int N_TABLE>
0137 void init_exp_table(typename CONFIG_T::table_t table_out[N_TABLE]) {
0138 for (unsigned ii = 0; ii < N_TABLE; ii++) {
0139
0140 float in_val = 2 * 8.0 * (ii - float(N_TABLE) / 2.0) / float(N_TABLE);
0141
0142 typename CONFIG_T::table_t real_val = exp_fcn_float(in_val);
0143
0144 table_out[ii] = real_val;
0145 }
0146 }
0147
0148 template <typename CONFIG_T, int N_TABLE>
0149 void init_invert_table(typename CONFIG_T::table_t table_out[N_TABLE]) {
0150
0151
0152 for (unsigned ii = 0; ii < N_TABLE; ii++) {
0153
0154 float in_val = 64.0 * ii / float(N_TABLE);
0155
0156 if (in_val > 0.0)
0157 table_out[ii] = 1.0 / in_val;
0158 else
0159 table_out[ii] = 0.0;
0160 }
0161 }
0162
0163 template <class data_T, class res_T, typename CONFIG_T>
0164 void softmax(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in]) {
0165
0166 typename CONFIG_T::table_t exp_table[CONFIG_T::table_size];
0167 init_exp_table<CONFIG_T, CONFIG_T::table_size>(exp_table);
0168
0169 typename CONFIG_T::table_t invert_table[CONFIG_T::table_size];
0170 init_invert_table<CONFIG_T, CONFIG_T::table_size>(invert_table);
0171
0172
0173 typename CONFIG_T::table_t exp_res[CONFIG_T::n_in];
0174 typename CONFIG_T::table_t exp_diff_res[CONFIG_T::n_in]
0175 [CONFIG_T::n_in];
0176 int data_round;
0177 int index;
0178 for (int ii = 0; ii < CONFIG_T::n_in; ii++) {
0179 exp_res[ii] = 0;
0180 }
0181 for (int ii = 0; ii < CONFIG_T::n_in; ii++) {
0182 for (int jj = 0; jj < CONFIG_T::n_in; jj++) {
0183 if (ii == jj)
0184 exp_diff_res[ii][jj] = 1;
0185 else {
0186 data_round = (data[jj] - data[ii]) * CONFIG_T::table_size / 16;
0187 index = data_round + 8 * CONFIG_T::table_size / 16;
0188 if (index < 0)
0189 index = 0;
0190 if (index > CONFIG_T::table_size - 1)
0191 index = CONFIG_T::table_size - 1;
0192 exp_diff_res[ii][jj] = exp_table[index];
0193 }
0194 exp_res[ii] += exp_diff_res[ii][jj];
0195 }
0196 }
0197
0198
0199 for (unsigned ii = 0; ii < CONFIG_T::n_in; ii++) {
0200 int exp_res_index = exp_res[ii] * CONFIG_T::table_size / 64;
0201 if (exp_res_index < 0)
0202 exp_res_index = 0;
0203 if (exp_res_index > CONFIG_T::table_size - 1)
0204 exp_res_index = CONFIG_T::table_size - 1;
0205
0206 res[ii] = (res_T)invert_table[exp_res_index];
0207 }
0208 }
0209
0210
0211
0212
0213 template <typename CONFIG_T, int N_TABLE>
0214 void init_tanh_table(typename CONFIG_T::table_t table_out[N_TABLE]) {
0215
0216 for (unsigned ii = 0; ii < N_TABLE; ii++) {
0217
0218 float in_val = 2 * 4.0 * (ii - float(N_TABLE) / 2.0) / float(N_TABLE);
0219
0220 typename CONFIG_T::table_t real_val = tanh(in_val);
0221
0222 table_out[ii] = real_val;
0223 }
0224 }
0225
0226 template <class data_T, class res_T, typename CONFIG_T>
0227 void tanh(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in]) {
0228
0229 typename CONFIG_T::table_t tanh_table[CONFIG_T::table_size];
0230 init_tanh_table<CONFIG_T, CONFIG_T::table_size>(tanh_table);
0231
0232
0233 int data_round;
0234 int index;
0235 for (int ii = 0; ii < CONFIG_T::n_in; ii++) {
0236 data_round = data[ii] * CONFIG_T::table_size / 8;
0237 index = data_round + 4 * CONFIG_T::table_size / 8;
0238
0239 if (index < 0)
0240 index = 0;
0241 if (index > CONFIG_T::table_size - 1)
0242 index = CONFIG_T::table_size - 1;
0243 res[ii] = (res_T)tanh_table[index];
0244 }
0245 }
0246
0247 }
0248
0249 #endif