Advertisement
WarPie90

Simba 2.0 KNN - Recognize number

Dec 23rd, 2024 (edited)
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 5.03 KB | None | 0 0
  1. // TARGET THE DEBUG IMAGE BEFORE RUNNING
  2. // PRESS ENTER TO TEST
  3. // PRESS BACK TO RESET
  4.  
  5. function BytesToInt32(Bytes: TByteArray; StartIndex: Integer): Integer;
  6. begin
  7.   Result := (Bytes[StartIndex] shl 24) or (Bytes[StartIndex + 1] shl 16) or
  8.             (Bytes[StartIndex + 2] shl 8) or Bytes[StartIndex + 3];
  9. end;
  10.  
  11. function ParseMNISTFile(FileName: string): array of TSingleMatrix;
  12. var
  13.   FileData: TByteArray;
  14.   MagicNumber, NumImages, NumRows, NumCols: Integer;
  15.   i, r, c, Offset: Integer;
  16. begin
  17.   if not FileExists(FileName) then
  18.   begin
  19.     WriteLn('File not found: ', FileName);
  20.     Exit;
  21.   end;
  22.  
  23.   // Read the entire file into memory
  24.   FileData := FileReadBytes(FileName);
  25.   if Length(FileData) = 0 then
  26.   begin
  27.     WriteLn('Failed to read file or file is empty.');
  28.     Exit;
  29.   end;
  30.  
  31.   // Parse the header (16 bytes)
  32.   MagicNumber := BytesToInt32(FileData, 0);
  33.   NumImages   := BytesToInt32(FileData, 4);
  34.   NumRows     := BytesToInt32(FileData, 8);
  35.   NumCols     := BytesToInt32(FileData, 12);
  36.  
  37.   if MagicNumber <> 2051 then
  38.   begin
  39.     WriteLn('Invalid magic number: ', MagicNumber);
  40.     Exit;
  41.   end;
  42.  
  43.   // Allocate memory for images
  44.   SetLength(Result, NumImages);
  45.   for i := 0 to NumImages - 1 do
  46.     SetLength(Result[i], NumRows, NumCols);
  47.  
  48.   // Parse image data
  49.   Offset := 16; // Image data starts after the header
  50.   for i := 0 to NumImages - 1 do
  51.   begin
  52.     for r := 0 to NumRows - 1 do
  53.     begin
  54.       for c := 0 to NumCols - 1 do
  55.       begin
  56.         Result[i][r][c] := FileData[Offset];
  57.         Inc(Offset);
  58.       end;
  59.     end;
  60.   end;
  61. end;
  62.  
  63. function ParseMNISTLabels(FileName: string): array of Byte;
  64. var
  65.   FileData: TByteArray;
  66.   MagicNumber, NumLabels, Offset: Integer;
  67.   i: Integer;
  68. begin
  69.   if not FileExists(FileName) then
  70.   begin
  71.     WriteLn('File not found: ', FileName);
  72.     Exit;
  73.   end;
  74.  
  75.   // Read the entire file into memory
  76.   FileData := FileReadBytes(FileName);
  77.   if Length(FileData) = 0 then
  78.   begin
  79.     WriteLn('Failed to read file or file is empty.');
  80.     Exit;
  81.   end;
  82.  
  83.   // Parse the header (8 bytes)
  84.   MagicNumber := BytesToInt32(FileData, 0);
  85.   NumLabels := BytesToInt32(FileData, 4);
  86.  
  87.   if MagicNumber <> 2049 then
  88.   begin
  89.     WriteLn('Invalid magic number: ', MagicNumber);
  90.     Exit;
  91.   end;
  92.  
  93.   // Allocate memory for labels
  94.   SetLength(Result, NumLabels);
  95.  
  96.   // Parse labels (starting at offset 8)
  97.   Offset := 8;
  98.   for i := 0 to NumLabels - 1 do
  99.   begin
  100.     Result[i] := FileData[Offset];
  101.     Inc(Offset);
  102.   end;
  103. end;
  104.  
  105.  
  106. function VectorDataBlock(Img: TSingleMatrix): TSingleArray;
  107. var
  108.   TPA: TPointArray;
  109.   Bounds: TBoxArray;
  110.   i: Int32;
  111. begin
  112.   SetLength(Result, 16);
  113.  
  114.   TPA     := Img.Indices(128, __GE__);
  115.   Bounds  := TPA.Bounds.Partition(4,4);
  116.  
  117.   for i:=0 to High(Bounds) do
  118.     Result[i] := TPA.ExtractBox(Bounds[i]).Length / ((24*24) / (4*4));
  119. end;
  120.  
  121. function ComputeVectors(Images: array of TSingleMatrix; Labels: TByteArray): TKDItems;
  122. var
  123.   i: Int32;
  124. begin
  125.   SetLength(Result, Length(Images));
  126.   for i:=0 to High(Images) do
  127.   begin
  128.     Result[i].Ref    := Labels[i];
  129.     Result[i].Vector := VectorDataBlock(Images[i]);//VectorData(Images[i]);
  130.   end;
  131. end;
  132.  
  133.  
  134. var
  135.   Tree: TKDTree;
  136.   x,y,i,j: Int32;
  137.   Images,TrainImages: array of TSingleMatrix;
  138.   Labels,TrainLabels: array of Byte;
  139.  
  140.   TrainingData, TestData: TKDItems;
  141.   best,t: Double;
  142.   accuracy,bidx: Int32;
  143.  
  144.   Raw: TSingleMatrix;
  145.   Test: TSingleArray;
  146.   Half, Temp, Image: TImage;
  147. begin
  148.  
  149.   TrainImages := ParseMNISTFile('Scripts\MNIST\train-images.idx3-ubyte');
  150.   TrainLabels := ParseMNISTLabels('Scripts\MNIST\train-labels.idx1-ubyte');
  151.  
  152.   t := PerformanceTimer();
  153.   TrainingData := ComputeVectors(TrainImages, TrainLabels);
  154.   WriteLn PerformanceTimer() - t;
  155.  
  156.  
  157.   WriteLn('Training on ', Length(TrainingData), ' samples');
  158.   t := PerformanceTimer();
  159.   Tree.Init(TrainingData);
  160.   WriteLn PerformanceTimer() - t;
  161.  
  162.   Image := TImage.Create(700,256);
  163.   DebugImageDisplay(700,256);
  164.  
  165.   Image.Show();
  166.   Image.DrawColor := $FFFFFF;
  167.  
  168.   while True do
  169.   begin
  170.     if Target.MousePressed(EMouseButton.LEFT) then
  171.       Image.DrawCircleFilled(Target.MouseXY,10);
  172.  
  173.     DebugImageUpdate(Image);
  174.  
  175.     if Target.KeyPressed(EKeyCode.RETURN) then
  176.     begin
  177.       Half := Image.Copy([0,0,255,255]);
  178.       Temp := Half.Downsample(11);
  179.       Temp.SetSize(24,24);
  180.       Temp.ToMatrix();
  181.  
  182.       Raw.SetSize(24,24);
  183.       for y:=0 to Temp.Height-1 do
  184.         for x:=0 to Temp.Width-1 do
  185.           Raw[y,x] := Temp.Pixel[x,y].ToHSL().L * 2.55;
  186.  
  187.       Temp.Show();
  188.       Temp.Free();
  189.       Half.Free();
  190.  
  191.       Test := VectorDataBlock(Raw);
  192.       t := PerformanceTimer();
  193.       bidx := Tree.KNearestClassify(Test, 7);
  194.       Writeln(PerformanceTimer() - t, 'ms');
  195.  
  196.       Image.FontSize := 12;
  197.       Image.DrawText('Predicted: ', [300, 30]);
  198.       Image.FontSize := 90;
  199.       Image.DrawText(ToStr(bidx),   [300, 50]);
  200.  
  201.       Sleep(1000);
  202.       DebugImageUpdate(Image);
  203.     end;
  204.  
  205.     if Target.KeyPressed(EKeyCode.BACK) then
  206.       Image.Clear();
  207.  
  208.     Sleep(10);
  209.   end;
  210.  
  211. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement