pytorch 移动端部署之helloworld的使用


Posted in Python onOctober 30, 2020

开始

安装Androidstudio 4.1

克隆此项目

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

使用androidstudio 打开 android-demo-app 中的HelloWordApp

打开之后androidstudio 会自动创建依赖 只需要等待即可

这个代码已经是官方写好的故而

开一下官方教程中的代码都在什么位置

这句

repositories {
  jcenter()
}

dependencies {
  implementation 'org.pytorch:pytorch_android:1.4.0'
  implementation 'org.pytorch:pytorch_android_torchvision:1.4.0'
}

位置

HelloWorldApp\app\build.gradle

里面的全部代码

apply plugin: 'com.android.application'
repositories {
  jcenter()
}

android {
  compileSdkVersion 28
  buildToolsVersion "29.0.2"
  defaultConfig {
    applicationId "org.pytorch.helloworld"
    minSdkVersion 21
    targetSdkVersion 28
    versionCode 1
    versionName "1.0"
  }
  buildTypes {
    release {
      minifyEnabled false
    }
  }
}

dependencies {
  implementation 'androidx.appcompat:appcompat:1.1.0'
  implementation 'org.pytorch:pytorch_android:1.4.0'
  implementation 'org.pytorch:pytorch_android_torchvision:1.4.0'
}

这句

Bitmap bitmap = BitmapFactory.decodeStream(getAssets().open("image.jpg"));
Module module = Module.load(assetFilePath(this, "model.pt"));
Tensor inputTensor = TensorImageUtils.bitmapToFloat32Tensor(bitmap,
  TensorImageUtils.TORCHVISION_NORM_MEAN_RGB, TensorImageUtils.TORCHVISION_NORM_STD_RGB);
  Tensor outputTensor = module.forward(IValue.from(inputTensor)).toTensor();
float[] scores = outputTensor.getDataAsFloatArray();
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];

都在这里

HelloWorldApp\app\src\main\java\org\pytorch\helloworld\MainActivity.java

全部代码

package org.pytorch.helloworld;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;

import org.pytorch.IValue;
import org.pytorch.Module;
import org.pytorch.Tensor;
import org.pytorch.torchvision.TensorImageUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  Bitmap bitmap = null;
  Module module = null;
  try {
   // creating bitmap from packaged into app android asset 'image.jpg',
   // app/src/main/assets/image.jpg
   bitmap = BitmapFactory.decodeStream(getAssets().open("image.jpg"));
   // loading serialized torchscript module from packaged into app android asset model.pt,
   // app/src/model/assets/model.pt
   module = Module.load(assetFilePath(this, "model.pt"));
  } catch (IOException e) {
   Log.e("PytorchHelloWorld", "Error reading assets", e);
   finish();
  }

  // showing image on UI
  ImageView imageView = findViewById(R.id.image);
  imageView.setImageBitmap(bitmap);

  // preparing input tensor
  final Tensor inputTensor = TensorImageUtils.bitmapToFloat32Tensor(bitmap,
    TensorImageUtils.TORCHVISION_NORM_MEAN_RGB, TensorImageUtils.TORCHVISION_NORM_STD_RGB);

  // running the model
  final Tensor outputTensor = module.forward(IValue.from(inputTensor)).toTensor();

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

 /**
  * Copies specified asset to the file in /files app directory and returns this file absolute path.
  *
  * @return absolute file path
  */
 public static String assetFilePath(Context context, String assetName) throws IOException {
  File file = new File(context.getFilesDir(), assetName);
  if (file.exists() && file.length() > 0) {
   return file.getAbsolutePath();
  }

  try (InputStream is = context.getAssets().open(assetName)) {
   try (OutputStream os = new FileOutputStream(file)) {
    byte[] buffer = new byte[4 * 1024];
    int read;
    while ((read = is.read(buffer)) != -1) {
     os.write(buffer, 0, read);
    }
    os.flush();
   }
   return file.getAbsolutePath();
  }
 }
}

在Build 中选择Build Bundile APK 的 Build APK 就可以了

生成的apk 在

HelloWorldApp\app\build\outputs\apk\debug

中 这个是可以直接安装的

安装后是一个固定的照片 就是检测了一个固定的照片

这是一个例子如果你只是想测试自己的模型调用能不能成功这个项目改改模型和模型加载即可

这个项目模型是一个resnet18 接着我们将其替换为resnet50

模型转换代码如下

import torch
import torchvision.models as models
from PIL import Image
import numpy as np
image = Image.open("test.jpg") #图片发在了build文件夹下
image = image.resize((224, 224),Image.ANTIALIAS)
image = np.asarray(image)
image = image / 255
image = torch.Tensor(image).unsqueeze_(dim=0)
image = image.permute((0, 3, 1, 2)).float()

