如何在TF Lite中添加预处理步骤

时间:2018-09-03 06:26:57

标签: python tensorflow tensorflow-estimator tensorflow-lite

我使用具有4个功能的简单虹膜数据。我想在进入网络之前做一些预处理步骤。例如,我希望我的NN仅接收3个特征,这些特征是两个连续原始特征的平均值。

# x shape is 120 data x 4 features
tmp = np.zeros((x.shape[0],x.shape[1]-1))
for i in range(x.shape[1]-1):
    tmp[:,i] = (x[:,i]+x[:,i+1])/2.
x = deepcopy(tmp) # after preprocess its shape 120 x 3 features

我尝试在input_function中添加这些步骤,并将所有feature_columns形状的定义更改为3:

def input_function(x, y, is_train):

    tmp = np.zeros((x.shape[0],x.shape[1]-1))
    for i in range(x.shape[1]-1):
        tmp[:,i] = (x[:,i]+x[:,i+1])/2.
    x = deepcopy(tmp)

    dict_x = { "thisisinput" : x }

    dataset = tf.data.Dataset.from_tensor_slices((
        dict_x, y
    ))

    if is_train:
        dataset = dataset.shuffle(num_train).repeat(num_epoch).batch(num_train)
    else:   
        dataset = dataset.batch(num_test)

    return dataset

我训练分类器的方式:

feature_columns = [
    tf.feature_column.numeric_column(key="featurename",shape=3),
]

classifier = tf.estimator.DNNClassifier(
    feature_columns=feature_columns,
    hidden_units=[50, 20],
    n_classes=3,
    optimizer=tf.train.GradientDescentOptimizer(0.001),
    activation_fn=tf.nn.relu,
    model_dir = 'modeliris2/'
)

classifier.train(
    input_fn=lambda:input_function(xtrain, ytrain, True)
)

我的服务输入功能:

def my_serving_input_fn2():
    input_data = {
        "featurename" : tf.placeholder(tf.float32, [None, 3], name='inputtensors')
    }
    return tf.estimator.export.ServingInputReceiver(input_data, input_data)

当我运行它时它可以工作,但是如果我冻结模型然后用它来进行预测,那它就行不通了。它说:

  

ValueError:无法为形状为((?,3)''的张量'import / inputtensors:0'输入形状(1,4)的值

如果我将feature_columns上的my_serving_input_fn更改为[None,4],则冻结模型后仍然出现错误:

  

InvalidArgumentError(请参见上面的回溯):重整形的输入是具有4个值的张量,但请求的形状为3

我的问题,如果我需要在模型中包括任何预处理或功能工程步骤(例如MFCC等在信号预处理中),该放在哪里?我的方法正确吗?为什么会发生错误?还是有更好的解决方案?

另一个问题是,如果在预处理步骤中我需要包括外部文件(例如文本预处理中的停用词列表等),仍然可以包括那些文件以使用TF lite进行预处理吗?

2 个答案:

答案 0 :(得分:1)

从技术上讲,您可以将预处理步骤放在两个位置。我将以tflite为例。

  1. 模型外部的预处理。这意味着您的驱动程序中有一个mfcc:

    model = new model(CNN, RNN, ...)
    while(stream) {
       energy = mfcc(audio)
       model.invoke(energy)
    }
    
  2. 如果预处理步骤已经是Op(通常不是...),则可以在模型中包括Op:

    model = new model(MFCC, CNN, RNN, ...)
    while(stream) {
        model.invoke(audio)
    }
    

话虽这么说,选项1最为平易近人。希望对您有所帮助。

答案 1 :(得分:0)

在这种情况下,预处理发生在python中。因此,如果您在python中调用TF Lite图,则可以使用任何python原语。