我正在尝试使用TPU在Google协作室上微调BERT模型。但我总是收到以下错误:
ValueError:在(tensorflow)的分配策略范围内未创建变量(tf.variable'bert_layer_module / bert / encoder / layer_10 / attention / output / LayerNorm / beta:0'shape =(768,)dtype = float32) .python.distribute.tpu_strategy.TPUStrategyV1对象位于0x7f6a1fad3390)。 这很可能是由于并非在分发策略范围之外创建了所有层或模型或优化器。尝试确保您的代码与以下代码相似。
with strategy.scope():
model = _create_model()
model.compile(...)
我的代码基于this notebook!我针对我的特定问题对其进行了更改,并且显然试图在TPU上运行它。
我有一个Costum Layer BertLayer,它显然是在范围之外创建的:
class BertLayer(tf.keras.layers.Layer):
def __init__(self, n_fine_tune_layers=10, **kwargs):
self.n_fine_tune_layers = n_fine_tune_layers
self.trainable = True
self.output_size = 768
super(BertLayer, self).__init__(**kwargs)
def build(self, input_shape):
self.bert = hub.Module(
bert_path,
trainable=self.trainable,
name="{}_module".format(self.name)
)
trainable_vars = self.bert.variables
# Remove unused layers
trainable_vars = [var for var in trainable_vars if not "/cls/" in var.name]
# Select how many layers to fine tune
trainable_vars = trainable_vars[-self.n_fine_tune_layers :]
# Add to trainable weights
for var in trainable_vars:
self._trainable_weights.append(var)
# Add non-trainable weights
for var in self.bert.variables:
if var not in self._trainable_weights:
self._non_trainable_weights.append(var)
super(BertLayer, self).build(input_shape)
def call(self, inputs):
inputs = [K.cast(x, dtype="int32") for x in inputs]
input_ids, input_mask, segment_ids = inputs
bert_inputs = dict(
input_ids=input_ids, input_mask=input_mask, segment_ids=segment_ids
)
result = self.bert(inputs=bert_inputs, signature="tokens", as_dict=True)[
"pooled_output"
]
return result
def compute_output_shape(self, input_shape):
return (input_shape[0], self.output_size)
模型创建在这里完成:
def build_model(max_seq_length):
output_classes = train_labels[0].shape
# Build model
in_id = tf.keras.layers.Input(shape=(max_seq_length,), name="input_ids")
in_mask = tf.keras.layers.Input(shape=(max_seq_length,), name="input_masks")
in_segment = tf.keras.layers.Input(shape=(max_seq_length,), name="segment_ids")
bert_inputs = [in_id, in_mask, in_segment]
# Instantiate the custom Bert Layer defined above
bert_output = BertLayer(n_fine_tune_layers=10)(bert_inputs)
# Build the rest of the classifier
dense = tf.keras.layers.Dense(256, activation='relu')(bert_output)
pred = tf.keras.layers.Dense(train_labels.shape[1], activation='sigmoid')(dense)
model = tf.keras.models.Model(inputs=bert_inputs, outputs=pred)
return model
调用model.compile时发生错误
strategy = tf.distribute.experimental.TPUStrategy(
tf.contrib.cluster_resolver.TPUClusterResolver(TPU_ADDRESS))
with strategy.scope():
model = build_model(256)
opt = tf.train.AdamOptimizer(0.001)
model.compile(loss='binary_crossentropy', optimizer=opt)
据我了解,BertLayer确实是在范围内创建的,但是我对keras和tensorflow还是比较陌生,因此很高兴为您提供帮助。我正在研究tensorflow 1.14
答案 0 :(得分:0)
考虑在策略范围内指定模型输入的形状,可以尝试以下操作之一:
1.创建模型后,调用model.build()
。
2.在input_shape
中定义模型第一层的__init__()
。
3.创建模型后,使用实张量(一个,零等)调用model(tensor)
。
无论如何,请指定模型输入的形状。这对我有用。 希望对您有帮助。