簡體   English   中英

使用 keras 回調對當前批次進行預測

[英]Using keras callback to make prediction on the current batch

我正在嘗試使用 keras callbck 在批處理結束時進行預測,如下所示:

from keras.layers import Dense
from keras.models import Sequential
from keras.callbacks import Callback
from keras import backend as K
import tensorflow as tf
import numpy as np


class CollectOutputAndTarget(Callback):
    def __init__(self):
        super(CollectOutputAndTarget, self).__init__()
        self.targets = []  # collect y_true batches
        self.inputs = []  # collect y_true batches
        self.outputs = []  # collect y_pred batches
        self.preds = []

        # the shape of these 2 variables will change according to batch shape
        # to handle the "last batch", specify `validate_shape=False`
        self.var_y_true = tf.Variable(0., validate_shape=False)
        self.var_input = tf.Variable(0., validate_shape=False)
        self.var_y_pred = tf.Variable(0., validate_shape=False)


    def on_batch_end(self, batch, logs=None):
        # evaluate the variables and save them into lists
        self.targets.append(K.eval(self.var_y_true))
        batch_inp = K.eval(self.var_input)
        self.inputs.append(batch_inp)
        self.outputs.append(K.eval(self.var_y_pred))
        current_pred = self.model.predict(batch_inp)
        self.preds.append(current_pred)


# build a simple model
K.clear_session()
# have to compile first for model.targets and model.outputs to be prepared
model = Sequential([Dense(5, input_shape=(2,)), Dense(2)])
model.compile(loss='mse', optimizer='adam')

# initialize the variables and the `tf.assign` ops
cbk = CollectOutputAndTarget()
fetches = [tf.assign(cbk.var_y_true, model.targets[0], validate_shape=False),
           tf.assign(cbk.var_input, model.inputs[0], validate_shape=False),
           tf.assign(cbk.var_y_pred, model.outputs[0], validate_shape=False)]
model._function_kwargs = {'fetches': fetches}  # use `model._function_kwargs` if using `Model` instead of `Sequential`


# fit the model and check results
X = np.arange(10).reshape((5, 2))
Y = X*2

model.fit(X, Y, epochs=1, batch_size=3, callbacks=[cbk], shuffle=False)

我收到以下錯誤:


InvalidArgumentError                      Traceback (most recent call last)
<ipython-input-114-adfad08009ad> in <module>
      3 Y = X*2
      4 
----> 5 model.fit(X, Y, epochs=1, batch_size=3, callbacks=[cbk], shuffle=False)

/usr/local/lib/python3.6/dist-packages/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)
   1037                                         initial_epoch=initial_epoch,
   1038                                         steps_per_epoch=steps_per_epoch,
-> 1039                                         validation_steps=validation_steps)
   1040 
   1041     def evaluate(self, x=None, y=None,

/usr/local/lib/python3.6/dist-packages/keras/engine/training_arrays.py in fit_loop(model, f, ins, out_labels, batch_size, epochs, verbose, callbacks, val_f, val_ins, shuffle, callback_metrics, initial_epoch, steps_per_epoch, validation_steps)
    202                     batch_logs[l] = o
    203 
--> 204                 callbacks.on_batch_end(batch_index, batch_logs)
    205                 if callback_model.stop_training:
    206                     break

/usr/local/lib/python3.6/dist-packages/keras/callbacks.py in on_batch_end(self, batch, logs)
    113         t_before_callbacks = time.time()
    114         for callback in self.callbacks:
--> 115             callback.on_batch_end(batch, logs)
    116         self._delta_ts_batch_end.append(time.time() - t_before_callbacks)
    117         delta_t_median = np.median(self._delta_ts_batch_end)

<ipython-input-111-65feb418f9ec> in on_batch_end(self, batch, logs)
     19         self.inputs.append(batch_inp)
     20         self.outputs.append(K.eval(self.var_y_pred))
---> 21         current_pred = self.model.predict(batch_inp)
     22         self.preds.append(current_pred)

/usr/local/lib/python3.6/dist-packages/keras/engine/training.py in predict_on_batch(self, x)
   1272             ins = x
   1273         self._make_predict_function()
-> 1274         outputs = self.predict_function(ins)
   1275         return unpack_singleton(outputs)
   1276 

/usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py in __call__(self, inputs)
   2713                 return self._legacy_call(inputs)
   2714 
-> 2715             return self._call(inputs)
   2716         else:
   2717             if py_any(is_tensor(x) for x in inputs):

/usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py in _call(self, inputs)
   2673             fetched = self._callable_fn(*array_vals, run_metadata=self.run_metadata)
   2674         else:
-> 2675             fetched = self._callable_fn(*array_vals)
   2676         return fetched[:len(self.outputs)]
   2677 

/usr/local/lib/python3.6/dist-packages/tensorflow/python/client/session.py in __call__(self, *args, **kwargs)
   1456         ret = tf_session.TF_SessionRunCallable(self._session._session,
   1457                                                self._handle, args,
-> 1458                                                run_metadata_ptr)
   1459         if run_metadata:
   1460           proto_data = tf_session.TF_GetBuffer(run_metadata_ptr)

InvalidArgumentError: You must feed a value for placeholder tensor 'dense_2_target' with dtype float and shape [?,?]
     [[{{node dense_2_target}}]]

我能夠在批次結束時從分配給model.outputs[0]的變量self.var_y_pred中獲取模型輸出。

然而,根據我的理解,這個預測是在當前步驟的反向傳播之前完成的。 我的目標是能夠使用模型版本對當前批次進行預測,該版本的權重已經通過當前批次訓練進行了更新。

我怎樣才能做到這一點?

答案是“你不能”。

對象model.inputsmodel.outputs是“張量”列表,而不是數據。 張量是空圖表示。

獲得批量預測的唯一方法是調用model.predict_on_batch(input_data_as_numpy)或類似的方法。 這意味着在您的情況下,讓模型對同一事物進行兩次預測。 一個可怕的性能缺陷。

要在訓練期間使用預測批次,您需要切換到使用 Eager 模式並進行自定義訓練循環:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM