为了账号安全,请及时绑定邮箱和手机立即绑定

加载时找不到keras模型的输入层

加载时找不到keras模型的输入层

Go
MYYA 2022-07-11 10:38:19
我已经在 TensorFlow 2.3.1 中使用 Keras 在 Python 中训练了一个顺序模型,生成了一个 saved_model.pb 文件,但是当我尝试在 Go 中使用该模型时,我看不到我指定的输入或输出层,只有偏差和内核。训练模型的 Python 代码:import numpy as npimport pandas as pdimport tensorflow as tffrom tensorflow import feature_columnfrom tensorflow.keras import layersfrom sklearn.model_selection import train_test_splitfrom sklearn.utils import shufflefrom sklearn import preprocessingfrom tensorflow.keras.models import Modelfrom tensorflow.keras.layers import Input, Dense# A utility method to create a tf.data dataset from a Pandas Dataframedef dataframe_to_dataset(dataframe, shuffle=True, batch_size=32):    dataframe = dataframe.copy()    labels = dataframe.pop("URLType")    ds = tf.data.Dataset.from_tensor_slices((dict(dataframe), labels))    if shuffle:        ds = ds.shuffle(buffer_size=len(dataframe), seed=0)    ds = ds.batch(batch_size)    return ds, labels# load full data list from csv filecsvList = pd.read_csv("./training-data.csv", sep='\t')# split the list into training and test data liststrainingList, _ = train_test_split(csvList, test_size=0.2, random_state=0)# split the training data list into validation and test data liststrainingList, validationList = train_test_split(    trainingList, test_size=0.2, random_state=0)# print the length of the individual listsprint("training: %d\nvalidation: %d" % (len(trainingList), len(validationList)))# set up empty list for feature columnsfeature_columns = []# add numeric columns to feature columnsfor header in ["ExcessLength", "PathTokens", "NumericPathTokens", "QueryTokens", "NumericQueryTokens", "LongestNumber"]:    feature_columns.append(feature_column.numeric_column(header))    # create datasets of the training and validation dataframesbatch_size = 32trainDataset, _ = dataframe_to_dataset(    trainingList, shuffle=False, batch_size=batch_size)validationDataset, _ = dataframe_to_dataset(    validationList, shuffle=False, batch_size=batch_size)
查看完整描述

1 回答

?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

找出输入签名


keras 的输入层与其他层有些不同。在您的情况下,您的DenseFeatures层用于定义模型的默认服务签名,即您应该提供给它的输入。


如果我们查看您的 go 示例程序的输出,我们会看到这些行:


serving_default_Ending

serving_default_ExcessLength

serving_default_HasArticleToken

serving_default_HasDate

serving_default_IsFile

serving_default_LongestNumber

serving_default_NumericPathTokens

serving_default_NumericQueryTokens

serving_default_OriginalURL

serving_default_PathTokens

serving_default_QueryTokens

这些操作实际上是模型的输入。如文档tf.keras.Model中所述,使用 a 时会自动推断它们:


TensorFlow Serving 和 saved_model_cli 等工具可以与 SavedModel 交互。为了帮助这些工具确定要使用的具体函数,您需要指定服务签名。tf.keras.Models 自动指定服务签名,但您必须为我们的自定义模块显式声明服务签名。


保存模型时,模型的签名(您必须提供以进行预测的输入)会自动从DenseFeatures.


找出输出签名


您还需要提供输出张量才能通过 Graph 获取操作。很难找到要运行的操作的名称。一个好的技巧是使用 tensorflow 服务中的saved_model_cli实用程序。


运行实用程序:


$ saved_model_cli show --dir ./url_recognizer --tag_set serve --signature_def serving_default

The given SavedModel SignatureDef contains the following input(s):

  inputs['ExcessLength'] tensor_info:

      dtype: DT_INT32

      shape: (-1, 1)

      name: serving_default_ExcessLength:0


  [...]


The given SavedModel SignatureDef contains the following output(s):

  outputs['output_1'] tensor_info:

      dtype: DT_FLOAT

      shape: (-1, 1)

      name: StatefulPartitionedCall:0

Method name is: tensorflow/serving/predict

我们看到提供模型输出的 OP 的名称是StatefulPartitionedCall。


运行预测


如果要运行预测,则必须使用那些“serving_default”键提供输入,并使用输出键提供输出张量。然后调用model.Session.Run()


所以我们设法收集了以下信息:


输入被命名serving_default_<Name of the feature column>

输入具有批量大小(形状 (-1,1))。这意味着模型将期望每个输入都有一个数组。

输出是StatefulPartitionedCall

有了这些,我们可以构建一个运行示例:(仅限部分:我省略了其他输入以避免重复,但该模式很容易复制)。


// defining inputs

excessLength, err := tf.NewTensor([1]int32{0})

// otherInput, err := tf.NewTensor([1]int32{0})


// Calling session Run

output, err := model.Session.Run(

    map[tf.Output]*tf.Tensor{

        model.Graph.Operation("serving_default_ExcessLength").Output(0): excessLength,

        // model.Graph.Operation("serving_default_<OtherInput>").Output(0): otherInput,

    },

    []tf.Output{

        model.Graph.Operation("StatefulPartitionedCall").Output(0),

    },

    nil)

if err != nil {

    fmt.Printf("Error using the model: %s\n", err.Error())

    return

}


// Getting the result of the run throigh the graph

val := output[0].Value()   

fmt.Printf("Output : %f\n", val)


请注意,使用Input图层时的行为是相似的。


 # set up the model layers

slp = tf.keras.Sequential(

    [

        # layers.DenseFeatures(feature_columns, name="layer_input"),

        layers.Input(shape=(1), name='layer_input'),

        layers.Dense(1, name="layer_label", activation='sigmoid'),

    ]

)


# compile the model

slp.compile(

    optimizer="adam", loss='mse', metrics=["accuracy"],

)

slp.save('./url_recognizer')

你的 go 程序输出:


layer_label/kernel

layer_label/kernel/Read/ReadVariableOp

layer_label/bias

layer_label/bias/Read/ReadVariableOp

NoOp

Const

serving_default_layer_input

StatefulPartitionedCall

saver_filename

StatefulPartitionedCall_1

注意serving_default_layer_input线。


查看完整回答
反对 回复 2022-07-11
  • 1 回答
  • 0 关注
  • 220 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信