UESMANN CPP  1.0
Reference implementation of UESMANN
/home/travis/build/jimfinnis/uesmanncpp/testBasic.cpp
Go to the documentation of this file.
1 
8 #include <iostream>
9 
10 #define BOOST_TEST_MAIN
11 #define BOOST_TEST_DYN_LINK
12 #include <boost/test/unit_test.hpp>
13 
14 #include "test.hpp"
15 
28 class TestExampleSet : public ExampleSet {
29 public:
30  TestExampleSet() : ExampleSet(10,5,2, 2){
31  for(int i=0;i<getCount();i++){
32  double *d = getInputs(i);
33  for(int j=0;j<getInputCount();j++)
34  d[j] = i*10+j;
35  d= getOutputs(i);
36  for(int j=0;j<getOutputCount();j++)
37  d[j] = i*20+j;
38  setH(i,i*1000);
39  }
40  }
41 };
42 
49 BOOST_AUTO_TEST_SUITE(basic)
50 
51 
52 
53 
59 
60  // just check the retrieved values are correct
61  for(int i=0;i<e.getCount();i++){
62  double *d = e.getInputs(i);
63  for(int j=0;j<e.getInputCount();j++)
64  BOOST_REQUIRE(d[j]== i*10+j);
65  d= e.getOutputs(i);
66  for(int j=0;j<e.getOutputCount();j++)
67  BOOST_REQUIRE(d[j]== i*20+j);
68  BOOST_REQUIRE(e.getH(i)==i*1000);
69  }
70 }
71 
77  TestExampleSet parent;
78 
79  // check that bad values throw
80  BOOST_REQUIRE_THROW(ExampleSet bad(parent,5,6),std::out_of_range);
81  BOOST_REQUIRE_THROW(ExampleSet bad(parent,-1,6),std::out_of_range);
82  BOOST_REQUIRE_THROW(ExampleSet bad(parent,5,6),std::out_of_range);
83  BOOST_REQUIRE_THROW(ExampleSet bad(parent,11,6),std::out_of_range);
84 
85  ExampleSet e(parent,5,5);
86  BOOST_REQUIRE(e.getCount()==5);
87  for(int i=0;i<e.getCount();i++){
88  int parentIndex = i+5;
89  double *d = e.getInputs(i);
90  for(int j=0;j<e.getInputCount();j++)
91  BOOST_REQUIRE(d[j]== parentIndex*10+j);
92  d= e.getOutputs(i);
93  for(int j=0;j<e.getOutputCount();j++)
94  BOOST_REQUIRE(d[j]== parentIndex*20+j);
95  BOOST_REQUIRE(e.getH(i)==parentIndex*1000);
96  }
97 
98 }
99 
104 template <class T> void sshuffle(T *x, int ct){
105  T tmp;
106  for(int i=ct-1;i>=1;i--){
107  long lr;
108  int j = rand()%(i+1);
109  tmp=x[i];
110  x[i]=x[j];
111  x[j]=tmp;
112  }
113 }
114 
115 
121  long t;
122  static const int NUMEXAMPLES = 100;
123  static const int CYCLE=5;
124 
125  srand(time(&t));
126  // make a bunch of numbers and shuffle them
127  int arr[NUMEXAMPLES];
128  for(int i=0;i<NUMEXAMPLES;i++){
129  arr[i] = i;
130  }
131  sshuffle<int>(arr,NUMEXAMPLES);
132 
133  // make them alternate odd and even
134  alternate<int>(arr,NUMEXAMPLES,CYCLE,[](int v){return v;});
135 
136 // for(int i=0;i<NUMEXAMPLES;i++)printf("%d ",arr[i]%CYCLE);
137 
138  // make sure each item is there only once and that the sequence
139  // alternates odd and even
140  bool seen[NUMEXAMPLES];
141  for(int i=0;i<NUMEXAMPLES;i++)seen[i]=false;
142  for(int i=0;i<NUMEXAMPLES;i++){
143  int n = arr[i];
144  BOOST_REQUIRE(!seen[n]);
145  seen[n]=true;
146  BOOST_REQUIRE((n%CYCLE) == (i%CYCLE));
147  }
148 }
149 
155  TestExampleSet e;
156  for(int i=0;i<e.getCount();i++){
157  e.setH(i, i<e.getCount()/2 ? 1:0);
158  }
159 
160  drand48_data rd;
161  srand48_r(10,&rd);
163  for(int i=0;i<e.getCount();i++){
164  BOOST_REQUIRE((e.getH(i)<0.5 ? 0 : 1) == i%2);
165  }
166 }
167 
173  static const int NUMBEREXAMPLES=32;
174  // 32 examples (or however many) with 2 inputs and 1 output, and 4
175  // different modulator values. We then create 4 different groups.
176  // Each group has 4 examples with the same inputs, but with different outputs
177  // between the groups. Examples within each group have the same modulator value.
178 
179  ExampleSet e(NUMBEREXAMPLES,2,1, 4);
180  for(int i=0;i<NUMBEREXAMPLES/4;i++){
181  int exbase = i*4;
182  for(int j=0;j<4;j++){
183  int ex = exbase+j;
184  double *d = e.getInputs(ex);
185  for(int k=0;k<e.getInputCount();k++)
186  d[k] = k*10+j;
187  *e.getOutputs(ex) = ex;
188  e.setH(ex,i);
189  }
190  }
191 
192  // shuffle the data with STRIDE, so that the four groups are each considered as
193  // a whole and moved en-bloc.
194 
195  drand48_data rd;
196  srand48_r(10,&rd);
198 
199  // check the results, both that the output is non-monotonic (i.e. data is shuffled)
200  // and that the inputs appear to show that the blocks are intact.
201 
202  int lasto = -1;
203  bool monotonic_increasing=true;
204  for(int i=0;i<NUMBEREXAMPLES;i++){
205  double *d = e.getInputs(i);
206  int i0 = (int)d[0];
207  int i1 = (int)d[1];
208  int o = (int)*e.getOutputs(i);
209  int h = (int)e.getH(i);
210  if(o<lasto)monotonic_increasing=false;
211  lasto=o;
212  BOOST_REQUIRE(i0 == i%4);
213  BOOST_REQUIRE(o/4 == h);
214  }
215  BOOST_REQUIRE(!monotonic_increasing);
216 }
217 
223  static const int NUMBEREXAMPLES=32;
224  // 32 examples (or however many) with 2 inputs and 1 output, and 4
225  // different modulator values. We then create 4 different groups.
226  // Each group has 4 examples with the same inputs, but with different outputs
227  // between the groups. Examples within each group have the same modulator value.
228  // Concretely, examples (index,in0,in1,out,h) will be
229  // (0 0 10 0 0) (1 1 11 1 0) (2 2 12 2 0) (3 3 13 3 0) (4 0 10 4 0) (5 1 11 5 0)
230  // (6 2 12 6 0) (7 3 13 7 0)
231  // (8 0 10 8 1) (9 1 11 9 1) (10 2 12 10 1) (11 3 13 11 1) (12 0 10 12 1) (13 1 11 13 1)
232  // (14 2 12 14 1) (15 3 13 15 1)
233  // and so on. These should be shuffled randomly, and then rearranged so that the
234  // h-value (the last value in the brackets) goes (0,1,2,3,0,1,2,3...)
235 
236  ExampleSet e(NUMBEREXAMPLES,2,1, 4);
237  for(int i=0;i<NUMBEREXAMPLES/4;i++){
238  int exbase = i*4;
239  for(int j=0;j<4;j++){
240  int ex = exbase+j;
241  double *d = e.getInputs(ex);
242  for(int k=0;k<e.getInputCount();k++)
243  d[k] = k*10+j;
244  *e.getOutputs(ex) = ex;
245  e.setH(ex,i/2); // gives four hormone levels
246  e.setHRange(0,i/2); // reset max h-level (will end up at 3)
247  }
248  }
249 
250  // shuffle the data with ALTERNATE, so everything is shuffled freely, but
251  // ensure afterwards that the h-levels go 01230123....
252 
253  drand48_data rd;
254  srand48_r(10,&rd);
256 
257  // check the results, both that the output is non-monotonic (i.e. data is shuffled)
258  // and that the h-sequence is correct
259 
260  int lasto = -1;
261  bool monotonic_increasing=true;
262  for(int i=0;i<NUMBEREXAMPLES;i++){
263  double *d = e.getInputs(i);
264  int i0 = (int)d[0];
265  int i1 = (int)d[1];
266  int o = (int)*e.getOutputs(i);
267  int h = (int)e.getH(i);
268  if(o<lasto)monotonic_increasing=false;
269  lasto=o;
270  BOOST_REQUIRE(i%4==h);
271  BOOST_REQUIRE(o%4==i0); // check internal integrity of datum
272  }
273  BOOST_REQUIRE(!monotonic_increasing);
274 }
275 
276 
282 void zero(Net *n){
283  int ct = n->getDataSize();
284  double *buf = new double[ct];
285  for(int i=0;i<ct;i++)buf[i]=0;
286  n->load(buf);
287  delete[] buf;
288 }
289 
300  TestExampleSet e;
301  // make a standard net
303  // zero it so all the nodes produce 0.5 as their output
304  zero(n);
305  // get the MSE on all examples, given the example values
306  // in the test set
307  double t = n->test(e);
308  delete n;
309 
310  // value determined by running the network with a lot of
311  // debug printing
312  BOOST_REQUIRE(t==11400.25);
313 
314 }
315 
323  MNIST m("../testdata/t10k-labels-idx1-ubyte","../testdata/t10k-images-idx3-ubyte");
324  ExampleSet e(m);
325 
326  // in this data set, example 1233 should be a 5.
327  double *in = e.getInputs(1233);
328 
329  for(int y=0;y<28;y++){
330  for(int x=0;x<28;x++){
331  uint8_t qq = *in++ * 10;
332  if(qq>9)putchar('?');
333  else putchar(qq?qq+'0':'.');
334  }
335  putchar('\n');
336  }
337  double *out = e.getOutputs(1233);
338  BOOST_REQUIRE(e.getOutputCount()==10);
339  for(int i=0;i<10;i++){
340  if(i==5)
341  BOOST_REQUIRE(out[i]==1.0);
342  else
343  BOOST_REQUIRE(out[i]==0.0);
344  }
345 }
346 
352 BOOST_AUTO_TEST_SUITE_END()
353 
int getCount() const
get the number of examples
Definition: data.hpp:327
void setH(int example, double h)
Set the h (modulator) for a given example.
Definition: data.hpp:378
This class encapsulates and loads data in the standard MNIST format. The data resides in two files...
Definition: mnist.hpp:24
Useful stuff for testing.
Shuffle single examples, but follow up by running a pass over the examples to ensure that they altern...
Definition: data.hpp:238
ExampleSet & setHRange(double mn, double mx)
Definition: data.hpp:300
double * getOutputs(int example)
Get a pointer to the outputs for a given example, for reading or writing.
Definition: data.hpp:349
Utility test class. Constructs a standard set: 10 examples, 5 ins, 2 outs:
Definition: testBasic.cpp:28
void shuffle(drand48_data *rd, ShuffleMode mode, int nExamples=0)
Shuffle the example using a PRNG and a Fisher-Yates shuffle.
Definition: data.hpp:259
int getInputCount() const
get the number of inputs in all examples
Definition: data.hpp:311
Shuffle blocks of numHLevels examples, rather than single examples. This is intended for cases where ...
Definition: data.hpp:228
void zero(Net *n)
set all parameters (weights and biases) in a network to zero
Definition: testBasic.cpp:282
void sshuffle(T *x, int ct)
simple shuffle for testing - performs a Fisher-Yates shuffle on an array of items of class T...
Definition: testBasic.cpp:104
static Net * makeNet(NetType t, ExampleSet &e, int hnodes)
Construct a single hidden layer network of a given type which conforms to the example set...
Definition: netFactory.hpp:32
int getOutputCount() const
get the number of outputs in all examples
Definition: data.hpp:319
BOOST_AUTO_TEST_CASE(example)
Test the basic example.
Definition: testBasic.cpp:57
virtual int getDataSize() const =0
Get the length of the serialised data block for this network.
virtual void load(double *buf)=0
Given that the pointer points to a data block of the correct size for the current network...
double getH(int example) const
Get the h (modulator) for a given example.
Definition: data.hpp:359
double test(ExampleSet &examples, int start=0, int num=-1)
Test a network. Runs the network over a set of examples and returns the mean MSE for all outputs whe...
Definition: net.hpp:142
The abstract network type upon which all others are based. It&#39;s not pure virtual, in that it encapsul...
Definition: net.hpp:39
double * getInputs(int example)
Get a pointer to the inputs for a given example, for reading or writing.
Definition: data.hpp:338
A set of example data. Each datum consists of hormone (i.e. modulator value), inputs and outputs...
Definition: data.hpp:57