在Android Studio里撰寫Python程序


Android Studio里撰寫Python程序

by 高煥堂

 

1. 首先建立一個Android項目

 首先建立一個新的Android程序開發項目。

   

  例如,檔案名稱是—myHello.py。

   

  並且開始撰寫Python程序:

   

      其完整程序如下:

# myHello.py

import numpy as np

from java import jclass

def sigmoid(x):

    return 1/(1+np.exp(-x))

def softmax(x):

    orig_shape=x.shape

    if len(x.shape)>1:

         #Matrix

         tmp=np.max(x,axis=1)

         x-=tmp.reshape((x.shape[0],1))

         x=np.exp(x)

         tmp=np.sum(x,axis=1)

         x/=tmp.reshape((x.shape[0],1))

    else:

         #Vector

         tmp=np.max(x)

         x-=tmp

         x=np.exp(x)

         tmp=np.sum(x)

         x/=tmp

    return x

 

hidden_nodes = 3

output_labels = 2

dx = np. array([[7.5, 5.5],  [3, 12.5],  [6.6,  3.5],  [1.2,  7.5]],

            dtype=np.float32)

test_x = np. array( [[2.8, 5.9], [4.8, 3.3]], dtype=np.float32)

dt = np. array([[1,0], [0,1], [1,0], [0,1]],dtype=np.float32)

wh = np. array([[0.1, 0.5, 0.1],

             [0.1, 0.5, 0.1]], dtype=np.float32)

bh = np.array([0.5, 0.5, 0.5], dtype=np.float32)

wo = np. array([[0.1, 0.5], [0.5, 0.5], [0.5, 0.1]], dtype=np.float32)

bo = np.array([0.5, 0.5], dtype=np.float32)

lr = 0.05

yv = 0

def one_round(x, t):

    global wh, bh, wo, bo, lr, yv

    #----- 開始訓練 -----------------------

    #feedforward

    yh = np.dot(x, wh) + bh

    zh = sigmoid(yh)

    yo = np.dot(zh, wo) + bo

    zo = softmax(yo)

    # BP for Output  ---------------------

    error = t - zo

   delta = lr * error

    error_h = np.dot(delta , wo.T)

    dw_o = np.zeros((3, 2), np.float32)

    for i in range(3):

        for j in range(2):

            dw_o[i, j] = zh[i] * delta[j]

    db_o = delta

    # BP for Hidden

    delta_h = zh * (1-zh) * error_h

    dw_h = np.zeros((2, 3), np.float32)

    for i in range(2):

        for j in range(3):

            dw_h[i, j] = x[i] * delta_h[j]

    db_h = delta_h

    # Update Weights

    wh += dw_h

    bh += db_h

    wo += dw_o

    bo += db_o

    yv += 1

#------------------------------------

def train(ep):

    global wh, bh, wo, bo, lr, yv

    for k in range(100):

        for i in range(4):

            one_round(dx[i], dt[i])

    return yv

#----- Predict ------------------------

def predict(x):

    global wh, bh, wo, bo, lr, yv, test_x

    yh = np.dot(test_x, wh) + bh

    zh = sigmoid(yh)

    yo = np.dot(zh, wo) + bo

    zo = softmax(yo)

    pv = np.round(zo, 5)

   return pv

#  END

 

2. 上述Python程式碼的說明

   這是一個二元分類的范例。其中有2只<玩具兔>和2只<玩具貓>。其中,主要的特征在於兔子是:耳朵長、尾巴短;而貓則是:尾巴長、耳朵短。其資料如下:

      

 ※ 正向推演(Feed-Forward)階段

   上述Python程式,建立了一個兩層的NN模型(含有一個隱藏層):

   

   其中,權重(W)則代表訊息傳遞的強弱。然后,需要使用到不同的數學式來計算各個y值(包括y0、y1、y2、y3),這些數學式,就如下圖所示:

  

   所謂正向推演部分,就是將x0和x1訓練資料喂給(Feed)這NN模型的輸入層,然后透過上圖的數學式的計算,推演出下一層(即隱藏層)的y0、y1和y2。,基於這些y[]值、計算出z[]值,再透過數學式的計算,推演到下一層(即輸出層)的 z3值。 

