TensorFlow1.15+Keras2.3.1加载h5预训练模型出现Input维度错误如何解决
问题根因
你在定义模型时重复声明了输入维度:首先你已经添加了InputLayer指定输入维度,后续每个Dense层又额外传入了不需要的input_shape=(None, xxx)参数,你传入的带None的二维input_shape会被Keras 2.3.x版本解析为包含序列维度的三维输入,导致序列化保存后加载时维度解析异常,输出shape多了一个额外的动态维度。
修复方案
方案1:已有训练好的模型,无需重新训练
加载模型后手动重建正确输入维度的模型,复用原有权重,代码示例:
from keras.models import Model from keras import layers as L dependencies = { 'precision': precision, 'recall': recall, 'f1': f1 } # 加载原模型 loaded_model = load_model('./tag_prediction_model.h5', custom_objects=dependencies) # 新建正确维度的输入层 new_input = L.Input(shape=(768,)) # 复用原有模型层的权重 x = loaded_model.layers[0](new_input) x = loaded_model.layers[1](x) new_output = loaded_model.layers[2](x) # 构建修复后的模型 fixed_model = Model(inputs=new_input, outputs=new_output) # 保持编译参数和原模型一致 fixed_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy', precision, recall, f1]) # 此时查看summary输出维度为正常的二维结构 fixed_model.summary()
方案2:从模型定义阶段彻底修正,后续保存加载无异常
删除多余的input_shape声明,正确的模型定义代码如下:
model = keras.Sequential() # 仅需在第一层指定输入维度即可,无需给后续层传input_shape model.add(L.Dense(units=256, activation='relu', input_shape=(768,))) model.add(L.Dense(units=128, activation='relu')) # 注意多分类任务搭配categorical_crossentropy损失,最后一层激活函数必须是softmax,漏写会导致结果异常 model.add(L.Dense(units=301, activation='softmax')) model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy', precision, recall, f1])
按上述代码重新训练后保存、加载,输出维度均为正常的(None, 维度数)二维结构,不会再出现多余的None维度。
内容的提问来源于stack exchange,提问作者Nick1899
相关产品推荐
相关产品推荐

