人工智能深度學習領域中Python之外的語言如何應用

深度學習領域目前主流的語言是Python,但一些深度學習框架也推出了其他語言的版本或適配方法。以谷歌(Google)公司著名的TensorFlow平臺為例,雖然訓練神經網絡的過程還需要使用Python語言,但對於已經訓練好的神經網絡模型,已經可以在Java、Javascript、C++、Go等語言中調用,以便利用這些模型進行計算並獲取神經網絡對於需解決問題的預測結果。下面我們來給出一個具體的實例幫助理解這種方式,實例將使用Go語言(Golang)。

人工智能深度學習領域中Python之外的語言如何應用


1. 搭建Go語言調用TensorFlow模型所需的環境

TensorFlow目前僅支持在Linux和MacOS下由Go語言調用,因此,如果想在Windows下使用,建議在Windows 10上安裝Ubuntu子系統(Ubuntu是Linux系統中的一種,Windows 10中支持以子系統的方式安裝Ubuntu,可以在Microsoft Store中搜索安裝,是免費的),或者使用VirtualBox等免費的虛擬機軟件安裝Linux的虛擬機。本節中演示的將是在Ubuntu系統中搭建Go語言調用TensorFlow模型所需的環境以及具體調用的過程與方法,其他操作系統中方法是類似的,命令名稱可能略有不同。

首先,雖然是在Go語言中調用TensorFlow模型,但仍然需要先安裝TensorFlow框架,而由於TensorFlow框架是基於Python的,所以還是要先安裝Python。TensorFlow需要Python 3.x系列版本,目前最好使用3.5或3.6大版本號下最新小版本,例如我們示例中使用的是Ubuntu 16.04版本,最新只能安裝到Python 3.5.2版本。更新Python版本可以用下面的命令(後面所有示例都是用root賬戶來進行的,如果使用其他賬戶,需要在命令前加上sudo來獲取超級用戶權限):

apt-get upgrade python3

或直接:

apt upgrade python3

之後用下面的命令安裝TensorFlow:

pip3 install -U TensorFlow

安裝完畢之後,可以啟動python3的交互式界面,然後輸入下面的命令來檢查是否正確安裝了TensorFlow。

import tensorflow

print(tensorflow.__version__)

如果看到類似下圖的輸出結果,就說明安裝正常。

人工智能深度學習領域中Python之外的語言如何應用


然後要保證Go語言在該系統中也正常安裝並設置好了GOPATH環境變量。之後需要再安裝TensorFlow的C語言API庫,這個庫用於與其他語言(包括Go語言)的綁定。從官網“Install”頁面的C語言下載頁面下載對應操作系統的最新版本,例如我們下載的是名為libtensorflow-cpu-linux-x86_64-1.12.0.tar.gz的文件。用下面的命令將其安裝到/usr/local目錄:

tar -xzf libtensorflow-cpu-linux-x86_64-1.12.0.tar.gz -C /usr/local

再運行ldconfig命令配置好鏈接器,然後可以用下面的C語言程序驗證是否正確安裝了TensorFlow的C語言庫。

#include <stdio.h>

#include <tensorflow>

int main() {

printf("Hello from TensorFlow C library version %s\\n", TF_Version());

return 0;

}

將這段程序保存為名為hello_tf.c或其他任何名字的C語言源代碼文件,然後用g++或gcc命令來編譯:


編譯時如果出現錯誤,要加上 -ltensorflow參數就可以編譯通過,運行編譯出來的hello_tf可執行文件看到如上圖的輸出,就說明安裝正確了。

再往後就可以正式開始安裝所需的Go語言第三方包,需要安裝兩個:

go get -v github.com/tensorflow/tensorflow/tensorflow/go

go get -v github.com/galeone/tfgo

安裝成功後就完成了所有的環境搭建,可以正式開始測試了。

2. 在Python中訓練TensorFlow模型並保存

為了演示需要,我們先在Python中訓練一個基於神經網絡的深度學習模型用於測試。

import tensorflow as tf

import random

import os

import sys

import shutil


random.seed()

x = tf.placeholder(tf.float32, name="x")

yTrain = tf.placeholder(tf.float32)

w1 = tf.Variable(tf.random_normal([4, 32], mean=0.5, stddev=0.1), dtype=tf.float32)

b1 = tf.Variable(0, dtype=tf.float32)

xr = tf.reshape(x, [1, 4])

n1 = tf.nn.tanh(tf.matmul(xr, w1) + b1)

w2 = tf.Variable(tf.random_normal([32, 32], mean=0.5, stddev=0.1), dtype=tf.float32)

b2 = tf.Variable(0, dtype=tf.float32)

n2 = tf.nn.sigmoid(tf.matmul(n1, w2) + b2)

