无法使用预先训练的模型

时间:2021-04-14 11:03:55

标签: python tensorflow keras neural-network transfer-learning

我希望在一个数据集上预训练模型并在另一个数据集上训练层。

这是我的第一个数据集的神经网络:

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(100, input_shape=(30,) ))
model.add(tf.keras.layers.Activation('relu'))
model.add(tf.keras.layers.Dropout(0.2))
model.add(tf.keras.layers.Dense(10))
model.add(tf.keras.layers.Activation('relu'))
model.add(tf.keras.layers.Dropout(0.2))
model.add(tf.keras.layers.Dense(1))
model.add(tf.keras.layers.Activation('sigmoid'))

model.summary()
# need sparse otherwise shape is wrong. check why
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

print('Fitting the data to the model')
batch_size = 20
epochs = 10
history = model.fit(X_train_orig_sm, Y_train_orig_sm, batch_size=batch_size, epochs=epochs, verbose=1, validation_split=0.2)
print('Evaluating the test data on the model')

以下是我保存模型的方法:

from tensorflow.keras.models import model_from_yaml
# serialize model to YAML
model_yaml = model.to_yaml()
with open("model.yaml", "w") as yaml_file:
    yaml_file.write(model_yaml)

这是我如何加载模型并使用前 5 个层:

yaml_file = open('model.yaml', 'r')
model_1_yaml = yaml_file.read()
yaml_file.close()
model_1 = model_from_yaml(model_1_yaml)
model_pre=model_1.layers[:5]

但是,当我结合第二个神经网络层进行训练时:

transfer_model = tf.keras.models.Sequential()
transfer_model.add(model_pre)
transfer_model.add(tf.keras.layers.Dropout(0.2))
transfer_model.add(tf.keras.layers.Dense(10))
transfer_model.add(tf.keras.layers.Activation('relu'))
transfer_model.add(tf.keras.layers.Dropout(0.2))
transfer_model.add(tf.keras.layers.Dense(1))
transfer_model.add(tf.keras.layers.Activation('sigmoid'))

transfer_model.summary()
# need sparse otherwise shape is wrong. check why
transfer_model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

print('Fitting the data to the model')
batch_size = 20
epochs = 10
history = transfer_model.fit(X_train_sm, Y_train_sm, batch_size=batch_size, epochs=epochs, verbose=1, validation_split=0.2)
print('Evaluating the test data on the model')
transfer_model.evaluate(X_test,Y_test)

我收到以下错误:

TypeError: The added layer must be an instance of class Layer. Found: [<tensorflow.python.keras.layers.core.Dense object at 0x7fc80dadccd0>, <tensorflow.python.keras.layers.core.Activation object at 0x7fc80dadcf50>, <tensorflow.python.keras.layers.core.Dropout object at 0x7fc80dafd350>, <tensorflow.python.keras.layers.core.Dense object at 0x7fc80daf4d50>]

有人能指出我在这里的错误吗?

1 个答案:

答案 0 :(得分:0)

这是您如何实现这一目标。我将引导您完成一个工作示例。首先,我们建立一个模型并训练它。使用训练好的权重保存整个模型。接下来,我们从这个模型中取出前 5 层,构建一个新的 5 层模型,最后,我们在最终模型中使用它。

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import load_model

# Training parameters
batch_size = 256
num_classes = 10
epochs = 5

# The data, split between train and test sets
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

x_train = x_train.reshape(-1, 784).astype("float32") / 255
x_test = x_test.reshape(-1, 784).astype("float32") / 255
# Build the model
model = keras.Sequential(
    [
        keras.Input(shape=(784,)),
        layers.Dense(32, activation='relu'),
        layers.BatchNormalization(),
        layers.Dropout(0.2),
        layers.Dense(64, activation='relu'),
        layers.BatchNormalization(),
        layers.Dropout(0.2),
        layers.Dense(128, activation='relu'),
        layers.BatchNormalization(),
        layers.Dropout(0.2),
        layers.Dense(256, activation='relu'),
        layers.Dropout(0.5),
        layers.Dense(10),
    ]
)

# Compile the model
model.compile(
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    optimizer=keras.optimizers.RMSprop(),
    metrics=[keras.metrics.SparseCategoricalAccuracy()],
)

# Train the model
model.fit(x_train, y_train, batch_size=batch_size,
          epochs=epochs, validation_data=(x_test, y_test))
model.save('my_model.h5') # save the entire model with trained weights
new_model = load_model('my_model.h5') # load this model with its weights

现在,我们从这个 new_model 中取出前 5 层并构建一个新层。 (这是你的学习点)。

top5layerModel = tf.keras.Model(
    inputs  = new_model.inputs,
    outputs = new_model.layers[5].output,
)

top5layerModel.summary()

现在,我们将这个模型 (top5layerModel) 用于最终模型,如下所示:

# Build the model
final_model = keras.Sequential(
    [
        top5layerModel,
        layers.Dense(256, activation='elu'),
        layers.Dense(10)
    ]
)

final_model.summary()

现在,您可以照常训练了。