1
1
// This unit is under development - do not use it.
2
2
unit neuralfit;
3
3
4
- { $mode objfpc}{ $H+}
4
+ { $IFDEF FPC}
5
+ { $mode objfpc}
6
+ { $H+}
7
+ { $DEFINE HASTHREADS}
8
+ { $ENDIF}
5
9
6
10
interface
7
11
8
12
uses
9
- Classes, SysUtils, neuralnetwork, neuralvolume, MTProcs;
13
+ Classes, SysUtils, neuralnetwork, neuralvolume
14
+ { $IFDEF HASTHREADS} , MTProcs{ $ENDIF}
15
+ ;
10
16
11
17
type
12
18
TCustomLearningRateScheduleFn = function(Epoch: integer): single;
13
19
TCustomLearningRateScheduleObjFn = function(Epoch: integer): single of object ;
14
20
21
+ { $IFNDEF HASTHREADS}
22
+ TMultiThreadProcItem = TObject;
23
+ { $ENDIF}
24
+
15
25
// / This is a base class. Do not use it directly.
16
26
TNeuralFitBase = class (TMObject)
17
27
protected
@@ -28,7 +38,7 @@ TNeuralFitBase = class(TMObject)
28
38
FGlobalTotalLoss: single;
29
39
FGlobalErrorSum: single;
30
40
FFinishedThread: TNNetVolume;
31
- FCritSec: TRTLCriticalSection;
41
+ { $IFDEF HASTHREADS } FCritSec: TRTLCriticalSection;{ $ENDIF }
32
42
FMultipleSamplesAtValidation: boolean;
33
43
FDataAugmentation: boolean;
34
44
FVerbose: boolean;
@@ -205,6 +215,9 @@ procedure TNeuralFit.Fit(pNN: TNNet; pTrainingVolumes, pValidationVolumes,
205
215
ValidationRecord: TNeuralFloat;
206
216
iEpochCount: integer;
207
217
begin
218
+ { $IFNDEF HASTHREADS}
219
+ FMaxThreadNum := 1 ;
220
+ { $ENDIF}
208
221
iEpochCount := FInitialEpoch;
209
222
FCurrentLearningRate := FInitialLearningRate;
210
223
FTrainingVolumes := pTrainingVolumes;
@@ -296,7 +309,11 @@ procedure TNeuralFit.Fit(pNN: TNNet; pTrainingVolumes, pValidationVolumes,
296
309
FGlobalErrorSum := 0 ;
297
310
FFinishedThread.Fill(0 );
298
311
FNN.ClearTime();
312
+ { $IFDEF HASTHREADS}
299
313
ProcThreadPool.DoParallel(@RunNNThread, 0 , FThreadNN.Count-1 , Nil , FThreadNN.Count);
314
+ { $ELSE}
315
+ RunNNThread(0 , nil , Self);
316
+ { $ENDIF}
300
317
if FClipDelta > 0 then
301
318
begin
302
319
MaxDelta := FNN.ForceMaxAbsoluteDelta(FClipDelta);
@@ -382,7 +399,11 @@ procedure TNeuralFit.Fit(pNN: TNNet; pTrainingVolumes, pValidationVolumes,
382
399
FGlobalTotalLoss := 0 ;
383
400
FGlobalErrorSum := 0 ;
384
401
FMessageProc(' Starting Validation.' );
402
+ { $IFDEF HASTHREADS}
385
403
ProcThreadPool.DoParallel(@TestNNThread, 0 , FThreadNN.Count-1 , Nil , FThreadNN.Count);
404
+ { $ELSE}
405
+ TestNNThread(0 , nil , Self);
406
+ { $ENDIF}
386
407
387
408
FGlobalTotal := (FGlobalHit + FGlobalMiss);
388
409
if FGlobalTotal > 0 then
@@ -433,7 +454,11 @@ procedure TNeuralFit.Fit(pNN: TNNet; pTrainingVolumes, pValidationVolumes,
433
454
FGlobalTotalLoss := 0 ;
434
455
FGlobalErrorSum := 0 ;
435
456
FMessageProc(' Starting Testing.' );
457
+ { $IFDEF HASTHREADS}
436
458
ProcThreadPool.DoParallel(@TestNNThread, 0 , FThreadNN.Count-1 , Nil , FThreadNN.Count);
459
+ { $ELSE}
460
+ TestNNThread(0 , nil , Self);
461
+ { $ENDIF}
437
462
438
463
FGlobalTotal := (FGlobalHit + FGlobalMiss);
439
464
if FGlobalTotal > 0 then
@@ -564,11 +589,11 @@ procedure TNeuralFit.RunNNThread(Index: PtrInt; Data: Pointer;
564
589
LocalNN.GetOutput( pOutput );
565
590
LocalNN.Backpropagate( FTrainingVolumes[ElementIdx].O );
566
591
567
- LocalErrorSum += vOutput.SumDiff( pOutput );
592
+ LocalErrorSum := LocalErrorSum + vOutput.SumDiff( pOutput );
568
593
569
594
// TODO: calculate loss here!
570
595
CurrentLoss := 0 ;
571
- LocalTotalLoss += CurrentLoss;
596
+ LocalTotalLoss := LocalTotalLoss + CurrentLoss;
572
597
573
598
if Assigned(FInferHitFn) then
574
599
begin
@@ -589,25 +614,35 @@ procedure TNeuralFit.RunNNThread(Index: PtrInt; Data: Pointer;
589
614
begin
590
615
while FFinishedThread.FData[Index + 1 ] = 0 do ;
591
616
LocalNN.SumDeltasNoChecks(FThreadNN[Index + 1 ]);
617
+ { $IFDEF FPC}
592
618
FFinishedThread.FData[Index] += FFinishedThread.FData[Index + 1 ];
619
+ { $ELSE}
620
+ FFinishedThread.FData[Index] := FFinishedThread.FData[Index] +
621
+ FFinishedThread.FData[Index + 1 ];
622
+ { $ENDIF}
593
623
end ;
594
624
end ;
595
- FFinishedThread.FData[Index] += 1 ;
625
+ FFinishedThread.FData[Index] := FFinishedThread.FData[Index] + 1 ;
596
626
if Index and 3 = 0 then
597
627
begin
598
628
if Index + 2 < FThreadNum then
599
629
begin
600
630
while FFinishedThread.FData[Index + 2 ] = 0 do ;
601
631
LocalNN.SumDeltasNoChecks(FThreadNN[Index + 2 ]);
632
+ { $IFDEF FPC}
602
633
FFinishedThread.FData[Index] += FFinishedThread.FData[Index + 2 ];
634
+ { $ELSE}
635
+ FFinishedThread.FData[Index] := FFinishedThread.FData[Index] +
636
+ FFinishedThread.FData[Index + 2 ];
637
+ { $ENDIF}
603
638
end ;
604
639
end ;
605
640
606
- EnterCriticalSection(FCritSec);
607
- FGlobalHit += LocalHit;
608
- FGlobalMiss += LocalMiss;
609
- FGlobalTotalLoss += LocalTotalLoss;
610
- FGlobalErrorSum += LocalErrorSum;
641
+ { $IFDEF HASTHREADS } EnterCriticalSection(FCritSec);{ $ENDIF }
642
+ FGlobalHit := FGlobalHit + LocalHit;
643
+ FGlobalMiss := FGlobalMiss + LocalMiss;
644
+ FGlobalTotalLoss := FGlobalTotalLoss + LocalTotalLoss;
645
+ FGlobalErrorSum := FGlobalErrorSum + LocalErrorSum;
611
646
612
647
FNN.ForwardTime := FNN.ForwardTime + LocalNN.ForwardTime;
613
648
FNN.BackwardTime := FNN.BackwardTime + LocalNN.BackwardTime;
@@ -616,7 +651,7 @@ procedure TNeuralFit.RunNNThread(Index: PtrInt; Data: Pointer;
616
651
{ $ELSE}
617
652
if Index and 3 = 0 then FNN.SumDeltasNoChecks(LocalNN);
618
653
{ $ENDIF}
619
- LeaveCriticalSection(FCritSec);
654
+ { $IFDEF HASTHREADS } LeaveCriticalSection(FCritSec);{ $ENDIF }
620
655
vInput.Free;
621
656
vOutput.Free;
622
657
pOutput.Free;
@@ -660,7 +695,7 @@ procedure TNeuralFit.TestNNThread(Index: PtrInt; Data: Pointer;
660
695
LocalNN.Compute( vInput );
661
696
LocalNN.GetOutput( pOutput );
662
697
663
- LocalErrorSum += FWorkingVolumes[ElementIdx].O.SumDiff( pOutput );
698
+ LocalErrorSum := LocalErrorSum + FWorkingVolumes[ElementIdx].O.SumDiff( pOutput );
664
699
665
700
if Assigned(FInferHitFn) then
666
701
begin
@@ -675,16 +710,16 @@ procedure TNeuralFit.TestNNThread(Index: PtrInt; Data: Pointer;
675
710
end ;
676
711
677
712
if Assigned(FLossFn)
678
- then LocalTotalLoss += FLossFn(FWorkingVolumes[ElementIdx].O);
713
+ then LocalTotalLoss := LocalTotalLoss + FLossFn(FWorkingVolumes[ElementIdx].O);
679
714
end ; // of for
680
715
LocalNN.EnableDropouts(true);
681
716
682
- EnterCriticalSection(FCritSec);
683
- FGlobalHit += LocalHit;
684
- FGlobalMiss += LocalMiss;
685
- FGlobalTotalLoss += LocalTotalLoss;
686
- FGlobalErrorSum += LocalErrorSum;
687
- LeaveCriticalSection(FCritSec);
717
+ { $IFDEF HASTHREADS } EnterCriticalSection(FCritSec);{ $ENDIF }
718
+ FGlobalHit := FGlobalHit + LocalHit;
719
+ FGlobalMiss := FGlobalMiss + LocalMiss;
720
+ FGlobalTotalLoss := FGlobalTotalLoss + LocalTotalLoss;
721
+ FGlobalErrorSum := FGlobalErrorSum + LocalErrorSum;
722
+ { $IFDEF HASTHREADS } LeaveCriticalSection(FCritSec);{ $ENDIF }
688
723
689
724
LocalFrequency.Free;
690
725
vInput.Free;
@@ -708,9 +743,13 @@ constructor TNeuralFitBase.Create();
708
743
begin
709
744
inherited Create();
710
745
FFinishedThread := TNNetVolume.Create();
746
+ { $IFDEF HASTHREADS}
711
747
FMaxThreadNum := ProcThreadPool.MaxThreadCount;
712
- FDataAugmentation := true;
713
748
InitCriticalSection(FCritSec);
749
+ { $ELSE}
750
+ FMaxThreadNum := 1 ;
751
+ { $ENDIF}
752
+ FDataAugmentation := true;
714
753
FMultipleSamplesAtValidation := true;
715
754
FVerbose := true;
716
755
FStaircaseEpochs := 1 ;
@@ -733,7 +772,9 @@ constructor TNeuralFitBase.Create();
733
772
734
773
destructor TNeuralFitBase.Destroy();
735
774
begin
775
+ { $IFDEF HASTHREADS}
736
776
DoneCriticalSection(FCritSec);
777
+ { $ENDIF}
737
778
FFinishedThread.Free;
738
779
inherited Destroy();
739
780
end ;
@@ -810,6 +851,9 @@ procedure TNeuralImageFit.Fit(pNN: TNNet;
810
851
ValidationRecord: TNeuralFloat;
811
852
iEpochCount: integer;
812
853
begin
854
+ { $IFNDEF HASTHREADS}
855
+ FMaxThreadNum := 1 ;
856
+ { $ENDIF}
813
857
iEpochCount := FInitialEpoch;
814
858
FCurrentLearningRate := FInitialLearningRate;
815
859
FImgVolumes := pImgVolumes;
@@ -902,7 +946,11 @@ procedure TNeuralImageFit.Fit(pNN: TNNet;
902
946
FGlobalErrorSum := 0 ;
903
947
FFinishedThread.Fill(0 );
904
948
FNN.ClearTime();
949
+ { $IFDEF HASTHREADS}
905
950
ProcThreadPool.DoParallel(@RunNNThread, 0 , FThreadNN.Count-1 , Nil , FThreadNN.Count);
951
+ { $ELSE}
952
+ RunNNThread(0 , nil , Self);
953
+ { $ENDIF}
906
954
if FClipDelta > 0 then
907
955
begin
908
956
MaxDelta := FNN.ForceMaxAbsoluteDelta(FClipDelta);
@@ -988,7 +1036,11 @@ procedure TNeuralImageFit.Fit(pNN: TNNet;
988
1036
FGlobalTotalLoss := 0 ;
989
1037
FGlobalErrorSum := 0 ;
990
1038
FMessageProc(' Starting Validation.' );
1039
+ { $IFDEF HASTHREADS}
991
1040
ProcThreadPool.DoParallel(@TestNNThread, 0 , FThreadNN.Count-1 , Nil , FThreadNN.Count);
1041
+ { $ELSE}
1042
+ TestNNThread(0 , nil , Self);
1043
+ { $ENDIF}
992
1044
993
1045
FGlobalTotal := (FGlobalHit + FGlobalMiss);
994
1046
if (FGlobalTotal > 0 ) then
@@ -1039,7 +1091,11 @@ procedure TNeuralImageFit.Fit(pNN: TNNet;
1039
1091
FGlobalTotalLoss := 0 ;
1040
1092
FGlobalErrorSum := 0 ;
1041
1093
FMessageProc(' Starting Testing.' );
1094
+ { $IFDEF HASTHREADS}
1042
1095
ProcThreadPool.DoParallel(@TestNNThread, 0 , FThreadNN.Count-1 , Nil , FThreadNN.Count);
1096
+ { $ELSE}
1097
+ TestNNThread(0 , nil , Self);
1098
+ { $ENDIF}
1043
1099
1044
1100
FGlobalTotal := (FGlobalHit + FGlobalMiss);
1045
1101
if (FGlobalTotal > 0 ) then
@@ -1203,7 +1259,7 @@ procedure TNeuralImageFit.RunNNThread(Index: PtrInt; Data: Pointer;
1203
1259
then vOutput.SetClassForSoftMax( ImgInput.Tag )
1204
1260
else vOutput.SetClass( ImgInput.Tag, +0.9 , -0.1 );
1205
1261
1206
- LocalErrorSum += vOutput.SumDiff( pOutput );
1262
+ LocalErrorSum := LocalErrorSum + vOutput.SumDiff( pOutput );
1207
1263
OutputValue := pOutput.FData[ ImgInput.Tag ];
1208
1264
if Not (FIsSoftmax) then
1209
1265
begin
@@ -1224,7 +1280,7 @@ procedure TNeuralImageFit.RunNNThread(Index: PtrInt; Data: Pointer;
1224
1280
WriteLn(' Error - invalid output value:' ,OutputValue);
1225
1281
CurrentLoss := 1 ;
1226
1282
end ;
1227
- LocalTotalLoss += CurrentLoss;
1283
+ LocalTotalLoss := LocalTotalLoss + CurrentLoss;
1228
1284
1229
1285
if pOutput.GetClass() = FImgVolumes[ImgIdx].Tag then
1230
1286
begin
@@ -1242,26 +1298,35 @@ procedure TNeuralImageFit.RunNNThread(Index: PtrInt; Data: Pointer;
1242
1298
begin
1243
1299
while FFinishedThread.FData[Index + 1 ] = 0 do ;
1244
1300
LocalNN.SumDeltasNoChecks(FThreadNN[Index + 1 ]);
1301
+ { $IFDEF FPC}
1245
1302
FFinishedThread.FData[Index] += FFinishedThread.FData[Index + 1 ];
1303
+ { $ELSE}
1304
+ FFinishedThread.FData[Index] := FFinishedThread.FData[Index] +
1305
+ FFinishedThread.FData[Index + 1 ];
1306
+ { $ENDIF}
1246
1307
end ;
1247
1308
end ;
1248
- FFinishedThread.FData[Index] += 1 ;
1309
+ FFinishedThread.FData[Index] := FFinishedThread.FData[Index] + 1 ;
1249
1310
if Index and 3 = 0 then
1250
1311
begin
1251
1312
if Index + 2 < FThreadNum then
1252
1313
begin
1253
1314
while FFinishedThread.FData[Index + 2 ] = 0 do ;
1254
1315
LocalNN.SumDeltasNoChecks(FThreadNN[Index + 2 ]);
1316
+ { $IFDEF FPC}
1255
1317
FFinishedThread.FData[Index] += FFinishedThread.FData[Index + 2 ];
1318
+ { $ELSE}
1319
+ FFinishedThread.FData[Index] := FFinishedThread.FData[Index] +
1320
+ FFinishedThread.FData[Index + 2 ];
1321
+ { $ENDIF}
1256
1322
end ;
1257
1323
end ;
1258
- // WriteLn('Index:',Index,' [',FFinishedThread.FData[Index],']');
1259
1324
1260
- EnterCriticalSection(FCritSec);
1261
- FGlobalHit += LocalHit;
1262
- FGlobalMiss += LocalMiss;
1263
- FGlobalTotalLoss += LocalTotalLoss;
1264
- FGlobalErrorSum += LocalErrorSum;
1325
+ { $IFDEF HASTHREADS } EnterCriticalSection(FCritSec);{ $ENDIF }
1326
+ FGlobalHit := FGlobalHit + LocalHit;
1327
+ FGlobalMiss := FGlobalMiss + LocalMiss;
1328
+ FGlobalTotalLoss := FGlobalTotalLoss + LocalTotalLoss;
1329
+ FGlobalErrorSum := FGlobalErrorSum + LocalErrorSum;
1265
1330
1266
1331
FNN.ForwardTime := FNN.ForwardTime + LocalNN.ForwardTime;
1267
1332
FNN.BackwardTime := FNN.BackwardTime + LocalNN.BackwardTime;
@@ -1270,7 +1335,7 @@ procedure TNeuralImageFit.RunNNThread(Index: PtrInt; Data: Pointer;
1270
1335
{ $ELSE}
1271
1336
if Index and 3 = 0 then FNN.SumDeltasNoChecks(LocalNN);
1272
1337
{ $ENDIF}
1273
- LeaveCriticalSection(FCritSec);
1338
+ { $IFDEF HASTHREADS } LeaveCriticalSection(FCritSec);{ $ENDIF }
1274
1339
ImgInputCp.Free;
1275
1340
ImgInput.Free;
1276
1341
vOutput.Free;
@@ -1356,10 +1421,10 @@ procedure TNeuralImageFit.TestNNThread(Index: PtrInt; Data: Pointer;
1356
1421
end ;
1357
1422
1358
1423
vOutput.SetClassForSoftMax( ImgInput.Tag );
1359
- LocalErrorSum += vOutput.SumDiff( pOutput );
1424
+ LocalErrorSum := LocalErrorSum + vOutput.SumDiff( pOutput );
1360
1425
1361
1426
OutputValue := pOutput.FData[ ImgInput.Tag ];
1362
- if Not (FIsSoftmax) then OutputValue += 0.5001 ;
1427
+ if Not (FIsSoftmax) then OutputValue := OutputValue + 0.5001 ;
1363
1428
1364
1429
if (OutputValue > 0 ) then
1365
1430
begin
@@ -1370,7 +1435,7 @@ procedure TNeuralImageFit.TestNNThread(Index: PtrInt; Data: Pointer;
1370
1435
WriteLn(' Error - invalid output value:' ,OutputValue);
1371
1436
CurrentLoss := 1 ;
1372
1437
end ;
1373
- LocalTotalLoss += CurrentLoss;
1438
+ LocalTotalLoss := LocalTotalLoss + CurrentLoss;
1374
1439
1375
1440
PredictedClass := pOutput.GetClass();
1376
1441
if PredictedClass = ImgInput.Tag then
@@ -1384,12 +1449,12 @@ procedure TNeuralImageFit.TestNNThread(Index: PtrInt; Data: Pointer;
1384
1449
end ; // of for
1385
1450
LocalNN.EnableDropouts(true);
1386
1451
1387
- EnterCriticalSection(FCritSec);
1388
- FGlobalHit += LocalHit;
1389
- FGlobalMiss += LocalMiss;
1390
- FGlobalTotalLoss += LocalTotalLoss;
1391
- FGlobalErrorSum += LocalErrorSum;
1392
- LeaveCriticalSection(FCritSec);
1452
+ { $IFDEF HASTHREADS } EnterCriticalSection(FCritSec);{ $ENDIF }
1453
+ FGlobalHit := FGlobalHit + LocalHit;
1454
+ FGlobalMiss := FGlobalMiss + LocalMiss;
1455
+ FGlobalTotalLoss := FGlobalTotalLoss + LocalTotalLoss;
1456
+ FGlobalErrorSum := FGlobalErrorSum + LocalErrorSum;
1457
+ { $IFDEF HASTHREADS } LeaveCriticalSection(FCritSec);{ $ENDIF }
1393
1458
1394
1459
sumOutput.Free;
1395
1460
ImgInputCp.Free;
@@ -1444,4 +1509,3 @@ procedure TNeuralImageFit.ClassifyImage(pNN: TNNet; pImgInput, pOutput: TNNetVol
1444
1509
end ;
1445
1510
1446
1511
end .
1447
-
0 commit comments