w3 = tf.Variable(tf.random_normal([32, 2], mean=0.5, stddev=0.1), dtype=tf.float32)

b3 = tf.Variable(0, dtype=tf.float32)

n3 = tf.matmul(n2, w3) + b3

y = tf.nn.softmax(tf.reshape(n3, [2]), name="y")

loss = tf.reduce_mean(tf.square(y - yTrain))

optimizer = tf.train.RMSPropOptimizer(0.01)

train = optimizer.minimize(loss)

sess = tf.Session()

sess.run(tf.global_variables_initializer())

lossSum = 0.0

for i in range(10000):

xDataRandom = [int(random.random() * 10), int(random.random() * 10), int(random.random() * 10), int(random.random() * 10)]

if xDataRandom[2] % 2 == 0:

yTrainDataRandom = [0, 1]

else:

yTrainDataRandom = [1, 0]

result = sess.run([train, x, yTrain, y, loss], feed_dict={x: xDataRandom, yTrain: yTrainDataRandom})

lossSum = lossSum + float(result[len(result) - 1])

print("i: %d, loss: %10.10f, avgLoss: %10.10f" % (i, float(result[len(result) - 1]), lossSum / (i + 1)))

if os.path.exists("export"):

shutil.rmtree("export")

print("Saving model...")

builder = tf.saved_model.builder.SavedModelBuilder("export")

builder.add_meta_graph_and_variables(sess, ["tag"])

builder.save()

代碼 18‑1 testtf/savemodel.py

代碼 18‑1是在Python語言中使用TensorFlow框架來訓練一個神經網絡的示例代碼,該神經網絡主要用於根據身份證的後四位數字推斷持有者的性別。具體神經網絡的實現我們在本書中不做過多解釋,僅需要了解運行這段Python程序後將在運行目錄下新建一個export目錄,其中保存了該神經網絡的訓練結果,下面我們介紹如何在Go語言中調用該神經網絡來進行預測。所謂的“預測”,指的是神經網絡根據大量數據和對應的正確結果訓練出一套算法,當再遇到新的數據時就可以根據該算法來計算出結果,這就是預測。

3. 使用Go語言調用TensorFlow模型進行預測

首先要獲得TensorFlow中保存的神經網絡模型,本例中就是export目錄及其中所有的文件。然後用下面的Go語言程序就可以進行載入、調用和預測。

package main

import (

"fmt"

tg "github.com/galeone/tfgo"

tf "github.com/tensorflow/tensorflow/tensorflow/go"

)

func main() {

model := tg.LoadModel("/root/py/export", []string{"tag"}, nil)

inputArray := [][]float32{{1, 2, 3, 4}}

fmt.Printf("input: %v\\n", inputArray)

fakeInput, _ := tf.NewTensor(inputArray)

results := model.Exec([]tf.Output{

model.Op("y", 0),

}, map[tf.Output]*tf.Tensor{

model.Op("x", 0): fakeInput,

})

predictions := results[0].Value().([]float32)

fmt.Printf("predict: %v\\n", predictions)

}

代碼 18‑2 testtf/testtf.go

代碼 18‑2中,從“/root/py/export”目錄載入了我們之前保存的TensorFlow模型(注意參數中的tag是在保存模型時指定的標記,兩邊必須一致才能正確載入模型),然後傳入正確形式的輸入參數(本例中是一個二維數組,但只有第一維有一個四個數字組成的向量)後調用model.Exec函數即可運行該神經網絡模型獲得預測的值。代碼 18‑2的運行結果是:

root@txVPC02:~/goprjs/src/testtf# go run testtf.go

2019-03-06 23:50:37.066663: I tensorflow/cc/saved_model/reader.cc:31] Reading SavedModel from: /root/py/export

2019-03-06 23:50:37.101462: I tensorflow/cc/saved_model/reader.cc:54] Reading meta graph with tags { tag }

2019-03-06 23:50:37.102592: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to

use: SSE4.1 SSE4.2 AVX AVX2 FMA

2019-03-06 23:50:37.258481: I tensorflow/cc/saved_model/loader.cc:162] Restoring SavedModel bundle.

2019-03-06 23:50:37.771518: I tensorflow/cc/saved_model/loader.cc:138] Running MainOp with key legacy_init_op on SavedModel bundle.

2019-03-06 23:50:37.771576: I tensorflow/cc/saved_model/loader.cc:259] SavedModel load for tags { tag }; Status: success. Took 704924 microseconds.

input: [[1 2 3 4]]

predict: [0.5751267 0.42487338]

可以看到,程序成功根據輸入數據獲得了預測值(我們暫時不用去管預測值的準確程度,因為訓練該模型時的訓練輪數並不夠),說明Go語言中調用神經網絡模型進行預測是成功的。


分享到:


相關文章: