人工智能时代的 Delphi
Delphi in the Age of AI

原始链接: https://learndelphi.org/delphi-ai-ultimate-guide/

这段代码片段实现了 TensorFlow Lite (TFLite) 模型的推理过程。它首先加载 TFLite 库和用户指定的文件(Edit1.Text)。然后创建一个解释器,并分配必要的张量。 核心功能包括处理图像(Image1)及其像素数据,将其转换为一个浮点数数组 (`fInput`),作为模型的输入。像素根据亮度转换为 1 或 0。这个输入被复制到 TFLite 解释器的输入张量中。 解释器被调用,如果成功,输出张量的数据将被复制到 `fOutput` 数组中。最后,代码遍历输出值,在 ListView (ListView1) 中显示小于等于 1 的值及其索引。列表按字母顺序排序,并在完成时播放提示音。TFLite 库在 `finally` 块中被卸载,以确保正确清理资源。

## 人工智能时代下的 Delphi:Hacker News 摘要 最近 Hacker News 上进行了一场关于 Delphi 编程语言在当今技术环境中相关性的讨论。对话源于 learndelphi.org 上的一个帖子,并强调了经验丰富的 Delphi 开发者在找工作时面临的困难,这通常是由于该语言流行度的下降所致。 许多评论员哀叹 Delphi 的“衰落”,承认其优势——特别是其快速应用程序开发(RAD)能力——但同时也认识到其现代应用有限。C#(由 Delphi 前首席架构师 Anders Hejlsberg 创建)和 TypeScript 经常被建议作为替代方案。 讨论还涉及了人工智能的影响。一些人担心人工智能工具会偏向于更广泛使用的语言,从而阻碍对 Delphi 等“冷门”语言的投资。另一些人认为人工智能应该*促进*学习不太常见的语言,但承认 Python 在人工智能训练数据中的主导地位。 尽管 Delphi 正在衰落,但它仍然在一些特定领域有应用,特别是在遗留系统和 RAD Windows 程序中,Lazarus(Delphi 的克隆版)提供了跨平台开发。然而,总体情绪表明 Delphi 的未来主要在于维护现有应用程序,而不是推动新的创新。
相关文章

原文

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;

 

  fInput: array [0 .. 28 * 28 - 1] of Float32;

  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);

 

      TfLiteInterpreterOptionsDelete(fInterpreterOptions);

      TfLiteModelDelete(fModel);

 

      if fInterpreter <> nil then

      begin

        fStatus := TfLiteInterpreterAllocateTensors(fInterpreter);

 

        fInputTensorCount := TfLiteInterpreterGetInputTensorCount(fInterpreter);

        fOutputTensorCount := TfLiteInterpreterGetOutputTensorCount

          (fInterpreter);

 

        fInputTensor := TfLiteInterpreterGetInputTensor(fInterpreter, 0);

        fOutputTensor := TfLiteInterpreterGetOutputTensor(fInterpreter, 0);

 

        if fInputTensor <> nil then

        begin

          fTensorByteSize := TfLiteTensorByteSize(fInputTensor);

 

          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;

 

          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);

 

            fTensorByteSize := TfLiteTensorByteSize(fOutputTensor);

 

            if fOutputTensor <> nil then

            begin

              fStatus := TfLiteTensorCopyToBuffer(fOutputTensor, @fOutput,

                fTensorByteSize);

 

              if fStatus = kTfLiteOk then

              begin

                ListView1.Items.Clear;

 

                for i := 0 to Length(fOutput) - 1 do

                begin

                  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;

联系我们 contact @ memedata.com