如何在Android App中使用matlab的神经网络代码

整个过程大概可以分成这么几步:

  1. 首先你要在matlab中写一个完整的神经网络

    1. 获取样本
    2. 样本导入
    3. 神经网络建模
    4. 神经网络训练
    5. 神经网络测试(优化建模)
  2. 然后你要在matlab中重写一个神经网络,第二个神经网络的特殊之处是
    1. 首先这个神经网络必须写成函数,具体有几个细节
    2. 把第一个神经网络的训练结果net网络保存成mat文件
    3. 把相关需要用的但无法直接写入代码的数据也保存成mat文件(比如数据归一化的参数)
    4. 然后在函数中把上面几个mat文件导入,基本上就是一个完整的神经网络模型了
    5. 再加上一个神经网络计算语句,并把结果返回,这个函数就完成了
  3. 然后把这个matlab神经网络函数进行打包,打包的结果是一个jar包
    1. 这块的打包需要注意几个问题

      1. 配置几个环境变量
      2. jdk的版本不能太高,它是与Matlab版本相对应的,目前我的这个matlab2015对应的是jdk7,8都不可以
  4. 然后把这个jar包连同另一个jar包一块导入Andorid工程,并添加为外部依赖
  5. 最后在Android工程中写一个专门调用这个Jar包接口代码的函数,传入输入变量,返回计算结果
  6. 结束开始运行测试,你会发现它报错了,是的,这样做是不行的,但是在java工程中是可以运行的
    1. 为什么不行?
    2. 有什么其他解决办法?

1.在matlab中写一个完整的神经网络

1.1.获取样本就不说了

1.2.样本导入

如何导入数据呢,一般matlab中有通用的数据存储格式,那就是Mat格式,但是我并不知道怎么编写这个格式

在我发现有办法可以把txt中的数据导入进去之后我就选定它了,因为这种格式也非常方便我用android输出,也就是说它是一种比较通用的信息交换格式

具体的操作方法非常简单:

  1. 你在txt中按这种格式保存数据:每行用回车隔开,每列用空格隔开
  2. 然后你在matlab中load这个文件,就能得到一个数据的矩阵了

代码如下:


alldata = load(‘alldata.txt‘);

alldata = alldata(:,:);

1.3. 1.4. 1.5. 这几个过程照着代码修改还是比较简单的(虽然我当时读得有点困难。。。),稍微提这么几点:

  1. (直接把matlab30个例子的源码包放到工作路径,复制里边的代码比较方便)
  2. 输出数据需要进行一下矩阵转换
  3. 归一化处理数据就是多走一步流程,很简单(虽然不知道原理)
  4. 使用newff工具函数来构建神经网络,使用matlab内部的工具箱(其实就是库函数)来建模、训练和计算,不需要自己写逻辑代码
  5. 参数配置不是特别懂
  6. 最后出图的时候好好修改调一调,不难
  7. 中间各种矩阵的变换感觉不是很习惯,可以参看一下工作空间里的变量状态,或者一步步打印一些变量的结果来看

clc;

clear;

%导入300组数据

alldata = load(‘alldata.txt‘);

alldata = alldata(:,:);

%输入输出数据

input = alldata(:,2:33);

outputtemp = alldata(:,1);

%输出数据需要处理一下

output = zeros(300,2);%预先分配内存

for i=1:300

switch outputtemp(i)

case 0

output(i,:) = [1 0];%意思是如果数据结果是0,则输出层的状态是[1 0],或者用第一个输出节点表示

case 1 %能直接识别带小数位的数据

output(i,:) = [0 1];

end

end

%从中随机抽取280组数据作为训练数据,20组数据作为预测数据

k = rand(1,300);

[m,n] = sort(k);

input_train = input(n(1:280),:)‘;

output_train = output(n(1:280),:)‘;

input_test = input(n(281:300),:)‘;

output_test = output(n(281:300),:)‘;

%输入输出数据进行归一化处理

[inputn,inputps] = mapminmax(input_train);

[outputn,outputps] = mapminmax(output_train);

%网络结构构建32-6-2

net=newff(inputn,outputn,6);

%网络参数配置(迭代次数,学习率,目标)

net.trainParam.epochs=100;

net.trainParam.lr=0.1;

net.trainParam.goal=0.0004;

%网络训练

net=train(net,inputn,outputn);

%BP网络预测

%预测数据归一化

inputn_test=mapminmax(‘apply‘,input_test,inputps);

%网络预测输出

an=sim(net,inputn_test);

%网络输出反归一化

BPoutput=mapminmax(‘reverse‘,an,outputps);

%结果分析

figure(1)

plot(BPoutput,‘:og‘)

hold on

plot(output_test,‘-*‘);

legend(‘预测输出‘,‘期望输出‘)

title(‘BP网络预测输出‘,‘fontsize‘,12)

