#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