Kri*_*tof 6 model neural-network keras tensorflow
我已经尝试了文档中描述的所有选项,但没有一个允许我在 tensorflow 2.0.0 beta1 中保存我的模型。我也尝试升级到(同样不稳定的)TF2-RC,但这甚至破坏了我在测试版中工作的代码,所以我现在很快回滚到测试版。
请参阅下面的最小复制代码。
我尝试过的:
model.save("mymodel.h5")
Run Code Online (Sandbox Code Playgroud)NotImplementedError:将模型保存为 HDF5 格式要求模型是功能模型或顺序模型。它不适用于子类模型,因为此类模型是通过 Python 方法的主体定义的,该方法不能安全地序列化。考虑保存为 Tensorflow SavedModel 格式(通过设置 save_format="tf")或使用
save_weights
.
model.save("mymodel", format='tf')
Run Code Online (Sandbox Code Playgroud)ValueError: Model < main .CVAE object at 0x7f1cac2e7c50> 无法保存,因为尚未设置输入形状。通常,输入形状是通过调用 .fit() 或 .predict() 自动确定的。要手动设置形状,请调用 model._set_inputs(inputs)。
3.
model._set_input(input_sample)
model.save("mymodel", format='tf')
Run Code Online (Sandbox Code Playgroud)
断言错误:tf.saved_model.save 在跟踪的@tf.function 中不受支持。将调用移动到外部急切执行的上下文。
这就是我现在卡住的地方,因为它没有给我任何合理的提示。那是因为我没有从@tf.function 调用 save() 函数,我已经从可能的最外层范围调用了它。事实上,我在下面这个最小的复制脚本中根本没有 @tf.function 并且仍然遇到相同的错误。
所以我真的不知道如何保存我的模型,我已经尝试了所有选项,但它们都抛出错误并且没有提供任何提示。
如果您设置 save_model=False,下面的最小复制示例工作正常,并且在 save_model=True 时它会重现错误。
在这个简化的自动编码器代码示例中似乎没有必要使用子类模型,但我在我需要的原始 VAE 代码中添加了许多自定义函数。
代码:
import tensorflow as tf
save_model = True
learning_rate = 1e-4
BATCH_SIZE = 100
TEST_BATCH_SIZE = 10
color_channels = 1
imsize = 28
(train_images, _), (test_images, _) = tf.keras.datasets.mnist.load_data()
train_images = train_images[:5000, ::]
test_images = train_images[:1000, ::]
train_images = train_images.reshape(-1, imsize, imsize, 1).astype('float32')
test_images = test_images.reshape(-1, imsize, imsize, 1).astype('float32')
train_images /= 255.
test_images /= 255.
train_dataset = tf.data.Dataset.from_tensor_slices(train_images).batch(BATCH_SIZE)
test_dataset = tf.data.Dataset.from_tensor_slices(test_images).batch(TEST_BATCH_SIZE)
class AE(tf.keras.Model):
def __init__(self):
super(AE, self).__init__()
self.network = tf.keras.Sequential([
tf.keras.layers.InputLayer(input_shape=(imsize, imsize, color_channels)),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(50),
tf.keras.layers.Dense(imsize**2 * color_channels),
tf.keras.layers.Reshape(target_shape=(imsize, imsize, color_channels)),
])
def decode(self, input):
logits = self.network(input)
return logits
optimizer = tf.keras.optimizers.Adam(learning_rate)
model = AE()
def compute_loss(data):
logits = model.decode(data)
loss = tf.reduce_mean(tf.losses.mean_squared_error(logits, data))
return loss
def train_step(data):
with tf.GradientTape() as tape:
loss = compute_loss(data)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
return loss, 0
def test_step(data):
loss = compute_loss(data)
return loss
input_shape_set = False
epoch = 0
epochs = 20
for epoch in range(epochs):
for train_x in train_dataset:
train_step(train_x)
if epoch % 1 == 0:
loss = 0.0
num_batches = 0
for test_x in test_dataset:
loss += test_step(test_x)
num_batches += 1
loss /= num_batches
print("Epoch: {}, Loss: {}".format(epoch, loss))
if save_model:
print("Saving model...")
if not input_shape_set:
# Note: Why set input shape manually and why here:
# 1. If I do not set input shape manually: ValueError: Model <main.CVAE object at 0x7f1cac2e7c50> cannot be saved because the input shapes have not been set. Usually, input shapes are automatically determined from calling .fit() or .predict(). To manually set the shapes, call model._set_inputs(inputs).
# 2. If I set input shape manually BEFORE the first actual train step, I get: RuntimeError: Attempting to capture an EagerTensor without building a function.
model._set_inputs(train_dataset.__iter__().next())
input_shape_set = True
# Note: Why choose tf format: model.save('MNIST/Models/model.h5') will return NotImplementedError: Saving the model to HDF5 format requires the model to be a Functional model or a Sequential model. It does not work for subclassed models, because such models are defined via the body of a Python method, which isn't safely serializable. Consider saving to the Tensorflow SavedModel format (by setting save_format="tf") or using save_weights.
model.save('MNIST/Models/model', save_format='tf')
Run Code Online (Sandbox Code Playgroud)
我在tensorflow-gpu 2.0.0-rc0中尝试了相同的最小再现示例,并且该错误比测试版给我的错误更能说明问题。RC 中的错误说:
NotImplementedError:当子类化 Model 类时,您应该实现一个 call 方法。
这让我通读了https://www.tensorflow.org/beta/guide/keras/custom_layers_and_models,其中我找到了如何以允许保存的方式在 TF2 中进行子类化的示例。在上面的示例中,我能够解决错误并通过将“解码”方法替换为“调用”来保存模型(尽管这对于我的实际代码来说会更加复杂,因为我为该类定义了各种方法)。这解决了 beta 和 rc 中的错误。奇怪的是,在 rc 中训练(或保存)也变得更快。
归档时间: |
|
查看次数: |
4195 次 |
最近记录: |