model = models.resnet50(pretrained=True)
model = model.eval()
resnet = torch.jit.trace(model, torch.rand(1,3,224,224))
# output=resnet(torch.ones(1,3,224,224))
output = resnet(image)
max_index = torch.max(output, 1)[1].item()
print(max_index) # ImageNet1000类的类别序
resnet.save('model.pt')
if __name__ == '__main__':
  pass

将这个保存的模型 覆盖掉下面路径中的模型
 (在覆盖之前最好备份一个原来的模型,这里我们选择修改原来模型的名字为model_1.pt)

HelloWorldApp\app\src\main\assets\model.pt

成功覆盖后再一次执行打包操作(在Build 中选择Build Bundile APK 的 Build APK 就可以了
生成的apk 在
HelloWorldApp\app\build\outputs\apk\debug)
而后打开文件发现一个123M的apk 之前的apk是73M

安装 并且测试

完美打开也就是说一切resnet 系列的 都可以通过这个 项目进行演化出来

到此这篇关于pytorch 移动端部署之helloworld的使用的文章就介绍到这了,更多相关pytorch 移动端部署helloworld内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
TensorFlow中权重的随机初始化的方法
Feb 11 Python
Python实现繁体中文与简体中文相互转换的方法示例
Dec 18 Python
python实现三维拟合的方法
Dec 29 Python
Django上线部署之IIS的配置方法
Aug 22 Python
Python获取当前脚本文件夹(Script)的绝对路径方法代码
Aug 27 Python
python中树与树的表示知识点总结
Sep 14 Python
python绘制无向图度分布曲线示例
Nov 22 Python
Python 使用threading+Queue实现线程池示例
Dec 21 Python
pytorch方法测试——激活函数(ReLU)详解
Jan 15 Python
python获取响应某个字段值的3种实现方法
Apr 30 Python
通过实例解析Python文件操作实现步骤
Sep 21 Python
关于python中remove的一些坑小结
Jan 04 Python
把Anaconda中的环境导入到Pycharm里面的方法步骤
Oct 30 #Python
Python模拟登录和登录跳转的参考示例
Oct 30 #Python
python中watchdog文件监控与检测上传功能
Oct 30 #Python
GitHub上值得推荐的8个python 项目
Oct 30 #Python
python读取excel数据绘制简单曲线图的完整步骤记录
Oct 30 #Python
用python写PDF转换器的实现
Oct 29 #Python
python查询MySQL将数据写入Excel
Oct 29 #Python
You might like
php中CI操作多个数据库的代码
2012/07/05 PHP
destoon实现底部添加你是第几位访问者的方法
2014/07/15 PHP
PHP判断json格式是否正确的实现代码
2017/09/20 PHP
PHP5.6.8连接SQL Server 2008 R2数据库常用技巧分析总结
2019/05/06 PHP
node.js中的fs.renameSync方法使用说明
2014/12/16 Javascript
JS实现超精简响应鼠标显示二级菜单代码
2015/09/12 Javascript
Jquery $when done then的用法详解
2016/05/20 Javascript
JS数组操作中的经典算法实例讲解
2017/07/26 Javascript
Vue框架中正确引入JS库的方法介绍
2017/07/30 Javascript
javascript获取指定区间范围随机数的方法
2017/09/08 Javascript
简单实现vue验证码60秒倒计时功能
2017/10/11 Javascript
谈谈vue中mixin的一点理解
2017/12/12 Javascript
JS+php后台实现文件上传功能详解
2019/03/02 Javascript
Vue CLI3创建项目部署到Tomcat 使用ngrok映射到外网
2019/05/16 Javascript
微信小程序点击图片实现长按预览、保存、识别带参数二维码、转发等功能
2019/07/20 Javascript
[01:46]新英雄登场
2019/09/10 DOTA
Python运行的17个时新手常见错误小结
2012/08/07 Python
Django实现的自定义访问日志模块示例
2017/06/23 Python
python爬取亚马逊书籍信息代码分享
2017/12/09 Python
django上传图片并生成缩略图方法示例
2017/12/11 Python
对numpy Array [: ,] 的取值方法详解
2018/07/02 Python
Python3.6使用tesseract-ocr的正确方法
2018/10/17 Python
Python使用Pickle模块进行数据保存和读取的讲解
2019/04/09 Python
Django框架使用mysql视图操作示例
2019/05/15 Python
python安装numpy和pandas的方法步骤
2019/05/27 Python
Python如何访问字符串中的值
2020/02/09 Python
Django choices下拉列表绑定实例
2020/03/13 Python
CSS3实现复选框动画特效示例代码
2016/09/27 HTML / CSS
工程监理应届生求职信
2013/11/09 职场文书
教师演讲稿范文
2014/01/08 职场文书
技校个人求职信范文
2014/01/25 职场文书
2014年除四害工作总结
2014/12/06 职场文书
创先争优承诺书
2015/01/20 职场文书
市场总监岗位职责
2015/02/11 职场文书
elasticSearch-api的具体操作步骤讲解
2021/06/28 Java/Android
Python中request的基本使用解决乱码问题
2022/04/12 Python