从其他模型图层创建的模型并不包含来自图层的所有权重。但是model.summary()/ plot_model将这些权重显示为图形的一部分

时间:2020-06-20 21:41:06

标签: tensorflow keras tensorflow2.0 tf.keras

我创建了一个模型,该模型从现有模型中抽取了两层,并从这两层中创建了一个模型。但是,生成的模型并不包含这些组件层中的所有权重/层。这是我用来解决这个问题的代码。

(编辑:这是一个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

0 个答案:

没有答案