12
12
#include " ndSandboxStdafx.h"
13
13
#include " ndTestDeepBrain.h"
14
14
15
+ // #define MNIST_USE_MINIST_CONVOLUTIONAL_LAYERS
16
+
17
+ // #define MINIST_MINIBATCH_BUFFER_SIZE 64
18
+ #define MINIST_MINIBATCH_BUFFER_SIZE 256
19
+ // #define MINIST_MINIBATCH_BUFFER_SIZE 2
20
+
21
+ #define MNIST_CONVOLUTIONAL_FEATURE_MAPS 32
22
+ // #define MIN_TRAIN_SCORE 0.9999f
23
+
24
+ #define MINIST_NUMBER_OF_EPOCKS 70
25
+
26
+ #ifdef MNIST_USE_MINIST_CONVOLUTIONAL_LAYERS
27
+ #if 1
28
+ #define MINIST_CONVOLUTIONAL_LAYER ndBrainLayerConvolutional_2d
29
+ #else
30
+ #define MINIST_CONVOLUTIONAL_LAYER ndBrainLayerConvolutionalWithDropOut_2d
31
+ #endif
32
+ #endif
33
+
34
+ #define MINIST_LINEAR_LAYERS_NEURONS 256
35
+ #define MINIST_LINEAR_DROPOUT_RATE ndFloat32 (0 .05f )
36
+
37
+ #define MINIST_ACTIVATION_TYPE ndBrainLayerActivationRelu
38
+ // #define MINIST_ACTIVATION_TYPE ndBrainLayerActivationElu
39
+ // #define MINIST_ACTIVATION_TYPE ndBrainLayerActivationSigmoidLinear
40
+
41
+ // #if 1
42
+ // //#define MINIST_DIGIT_FILTER_LAYER_TYPE ndBrainLayerConvolutional_2d
43
+ // #define MINIST_DIGIT_FILTER_LAYER_TYPE ndBrainLayerConvolutionalWithDropOut_2d
44
+ // #else
45
+ // #define MINIST_DIGIT_FILTER_LAYER_TYPE ndBrainLayerCrossCorrelation_2d
46
+ // #endif
47
+
48
+
15
49
static ndBrainMatrix* LoadMnistLabelData (const char * const filename)
16
50
{
17
51
ndBrainMatrix* labelData = nullptr ;
@@ -107,43 +141,6 @@ static ndBrainMatrix* LoadMnistSampleData(const char* const filename)
107
141
108
142
static void MnistTrainingSet ()
109
143
{
110
- // #define USE_CONVOLUTIONAL_LAYERS
111
-
112
- // #define MINIBATCH_BUFFER_SIZE 64
113
- #define MINIBATCH_BUFFER_SIZE 256
114
- // #define MINIBATCH_BUFFER_SIZE 2
115
-
116
- #define CONVOLUTIONAL_FEATURE_MAPS 32
117
- #define MIN_TRAIN_SCORE 0 .9999f
118
-
119
- #define NUMBER_OF_EPOCKS 150
120
-
121
- #ifdef USE_CONVOLUTIONAL_LAYERS
122
- #if 1
123
- #define CONVOLUTIONAL_LAYER ndBrainLayerConvolutional_2d
124
- #else
125
- #define CONVOLUTIONAL_LAYER ndBrainLayerConvolutionalWithDropOut_2d
126
- #endif
127
- #endif
128
-
129
- #define LINEAR_LAYERS_NEURONS 256
130
- #define LINEAR_DROPOUT_RATE ndFloat32 (0 .05f )
131
-
132
- #if 0
133
- #define ACTIVATION_TYPE ndBrainLayerActivationTanh
134
- #else
135
- #define ACTIVATION_TYPE ndBrainLayerActivationRelu
136
- // #define ACTIVATION_TYPE ndBrainLayerActivationElu
137
- // #define ACTIVATION_TYPE ndBrainLayerActivationSigmoidLinear
138
- #endif
139
-
140
- // #if 1
141
- // //#define DIGIT_FILTER_LAYER_TYPE ndBrainLayerConvolutional_2d
142
- // #define DIGIT_FILTER_LAYER_TYPE ndBrainLayerConvolutionalWithDropOut_2d
143
- // #else
144
- // #define DIGIT_FILTER_LAYER_TYPE ndBrainLayerCrossCorrelation_2d
145
- // #endif
146
-
147
144
ndSharedPtr<ndBrainMatrix> trainingLabels (LoadMnistLabelData (" mnistDatabase/train-labels.idx1-ubyte" ));
148
145
ndSharedPtr<ndBrainMatrix> trainingDigits (LoadMnistSampleData (" mnistDatabase/train-images.idx3-ubyte" ));
149
146
@@ -158,7 +155,7 @@ static void MnistTrainingSet()
158
155
,m_context()
159
156
,m_prioritySamples()
160
157
,m_learnRate(ndReal(5 .0e-4f ))
161
- ,m_miniBatchSize(MINIBATCH_BUFFER_SIZE )
158
+ ,m_miniBatchSize(MINIST_MINIBATCH_BUFFER_SIZE )
162
159
,m_minCombinedScore(ndInt64(1000000 ) * ndInt64 (1000000 ))
163
160
,m_minValidationFail(ndInt64(1000000 )* ndInt64(1000000 ))
164
161
,m_hasGpuSupport(m_brain->IsGpuReady ())
@@ -272,7 +269,7 @@ static void MnistTrainingSet()
272
269
m_bestBrain = ndSharedPtr<ndBrain>(new ndBrain (**trainer->GetBrain ()));
273
270
274
271
ndBrainLossCategoricalCrossEntropy loss (outputSize);
275
- for (ndInt32 epoch = 0 ; epoch < NUMBER_OF_EPOCKS ; ++epoch)
272
+ for (ndInt32 epoch = 0 ; epoch < MINIST_NUMBER_OF_EPOCKS ; ++epoch)
276
273
{
277
274
shuffleBuffer.RandomShuffle (shuffleBuffer.GetCount ());
278
275
for (ndInt32 batchStart = 0 ; batchStart < batchesSize; batchStart += m_miniBatchSize)
@@ -366,7 +363,7 @@ static void MnistTrainingSet()
366
363
ndSharedPtr<ndBrain> m_bestBrain;
367
364
ndSharedPtr<ndBrainTrainer> m_trainer;
368
365
ndSharedPtr<ndBrainContext> m_context;
369
- ndFixSizeArray<ndFixSizeArray<ndUnsigned32, 16 >, MINIBATCH_BUFFER_SIZE > m_prioritySamples;
366
+ ndFixSizeArray<ndFixSizeArray<ndUnsigned32, 16 >, MINIST_MINIBATCH_BUFFER_SIZE > m_prioritySamples;
370
367
ndReal m_learnRate;
371
368
ndInt32 m_miniBatchSize;
372
369
ndInt64 m_minCombinedScore;
@@ -379,44 +376,44 @@ static void MnistTrainingSet()
379
376
ndSharedPtr<ndBrain> brain (new ndBrain);
380
377
ndFixSizeArray<ndBrainLayer*, 32 > layers;
381
378
382
- #ifdef USE_CONVOLUTIONAL_LAYERS
379
+ #ifdef MNIST_USE_MINIST_CONVOLUTIONAL_LAYERS
383
380
ndInt32 height = 28 ;
384
381
ndInt32 width = trainingDigits->GetColumns () / height;
385
382
ndAssert ((height * width) == trainingDigits->GetColumns ());
386
383
387
- const CONVOLUTIONAL_LAYER * conv;
384
+ const MINIST_CONVOLUTIONAL_LAYER * conv;
388
385
const ndBrainLayerImagePolling_2x2* pooling;
389
386
390
- layers.PushBack (new CONVOLUTIONAL_LAYER (width, height, 1 , 3 , CONVOLUTIONAL_FEATURE_MAPS ));
391
- conv = (CONVOLUTIONAL_LAYER *)(layers[layers.GetCount () - 1 ]);
392
- layers.PushBack (new ACTIVATION_TYPE (conv->GetOutputSize ()));
387
+ layers.PushBack (new MINIST_CONVOLUTIONAL_LAYER (width, height, 1 , 3 , MNIST_CONVOLUTIONAL_FEATURE_MAPS ));
388
+ conv = (MINIST_CONVOLUTIONAL_LAYER *)(layers[layers.GetCount () - 1 ]);
389
+ layers.PushBack (new MINIST_ACTIVATION_TYPE (conv->GetOutputSize ()));
393
390
layers.PushBack (new ndBrainLayerImagePolling_2x2 (conv->GetOutputWidth (), conv->GetOutputHeight (), conv->GetOutputChannels ()));
394
391
pooling = (ndBrainLayerImagePolling_2x2*)(layers[layers.GetCount () - 1 ]);
395
392
396
- layers.PushBack (new CONVOLUTIONAL_LAYER (pooling->GetOutputWidth (), pooling->GetOutputHeight (), pooling->GetOutputChannels (), 3 , CONVOLUTIONAL_FEATURE_MAPS ));
397
- conv = (CONVOLUTIONAL_LAYER *)(layers[layers.GetCount () - 1 ]);
398
- layers.PushBack (new ACTIVATION_TYPE (conv->GetOutputSize ()));
393
+ layers.PushBack (new MINIST_CONVOLUTIONAL_LAYER (pooling->GetOutputWidth (), pooling->GetOutputHeight (), pooling->GetOutputChannels (), 3 , MNIST_CONVOLUTIONAL_FEATURE_MAPS ));
394
+ conv = (MINIST_CONVOLUTIONAL_LAYER *)(layers[layers.GetCount () - 1 ]);
395
+ layers.PushBack (new MINIST_ACTIVATION_TYPE (conv->GetOutputSize ()));
399
396
layers.PushBack (new ndBrainLayerImagePolling_2x2 (conv->GetOutputWidth (), conv->GetOutputHeight (), conv->GetOutputChannels ()));
400
397
pooling = (ndBrainLayerImagePolling_2x2*)(layers[layers.GetCount () - 1 ]);
401
398
402
- layers.PushBack (new CONVOLUTIONAL_LAYER (pooling->GetOutputWidth (), pooling->GetOutputHeight (), pooling->GetOutputChannels (), 3 , CONVOLUTIONAL_FEATURE_MAPS ));
403
- conv = (CONVOLUTIONAL_LAYER *)(layers[layers.GetCount () - 1 ]);
404
- layers.PushBack (new ACTIVATION_TYPE (conv->GetOutputSize ()));
399
+ layers.PushBack (new MINIST_CONVOLUTIONAL_LAYER (pooling->GetOutputWidth (), pooling->GetOutputHeight (), pooling->GetOutputChannels (), 3 , MNIST_CONVOLUTIONAL_FEATURE_MAPS ));
400
+ conv = (MINIST_CONVOLUTIONAL_LAYER *)(layers[layers.GetCount () - 1 ]);
401
+ layers.PushBack (new MINIST_ACTIVATION_TYPE (conv->GetOutputSize ()));
405
402
layers.PushBack (new ndBrainLayerImagePolling_2x2 (conv->GetOutputWidth (), conv->GetOutputHeight (), conv->GetOutputChannels ()));
406
403
pooling = (ndBrainLayerImagePolling_2x2*)(layers[layers.GetCount () - 1 ]);
407
404
408
405
#else
409
- layers.PushBack (new ndBrainLayerLinear (trainingDigits->GetColumns (), LINEAR_LAYERS_NEURONS ));
406
+ layers.PushBack (new ndBrainLayerLinear (trainingDigits->GetColumns (), MINIST_LINEAR_LAYERS_NEURONS ));
410
407
layers.PushBack (new ndBrainLayerLinearWithDropOut (layers[layers.GetCount () - 1 ]->GetOutputSize ()));
411
- layers.PushBack (new ACTIVATION_TYPE (layers[layers.GetCount () - 1 ]->GetOutputSize ()));
408
+ layers.PushBack (new MINIST_ACTIVATION_TYPE (layers[layers.GetCount () - 1 ]->GetOutputSize ()));
412
409
413
- layers.PushBack (new ndBrainLayerLinear (layers[layers.GetCount () - 1 ]->GetOutputSize (), LINEAR_LAYERS_NEURONS ));
410
+ layers.PushBack (new ndBrainLayerLinear (layers[layers.GetCount () - 1 ]->GetOutputSize (), MINIST_LINEAR_LAYERS_NEURONS ));
414
411
layers.PushBack (new ndBrainLayerLinearWithDropOut (layers[layers.GetCount () - 1 ]->GetOutputSize ()));
415
- layers.PushBack (new ACTIVATION_TYPE (layers[layers.GetCount () - 1 ]->GetOutputSize ()));
412
+ layers.PushBack (new MINIST_ACTIVATION_TYPE (layers[layers.GetCount () - 1 ]->GetOutputSize ()));
416
413
417
- layers.PushBack (new ndBrainLayerLinear (layers[layers.GetCount () - 1 ]->GetOutputSize (), LINEAR_LAYERS_NEURONS ));
414
+ layers.PushBack (new ndBrainLayerLinear (layers[layers.GetCount () - 1 ]->GetOutputSize (), MINIST_LINEAR_LAYERS_NEURONS ));
418
415
layers.PushBack (new ndBrainLayerLinearWithDropOut (layers[layers.GetCount () - 1 ]->GetOutputSize ()));
419
- layers.PushBack (new ACTIVATION_TYPE (layers[layers.GetCount () - 1 ]->GetOutputSize ()));
416
+ layers.PushBack (new MINIST_ACTIVATION_TYPE (layers[layers.GetCount () - 1 ]->GetOutputSize ()));
420
417
#endif
421
418
422
419
layers.PushBack (new ndBrainLayerLinear (layers[layers.GetCount () - 1 ]->GetOutputSize (), trainingLabels->GetColumns ()));
@@ -437,7 +434,7 @@ static void MnistTrainingSet()
437
434
time = ndGetTimeInMicroseconds () - time ;
438
435
439
436
char path[256 ];
440
- #ifdef USE_CONVOLUTIONAL_LAYERS
437
+ #ifdef MNIST_USE_MINIST_CONVOLUTIONAL_LAYERS
441
438
ndGetWorkingFileName (" mnistDatabase/mnist-cnn.dnn" , path);
442
439
#else
443
440
ndGetWorkingFileName (" mnistDatabase/mnist.dnn" , path);
@@ -473,32 +470,88 @@ static void MnistTestSet()
473
470
if (testLabels && testDigits)
474
471
{
475
472
char path[256 ];
476
- #ifdef USE_CONVOLUTIONAL_LAYERS
473
+ #ifdef MNIST_USE_MINIST_CONVOLUTIONAL_LAYERS
477
474
ndGetWorkingFileName (" mnistDatabase/mnist-cnn.dnn" , path);
478
475
#else
479
476
ndGetWorkingFileName (" mnistDatabase/mnist.dnn" , path);
480
477
#endif
481
478
482
- // ndSharedPtr<ndBrain> brain (ndBrainLoad::Load(path));
483
- // ndInt32 numbeOfParam = brain->GetNumberOfParameters();
484
- // ndUnsigned64 time = ndGetTimeInMicroseconds();
485
- // ndExpandTraceMessage("mnist database, number of Parameters %d\n", numbeOfParam);
486
- // if (ndBrainGpuContext::HasGpuSupport())
487
- // {
488
- // ValidateDataGpu("test data", *(*brain), *testLabels, *testDigits);
489
- // }
490
- // else
491
- // {
492
- // ValidateData("test data", *(*brain), *testLabels, *testDigits);
493
- // }
494
- // time = ndGetTimeInMicroseconds() - time;
495
- // ndExpandTraceMessage("time %f (sec)\n\n", ndFloat64(time) / 1000000.0f);
479
+ ndSharedPtr<ndBrain> brain (ndBrainLoad::Load (path));
480
+ ndInt32 numbeOfParam = brain->GetNumberOfParameters ();
481
+
482
+ ndInt32 threadCount = ndMin (ndBrainThreadPool::GetMaxThreads (), 8 );
483
+ ndSharedPtr<ndBrainContext> context (new ndBrainCpuContext);
484
+ context->GetAsCpuContext ()->SetThreadCount (threadCount);
485
+
486
+ ndInt32 minibatchSize = 256 ;
487
+ ndSharedPtr<ndBrainTrainer> inference (ndSharedPtr<ndBrainTrainer>(new ndBrainTrainerCpuInference (brain, context, minibatchSize)));
488
+
489
+ ndBrainVector groundTruth;
490
+ ndBrainVector miniBatchInput;
491
+ ndBrainVector miniBatchOutput;
492
+
493
+ ndInt32 inputSize = testDigits->GetColumns ();
494
+ ndInt32 outputSize = testLabels->GetColumns ();
495
+
496
+ miniBatchInput.SetCount (inputSize * minibatchSize);
497
+ groundTruth.SetCount (outputSize * minibatchSize);
498
+
499
+ ndUnsigned64 time = ndGetTimeInMicroseconds ();
500
+
501
+ ndInt32 failCount = 0 ;
502
+ ndInt32 batchesCount = testDigits->GetRows () / minibatchSize;
503
+ ndInt32 batchesSize = batchesCount * minibatchSize;
504
+ for (ndInt32 batchStart = 0 ; batchStart < batchesSize; batchStart += minibatchSize)
505
+ {
506
+ for (ndInt32 i = 0 ; i < minibatchSize; ++i)
507
+ {
508
+ ndBrainMemVector input (&miniBatchInput[i * inputSize], inputSize);
509
+ input.SetCount (inputSize);
510
+ input.Set ((**testDigits)[batchStart + i]);
511
+ }
512
+ inference->MakePrediction (miniBatchInput);
513
+ inference->GetOutput (miniBatchOutput);
514
+
515
+ for (ndInt32 i = 0 ; i < minibatchSize; ++i)
516
+ {
517
+ ndBrainMemVector truth (&groundTruth[i * outputSize], outputSize);
518
+ const ndBrainMemVector output (&miniBatchOutput[i * outputSize], outputSize);
519
+
520
+ truth.SetCount (outputSize);
521
+ truth.Set ((**testLabels)[batchStart + i]);
522
+
523
+ ndInt32 maxProbIndex = -1 ;
524
+ ndBrainFloat maxProbability = ndBrainFloat (-1 .0f );
525
+ for (ndInt32 j = 0 ; j < output.GetCount (); j++)
526
+ {
527
+ if (output[j] > maxProbability)
528
+ {
529
+ maxProbIndex = j;
530
+ maxProbability = output[j];
531
+ }
532
+ }
533
+
534
+ ndAssert (maxProbIndex >= 0 );
535
+ if (truth[maxProbIndex] == ndReal (0 .0f ))
536
+ {
537
+ failCount++;
538
+ }
539
+ }
540
+ }
541
+
542
+ time = ndGetTimeInMicroseconds () - time ;
543
+
544
+ ndFloat32 score = (ndFloat32)(batchesSize - failCount) / (ndFloat32)batchesSize;
545
+ ndExpandTraceMessage (" mnist database, number of Parameters %d\n " , numbeOfParam);
546
+ ndExpandTraceMessage (" success rate:%f%%" , score * 100 .0f );
547
+ ndExpandTraceMessage (" test fail count:%d\n " , failCount);
548
+ ndExpandTraceMessage (" time %f (sec)\n\n " , ndFloat64 (time ) / 1000000 .0f );
496
549
}
497
550
}
498
551
499
552
void ndHandWrittenDigits ()
500
553
{
501
554
ndSetRandSeed (53 );
502
555
MnistTrainingSet ();
503
- // MnistTestSet();
556
+ MnistTestSet ();
504
557
}
0 commit comments