在用cnn做文本分类时我是自定义的模型类,并没有用到Sequential,因此在保存模型和加载模型时会遇到各种各样的报错,经过尝试,找到以下方法可以解决。
1、首先,看一下自定义的模型类:
class TextCnn(tf.keras.Model):
def __init__(self, maxlen, max_features,class_num,embedding_dims,embeddings_matrix,kernel_sizes=[1,2,3,4,5],
last_activation='sigmoid'): # 没有赋值的写在前面
super(TextCnn, self).__init__()
self.maxlen = maxlen
self.max_features = max_features
self.embedding_dims = embedding_dims
self.kernel_sizes = kernel_sizes
self.class_num = class_num
self.last_activation = last_activation
self.embeddings_matrix = embeddings_matrix
self.embedding = keras.layers.Embedding(self.max_features, self.embedding_dims,weights=[embeddings_matrix],input_length=self.maxlen) # 重点:weights预训练的词向量
self.convs = []
self.max_poolings = []
for kernel_size in self.kernel_sizes:
self.convs.append(keras.layers.Conv1D(128, kernel_size))
self.max_poolings.append(keras.layers.GlobalMaxPooling1D())
self.classifier = keras.layers.Dense(self.class_num,activation=self.last_activation)
self.dropout=keras.layers.Dropout(0.15) #百分之20的神经元不工作
self.norma=keras.layers.LayerNormalization()
self.act=keras.layers.Activation('relu')
self.softmax=keras.layers.Softmax()
def call(self, inputs):
if inputs.get_shape()[1] != self.maxlen:
raise ValueError(
'The maxlen of inputs of TextCNN must be %d, but now is %d' % (self.maxlen, inputs.get_shape()[1]))
embedding = self.embedding(inputs)
convs = []
for i in range(len(self.kernel_sizes)):
c = self.convs[i](embedding)
c=self.norma(c)
c=self.act(c)
c = self.max_poolings[i](c)
convs.append(c)
x = keras.layers.Concatenate()(convs)
x_1=self.dropout(x)
output = self.classifier(x_1)
score=self.softmax(output) #将全链接层的输出,进行softmax运算,得到每个类的概率
return score
2、接着是模型的训练
model = TextCnn(length_max, max_features,class_num,embedding_dims,word_matrix)
optimizer = tf.keras.optimizers.Adam(1e-3)
model.compile(optimizer=optimizer,
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(x_input, y_train, epochs=20, batch_size=38, validation_split=0.2, verbose=2)
3、保存模型
训练完成后,要保存模型,一开始我用的是model.save(model_path),却报错说这种方式只能保存Sequential模型,保存为.h5格式;最后,我用的是tf.saved_model.save(model, model_path),保存为pb格式的模型。
4、加载模型
相应的,加载模型用:new_model =tf.saved_model.load(model_path)。
之后,模型预测的时候:
infer = new_model.signatures['serving_default'] #signatures['serving_default']默认是call方法 c=infer(x_input) print(infer.structured_outputs) c=c['output'].numpy()
这里注意x_input是tensor张量