golang調用tensor flow模型


1. 安裝Go版TensorFlow

TensorFlow 提供了一個 Go API,該 API 特別適合加載用 Python 創建的模型並在 Go 應用中運行這些模型。

安裝TensorFlow C庫

下載地址

TensorFlow C 庫 網址
Linux
Linux CPU only https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-linux-x86_64-1.14.0.tar.gz
Linux GPU support https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-gpu-linux-x86_64-1.14.0.tar.gz
macOS
macOS CPU only https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-darwin-x86_64-1.14.0.tar.gz
Windows
Windows CPU only https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-windows-x86_64-1.14.0.zip
Windows GPU only https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-gpu-windows-x86_64-1.14.0.zip

解壓 :

tar -C $dir -xzf tar_file

添加到動態庫:

export LIBRARY_PATH=$LIBRARY_PATH:$dir/lib

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$dir/lib

如果你已經解壓到了/usr/local下,則不需要配置LIBRARY_PATH和LD_LIBRARY_PATH,只需要執行sudo ldconfig即可

安裝 TensorFlow Go

go get github.com/tensorflow/tensorflow/tensorflow/go

2. 用Python訓練tensor flow模型並保存

注意:python的tensor flow版本不能高於go的tensor flow版本,否則go加載模型文件時會報錯。

import tensorflow as tf
from keras import backend as K

sess = tf.Session()
K.set_session(sess)

def build_deep_cross():
    inputs = []
    for i, feature_name in enumerate(feature_names):
        cate_in = Input((1,), name=feature_name)
        inputs.append(cate_in)
        # 此處略去很多代碼
    cross_net = build_cross_net(f_dim_vectors)  # CrossNet
    deep_out = build_dnn(f_dim_vectors, continuous_input)  # 深層網絡
    # 結合CrossNet和深層網絡
    concat_cross_deep = Concatenate()([cross_net, deep_out])
    outputs = Dense(1, activation="sigmoid", name="output_layer")(concat_cross_deep)
    # 留意模型的inputs和outputs,寫Golang時要用
    model = Model(inputs=inputs, outputs=outputs)
    solver = Adam(lr=0.01, decay=0.1)
    model.compile(optimizer=solver, loss='binary_crossentropy', metrics=['acc'])
    return model

model=build_deep_cross()
model.fit(X_train, Y_train, batch_size=256, epochs=10)
# 專門為Golang保存一個模型
builder = tf.compat.v1.saved_model.builder.SavedModelBuilder("dcnModel")
# 必須為模型打個Tag,否則golang無法加載
builder.add_meta_graph_and_variables(sess, ["myTag"])
# 保存
builder.save()

 

3. Golang加載tensor flow模型

package main

import (
    tf "github.com/tensorflow/tensorflow/tensorflow/go"
    "strconv"
    "strings"
    "sync"
    "fmt"
)

type DCN struct {
    model        *tf.SavedModel
    featureNames []string
}

var (
    dcn     *DCN
    dcnOnce sync.Once
)

func GetDCNInstance(modelFile string, tags []string) *DCN {
    if dcn != nil {
        return dcn
    }
    dcnOnce.Do(func() {
        dcn = &DCN{}
        //LoadSavedModel時使用的go tensorflow版本不能低於tf.saved_model.builder.SavedModelBuilder時使用的tensorflow版本
        if model, err := tf.LoadSavedModel(modelFile, tags, nil); err == nil {
            dcn.model = model
            dcn.featureNames = []string{"age", "work_year", "gender"}
            //第一次執行model.Session.Run很耗時,所以初始化后先預熱一下
            X := []float32{0.31,0.09,1.0}
            input := [][]float32{X}
            dcn.Predict(input)
        } else {
            fmt.Printf("read dcn model file %s failed: %v", modelFile, err)
            return
        }
    })
    return dcn
}

//Predict 預測點擊率。X的連續特征需要事先做好歸一化,離散特征要轉成index
func (self DCN) Predict(X [][]float32) []float32 {
    if len(X[0]) != len(self.featureNames) {
        fmt.Printf("feature number of x is %d, but should be %d", len(X[0]), len(self.featureNames))
        return nil
    }
    input_layer := make(map[tf.Output]*tf.Tensor)
    for i := 0; i < len(X[0]); i++ { //第i列
        input := [][]float32{}
        for j := 0; j < len(X); j++ { //第j行
            input = append(input, []float32{X[j][i]})
        }
        tensor, _ := tf.NewTensor(input)
        // python版tensorflow/keras中定義的輸入層input_layer
        out := self.model.Graph.Operation(self.featureNames[i]).Output(0)
        input_layer[out] = tensor
    }
    output_layer := []tf.Output{
        //python版tensorflow/keras中定義的輸出層output_layer
        self.model.Graph.Operation("output_layer/Sigmoid").Output(0),
    }
    if result, err := self.model.Session.Run(input_layer, output_layer, nil); err == nil { //不論是1條數據還是300條數據,執行該行代碼只需要2毫秒
        scores := result[0].Value().([][]float32)
        rect := make([]float32, len(scores))
        for i, arr := range scores {
            rect[i] = arr[0]
        }
        return rect
    } else {
        fmt.Printf("predict failed: %v", err)
        return nil
    }
}

func main(){
    dcn := rank.GetDCNInstance("dcnModel", []string{"myTag"})
    X := []float32{0.31,0.09,1.0}
    input := [][]float32{X}
    scores := dcn.Predict(input)
}

 


免責聲明!

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



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