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 相关文章推荐
python通过urllib2爬网页上种子下载示例
Feb 24 Python
python妹子图简单爬虫实例
Jul 07 Python
Python获取系统所有进程PID及进程名称的方法示例
May 24 Python
对python模块中多个类的用法详解
Jan 10 Python
Python实现生成密码字典的方法示例
Sep 02 Python
使用PyTorch训练一个图像分类器实例
Jan 08 Python
Python openpyxl模块原理及用法解析
Jan 19 Python
使用keras和tensorflow保存为可部署的pb格式
May 25 Python
Keras设置以及获取权重的实现
Jun 19 Python
解决Pytorch自定义层出现多Variable共享内存错误问题
Jun 28 Python
python如何建立全零数组
Jul 19 Python
python爬虫多次请求超时的几种重试方法(6种)
Dec 01 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实现像JSP,ASP里Application那样的全局变量
2007/01/12 PHP
php知道与问问的采集插件代码
2010/10/12 PHP
一文掌握PHP Xdebug 本地与远程调试(小结)
2019/04/23 PHP
laravel异步监控定时调度器实例详解
2019/06/21 PHP
setTimeout 不断吐食CPU的问题分析
2009/04/01 Javascript
jQuery Flash/MP3/Video多媒体插件
2010/01/18 Javascript
extjs 3.31 TreeGrid实现静态页面加载json到TreeGrid里面
2013/04/02 Javascript
Microsfot .NET Framework4.0框架 安装失败的解决方法
2013/08/14 Javascript
jquery实现图片裁剪思路及实现
2013/08/16 Javascript
chrome下jq width()方法取值为0的解决方法
2014/05/26 Javascript
JS打开新窗口防止被浏览器阻止的方法
2015/01/03 Javascript
jquery UI Datepicker时间控件的使用方法(基础版)
2015/11/07 Javascript
jQuery zTree加载树形菜单功能
2016/02/25 Javascript
vue用addRoutes实现动态路由的示例
2017/09/15 Javascript
基于Vue实现图书管理功能
2017/10/17 Javascript
JavaScript插件Tab选项卡效果
2017/11/14 Javascript
JavaScript实现左侧菜单效果
2017/12/14 Javascript
在vue中,v-for的索引index在html中的使用方法
2018/03/06 Javascript
在小程序/mpvue中使用flyio发起网络请求的方法
2018/09/13 Javascript
vue项目使用axios发送请求让ajax请求头部携带cookie的方法
2018/09/26 Javascript
[02:15]2014DOTA2国际邀请赛 赛后退役选手回顾
2014/08/01 DOTA
Python 初始化多维数组代码
2008/09/06 Python
python改变日志(logging)存放位置的示例
2014/03/27 Python
Python requests模块实例用法
2019/02/11 Python
python字符串拼接+和join的区别详解
2020/12/03 Python
世界上最大的专业美容用品零售商:Sally Beauty
2017/07/02 全球购物
美国专业消费电子及摄影器材网站:B&H Photo Video
2019/12/18 全球购物
信息系统专业个人求职信范文
2013/12/07 职场文书
《搭石》教学反思
2014/04/07 职场文书
协议书的格式
2014/04/23 职场文书
班级学习雷锋活动总结
2014/07/04 职场文书
基层党员对照检查材料
2014/08/25 职场文书
2015年宣传思想工作总结
2015/05/22 职场文书
如何制定一份可行的计划!
2019/06/21 职场文书
python自动化八大定位元素讲解
2021/07/09 Python
Win11 Build 22000.51版本文件资源管理器“命令栏”和上下文菜单有什么新变化?
2021/11/21 数码科技