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开发之快速搭建自动回复微信公众号功能
Apr 22 Python
关于Python中空格字符串处理的技巧总结
Aug 10 Python
详细解读tornado协程(coroutine)原理
Jan 15 Python
python3.5 tkinter实现页面跳转
Jan 30 Python
shell命令行,一键创建 python 模板文件脚本方法
Mar 20 Python
使用DataFrame删除行和列的实例讲解
Apr 08 Python
Python实现的矩阵转置与矩阵相乘运算示例
Mar 26 Python
Python生成指定数量的优惠码实操内容
Jun 18 Python
Python中查看变量的类型内存地址所占字节的大小
Jun 26 Python
Python统计时间内的并发数代码实例
Dec 28 Python
scrapy中如何设置应用cookies的方法(3种)
Sep 22 Python
关于探究python中sys.argv时遇到的问题详解
Feb 23 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
一个简易需要注册的留言版程序
2006/10/09 PHP
PHP 翻页 实例代码
2009/08/07 PHP
PHP实现多维数组转字符串和多维数组转一维数组的方法
2015/08/08 PHP
PHP XML和数组互相转换详解
2016/10/26 PHP
php实现的XML操作(读取)封装类完整实例
2017/02/23 PHP
PHP使用curl_multi实现并发请求的方法示例
2018/04/29 PHP
PHP设计模式之装饰器模式定义与用法简单示例
2018/08/13 PHP
javascript操作excel生成报表示例
2014/05/08 Javascript
jQuery中DOM树操作之使用反向插入方法实例分析
2015/01/23 Javascript
jquery实现鼠标滑过显示二级下拉菜单效果
2015/08/24 Javascript
jQuery添加和删除指定标签的方法
2015/12/16 Javascript
Angularjs中UI Router全攻略
2016/01/29 Javascript
jQuery操作复选框(CheckBox)的取值赋值实现代码
2017/01/10 Javascript
将angular.js项目整合到.net mvc中的方法详解
2017/06/29 Javascript
vue.js使用代理和使用Nginx来解决跨域的问题
2018/02/03 Javascript
JavaScript检查数据中是否存在相同的元素(两种方法)
2018/10/07 Javascript
详解JavaScript 新语法之Class 的私有属性与私有方法
2019/04/23 Javascript
Node.js之删除文件夹(含递归删除)代码实例
2019/09/09 Javascript
[01:02:55]CHAOS vs Mineski 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/18 DOTA
如何将python中的List转化成dictionary
2016/08/15 Python
Python 批量读取文件中指定字符的实现
2020/03/06 Python
Django缓存Cache使用详解
2020/11/30 Python
HTML5 History API 实现无刷新跳转
2016/01/11 HTML / CSS
中国跨镜手机配件批发在线商店:TVC-Mall
2019/08/20 全球购物
欧洲著名的二手奢侈品网站:Vestiaire Collective
2020/03/07 全球购物
Ajax主要包含了哪些技术
2014/06/12 面试题
黄河的主人教学反思
2014/02/07 职场文书
《夏夜多美》教学反思
2014/02/17 职场文书
平面设计求职信
2014/03/10 职场文书
党员公开承诺事项
2014/03/25 职场文书
关于读书的演讲稿1000字
2014/08/27 职场文书
竞选纪律委员演讲稿
2014/09/13 职场文书
人生遥控器观后感
2015/06/11 职场文书
小学一年级数学教学反思
2016/02/16 职场文书
2016年国庆节假期旅游工作总结
2016/04/01 职场文书
关于拾金不昧的感谢信(五篇)
2019/10/18 职场文书