HOG2
Perceptron.cpp
Go to the documentation of this file.
1 /*
2  * perceptron.cpp
3  * games
4  *
5  * Created by Nathan Sturtevant on 3/2/05.
6  * Copyright 2005 __MyCompanyName__. All rights reserved.
7  *
8  */
9 
10 #include <math.h>
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <unistd.h>
14 #include "perceptron.h"
15 
16 static const float VERSION = 1.0;
17 
18 perceptron::perceptron(int _inputs, int _outputs, double _rate)
19 {
21  inputs = _inputs;
22  outputs = _outputs;
23  rate = _rate;
24  weight.resize(0);
25  //weight = 0;
27 }
28 
30 {
31  inputs = perp->inputs;
32  outputs = perp->outputs;
33  rate = perp->rate;
35  weight.resize(0);
36  //weight = 0;
38 }
39 
41 {
42  weight.resize(0);
43  //weight = 0;
44  inputs = outputs = -1;
45  load(f);
46 }
47 
49 {
50  perceptron *perp = (perceptron *)fa;
51  inputs = perp->inputs;
52  outputs = perp->outputs;
54  rate = perp->rate;
55  weight.resize(0);
56  //weight = 0;
58  load((perceptron*)fa);
59 }
60 
62 {
63  freeMemory();
64 }
65 
67 {
68 // if (weight.size() != 0)
69 // freeMemory();
70  fflush(stdin);
71  weight.resize(outputs);// = new double*[outputs];
72  for (int x = 0; x < outputs; x++)
73  {
74  fflush(stdin);
75  weight[x].resize(inputs+1);// = new double[inputs+1];
76  for (int y = 0; y <= inputs; y++)
77  weight[x][y] = ((double)2*random()/RAND_MAX-1)/(double)inputs;
78  }
79  output.resize(outputs);// = new double[outputs];
80 }
81 
83 {
84 // if (weight != 0)
85 // {
90  weight.resize(0);
91 // //weight = 0;
92 // }
93 }
94 
95 void perceptron::load(const char *fname)
96 {
97  FILE *f;
98  f = fopen(fname, "r");
99  if (f == 0)
100  {
101  fprintf(stderr, "PERP Error: could not open file '%s' for loading; trying once more.\n", fname);
102  sleep(1);
103  f = fopen(fname, "r");
104  if (f == 0)
105  {
106  fprintf(stderr, "PERP Error: could not open file '%s' for loading.\n", fname);
107  exit(0);
108  return;
109  }
110  }
111  load(f);
112  fclose(f);
113 }
114 
115 void perceptron::load(FILE *f)
116 {
117  int inputs1, outputs1;
118  float version;
119  int res = fscanf(f, "PERP %f %d %d\n", &version, &inputs1, &outputs1);
120  if (res != 3)
121  {
122  printf("Error: unrecognized perceptron file. Expected header 'PERP <version> <inputs> <outputs>'.");
123  exit(0);
124  }
125  if (version > VERSION)
126  {
127  printf("Error: loaded network is %1.2f, but code can only handle %1.2f.",
128  version, VERSION);
129  exit(0);
130  }
131  if ((inputs1 != inputs) || (outputs1 != outputs))
132  {
133  freeMemory();
134  inputs = inputs1;
135  outputs = outputs1;
136  allocateMemory();
137  }
138 
139  for (int y = 0; y < outputs; y++)
140  {
141  for (int x = 0; x <= inputs; x++)
142  {
143  fscanf(f, "%le ", &weight[y][x]);
144  }
145  }
146 }
147 
149 {
150  if (p && ((p->inputs != inputs) || (p->outputs != outputs)))
151  {
152  freeMemory();
153  inputs = p->inputs;
154  outputs = p->outputs;
156 
157  allocateMemory();
158  }
159  for (int y = 0; y < outputs; y++)
160  {
161  for (int x = 0; x <= inputs; x++)
162  {
163  weight[y][x] = p->weight[y][x];
164  }
165  }
166 }
167 
168 bool perceptron::validSaveFile(char *fname)
169 {
170  FILE *f;
171  f = fopen(fname, "r");
172  if (f == 0)
173  {
174  return false;
175  }
176  int finput, foutput;
177  float version;
178  int res = fscanf(f, "PERP %f %d %d\n", &version, &finput, &foutput);
179  fclose(f);
180  if (res != 3)
181  {
182  return false;
183  }
184  if (version > VERSION)
185  {
186  return false;
187  }
188  return true;
189 }
190 
191 void perceptron::save(const char *fname)
192 {
193  FILE *f;
194  f = fopen(fname, "w+");
195  if (f == 0)
196  {
197  fprintf(stderr, "Error: could not open file for saving.\n");
198  return;
199  }
200  save(f);
201  fclose(f);
202 }
203 
204 void perceptron::save(FILE *f)
205 {
206  fprintf(f, "PERP %1.2f %d %d\n", VERSION, inputs, outputs);
207 
208  for (int y = 0; y < outputs; y++)
209  {
210  for (int x = 0; x <= inputs; x++)
211  {
212  fprintf(f, "%le ", weight[y][x]);
213  }
214  fprintf(f, "\n");
215  }
216 }
217 
218 //double perceptron::g(double a)
219 //{
220 // return (1/(1+exp(-a)));
221 //}
222 //
223 //double perceptron::dg(double a)
224 //{
225 // double g_a = g(a);
226 // return g_a*(1-g_a);
228 //}
229 
230 double perceptron::outputerr(const std::vector<double> &out, const std::vector<double> &expected, int which)
231 {
232  double err = (out[which]-expected[which]);
233 
234  return err;
235 }
236 
237 double perceptron::train(std::vector<double> &input, std::vector<double> &target)
238 {
239  double totalErr = 0;
240  test(input);
241  for (int x = 0; x < outputs; x++)
242  {
243  double err = outputerr(output,target,x);
244  totalErr+=err*err;
245  for (int y = 0; y < inputs; y++)
246  {
247  weight[x][y] -= rate*err*input[y];
248  }
249  weight[x][inputs] -= rate*err*(1); // bias
250  }
251  return totalErr;
252 }
253 
254 double perceptron::train(std::vector<unsigned int> &input, std::vector<double> &target)
255 {
256  double totalErr = 0;
257  test(input);
258  for (int x = 0; x < outputs; x++)
259  {
260  double err = outputerr(output,target,x);
261  totalErr+=err*err;
262  double rateTimesError = rate*err;
263  for (unsigned int y = 0; y < input.size(); y++)
264  {
265  weight[x][input[y]] -= rateTimesError;
266  }
267  weight[x][inputs] -= rateTimesError; // bias
268  }
269  return totalErr;
270 }
271 
272 double *perceptron::test(const std::vector<double> &input)
273 {
274  for (int y = 0; y < outputs; y++)
275  {
276  output[y] = weight[y][inputs];
277  for (int x = 0; x < inputs; x++)
278  {
279  output[y] += weight[y][x]*input[x];
280  }
281  if (outputActivation == kStep)
282  {
283  if(output[y] > .5)
284  output[y] = 1.0;
285  else
286  output[y] = 0.0;
287  }
288 
289  }
290  return &output[0];
291 }
292 
293 double *perceptron::test(const std::vector<unsigned int> &input)
294 {
295  for (int y = 0; y < outputs; y++)
296  {
297  output[y] = weight[y][inputs]; // bias
298  for (unsigned int x = 0; x < input.size(); x++)
299  {
300  output[y] += weight[y][input[x]];
301  }
302  }
303  return &output[0];
304 }
305 
307 {
308  for (int y = 0; y < outputs; y++)
309  for (int x = 0; x <= inputs; x++)
310  {
311  printf("%1.3f ", weight[y][x]);
312  }
313  printf("\n");
314 }
perceptron::allocateMemory
void allocateMemory()
Definition: Perceptron.cpp:66
perceptron::train
double train(std::vector< double > &input, std::vector< double > &output2)
Definition: Perceptron.cpp:237
perceptron::output
std::vector< double > output
Definition: Perceptron.h:49
perceptron::save
void save(const char *)
Definition: Perceptron.cpp:191
perceptron::test
double * test(const std::vector< double > &input)
Definition: Perceptron.cpp:272
FunctionApproximator::rate
double rate
Definition: FunctionApproximator.h:61
FunctionApproximator
Definition: FunctionApproximator.h:25
perceptron::~perceptron
~perceptron()
Definition: Perceptron.cpp:61
VERSION
static const float VERSION
Definition: Perceptron.cpp:16
perceptron::perceptron
perceptron(int inputs, int outputs, double learnrate)
Definition: Perceptron.cpp:18
perceptron::load
void load(const char *)
Definition: Perceptron.cpp:95
Perceptron.h
kStep
@ kStep
Definition: FunctionApproximator.h:21
perceptron
Definition: Perceptron.h:14
perceptron::outputs
int outputs
Definition: Perceptron.h:52
kLinear
@ kLinear
Definition: FunctionApproximator.h:20
perceptron::freeMemory
void freeMemory()
Definition: Perceptron.cpp:82
perceptron::weight
std::vector< std::vector< double > > weight
Definition: Perceptron.h:48
perceptron::outputerr
double outputerr(const std::vector< double > &output, const std::vector< double > &expected, int which)
Definition: Perceptron.cpp:230
perceptron::Print
void Print()
Definition: Perceptron.cpp:306
perceptron::inputs
int inputs
Definition: Perceptron.h:52
FunctionApproximator::outputActivation
tActivation outputActivation
Definition: FunctionApproximator.h:62
perceptron::validSaveFile
static bool validSaveFile(char *fname)
Definition: Perceptron.cpp:168