我创建了一个模型,该模型从现有模型中抽取了两层,并从这两层中创建了一个模型。但是,生成的模型并不包含这些组件层中的所有权重/层。这是我用来解决这个问题的代码。
(编辑:这是一个colab笔记本,可以直接修改代码https://colab.research.google.com/drive/1tbel6PueW3fgFsCd2u8V8eVwLfFk0SEi?usp=sharing)
!pip install transformers --q
%tensorflow_version 2.x
from transformers import TFBertModel, AutoModel, TFRobertaModel, AutoTokenizer
import tensorflow as tf
import tensorflow_addons as tfa
tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)
from tensorflow import keras
from tensorflow.keras import layers
from copy import deepcopy
logger = tf.get_logger()
logger.info(tf.__version__)
def get_mini_models():
tempModel = TFRobertaModel.from_pretrained('bert-base-uncased', from_pt=True)
layer9 = deepcopy(tempModel.layers[0].encoder.layer[8])
layer10 = deepcopy(tempModel.layers[0].encoder.layer[9])
inputHiddenVals = tf.keras.Input(shape=[None, None], dtype=tf.float32, name='input_Q',
batch_size=None)
hidden1 = layer9((inputHiddenVals, None, None))
hidden2 = layer10((hidden1[0], None, None))
modelNew = tf.keras.Model(inputs=inputHiddenVals, outputs=hidden2)
del tempModel
return modelNew
@tf.function
def loss_fn(_, probs):
bs = tf.shape(probs)[0]
labels = tf.eye(bs, bs)
return tf.losses.categorical_crossentropy(labels,
probs,
from_logits=True)
model = get_mini_models()
model.compile(loss=loss_fn,
optimizer=tfa.optimizers.AdamW(weight_decay=1e-4, learning_rate=1e-5,
epsilon=1e-06))
# Get model and layers directly to compare
tempModel = TFRobertaModel.from_pretrained('bert-base-uncased', from_pt=True)
layer9 = deepcopy(tempModel.layers[0].encoder.layer[8])
layer10 = deepcopy(tempModel.layers[0].encoder.layer[9])
当我打印出可训练的权重时,仅打印键,查询和值,但是每一层还包含一些密集层和layer_norm层。此外,还会打印一层中的键,查询和值,但是有两个。
# Only one layer, and that layer also has missing weights.
for i, var in enumerate(model.weights):
print(model.weights[i].name)
tf_roberta_model_6 / roberta / encoder / layer _。 8 / attention / self / query / kernel:0 tf_roberta_model_6 / roberta / encoder / layer 。 8 / attention / self / query / bias:0 tf_roberta_model_6 / roberta / encoder / layer 。 8 / attention / self / key / key / kernel :0 tf_roberta_model_6 / roberta / encoder / layer 。 8 / attention / self / key / bias:0 tf_roberta_model_6 / roberta / encoder / layer 。 8 / attention / self / value / kernel:0 tf_roberta_model_6 / roberta / encoder / layer ._ 8 / attention / self / value / bias:0
这里是完整的单层
# Full weights for only one layer
for i, var in enumerate(layer9.weights):
print(layer9.weights[i].name)
输出为
tf_roberta_model_7 / roberta / encoder / layer _。 8 / attention / self / query / kernel:0 tf_roberta_model_7 / roberta / encoder / layer 。 8 / attention / self / query / bias:0 tf_roberta_model_7 / roberta / encoder / layer 。 8 / attention / self / key / key / kernel :0 tf_roberta_model_7 / roberta / encoder / layer 。 8 / attention / self / key / bias:0 tf_roberta_model_7 / roberta / encoder / layer 。 8 / attention / self / value / kernel:0 tf_roberta_model_7 / roberta / encoder / layer 。 8 / attention / self / value / bias:0 tf_roberta_model_7 / roberta / encoder / layer 。 8 / attention / output / dense / kernel 0: tf_roberta_model_7 / roberta / encoder / layer 。 8 / attention / output / dense / bias:0 tf_roberta_model_7 / roberta / encoder / layer 。 8 / attention / output / LayerNorm / gamma:0 tf_roberta_model_7 / roberta / encoder / layer 。 8 / attention / output / LayerNorm / beta:0 tf_roberta_model_7 / roberta / encoder / layer 。 8 / intermediate / dense / kernel:0 tf_roberta_model_7 / roberta / encoder / layer 。 8 / intermediate / dense / bias:0 tf_roberta_model_7 / roberta / encoder / layer 。 8 / output / dense / kernel:0 tf_roberta_model_7 / roberta / encoder / layer 。 8 / output / dense / bias:0 tf_roberta_model_7 / roberta / encoder / layer 。 8 / output / LayerNorm / gamma:0 tf_roberta_model_7 / roberta / encoder / layer ._ 8 / output / LayerNorm / beta:0
如您所见,单层的权重更大。
所有缺少的图层/权重均在模型摘要中表示
model.summary()
输出(编辑:输出超出了Stackoverflow的字符数限制,因此我仅粘贴了部分输出,但是完整的输出可以在此colab笔记本https://colab.research.google.com/drive/1n3_XNhdgH6Qo7GT-M570lIKWAoU3TML5?usp=sharing中看到)
这些重物肯定是相连的,并且通过了前传。如果执行,就可以看到
tf.keras.utils.plot_model(
model, to_file='model.png', show_shapes=False, show_layer_names=True,
rankdir='TB', expand_nested=False, dpi=96
)
图像太大,无法显示,但为方便起见,此colab笔记本包含所有可以运行的代码。即使不执行任何操作,输出图像也将位于底部
https://colab.research.google.com/drive/1tbel6PueW3fgFsCd2u8V8eVwLfFk0SEi?usp=sharing
最后,我测试了keras模型的输出,并直接运行各层,它们并不相同。
# Test what correct output should be
tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased')
inputt = tokenizer.encode('This is a sentence', return_tensors='tf')
outt = tempModel(inputt)[0]
hidden1 = layer9((outt, None, None))
layer10((hidden1[0], None, None))
vs
model(outt)
编辑:
我尝试从头开始制作图层。我再次遇到相同的问题。创建模型似乎会删除整套权重。这是从头开始尝试的colab笔记本编辑:我也尝试过从头开始制作图层,并直接设置权重,结果相同。这是一个可以做htis的colab笔记本。 https://colab.research.google.com/drive/1EC_fObSp9lUsj_PFaYgFtRI93ErPYmU9?usp=sharing