精华内容
下载资源
问答
  • 使用Dev Pytorch 1.0将Pytorch模型加载到C
    2021-04-17 09:17:42

    Pytorch 1.0具有将模型转换为火炬脚本程序(以某种方式序列化)的功能,以使其能够在没有Python依赖性的情况下在C中执行 .

    这是如何做到的:

    import torch

    import torchvision

    # An instance of your model.

    model = A UNET MODEL FROM FASTAI which has hooks as required by UNET

    # An example input you would normally provide to your model's forward() method.

    example = torch.rand(1, 3, 224, 224)

    # Use torch.jit.trace to generate a torch.jit.ScriptModule via tracing.

    traced_script_module = torch.jit.trace(model, example)

    在我的用例中,我使用UNET模型进行语义分割 . 但是,我使用此方法跟踪模型,我得到以下错误 .

    Forward or backward hooks can't be compiled

    UNET模型使用钩子来保存在网络中后续层使用的中间特征 . 有办法解决吗?或者这仍然是这种新方法的限制,它不能与使用这种钩子的模型一起使用 .

    更多相关内容
  • Android设备部署PyTorch模型

    千次阅读 2021-07-15 11:05:54
    Pytorch Mobile Android参考文献 ...而从Pytorch 1.3开始,我们就可以使用Pytorch模型部署到Android或者ios设备。 参考文献 https://blog.csdn.net/karry_zzj/article/details/102827337 ...

    在这里插入图片描述


    现如今,在边缘设备上运行机器学习/深度学习变得越来越流行,它需要更低的时延。

    而从Pytorch 1.3开始,我们就可以使用Pytorch将模型部署到Android或者ios设备中。

    Pytorch官方文档:https://pytorch.org/mobile/home/

    Pytorch官方文档中提供关于Pytorch-mobile的Demo:https://github.com/pytorch/android-demo-app

    在这里插入图片描述
    主要包含了两个APP应用,一个简单的在神经网络领域中的“hello world"项目,另一个就更复杂了一些,有图形识别和语言识别。

    我们接下来研究一下Pytorch Mobile的项目流程。

    Demo 1 HelloWorldApp

    1 模型准备

    首先我们需要先训练好的模型保存好。比如我在Pycharm写了经典CNN模型MobileNet-v3。

    import torch
    import torchvision
    from torch.utils.mobile_optimizer import optimize_for_mobile
    
    model = torchvision.models.mobilenet_v3_small(pretrained=True)
    model.eval()
    example = torch.rand(1, 3, 224, 224)
    traced_script_module = torch.jit.trace(model, example)
    optimized_traced_model = optimize_for_mobile(traced_script_module)
    optimized_traced_model._save_for_lite_interpreter("./mobilenet_v3_small_model.pt")
    

    在 checkpoints/ 文件夹中保存了 mobilenet_v3_small_model.pt ,有了这个模型,我们就可以进行Android的部署了。

    2 源码分析

    Clone 源码

    我们先在本地clone一下github上的源码(吐槽一下git clone的速度,龟速!):

    git clone https://github.com/pytorch/android-demo-app.git
    

    然后便得到这个项目。

    前提先确保一下Android安装好了SDK和NDK。

    向 Gradle 添加依赖

    然后我们会在 app 下的 build.gradle 中发现这样的依赖:

    在这里插入图片描述
    最下面两行中的

    • org.pytorch:pytorch_android : Pytorch Android API 的主要依赖,包含为4个Android abis (armeabi-v7a, arm64-v8a, x86, x86_64) 的 libtorch 本地库。
    • org.pytorch:pytorch_android_torchvision :它是具有将 android.media.image 和 android.graphics.bitmap 转换为 Tensor 的附加库。

    3 读取图片数据

    MainActivity.java 文件中,有这么一行:
    在这里插入图片描述

    bitmap = BitmapFactory.decodeStream(getAssets().open("image.jpg"));
    

    Bitmap 为位图,其包括像素以及长、宽、颜色等描述信息。长、宽、像素位数用来描述图片,并可以通过这些信息计算出图片的像素占用内存的大小。

    通过 BitmapFactory.decodeStream( ) 这一函数加载图像。

    4 读取模型

    同样在 MainActivity.java文件中,有这么一行:
    在这里插入图片描述

    module = Module.load(assetFilePath(this, "model.pt"));
    

    当然我们需要 import org.pytorch.Module
    然后通过 Module 定义一个对象后使用 Module.load() 来读取模型。

    5 将图像转换为Tensor

    在这里插入图片描述
    org.pytorch.torchvision.TensorImageUtils 就是org.pytorch:pytorch_android_torchvision库中的一部分,TensorImageUtils.bitmapToFloat32Tensor 创建一个Tensor类型。

    inputTensor 的 大小为 1x3xHxW, 其中 H 和 W 分别为 Bitmap 的高和宽。

    6 运行模型

    在这里插入图片描述
    将 inputTensor 放到模型中运行,通过 module.forward() 得到一个 outputTensor。

    7 处理结果

        // getting tensor content as java array of floats
        final float[] scores = outputTensor.getDataAsFloatArray();
    
        // searching for the index with maximum score
        float maxScore = -Float.MAX_VALUE;
        int maxScoreIdx = -1;
        for (int i = 0; i < scores.length; i++) {
          if (scores[i] > maxScore) {
            maxScore = scores[i];
            maxScoreIdx = i;
          }
        }
    
        String className = ImageNetClasses.IMAGENET_CLASSES[maxScoreIdx];
    
        // showing className on UI
        TextView textView = findViewById(R.id.text);
        textView.setText(className);
    
    

    判断最高分数,并将结果显示到textView中。

    Demo2 Pytorch Demo APP

    这是另一个Demo App,它可以进行图像分类和文字分类。而图像分类就需要利用摄像头。

    1 摄像头API

    摄像头API通过使用 org.pytorch.demo.vision.AbstractCameraXActivity 类。
    AbstractCameraXActivity.java 中的具体源码如下:

      private void setupCameraX() {
        final TextureView textureView = getCameraPreviewTextureView();
        // 实现摄像头预览
        final PreviewConfig previewConfig = new PreviewConfig.Builder().build();
        final Preview preview = new Preview(previewConfig);
        preview.setOnPreviewOutputUpdateListener(output -> textureView.setSurfaceTexture(output.getSurfaceTexture()));
    	
    	// 实现数据分析并回调
        final ImageAnalysisConfig imageAnalysisConfig =
            new ImageAnalysisConfig.Builder()
                .setTargetResolution(new Size(224, 224))
                .setCallbackHandler(mBackgroundHandler)
                .setImageReaderMode(ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE)
                .build();
        final ImageAnalysis imageAnalysis = new ImageAnalysis(imageAnalysisConfig);
        imageAnalysis.setAnalyzer(
            (image, rotationDegrees) -> {
              if (SystemClock.elapsedRealtime() - mLastAnalysisResultTime < 500) {
                return;
              }
              final R result = analyzeImage(image, rotationDegrees);
              if (result != null) {
                mLastAnalysisResultTime = SystemClock.elapsedRealtime();
                runOnUiThread(() -> applyToUiAnalyzeImageResult(result));
              }
            });
    
        CameraX.bindToLifecycle(this, preview, imageAnalysis);
      }
      // analyzeImage函数是用来处理摄像头输出
      void analyzeImage(android.media.Image, int rotationDegrees)
    
    

    2 图像分类

    而在 ImageClassificationActivity.java 中的源码如下:

    protected AnalysisResult analyzeImage(ImageProxy image, int rotationDegrees) {
        if (mAnalyzeImageErrorState) {
          return null;
        }
    
        try {
          if (mModule == null) {
            final String moduleFileAbsoluteFilePath = new File(
                Utils.assetFilePath(this, getModuleAssetName())).getAbsolutePath();
            // 导入模型
            mModule = Module.load(moduleFileAbsoluteFilePath);
    
            mInputTensorBuffer =
                Tensor.allocateFloatBuffer(3 * INPUT_TENSOR_WIDTH * INPUT_TENSOR_HEIGHT);
            mInputTensor = Tensor.fromBlob(mInputTensorBuffer, new long[]{1, 3, INPUT_TENSOR_HEIGHT, INPUT_TENSOR_WIDTH});
          }
    
          final long startTime = SystemClock.elapsedRealtime();
          // 将以YUV420形式的Image类型转化为输入Tensor
          TensorImageUtils.imageYUV420CenterCropToFloatBuffer(
              image.getImage(), rotationDegrees,
              INPUT_TENSOR_WIDTH, INPUT_TENSOR_HEIGHT,
              TensorImageUtils.TORCHVISION_NORM_MEAN_RGB,
              TensorImageUtils.TORCHVISION_NORM_STD_RGB,
              mInputTensorBuffer, 0);
    
          final long moduleForwardStartTime = SystemClock.elapsedRealtime();
          // 利用模型进行运算
          final Tensor outputTensor = mModule.forward(IValue.from(mInputTensor)).toTensor();
          final long moduleForwardDuration = SystemClock.elapsedRealtime() - moduleForwardStartTime;
          
          // 从模型中得到预测分数
          final float[] scores = outputTensor.getDataAsFloatArray();
          // 找到得分最高的前k个类
          final int[] ixs = Utils.topK(scores, TOP_K);
          final String[] topKClassNames = new String[TOP_K];
          final float[] topKScores = new float[TOP_K];
          for (int i = 0; i < TOP_K; i++) {
            final int ix = ixs[i];
            topKClassNames[i] = Constants.IMAGENET_CLASSES[ix];
            topKScores[i] = scores[ix];
          }
          final long analysisDuration = SystemClock.elapsedRealtime() - startTime;
          return new AnalysisResult(topKClassNames, topKScores, moduleForwardDuration, analysisDuration);
        } catch (Exception e) {
          Log.e(Constants.TAG, "Error during image analysis", e);
          mAnalyzeImageErrorState = true;
          runOnUiThread(() -> {
            if (!isFinishing()) {
              showErrorDialog(v -> ImageClassificationActivity.this.finish());
            }
          });
          return null;
        }
      }
    
    

    3 显示结果

    最后将得到的前k个类加载到UI上。

    protected void applyToUiAnalyzeImageResult(AnalysisResult result) {
        mMovingAvgSum += result.moduleForwardDuration;
        mMovingAvgQueue.add(result.moduleForwardDuration);
        if (mMovingAvgQueue.size() > MOVING_AVG_PERIOD) {
          mMovingAvgSum -= mMovingAvgQueue.remove();
        }
    
        for (int i = 0; i < TOP_K; i++) {
          final ResultRowView rowView = mResultRowViews[i];
          rowView.nameTextView.setText(result.topNClassNames[i]);
          rowView.scoreTextView.setText(String.format(Locale.US, SCORES_FORMAT,
              result.topNScores[i]));
          rowView.setProgressState(false);
        }
    
        mMsText.setText(String.format(Locale.US, FORMAT_MS, result.moduleForwardDuration));
        if (mMsText.getVisibility() != View.VISIBLE) {
          mMsText.setVisibility(View.VISIBLE);
        }
        mFpsText.setText(String.format(Locale.US, FORMAT_FPS, (1000.f / result.analysisDuration)));
        if (mFpsText.getVisibility() != View.VISIBLE) {
          mFpsText.setVisibility(View.VISIBLE);
        }
    
        if (mMovingAvgQueue.size() == MOVING_AVG_PERIOD) {
          float avgMs = (float) mMovingAvgSum / MOVING_AVG_PERIOD;
          mMsAvgText.setText(String.format(Locale.US, FORMAT_AVG_MS, avgMs));
          if (mMsAvgText.getVisibility() != View.VISIBLE) {
            mMsAvgText.setVisibility(View.VISIBLE);
          }
        }
     }
    
    

    Demo3 Image Segmentation

    Semantic Image Segmentation DeepLabV3 with Mobile Interpreter on Android

    This repo offers a Python script that converts the PyTorch DeepLabV3 model to the Lite Interpreter version of model, also optimized for mobile, and an Android app that uses the model to segment images.

    1.Prepare the Model

    import torch
    from torch.utils.mobile_optimizer import optimize_for_mobile
    
    # 加载训练好的模型
    model = torch.hub.load('pytorch/vision:v0.9.0', 'deeplabv3_resnet50', pretrained=True)
    # 设置为推理模式
    model.eval()
    
    # 将训练好的模型转换为jit脚本模型
    scripted_module = torch.jit.script(model)
    # 优化jit脚本模型,提高在移动设备上的推理性能
    optimized_scripted_module = optimize_for_mobile(scripted_module)
    
    # 导出完整的jit版本模型(不兼容轻量化解释器)
    scripted_module.save("deeplabv3_scripted.pt")
    # 导出轻量化解释器版本模型(与轻量化解释器兼容)
    scripted_module._save_for_lite_interpreter("deeplabv3_scripted.ptl")
    # 使用优化的轻量化解释器模型比未优化的轻量化解释器模型推理速度快60%左右,比未优化的jit脚本模型推理速度快6%左右
    optimized_scripted_module._save_for_lite_interpreter("deeplabv3_scripted_optimized.ptl")
    

    2.Use Android Studio

    使用Android Studio打开ImageSegment项目。注意应用程序的build.gradle文件有以下行:

    implementation 'org.pytorch:pytorch_android_lite:1.9.0'
    implementation 'org.pytorch:pytorch_android_torchvision:1.9.0'
    

    在MainActive . java中,下面的代码用于加载模型:

    mModule = LiteModuleLoader.load(MainActivity.assetFilePath(getApplicationContext(), "deeplabv3_scripted_optimized.ptl"));
    

    3.Run the app

    在这里插入图片描述
    在这里插入图片描述

    参考文献

    1. https://blog.csdn.net/karry_zzj/article/details/102827337
    展开全文
  • java web项目部署pytorch模型方案探索

    千次阅读 2021-07-08 15:14:38
    1. 使用java部署推理模型 1.1 资料: onnx支持使用java api:https://github.com/microsoft/onnxruntime/tree/master/java pytorch模型转成onnx格式:https://github.com/microsoft/onnxrun...

    一、背景

            使用pytorch做模型训练,训练完成后想集成到java web项目中。同时整体项目后续也会做离线环境的前场化部署。因此,想寻求一种部署简单的方案。

    二、方案探索

    1. 使用java部署推理模型

    1.1 资料:

    onnx支持使用java api:https://github.com/microsoft/onnxruntime/tree/master/java

    pytorch模型转成onnx格式:https://github.com/microsoft/onnxruntime/blob/008065aab16e46d37b3847a4759ff0e6d5963b18/onnxruntime/python/tools/transformers/notebooks/PyTorch_Bert-Squad_OnnxRuntime_CPU.ipynb

    1.2 实操:

    • 将pytorch transformers模型顺利转成onnx格式
    • 仍需要使用pytorch+transformers模型将文本转成onnx输入需要的tensor格式,最终还是要保留原模型以及onnx格式模型,两者差不多大。(我不确定原模型能不能用其他方法省略掉)
    • 我自定义了将文本转成tensor的方法,改用java时需要用java重写一遍逻辑。(我没用java重写逻辑,这个方案就没继续做下去,我不想维护训练和推理两套代码,还是不同的语言)
    • 转成onnx格式确实加速了推理过程,大概提升了3倍左右。

    1.3 总结:

    • 原本设想的是将模型及推理过程封装成一个jar,直接调用,但训练过程用的是python,两套语言维护起来比较复杂。
    • 后续我会继续探索原模型能不能省略掉。

    2.pyinstaller打包python项目

    1.1 资料:

    1.2 实操:

    • pyinstaller命令打包项目代码及其依赖
    • 可以通过shell命令或直接运行main.py
    • 发现只能通过接收控制台输出的方式,获取模型结果。而且不能提前初始化模型,每次运行都得从初始化模型开始。
    • springboot对执行shell脚本的支持较差,且无法应用于多线程。(百度的,未验证过该说法)

    1.3 总结:

    • pyinstaller比较适合项目需要打包成exe的场景,不太适合我的需求

    3.docker打包项目

    1.1 资料:

    1.2 实操:

    • 添加flask接口调用模型,实现还是比较简单的
    • 将整个项目以及依赖打包成docker镜像

    1.3 总结:

    • 还是回到最开始的想法,将模型推理过程打包成一个服务,对外开放API接口
    • 但目前公司内部没有使用docker,前场部署时还得格外安装一个docker,还得继续优化这个方案。(我个人推荐这个方案,他们会后悔的。。。)

    4.python打包项目

    1.1 资料:

    1.2 实操:

    • 用flask给项目安个接口
    • 用pipreqs打包出项目的python依赖包
    • 将依赖包连同代码一起打包到新机器,先安装python依赖,再运行python项目

    1.3 总结:

    • 总体类似于docker项目打包。但个人认为,如果项目多了之后不太好管理python依赖,还是推荐docker那种部署方式。
    • pipreqs打包依赖包会多打包一些类库(可能是打包整个python环境的依赖库),需要人工check
    展开全文
  • C++加载PYTORCH模型PyTorch的主要接口为Python。虽然Python有动态编程和易于迭代的优势,但很多情况下,正是Python的这些属性会带来不利。我们经常遇到的生产环境,要满足低延迟和严格部署要求。对于生产场景...

    在C++中加载PYTORCH模型

    PyTorch的主要接口为Python。虽然Python有动态编程和易于迭代的优势,但在很多情况下,正是Python的这些属性会带来不利。我们经常遇到的生产环境,要满足低延迟和严格部署要求。对于生产场景而言,C++通常是首选语言,也能很方便的将其绑定到另一种语言,如Java,Rust或Go。本教程将介绍从将PyTorch训练的模型序列化表示,到C++语言_加载_和_执行_的过程。

    第一步:将PyTorch模型转换为Torch Script

    PyTorch模型从Python到C++的转换由Torch Script实现。Torch Script是PyTorch模型的一种表示,可由Torch Script编译器理解,编译和序列化。如果使用基础的“eager”API编写的PyTorch模型,则必须先将模型转换为Torch Script,当然这也是比较容易的。如果已有模型的Torch Script,则可以跳到本教程的下一部分。

    将PyTorch模型转换为Torch Script有两种方法。

    第一种方法是Tracing。该方法通过将样本输入到模型中一次来对该过程进行评估从而捕获模型结构.并记录该样本在模型中的flow。该方法适用于模型中很少使用控制flow的模型。

    第二个方法就是向模型添加显式注释(Annotation),通知Torch Script编译器它可以直接解析和编译模型代码,受Torch Script语言强加的约束。

    小贴士

    可以在官方的Torch Script 参考中找到这两种方法的完整文档,以及有关使用哪个方法的细节指导。

    利用Tracing将模型转换为Torch Script

    要通过tracing来将PyTorch模型转换为Torch脚本,必须将模型的实例以及样本输入传递给torch.jit.trace函数。这将生成一个 torch.jit.ScriptModule对象,并在模块的forward方法中嵌入模型评估的跟踪:

    import torch

    import torchvision

    # 获取模型实例

    model = torchvision.models.resnet18()

    # 生成一个样本供网络前向传播 forward()

    example = torch.rand(1, 3, 224, 224)

    # 使用 torch.jit.trace 生成 torch.jit.ScriptModule 来跟踪

    traced_script_module = torch.jit.trace(model, example)

    现在,跟踪的ScriptModule可以与常规PyTorch模块进行相同的计算:

    In[1]: output = traced_script_module(torch.ones(1, 3, 224, 224))

    In[2]: output[0, :5]

    Out[2]: tensor([-0.2698, -0.0381, 0.4023, -0.3010, -0.0448], grad_fn=)

    通过Annotation将Model转换为Torch Script

    在某些情况下,例如,如果模型使用特定形式的控制流,如果想要直接在Torch Script中编写模型并相应地标注(annotate)模型。例如,假设有以下普通的 Pytorch模型:

    import torch

    class MyModule(torch.nn.Module):

    def __init__(self, N, M):

    super(MyModule, self).__init__()

    self.weight = torch.nn.Parameter(torch.rand(N, M))

    def forward(self, input):

    if input.sum() > 0:

    output = self.weight.mv(input)

    else:

    output = self.weight + input

    return output

    由于此模块的forward方法使用依赖于输入的控制流,因此它不适合利用Tracing的方法生成Torch Script。为此,可以通过继承torch.jit.ScriptModule并将@ torch.jit.script_method标注添加到模型的forward中的方法,来将model转换为ScriptModule:

    import torch

    class MyModule(torch.jit.ScriptModule):

    def __init__(self, N, M):

    super(MyModule, self).__init__()

    self.weight = torch.nn.Parameter(torch.rand(N, M))

    @torch.jit.script_method

    def forward(self, input):

    if input.sum() > 0:

    output = self.weight.mv(input)

    else:

    output = self.weight + input

    return output

    my_script_module = MyModule()

    现在,创建一个新的MyModule对象会直接生成一个可序列化的ScriptModule实例了。

    第二步:将Script Module序列化为一个文件

    不论是从上面两种方法的哪一种方法获得了ScriptModule,都可以将得到的ScriptModule序列化为一个文件,然后C++就可以不依赖任何Python代码来执行该Script所对应的Pytorch模型。

    假设我们想要序列化前面trace示例中显示的ResNet18模型。要执行此序列化,只需在模块上调用 save并给个文件名:

    traced_script_module.save("model.pt")

    这将在工作目录中生成一个model.pt文件。现在可以离开Python,并准备跨越到C ++语言调用。

    第三步:在C++中加载你的Script Module

    要在C ++中加载序列化的PyTorch模型,应用程序必须依赖于PyTorch C ++ API - 也称为_LibTorch_。_LibTorch发行版_包含一组共享库,头文件和CMake构建配置文件。虽然CMake不是依赖LibTorch的要求,但它是推荐的方法,并且将来会得到很好的支持。在本教程中,我们将使用CMake和LibTorch构建一个最小的C++应用程序,加载并执行序列化的PyTorch模型。

    最小的C++应用程序

    以下内容可以做到加载模块:

    #include // One-stop header.

    #include

    #include

    int main(int argc, const char* argv[]) {

    if (argc != 2) {

    std::cerr << "usage: example-app \n";

    return -1;

    }

    // Deserialize the ScriptModule from a file using torch::jit::load().

    std::shared_ptr<:jit::script::module> module = torch::jit::load(argv[1]);

    assert(module != nullptr);

    std::cout << "ok\n";

    }

    头文件包含运行该示例所需的LibTorch库中的所有相关include。main函数接受序列化ScriptModule的文件路径作为其唯一的命令行参数,然后使用torch::jit::load()函数反序列化模块,得到一个指向torch::jit::script::Module的共享指针,相当于C ++中的torch.jit.ScriptModule对象。最后,我们只验证此指针不为null。我们展示如何在接下来执行它。

    依赖库LibTorch和构建应用程序

    我们将上面的代码保存到名为example-app.cpp的文件中。对应的构建它的简单CMakeLists.txt为:

    cmake_minimum_required(VERSION 3.0 FATAL_ERROR)

    project(custom_ops)

    find_package(Torch REQUIRED)

    add_executable(example-app example-app.cpp)

    target_link_libraries(example-app "${TORCH_LIBRARIES}")

    set_property(TARGET example-app PROPERTY CXX_STANDARD 11)

    我们构建示例应用程序的最后一件事是下载LibTorch发行版。从PyTorch网站的下载页面获取最新的稳定版本 download page。如果下载并解压缩最新存档,则有以下目录结构:

    libtorch/

    bin/

    include/

    lib/

    share/

    lib/ 包含含链接的共享库,

    include/ 包含程序需要include的头文件,

    share/包含必要的CMake配置文件使得 find_package(Torch) 。

    小贴士

    在Windows平台上, debug and release builds are not ABI-compatible. 如果要使用debug, 要使用 源码编译 PyTorch方法。

    最后一步是构建应用程序。为此,假设我们的示例目录布局如下:

    example-app/

    CMakeLists.txt

    example-app.cpp

    我们现在可以运行以下命令从example-app/文件夹中构建应用程序:

    mkdir build

    cd build

    cmake -DCMAKE_PREFIX_PATH=/path/to/libtorch ..

    make

    其中 /path/to/libtorch 应该是解压缩的LibTorch发行版的完整路径。如果一切顺利,它将看起来像这样:

    root@4b5a67132e81:/example-app# mkdir build

    root@4b5a67132e81:/example-app# cd build

    root@4b5a67132e81:/example-app/build# cmake -DCMAKE_PREFIX_PATH=/path/to/libtorch ..

    -- The C compiler identification is GNU 5.4.0

    -- The CXX compiler identification is GNU 5.4.0

    -- Check for working C compiler: /usr/bin/cc

    -- Check for working C compiler: /usr/bin/cc -- works

    -- Detecting C compiler ABI info

    -- Detecting C compiler ABI info - done

    -- Detecting C compile features

    -- Detecting C compile features - done

    -- Check for working CXX compiler: /usr/bin/c++

    -- Check for working CXX compiler: /usr/bin/c++ -- works

    -- Detecting CXX compiler ABI info

    -- Detecting CXX compiler ABI info - done

    -- Detecting CXX compile features

    -- Detecting CXX compile features - done

    -- Looking for pthread.h

    -- Looking for pthread.h - found

    -- Looking for pthread_create

    -- Looking for pthread_create - not found

    -- Looking for pthread_create in pthreads

    -- Looking for pthread_create in pthreads - not found

    -- Looking for pthread_create in pthread

    -- Looking for pthread_create in pthread - found

    -- Found Threads: TRUE

    -- Configuring done

    -- Generating done

    -- Build files have been written to: /example-app/build

    root@4b5a67132e81:/example-app/build# make

    Scanning dependencies of target example-app

    [ 50%] Building CXX object CMakeFiles/example-app.dir/example-app.cpp.o

    [100%] Linking CXX executable example-app

    [100%] Built target example-app

    如果我们提供前面的序列化ResNet18模型的路径给example-app,C++输出的结果应该是 OK:

    root@4b5a67132e81:/example-app/build# ./example-app model.pt

    ok

    在C++代码中运行Script Module

    在C ++中成功加载了我们的序列化ResNet18后,我们再加几行执行代码,添加到C++应用程序的main()函数中:

    // Create a vector of inputs.

    std::vector<:jit::ivalue> inputs;

    inputs.push_back(torch::ones({1, 3, 224, 224}));

    // Execute the model and turn its output into a tensor.

    at::Tensor output = module->forward(inputs).toTensor();

    std::cout << output.slice(/*dim=*/1, /*start=*/0, /*end=*/5) << '\n';

    前两行设置我们模型的输入。 创建了一个 torch::jit::IValue (script::Module 对象可接受和返回的一种数据类型) 的向量和添加一个输入。要创建输入张量,我们使用torch::ones()(C++ API)和python中的torch.ones 一样。 然后我们运行script::Module的forward方法,传入我们创建的输入向量,返回一个新的IValue,通过调用toTensor()可将其转换为张量。

    小贴士

    更多关于torch::ones 和 PyTorch的对应 C++ API的内容 https://pytorch.org/cppdocs。PyTorch C++ API 和Python API差不多,可以使你像python 中一样操作处理tensors。

    在最后一行中,我们打印输出的前五个条目。由于我们在本教程前面的Python中为我们的模型提供了相同的输入,因此理想情况下我们应该看到相同的输出。让我们通过重新编译我们的应用程序并使用相同的序列化模型运行它来尝试:

    root@4b5a67132e81:/example-app/build# make

    Scanning dependencies of target example-app

    [ 50%] Building CXX object CMakeFiles/example-app.dir/example-app.cpp.o

    [100%] Linking CXX executable example-app

    [100%] Built target example-app

    root@4b5a67132e81:/example-app/build# ./example-app model.pt

    -0.2698 -0.0381 0.4023 -0.3010 -0.0448

    [ Variable[CPUFloatType]{1,5} ]

    作为参考,之前Python代码的输出是:

    tensor([-0.2698, -0.0381, 0.4023, -0.3010, -0.0448], grad_fn=)

    由此可见,C++的输出与Python的输出是一样的,成功啦!

    小贴士

    将你的模型放到GPU上,可以写成model->to(at::kCUDA);。确保你的输入也在CUDA的存储空间里面,可以使用tensor.to(at::kCUDA)检查,这个函数返回一个新的在CUDA里面的tensor。

    第五步:进阶教程和详细API

    本教程希望能使你理解PyTorch模型从python到c++的调用过程。通过上述教程,你能够通过“eager” PyTorch做一个简单模型,转成ScriptModule,并序列化保存。然后在C++里面通过 script::Module加载运行模型。

    当然,还有好多内容我们没有涉及。举个例子,你希望在C++或者CUDA中实现ScriptModule中的自定义操作,然后就可以在C++调用运行ScriptModule模型。这种是可以做到的,可以参考this。下面还有一些文档可以参考,比较有帮助:

    展开全文
  • Spring Boot部署深度学习模型Java/Pytorch

    千次阅读 多人点赞 2020-06-26 22:11:13
    使用java部署图片识别模型(yolo)spring boot部署深度学习模型java service使用flask提供http接口pytorch部署深度学习模型,以yolov3为例 spring boot部署深度学习模型 之前训练好深度学习模型后,遇到了部署模型...
  • 如何将pytorch模型部署到安卓

    万次阅读 多人点赞 2022-02-10 14:36:29
    如何将pytorch模型部署到安卓上 这篇文章演示如何将训练好的pytorch模型部署到安卓设备上。我也是刚开始学安卓,代码写的简单。 环境: pytorch版本:1.10.0 模型转化 pytorch_android支持的模型是.pt模型,我们训练...
  • Sanic框架下部署Pytorch模型

    千次阅读 2022-03-18 22:42:11
    使用Sanic框架部署pytorch模型实现web上线,部署深度学习模型
  • 如何用flask部署pytorch模型

    万次阅读 多人点赞 2018-09-30 18:04:17
    然而实际的工业场景,我们往往更加关注如何部署一个已经训练好的模型这一点上,tensorflow做得非常好,提供了tensorflow serving来帮助我们非常方便地部署到工业场景下。众所周知,PyTorch的一个...
  • Pytorch模型部署到Android端

    万次阅读 多人点赞 2020-03-09 15:07:35
    已经训练好的pytorch模型 Jetpack组件:CameraX(这个用来调用相机的) 如有需要,可以先看看我这两篇博文: 如果pytorch环境不满足,进行pytorch环境升级:win10+pytorch1.4+cuda10.1安装:从显卡驱动开始 ...
  • PyTorch部署模型

    千次阅读 2020-09-07 10:00:00
    点击上方“AI公园”,关注公众号,选择加“星标“或“置顶”作者:Francesco Zuppichini编译:ronghuaiyang导读演示了使用PyTorch最近发布的新工具torc...
  • 训练模型 使用pytorch对resnet18 进行迁移学习,实现对自己的数据进行图像分类。需要将最后一个全连接层的输出节点数目修改,因为我的数据集中包含有5图像,所以这里的输出节点数目修改成5 DEVICE = torch....
  • Pytorch模型的TF-Serving部署

    千次阅读 2020-11-20 14:58:18
    Pytorch模型的TF-Serving部署前面 目前PyTorch学术界几乎完全盖过了Tensorflow,从个人体验来说: PyTorch并没有表现出比Tensorflow性能差很多,基本是相当; 与Tensorflow的非Eager API相比,PyTorch上手...
  • Java 机器学习--DJL 安装 部署 基于Windows 10/11 初步尝试
  • 鱼羊 编辑整理量子位 报道 | 公众号 QbitAI编者按:作为一个Java开发者,你是否曾为在PyTorch部署模型而苦恼?这篇来自AWS软件工程师的投稿,结合实例,详细介绍了DJL这个为Java开发者设计的深度学习库:5分钟,你...
  • 目的:把训练好的pth模型参数提取出来,然后用其他方式部署到边缘设备。pytorch给了很方便的读取参数接口:nn.module.parameters()直接看demo:from torchvision.models.alexnet import alexnetmodel = alexnet...
  • Gradle7.0以上加载国内镜像源 ...(注意buildscript模块一定要写plugins模块上方) buildscript { repositories { maven { allowInsecureProtocol = true url 'http://maven.aliyun.com/nexus/content/group
  • 预训练模型在不同深度学习框架的转换是一种常见的任务。今天刚好DPN预训练模型转换问题,顺手将这个过程记录一下。核心转换函数如下所示:def convert_from_mxnet(model, checkpoint_prefix, debug=False):_, ...
  • 5分钟!用Java实现目标检测 | PyTorch

    千次阅读 2021-03-21 10:45:26
    鱼羊 编辑整理量子位 报道 | 公众号 QbitAI编者按:作为一个Java开发者,你是否曾为在PyTorch部署模型而苦恼?这篇来自AWS软件工程师的投稿,结合实例,详细介绍了DJL这个为Java开发者设计的深度学习库:5分钟,你...
  • PyTorch 团队上周发布了最新的PyTorch 1.4 版本。更新日志显示,此版本包含了 ...1.4 还增加了新的实验性功能,其中包括基于 RPC 的分布式模型并行训练以及对 Java 的语言绑定。此外,PyTorch 1.4 是支持 Python 2...
  • 【DJL】Springboot+Maven+DJL实现java调取pytorch模型

    千次阅读 多人点赞 2020-08-23 21:39:49
    这个技术是一个特别新的技术,是亚马逊云服务2019年re:Invent大会推出的专为Java开发者量身定制的深度学习框架,网上的资料比较少,只有官方文档可以参考,研究起来难度比较大,但是经过不懈的努力,终于搞定了,接...
  • 使用TorchServe服务PyTorch模型 :fire: TorchServe是由PyTorch开发的ML模型服务框架。 沿着该存储库,该过程将使用作为主干来训练和部署转移学习CNN模型,该模型对从众所周知的食物数据集的切片检索到的图像进行...
  • 最近有一个比较火的ocr项目:chineseocr_lite[1],项目很贴心地提供了ncnn的模型推理代码,只需要交叉编译opencv添加一点bitmap转cv::Mat的代码写个简单的界面具体过程参考:安卓端深度学习模型部署-以NCNN为例 - ...
  • 生产与学术写于 2019-01-08 的旧文, 当时是针对一个比赛的探索. 觉得可能对其他人有用, 就放出来分享一下生产与学术, 真实的对立....这两天最近研究将pytorch模型转换为独立的app, 网上寻找, 找到了一个流程: py...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,116
精华内容 846
关键字:

在java中部署pytorch模型

java 订阅