※ 反向傳播(Back-Propagation)階段

  經由剛才的正向推演計算,得到了輸出層的z3值之后,就可以展開反向傳播的運算了。首先計算落差值(t-z3),再從這落差值計算出<反向修正值(Delta)>,如下圖:

  

  然后,拿這反向修正(Delta)值來與w03相乘,就反向推演出隱藏層第#0神經元(即y0)的誤差值了。如下圖:

  

  同樣地,拿這delta值來與w13相乘,就反向推演出隱藏層y1神經元的誤差值了。如下圖:

  

    同樣地,拿這delta值來與w13相乘,就反向推演出隱藏層y2神經元的誤差值了。如下圖:

  

    到此已經反向推演出隱藏層的各神經元的落差值:loss_y0、loss_y1和loss_y2值了。接下來,就依據落差值來計算出修正值:delta_y0、delta_y1和delta_y2值。以便修正各相關的權重(Weight)值了。例如,從loss_y0計算出delta_y0,繼續藉由delta_y0來修正w00和w10值,來提升這NN模型的智慧,如下圖:

  

        同樣地,也從loss_y1計算出delta_y1,繼續藉由delta_y1來修正w01和w11的值。一樣地,也從loss_y2計算出delta_y2,繼續藉由delta_y2來修正w02和w12的值,來記錄NN模型的智慧,如下圖:

  

    最后,依據輸出層的delta值來修正輸出層的權重(Weight)如下圖:

  

          於是,完成了這個2層AI模型的訓練了。

3. 開發Java程式:定義UI

   開始以Java設計UI部分,茲修改myActivity.java如下:

  

   其完整程序如下:

#myActivity.java

package com.example.chaquo01;

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.widget.TextView;

import java.util.List;

import com.chaquo.python.android.AndroidPlatform;

import com.chaquo.python.*;

 

public class myActivity extends AppCompatActivity {

    TextView tv1, tv2, tv3, tv4, tv5, tv6;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        tv1 = (TextView) findViewById(R.id.tv_device);

        tv2 = (TextView) findViewById(R.id.tv_device2);

        tv3 = (TextView) findViewById(R.id.tv_device3);

        tv4 = (TextView) findViewById(R.id.tv_device4);

        tv5 = (TextView) findViewById(R.id.tv_device5);

        tv6 = (TextView) findViewById(R.id.tv_device6);

        tv2.setText("    ....... Prediction .......");

        //-------------------------------------------------------------------------

        if (!Python.isStarted()) {

            Python.start(new AndroidPlatform(this));

        }

        //------- 呼叫 Python(myHello)程式里的函數:mul_add()

        Python py = Python.getInstance();

        PyObject obj1 = py.getModule("myHello").callAttr("train", 1000);

        PyObject obj2 =

py.getModule("myHello").callAttr("predict", 1000);

        List<PyObject> pyList = obj2.asList();

        String ss1 = pyList.get(0).toString();

        String ss2 = pyList.get(1).toString();

        tv3.setText("    ["+ss1);

        tv4.setText("     "+ss2 + "]");

   }}

4. 執行這個Android App程序

  執行這個Android App程序,它首先啟動myActivity.java。執行到指令:

     PyObject obj1 = py.getModule("myHello").callAttr("train", 1000);

就呼叫myHello.py的train()函數。進行AI模型的訓練。訓練好了,就執行到指令:

     PyObject obj2 = py.getModule("myHello").callAttr("predict", 1000);

就呼叫myHello.py的predicyt()函數,進行預測的任務。然后,輸出預測的結果,如下圖所示:

  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM