我正在尝试将一个在tensorflow 1中保存的模型转换为tensorflow 2。如tensorflow文档中所示,我正在将代码迁移到tensorflow 2。然而,我想简单地将我的model_weights.ckpt
更新到tensorflow 2。一些权重(Linear
,Embdedding
)与tensorflow 2语法具有类似的形状,但我正在努力将我的GRUCell
权重从旧版compat.v1.nn.rnn_cell.GRUCell
转换为keras.layers.GRUCell
。
如何将GRUCell
权重从compat.v1.nn.rnn_cell.GRUCell
转换为keras.layers.GRUCell
?
GRUCell
有四个权重:
gru_cell/gates/kernel:0
的形状为(S + H, 2 x H)
,gru_cell/gates/bias:0
的形状为(2 x H, )
,gru_cell/candidate/kernel:0
的形状为(S + H, H)
,gru_cell/candidate/bias:0
的形状为(H, )
我想要的权重与tensorflow 2 API(或PyTorch API)具有类似的形状,即一个带有以下权重的GRUCell
:
gru_cell/kernel:0
的形状为(S, 3 x H)
gru_cell/recurrent_kernel:0
的形状为(H, 3 x H)
gru_cell/bias:0
的形状为(2, 3 x H)
你可以复制以下结果以说明:
1. 具有tensorflow 1 API的GRUCell
import tensorflow as tf
SEQ_LENGTH = 4
HIDDEN_SIZE = 512
BATCH_SIZE = 1
inputs = tf.random.normal([BATCH_SIZE, SEQ_LENGTH])
# GRU cell
gru = tf.compat.v1.nn.rnn_cell.GRUCell(HIDDEN_SIZE)
# Hidden state
state = gru.zero_state(BATCH_SIZE, tf.float32)
# Forward
output, state = gru(inputs, state)
for weight in gru.weights:
print(weight.name, weight.shape)
输出:
gru_cell/gates/kernel:0 (516, 1024)
gru_cell/gates/bias:0 (1024,)
gru_cell/candidate/kernel:0 (516, 512)
gru_cell/candidate/bias:0 (512,)
2. 使用tensorflow 2 API的GRUCell
import tensorflow as tf
SEQ_LENGTH = 4
HIDDEN_SIZE = 512
BATCH_SIZE = 1
inputs = tf.random.normal([BATCH_SIZE , SEQ_LENGTH])
# GRU cell
gru = tf.keras.layers.GRUCell(HIDDEN_SIZE)
# Hidden state
state = tf.zeros((BATCH_SIZE, HIDDEN_SIZE), dtype=tf.float32)
# Forward
output, state = gru(inputs, state)
# Display the weigths
for weight in gru.weights:
print(weight.name, weight.shape)
输出:
gru_cell/kernel:0 (4, 1536)
gru_cell/recurrent_kernel:0 (512, 1536)
gru_cell/bias:0 (2, 1536)
注意
- 我尝试了
_convert_rnn_weights
Tensorflow函数来转换所需的权重。它可以工作,但仅适用于CuDNN
权重,因此在我的情况下无法使用。
DNN
,Linear
或Combined
估算器。它不支持复杂模型(例如GAN和其他模型)。然而,如果我能够手动将GRUCell
权重转换为keras
语法,那么它将解决我的问题,因为我将能够加载检查点/模型。 - polop