1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <iostream> #include <functional> #include <random>
#define INP 4 #define HID 10 #define OUT 3 #define LR 0.1
using namespace std;
default_random_engine engine; uniform_real_distribution<float> distr(0, 1); function<float()> rnd = bind(distr, engine);
float train_data[3][25][4]; float test_data[3][25][4];
class nodeclass { public: int num_input; vector<float> weight_input; float value; function<float(float)> f;
nodeclass(int n, function<float(float)> ff): num_input(n), f(ff) { init_weight(); } ~nodeclass(){} void init_weight() { for (int i=0;i<num_input;i++) weight_input.push_back(rnd()); } void calcf(float x) { value = f(x); } };
vector<nodeclass*> inpnode, hidnode, outnode;
float sigmoid(float x) { if (x < -45.0) return 0.0; else if (x > 45.0) return 1.0; else return 1.0 / (1.0 + exp(-x)); }
void init_nodes() { for (int i=0;i<INP;i++) inpnode.push_back(new nodeclass(0, NULL)); for (int i=0;i<HID;i++) hidnode.push_back(new nodeclass(INP, sigmoid)); for (int i=0;i<OUT;i++) outnode.push_back(new nodeclass(HID, sigmoid)); }
void init_dataset() { FILE * fp = fopen("iris.data", "r"); for (int j=0; j<3; j++) { char temp[100]; for (int i=0; i<25; i++) fscanf(fp, "%f,%f,%f,%f,%s", &train_data[j][i][0], &train_data[j][i][1], &train_data[j][i][2], &train_data[j][i][3], temp); for (int i=0; i<25; i++) fscanf(fp, "%f,%f,%f,%f,%s", &test_data[j][i][0], &test_data[j][i][1], &test_data[j][i][2], &test_data[j][i][3], temp); } fclose(fp); }
void inference(int type, int clas, int index) { if (type) { int i = 0; for (auto now : inpnode) now->value = test_data[clas][index][i++]; } else { int i = 0; for (auto now : inpnode) now->value = train_data[clas][index][i++]; } for (auto now : hidnode) { float temp = 0.0; int i = 0; for (auto front : inpnode) temp += front->value * now->weight_input[i++]; now->calcf(temp); } for (auto now : outnode) { float temp = 0.0; int i = 0; for (auto front : hidnode) temp += front->value * now->weight_input[i++]; now->calcf(temp); } }
void train() { for (int j=0;j<3;j++) { float expected[] = {0.0, 0.0, 0.0}; expected[j] = 1.0; for (int index = 0; index < 25; ++index) { inference(0, j, index); int i = 0; for (auto now : outnode) { float delta = (expected[i++] - now->value) * (1 - now->value) * now->value; int k = 0; for (auto front : hidnode) now->weight_input[k++] += LR * delta * front->value; } i = 0; for (auto now : hidnode) { float delta = 0.0; int k = 0; for (auto back : outnode) delta += (expected[k++] - back->value) * (1 - back->value) * back->value * back->weight_input[i] * (1 - now->value) * now->value; k = 0; for (auto front : inpnode) now->weight_input[k++] += LR * delta * front->value; i++; } } } }
int select(vector<nodeclass*> arr) { int max = (arr[1]->value > arr[0]->value) ? 1 : 0; if (arr[2]->value > arr[max]->value) max = 2; return max; }
int test() { int count = 0; for (int clas = 0; clas < 3; ++clas) { for (int index = 0; index < 25; ++index) { inference(0, clas, index); if (select(outnode) == clas) { ++count; } } } printf("Accuracy rate: %lf\n", (double)count / 75); return count; }
int main() { init_nodes(); init_dataset(); while (test() < 75) { train(); } test();
return 0; }
|