我有一个训练有素的TF模型,该模型具有以下架构:
输入:
word_a
,一次性表示,vocab大小:50000
word_b
,一口气表示,vocab大小:50
输出:
probs
,大小:1x10000
该网络由嵌入矩阵中嵌入的word_a
(1x100
)大小为dense_word_a
(word_b
)组成。使用字符CNN将1x250
转换为相似的向量,大小为1x350
的密集向量。这两个向量都串联成一个1x10000
向量,并使用解码器层和Sigmoid,将其映射到输出层和Sigmoid,其向量大小为word_a
。
我需要在客户端上运行此模型,为此,我将其转换为TFLite。 但是,我还需要将模型分为具有以下输入和输出的两个子模型:
模型1:
输入:
1x50000
:一次性表示,(50000
)vocab大小:dense_word_a
输出:
1x100
:从嵌入矩阵(word_a
)中查找密集的词嵌入
网络:
通过嵌入矩阵对dense_word_a
进行简单的嵌入查找。
模型2:
输入:
word_a
:为从模型1(1x100
)收到的word_b
嵌入。
50
,一次性表示,vocab大小:1x50
(probs
)
输出:
1x10000
,大小:word_a
在模型1中,输入dense_word_a
是一个占位符,而dense_word_a
是一个变量。在模型2中,word_b
是一个占位符,其值与word_b
的嵌入串联在一起。
我模型中的嵌入没有经过预训练,而是作为模型训练过程本身的一部分进行训练的。因此,我需要将模型训练为组合模型,但是在推论过程中,我想如上所述将其分解为模型1和模型2。
这个想法是在服务器端运行Model 1并将嵌入值传递给客户端,以便它可以使用dense_word_a
执行推理,并且客户端上没有5MB的嵌入矩阵。因此,我不受模型1大小的限制,但是由于模型2在客户端上运行,因此我需要使其较小。
这是我尝试过的方法:
1.在模型冻结期间,我冻结了整个模型,但是在输出节点列表中,我还添加了变量名称probs
和dense_word_a
。然后,我将模型转换为TFLite。在推论过程中,我能够看到1x100
输出为probs
向量。这似乎很好。我也得到了dense_word_a
作为输出,
要生成模型2,我只需要删除tf.placeholder
变量并将其转换为占位符(使用word_a
),删除probs
的占位符并再次冻结图形即可。
但是,我无法匹配probs
的值。完整模型生成的probs
向量与模型2生成的crossAxisAlignment: CrossAxisAlignment.baseline
值向量不匹配。
如何将模型分为子模型并匹配结果?