Сохраненная и загруженная подклассовая модель keras выдает ошибку ValueError «Не удалось найти соответствующую функцию» для нестандартного вызова args tensorflow 2

#python #tensorflow #keras #deep-learning #tensorflow2.0

Вопрос:

Я пытаюсь загрузить пользовательскую подклассовую модель keras, а затем вызвать ее в новой партии.

Однако вызов загруженной модели выдает ошибку «Ошибка значения: не удалось найти соответствующую функцию для вызова загруженной из сохраненной модели». когда он вызывается с использованием аргументов, которые отличаются по значению от значений по умолчанию. Когда вызов использует значения arg по умолчанию, модель делает вывод без проблем. Кроме того, перед сохранением и перезагрузкой модель может выполнить вызов как со значениями arg по умолчанию, так и со значениями, отличными от значений по умолчанию. Последнее замечание: «обучение» arg, похоже, работает нормально — эта проблема возникает только тогда, когда я добавляю новый arg («full_batch_eval» в примере ниже).

Ниже приведен самостоятельный пример, демонстрирующий проблему. Есть какие-нибудь идеи о том, в чем заключается эта проблема? Я предполагаю, что функция вызова не отслеживается во время сохранения всех значений аргументов, и, следовательно, они недоступны в загруженной версии модели? Заранее спасибо!

 import tensorflow as tf from tensorflow import keras from tensorflow.keras.layers import Flatten, Dense  (x_train, y_train), (x_test, y_test) = tf.keras.datasets.fashion_mnist.load_data() x_train = tf.expand_dims(x_train.astype("float32")/255.,-1) x_test = tf.expand_dims(x_test.astype("float32")/255.,-1) y_train = y_train.astype("float32") y_test = y_test.astype("float32")  batch_size = 32 buffer_size = 1024 train_ds = tf.data.Dataset.from_tensor_slices((x_train,y_train)) train_ds = train_ds.shuffle(buffer_size=buffer_size).batch(batch_size)  class TestModel(keras.Model):  def __init__(self,**kwargs):  super(TestModel,self).__init__(**kwargs)  self.f = Flatten()  self.dense_1 = Dense(units=10,activation=tf.nn.relu)    def call(self,inputs,training=False,full_batch_eval=True):  x = inputs.get('x')  return self.dense_1(self.f(x))  def trainTestModel(m,ds,l,opt,epochs=1):  @tf.function  def train_step(x,y):  with tf.GradientTape() as t0:  out0 = m({'x':x,'y':y})  l0 = l(y_true=y,y_pred=out0)  g0 = t0.gradient(target=l0,sources=m.trainable_variables)  opt.apply_gradients(zip(g0,m.trainable_variables))    for epoch in range(epochs):  for (x,y) in ds:  train_step(x,y)  m = TestModel()  l = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True) opt = tf.keras.optimizers.Adam(learning_rate=1e-4) trainTestModel(m=m,ds=train_ds.take(1000),l=l,opt=opt)  for (x,y) in train_ds.take(1):  t = m({'x':x,'y':y}) #works  t = m({'x':x,'y':y},training=True) #works  t = m({'x':x,'y':y},training=False,full_batch_eval=True) #works  t = m(inputs={'x':x,'y':y},training=True,full_batch_eval=False) #works  t = m(inputs={'x':x,'y':y},training=True,full_batch_eval=True) #works  t = m(inputs={'x':x,'y':y},training=False,full_batch_eval=False) #works  prefix = 'saved_model_dir' tf.saved_model.save(m,export_dir=prefix)  m = tf.saved_model.load(prefix)  for (x,y) in train_ds.take(1):  t = m({'x':x,'y':y}) #works  t = m({'x':x,'y':y},training=True) #works  t = m({'x':x,'y':y},training=False,full_batch_eval=True) #works  t = m(inputs={'x':x,'y':y},training=True,full_batch_eval=False) #error  t = m(inputs={'x':x,'y':y},training=True,full_batch_eval=True) #works  t = m(inputs={'x':x,'y':y},training=False,full_batch_eval=False) #error