ylabel(‘函数输出‘,‘fontsize‘,12)

xlabel(‘样本‘,‘fontsize‘,12)

%预测误差

error=BPoutput-output_test;

figure(2)

plot(error,‘-*‘)

title(‘BP网络预测误差‘,‘fontsize‘,12)

ylabel(‘误差‘,‘fontsize‘,12)

xlabel(‘样本‘,‘fontsize‘,12)

figure(3)

plot((output_test-BPoutput)./BPoutput,‘-*‘);

title(‘神经网络预测误差百分比‘)

errorsum = sum(abs(error))

2.在matlab中重写这个神经网络,为导出jar包做准备

2.1.首先这个神经网络必须写成函数

在matlab写一个函数的过程是这样的

  1. 在工作空间中右键新建函数,重命名后打开,就是这样
  2. matlab中的函数有点特殊,在这里一起趁热讲了
    1. 整个函数有一头一尾两句固定的声明,头是以function开始,然后是:返回值 = 函数名(函数参数),尾是end,虽然一开始看得不适应,但是习惯还是很好理解的,跟其他的语言差不多

      1. 返回值可以没有,那就是直接 函数名(函数参数)
      2. 返回值可以有多个,参数也可以有多个,他们的形式是这样:function [x,y,z]=sphere(theta,phi,rho)
      3. 注意Matlab中不会对函数类型进行声明,所以很多时候你在写函数的时候一开始就要对输入参数进行一个检查
    2. 然后下面接着是官方注释,第一句是摘要,之后是详细说明,这些东西会在预览的时候显示
    3. 接下来就是函数体了,你可以做各种事情,逻辑语句、调用其他函数
    4. 最后在end之前你需要定义返回值,matlab在这块有点特殊,你不用显示地指定return哪个变量,因为你第一句声明里有返回值变量,所以只要你的函数内容中有这个变量,那么最后执行到end的时候就会自动返回这个变量这时候的状态
    5. -----调用函数------
    6. 调用函数的形式跟函数声明的第一句是一毛一样的:[输出参数表]=函数名(输入参数表)
    7. 调用函数时,输入和输出参数的顺序应与函数定义时的一致,数目一定不能多于函数定于中的,可能可以少于
    8. 为什么可以少于,因为在函数内部可以通过nargin()和nargout()获取函数被调用时用户指定的输入、输出参数个数。所以如果这个函数里边有针对不同的少于输入少于输出的情况进行if else的话,就可以自动适应
  3. 那么在这里,我的输出是一个int,输入是一个行矩阵,或者说一个数组,我的函数开头就这么写了:
    function output = annforecastthi(input_test)

2.2.然后为了不在这个函数里对神经网络进行训练(因为matlab的设定就是无法把训练函数导出成Jar包),需要把先前神经网络中训练好的net保存成mat文件再在这里直接导出

  1. 把先前神经网络中训练好的net保存成mat文件 非常简单。直接在运算结束后再工作空间中右键net变量,保存为mat文件就可以了
  2. 然后导入的时候稍微有点麻烦
    1. 其实load mat文件有两种方式,一种是命令行方式,一种是函数方式。我查了一下两种方式功能上没什么区别,但是推荐在函数里用函数方式,而命令行方式的形式还会简单很多
    2. 以导入一个结构体(归一化参数)为例:
      1. 命令行方式 :load anninputps inputps;
      2. 函数方式:
    3. 而导入net数据的时候还要麻烦一些:
      1. 命令行方式:load annnet net;
      2. 函数方式:(后边还要加一句把结构体转型成网络格式)
  3. 这里需要导入三个mat文件,一个net和两个归一化参数(后边要用来反归一化)

2.3.最后返回计算结果,第二个神经网络模型也是神经网络计算函数就完成了

output=find(BPoutput(:,1)==max(BPoutput(:,1)));

整个函数是这样:


function output = annforecastthi(input_test)

%ANNFORECAST

%   输入长度为32的行矩阵,输出为1或2

A = load(‘annnet.mat‘);

B = fieldnames(A);

net = A.(B{1});

net = network(net);

C = load(‘anninputps.mat‘);

D = fieldnames(C);

inputps = C.(D{1});

E = load(‘annoutputps.mat‘);

F = fieldnames(E);

outputps = E.(F{1});

%BP网络预测

%预测数据归一化

inputn_test=mapminmax(‘apply‘,input_test‘,inputps);

%网络预测输出

an=sim(net,inputn_test);

%网络输出反归一化

BPoutput=mapminmax(‘reverse‘,an,outputps);

%结果分析

%根据网络输出找出数据属于哪类

output=find(BPoutput(:,1)==max(BPoutput(:,1)));

end

---待续

时间: 2024-08-25 09:34:07

如何在Android App中使用matlab的神经网络代码的相关文章

如何在android app中使用STL库

