2 回答

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超5個(gè)贊
在我遇到的幾個(gè)實(shí)例中,TF2通常表現(xiàn)出糟糕且類似錯(cuò)誤的內(nèi)存管理 - 此處和此處的簡(jiǎn)要說明。特別是對(duì)于預(yù)測(cè),最有效的喂養(yǎng)方法是直接通過 - 請(qǐng)參閱此處及其鏈接的討論。model(x)
簡(jiǎn)而言之:通過其方法(它從base_layer繼承)起作用。Layer
),而 、 等通過 _select_training_loop();
每個(gè)都利用不同的數(shù)據(jù)預(yù)處理和后處理方法,適合不同的用例,并且在2.1中專門設(shè)計(jì)用于產(chǎn)生最快的小模型/小批量(可能是任何尺寸)性能(并且在2.0中仍然最快)。model(x)
__call__
predict()
predict_classes()
model(x)
引用鏈接討論中一位TensorFlow開發(fā)者的話:
您可以使用模型調(diào)用來預(yù)測(cè)輸出,而不是模型預(yù)測(cè),也就是說,調(diào)用將使這更快,因?yàn)闆]有“轉(zhuǎn)換為數(shù)據(jù)集”部分,并且它還直接調(diào)用緩存。
model(x)
tf.function
注意:這在2.1中應(yīng)該不是一個(gè)問題,尤其是2.2 - 但無論如何都要測(cè)試每種方法。我也意識(shí)到這并不能直接回答你關(guān)于時(shí)間峰值的問題;我懷疑它與 Eager 緩存機(jī)制有關(guān),但最可靠的確定方法是通過 TF Profiler
,這在 2.1 中被破壞了。
更新:關(guān)于增加峰值,可能的GPU限制;你已經(jīng)做了大約1000次迭代,嘗試10,000次 - 最終,增加應(yīng)該停止。正如您在評(píng)論中指出的那樣,這在 ;這是有道理的,因?yàn)樯婕暗腉PU步驟更少(“轉(zhuǎn)換為數(shù)據(jù)集”)。model(x)
Update2:如果您遇到此問題,您可以在此處對(duì)開發(fā)人員進(jìn)行錯(cuò)誤處理;主要是我在那里唱歌

TA貢獻(xiàn)1816條經(jīng)驗(yàn) 獲得超6個(gè)贊
雖然我無法解釋執(zhí)行時(shí)間的不一致,但我可以建議您嘗試將模型轉(zhuǎn)換為TensorFlow Lite,以加快對(duì)單個(gè)數(shù)據(jù)記錄或小批量的預(yù)測(cè)。
我在這個(gè)模型上運(yùn)行了一個(gè)基準(zhǔn)測(cè)試:
model = tf.keras.models.Sequential([ tf.keras.layers.Dense(384, activation='elu', input_shape=(256,)), tf.keras.layers.Dense(384, activation='elu'), tf.keras.layers.Dense(256, activation='elu'), tf.keras.layers.Dense(128, activation='elu'), tf.keras.layers.Dense(32, activation='tanh') ])
單個(gè)記錄的預(yù)測(cè)時(shí)間為:
model.predict(input)
: 18毫秒model(input)
: 1.3毫秒轉(zhuǎn)換為TensorFlow Lite的模型:43us
轉(zhuǎn)換模型的時(shí)間為 2 秒。
下面的類演示如何轉(zhuǎn)換和使用模型,并提供類似于 Keras 模型的方法。請(qǐng)注意,它需要修改以用于不僅具有單個(gè)1-D輸入和單個(gè)1-D輸出的模型。predict
class LiteModel:
@classmethod
def from_file(cls, model_path):
return LiteModel(tf.lite.Interpreter(model_path=model_path))
@classmethod
def from_keras_model(cls, kmodel):
converter = tf.lite.TFLiteConverter.from_keras_model(kmodel)
tflite_model = converter.convert()
return LiteModel(tf.lite.Interpreter(model_content=tflite_model))
def __init__(self, interpreter):
self.interpreter = interpreter
self.interpreter.allocate_tensors()
input_det = self.interpreter.get_input_details()[0]
output_det = self.interpreter.get_output_details()[0]
self.input_index = input_det["index"]
self.output_index = output_det["index"]
self.input_shape = input_det["shape"]
self.output_shape = output_det["shape"]
self.input_dtype = input_det["dtype"]
self.output_dtype = output_det["dtype"]
def predict(self, inp):
inp = inp.astype(self.input_dtype)
count = inp.shape[0]
out = np.zeros((count, self.output_shape[1]), dtype=self.output_dtype)
for i in range(count):
self.interpreter.set_tensor(self.input_index, inp[i:i+1])
self.interpreter.invoke()
out[i] = self.interpreter.get_tensor(self.output_index)[0]
return out
def predict_single(self, inp):
""" Like predict(), but only for a single record. The input data can be a Python list. """
inp = np.array([inp], dtype=self.input_dtype)
self.interpreter.set_tensor(self.input_index, inp)
self.interpreter.invoke()
out = self.interpreter.get_tensor(self.output_index)
return out[0]
完整的基準(zhǔn)代碼和繪圖可以在這里找到:https://medium.com/@micwurm/using-tensorflow-lite-to-speed-up-predictions-a3954886eb98
添加回答
舉報(bào)