Python TensorFlow 2.x:使用嵌入列时无法加载h5格式的训练模型(ValueError:形状(101,15)和(57218,15)不兼容)

Python TensorFlow 2.x:使用嵌入列时无法加载h5格式的训练模型(ValueError:形状(101,15)和(57218,15)不兼容),python,tensorflow,machine-learning,keras,h5py,Python,Tensorflow,Machine Learning,Keras,H5py,经过长时间的反复,我设法保存了我的模型(见我的问题)。但是现在我在加载保存的模型时遇到问题。首先,我通过加载模型得到以下错误: ValueError: You are trying to load a weight file containing 1 layers into a model with 0 layers. 将顺序API更改为函数API后,我得到以下错误: ValueError: Cannot assign to variable dense_features/NAME1W1_em

经过长时间的反复,我设法保存了我的模型(见我的问题)。但是现在我在加载保存的模型时遇到问题。首先,我通过加载模型得到以下错误:

ValueError: You are trying to load a weight file containing 1 layers into a model with 0 layers.
将顺序API更改为函数API后,我得到以下错误:

ValueError: Cannot assign to variable dense_features/NAME1W1_embedding/embedding_weights:0 due to variable shape (101, 15) and value shape (57218, 15) are incompatible
我尝试了TensorFlow的不同版本。我每晚都会在tf版本中看到所描述的错误。在版本2.1中,我遇到了一个非常类似的错误:

ValueError: Shapes (101, 15) and (57218, 15) are incompatible.
在2.2版和2.3版中,我甚至无法保存我的模型(如前一个问题中所述)

以下是功能API的相关代码:

def\uuu加载模型(args):
filepath=args.loadModel
model=tf.keras.models.load\u模型(文件路径)
打印(“开始预处理…”)
(u,u,test_ds)=预处理.getPrepreprocessedDataset(args.data,args.batchSize)
打印(“预处理完成”)
_,准确度=模型。评估(测试)
打印(“准确度”,准确度)
def__列车模型(参数):
(train_ds,val_ds,test_ds)=预处理.getPrepreprocessedDataset(args.data,args.batchSize)
对于args.bucketSizeGEO中的bucketSizeGEO:
打印(“开始预处理…”)
feature_columns=preprocessing.getFutureColumns(args.data、args.zip、bucketsizego、True)
#Todo:将可培训=False与可培训=True进行比较
特征层=tf.keras.layers.DenseFeatures(特征列,可训练=假)
打印(“预处理完成”)
feature\u layer\u inputs=预处理。getFeatureLayerInputs()
特征层输出=特征层(特征层输入)
输出层=tf.keras.layers.density(1,激活层=tf.nn.sigmoid)(特征层输出)
model=tf.keras.model(输入=[v表示特征层中的v\u输入值()],输出=输出层)
model.compile(优化器='sgd',
损失='binary\u交叉熵',
指标=[‘准确度’])
paramString=“Arg-e{}-b{}-z{}”。格式(args.epoch、args.batchSize、bucketSizeGEO)
log_dir=“logs\\logR\\”+paramString+datetime.datetime.now().strftime(“%Y%m%d-%H%m%S”)
tensorboard\u callback=tf.keras.callbacks.tensorboard(log\u dir=log\u dir,直方图\u freq=1)
模型安装(列车),
验证数据=val\U ds,
epochs=args.epoch,
回调=[tensorboard_回调])
model.summary()
损失,精度=模型评估(测试)
打印(“准确度”,准确度)
paramString=paramString+“-a{.4f}”。格式(精度)
outputName=“logReg”+datetime.datetime.now().strftime(“%Y%m%d-%H%m%S”)+paramString
如果args.saveModel:
对于枚举中的i,w(模型权重):打印(i,w.name)
路径='./已保存的_模型/'+outputName+'.h5'
model.save(路径,save_format='h5')
有关预处理部分,请参见本问题开头的问题<代码>枚举(模型权重)中的i,w:打印(i,w.name)返回以下内容:

0 dense_features/NAME1W1_embedding/embedding_weights:0
1 dense_features/NAME1W2_embedding/embedding_weights:0
2 dense_features/STREETW_embedding/embedding_weights:0
3 dense_features/ZIP_embedding/embedding_weights:0
4 dense/kernel:0
5 dense/bias:0

我的英语很差,所以我用中文回答你的问题

以英文答覆如下:

这是由于训练和预测中矩阵维数不一致造成的

通常,在使用嵌入矩阵之前,我们会形成一个字典。这里我们暂时称这个字典词为_index。如果代码的作者考虑不周,它会导致在训练和预测中出现两个不同的词_index(因为训练和预测中使用的数据不同),矩阵的维数会发生变化

您可以从您的bug中看到,当您的训练为57218时,您得到len(单词索引)+1,而len(单词索引)+1是在预测为101时得到的


如果我们想正确运行代码,当我们需要使用单词索引的预测时,我们不能在预测期间重新生成单词索引。因此,这个问题最简单的解决方案是保存训练时得到的单词索引,它在预测时被调用,这样我们就可以正确地加载训练时得到的权重。

我能够解决我相当愚蠢的错误:

我正在使用feature_列库对数据进行预处理。不幸的是,我在函数category_column_with_identity中的参数num_bucket中指定了词汇表列表的固定大小,而不是实际大小。 错误版本:

street\u voc=tf.feature\u column.categorical\u column\u带有标识(
key='STREETW',num_bucket=100)
正确版本:

street\u voc=tf.feature\u column.categorical\u column\u带有标识(
key='STREETW',num_bucket=\uu getNumberOfWords(数据'STREETPRO')+1)

函数
\uu getNumberOfWords(数据,'STREETPRO')
返回pandas数据框的'STREETPRO'列中的不同字数。

很抱歉我的回复太晚了!您能否提供保存“word_索引”的近似代码或我如何解释变量形状(101,15)和值形状(57218,15)的进一步信息?`我想我理解(57218,15)的形状:57218=训练数据的大小,15=嵌入向量的维数。但是形状(101,15)呢,尤其是101?我想在保存操作中会保存其他信息,如所谓的“word_索引”,因为我找不到任何与TensorFlow嵌入相关的进一步文档。您解决了吗?如果是,怎么做?嘿,看看我的答案。