方法: 1.在jni目录下新建Application.mk; 加入 APP_STL := stlport_static右边的值还可以换成下面几个: system - 使用默认最小的C++运行库,这样生成的应用体积小,内存占用小,但部分功能将无法支持 stlport_static - 使用STLport作为静态库,这项是Android开发网极力推荐的 stlport_shared - STLport作为动态库,这个可能产生兼容性和部分低版本的Android固件,目前不推荐使用. gnustl_st

如何在Android开发中让你的代码更有效率

如何在Android开发中让你的代码更有效率 最近看了一个视频,名字叫做Doing More With Less: Being a Good Android Citizen,主要是讲如何用少少的几句代码来改善Android App的性能.在这个视频里面,演讲者以一个图片app为例讲解如何应用Android中现有的东西来改善app性能问题. 这个图片app的代码:https://github.com/penkzhou/iogallery.ppt:http://greenrobot.qiniudn.

低功耗蓝牙(BLE)在 Android APP 中的应用

低功耗蓝牙(BLE)在 Android APP 中的应用 前言 最近公司接了一个新项目,用户可以把自己的乐器跟Phone或Pad连接起来,当弹奏乐器的时候,会把演奏情况同步反馈到设备上,方便用户练习,有点类似于之前玩过的一款叫[ 吉他英雄 ]的游戏.不过这次不用插线,直接蓝牙无线连接就可以了. 那么问题来了,因为弹奏的时候数据传输一直在进行,但是如果要一直打开蓝牙的话是很费电的,也许没几首曲子下来设备的电量就耗掉了不少,这当然是无法接受的.那有没有什么好的解决方案呢? 运气真好,Android在

通过Appium获取Android app中webview

因为要测试Android app中嵌入的web页面,所以需要从native切换到webview.网上查了好多帖子,都用到类似下面代码: //判断是否有 WEBVIEWSet<String> contextNames = driver.getContextHandles();for (String contextName : contextNames) {System.out.println(contextName);if (contextName.contains("WEBVIEW&

【转】如何在 Android 程序中禁止屏幕旋转和重启Activity

原文网址:http://www.cnblogs.com/bluestorm/p/3665890.html 禁止屏幕随手机旋转变化 有时候我们希望让一个程序的界面始终保持在一个方向,不随手机方向旋转而变化:在AndroidManifest.xml的每一个需要禁止转向的Activity配置中加入android:screenOrientation=”landscape” 属性. landscape = 横向portrait = 纵向 避免在转屏时重启Activity android中每次屏幕方向切换时

DAVE SDK 4.1.2 Help content —— 如何在父APP中建立多个APP

 如何在父APP中建立多个APP 在这个demo APP中,我们需要2-5个DIGITAL_IO APP 根据微处理器的型号(XMC4500两个XMC1200五个).最简单的方法是写下建立一个APP的语句复制2遍然后用if判断是不是1200来决定是否有接下来的3遍定义. 然而,我们可以用循环,Groovy来使它更为紧凑. 首先,我们以最大可能用的数目来定义"MRequiredApp" 82 83 84 85 86 87 88 // Begin : User APP property

Hybrid Android App中通过js访问Shared Preferences的问题

昨天研究Hybrid Android App中js和java代码之间数据共享的问题,具体场景是用户登录是android java实现,但有些业务是使用html5开发的,因此登录后到主页后,调整到某些HTML5业务页面需要传递用户的access_token,  目前想到的办法是在js端通过cordova插件访问存在Shared Preferences中的数据,但由于数据是异步返回的,需要一定的时间,有时不能及时取得数据,所以问题不能完美的解决. 目前访问Shared Preferences的Cor

如何在 iOS App 中整合 Facebook 廣告

原文:Displaying Facebook Ads in Your iOS Apps 作者:GABRIEL THEODOROPOULOS 译者:kmyhy 不久前有人問我如何在項目中集成 Facebook 的廣告.因為之前沒用過,以為一定很難,所以事先查閱了大量文檔.在通讀完文檔之後,發現其實並不是很難,僅僅幾分鐘我就能夠搞定我的第一個 Facebook 廣告 App! Facebook 廣告是一種將廣告集成到你的 app 中的方法,使你可以通過廣告的點擊量來獲得收入.這個方法(集成廣告)并不

如何在android studio中cordova的混合开发

基于Android Studio 中Cordova的开发 cordova简介 Cordova的前身是PhoneGap 官网: (http://cordova.io) Cordova应是运行在客户端本地应用容器的web应用.因此,运行在Cordova容器中的Html5应用的结构和传统的基于web服务器的有所不同.传统的web应用中服务器端做了大部分工作,比如按照用户请求传回生成的内容.而Cordova这种容器中的应用本身包括了所需要的静态页面,用户请求一般由js代码响应并与服务器交互,这样与服务器