How To Build a Digit Classifier In Tensorflow
procedure TForm1.Button2Click(Sender: TObject);
var
i, X, Y: DWORD;
fLibrary: HMODULE;
fModel: Pointer;
fInterpreterOptions: Pointer;
fInterpreter: Pointer;
fStatus: TfLiteStatus;
fInputTensorCount, fOutputTensorCount, fNumDims: Int32;
fInputTensor, fOutputTensor: Pointer;
fInputDims: Integer;
fTensorName: PAnsiChar;
fTensorType: TfLiteType;
fTensorByteSize: SIZE_T;
// 28×28 pixel image as input
fInput: array [0 .. 28 * 28 – 1] of Float32;
// output 0 to 9
fOutput: array [0 .. 10 – 1] of Float32;
fValue: Extended;
begin
fLibrary := LoadLibrary(LibraryName);
if fLibrary = 0 then
begin
ShowMessage(‘Error: Load tensorflow lite library ‘ + LibraryName + ‘ – ‘ +
SysErrorMessage(GetLastError));
Exit;
end;
try
fModel := TfLiteModelCreateFromFile(PAnsiChar(AnsiString(Edit1.Text)));
if fModel = nil then
begin
ShowMessage(‘Error: Create model from file – ‘ +
SysErrorMessage(GetLastError));
Exit;
end;
fInterpreterOptions := TfLiteInterpreterOptionsCreate;
if fInterpreterOptions > nil then
begin
TfLiteInterpreterOptionsSetNumThreads(fInterpreterOptions, 2);
fInterpreter := TfLiteInterpreterCreate(fModel, fInterpreterOptions);
// parameters / model can be removed immediately after the interpreter is created
TfLiteInterpreterOptionsDelete(fInterpreterOptions);
TfLiteModelDelete(fModel);
if fInterpreter > nil then
begin
fStatus := TfLiteInterpreterAllocateTensors(fInterpreter);
fInputTensorCount := TfLiteInterpreterGetInputTensorCount(fInterpreter);
fOutputTensorCount := TfLiteInterpreterGetOutputTensorCount
(fInterpreter);
// fLiteTensor* TfLiteInterpreterGetInputTensor(const TfLiteInterpreter* interpreter, int32_t input_index);
// returned structure TfLiteTensor
// an example is simple, there is no need to translate everything from the
// in general, the source of the: https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/c
{ typedef struct TfLiteTensor {
TfLiteType type;
TfLitePtrUnion data;
TfLiteIntArray* dims;
TfLiteQuantizationParams params;
TfLiteAllocationType allocation_type;
size_t bytes;
const void* allocation;
const char* name;
struct TfLiteDelegate* delegate;
TfLiteBufferHandle buffer_handle;
bool data_is_stale;
bool is_variable;
TfLiteQuantization quantization;
TfLiteSparsity* sparsity;
const TfLiteIntArray* dims_signature; }
fInputTensor := TfLiteInterpreterGetInputTensor(fInterpreter, 0);
fOutputTensor := TfLiteInterpreterGetOutputTensor(fInterpreter, 0);
if fInputTensor > nil then
begin
// info about tensor
// fNumDims := TfLiteTensorNumDims(fInputTensor);
// fTensorName := TfLiteTensorName(fInputTensor);
// fTensorType := TfLiteTensorType(fInputTensor);
fTensorByteSize := TfLiteTensorByteSize(fInputTensor);
// writing pixels to fInput, top to bottom, left to right
for Y := 0 to Image1.Picture.Bitmap.Height – 1 do
begin
for X := 0 to Image1.Picture.Bitmap.Width – 1 do
begin
if (Image1.Canvas.Pixels[X, Y] > 0) then
fInput[X + (Y * Image1.Picture.Bitmap.Width)] := 1
else
fInput[X + (Y * Image1.Picture.Bitmap.Width)] := 0;
end;
end;
// fTensorByteSize = Length(fInput) * SizeOf(Float32)
fStatus := TfLiteTensorCopyFromBuffer(fInputTensor, @fInput,
fTensorByteSize);
fStatus := TfLiteInterpreterInvoke(fInterpreter);
if fStatus = kTfLiteOk then
begin
for i := 0 to High(fOutput) do
fOutput[i] := 0;
fOutputTensor := TfLiteInterpreterGetOutputTensor(fInterpreter, 0);
// info about tensor
// fNumDims := TfLiteTensorNumDims(fOutputTensor);
// fTensorName := TfLiteTensorName(fOutputTensor);
// fTensorType := TfLiteTensorType(fOutputTensor);
fTensorByteSize := TfLiteTensorByteSize(fOutputTensor);
if fOutputTensor > nil then
begin
// fTensorByteSize = Length(fOutput) * SizeOf(Float32)
fStatus := TfLiteTensorCopyToBuffer(fOutputTensor, @fOutput,
fTensorByteSize);
if fStatus = kTfLiteOk then
begin
ListView1.Items.Clear;
for i := 0 to Length(fOutput) – 1 do
begin
// ingenious solution, coolest conversion
fValue := StrToFloat(Copy(FloatToStr(fOutput[i]), 1, 17));
if fValue = 1 then
begin
with ListView1.Items.Add do
begin
Caption := FloatToStrF(fValue, ffNumber, 17, 17);
SubItems.Add(IntToStr(i));
end;
end;
end;
ListView1.AlphaSort;
Beep;
end;
end;
end;
end;
end;
end;
finally
FreeLibrary(fLibrary);
end;
end;