[中文|Inglês]
Implementação do BERT. Modelos oficiais pré-treinados podem ser carregados para extração e previsão de recursos.
pip install keras-bert
Na demonstração de extração de recursos, você poderá obter os mesmos resultados de extração que o modelo oficial chinese_L-12_H-768_A-12
. E na demonstração de previsão, a palavra que falta na frase pode ser prevista.
A demonstração de extração mostra como converter para um modelo executado em TPU.
A demonstração de classificação mostra como aplicar o modelo a tarefas simples de classificação.
A classe Tokenizer
é usada para dividir textos e gerar índices:
from keras_bert import Tokenizer
token_dict = {
'[CLS]' : 0 ,
'[SEP]' : 1 ,
'un' : 2 ,
'##aff' : 3 ,
'##able' : 4 ,
'[UNK]' : 5 ,
}
tokenizer = Tokenizer ( token_dict )
print ( tokenizer . tokenize ( 'unaffable' )) # The result should be `['[CLS]', 'un', '##aff', '##able', '[SEP]']`
indices , segments = tokenizer . encode ( 'unaffable' )
print ( indices ) # Should be `[0, 2, 3, 4, 1]`
print ( segments ) # Should be `[0, 0, 0, 0, 0]`
print ( tokenizer . tokenize ( first = 'unaffable' , second = '钢' ))
# The result should be `['[CLS]', 'un', '##aff', '##able', '[SEP]', '钢', '[SEP]']`
indices , segments = tokenizer . encode ( first = 'unaffable' , second = '钢' , max_len = 10 )
print ( indices ) # Should be `[0, 2, 3, 4, 1, 5, 1, 0, 0, 0]`
print ( segments ) # Should be `[0, 0, 0, 0, 0, 1, 1, 0, 0, 0]`
from tensorflow import keras
from keras_bert import get_base_dict , get_model , compile_model , gen_batch_inputs
# A toy input example
sentence_pairs = [
[[ 'all' , 'work' , 'and' , 'no' , 'play' ], [ 'makes' , 'jack' , 'a' , 'dull' , 'boy' ]],
[[ 'from' , 'the' , 'day' , 'forth' ], [ 'my' , 'arm' , 'changed' ]],
[[ 'and' , 'a' , 'voice' , 'echoed' ], [ 'power' , 'give' , 'me' , 'more' , 'power' ]],
]
# Build token dictionary
token_dict = get_base_dict () # A dict that contains some special tokens
for pairs in sentence_pairs :
for token in pairs [ 0 ] + pairs [ 1 ]:
if token not in token_dict :
token_dict [ token ] = len ( token_dict )
token_list = list ( token_dict . keys ()) # Used for selecting a random word
# Build & train the model
model = get_model (
token_num = len ( token_dict ),
head_num = 5 ,
transformer_num = 12 ,
embed_dim = 25 ,
feed_forward_dim = 100 ,
seq_len = 20 ,
pos_num = 20 ,
dropout_rate = 0.05 ,
)
compile_model ( model )
model . summary ()
def _generator ():
while True :
yield gen_batch_inputs (
sentence_pairs ,
token_dict ,
token_list ,
seq_len = 20 ,
mask_rate = 0.3 ,
swap_sentence_rate = 1.0 ,
)
model . fit_generator (
generator = _generator (),
steps_per_epoch = 1000 ,
epochs = 100 ,
validation_data = _generator (),
validation_steps = 100 ,
callbacks = [
keras . callbacks . EarlyStopping ( monitor = 'val_loss' , patience = 5 )
],
)
# Use the trained model
inputs , output_layer = get_model (
token_num = len ( token_dict ),
head_num = 5 ,
transformer_num = 12 ,
embed_dim = 25 ,
feed_forward_dim = 100 ,
seq_len = 20 ,
pos_num = 20 ,
dropout_rate = 0.05 ,
training = False , # The input layers and output layer will be returned if `training` is `False`
trainable = False , # Whether the model is trainable. The default value is the same with `training`
output_layer_num = 4 , # The number of layers whose outputs will be concatenated as a single output.
# Only available when `training` is `False`.
)
O otimizador AdamWarmup
é fornecido para aquecimento e decaimento. A taxa de aprendizagem atingirá lr
em etapas warmpup_steps
e diminuirá para min_lr
em etapas decay_steps
. Existe uma função auxiliar calc_train_steps
para calcular as duas etapas:
import numpy as np
from keras_bert import AdamWarmup , calc_train_steps
train_x = np . random . standard_normal (( 1024 , 100 ))
total_steps , warmup_steps = calc_train_steps (
num_example = train_x . shape [ 0 ],
batch_size = 32 ,
epochs = 10 ,
warmup_proportion = 0.1 ,
)
optimizer = AdamWarmup ( total_steps , warmup_steps , lr = 1e-3 , min_lr = 1e-5 )
Vários URLs de download foram adicionados. Você pode obter o caminho baixado e descompactado de um ponto de verificação:
from keras_bert import get_pretrained , PretrainedList , get_checkpoint_paths
model_path = get_pretrained ( PretrainedList . multi_cased_base )
paths = get_checkpoint_paths ( model_path )
print ( paths . config , paths . checkpoint , paths . vocab )
Você pode usar a função auxiliar extract_embeddings
se os recursos de tokens ou frases (sem ajustes adicionais) forem o que você precisa. Para extrair os recursos de todos os tokens:
from keras_bert import extract_embeddings
model_path = 'xxx/yyy/uncased_L-12_H-768_A-12'
texts = [ 'all work and no play' , 'makes jack a dull boy~' ]
embeddings = extract_embeddings ( model_path , texts )
O resultado retornado é uma lista com o mesmo comprimento dos textos. Cada item da lista é uma matriz numpy truncada pelo comprimento da entrada. As formas das saídas neste exemplo são (7, 768)
e (8, 768)
.
Quando as entradas são sentenças emparelhadas e você precisa das saídas do NSP
e do pool máximo das últimas 4 camadas:
from keras_bert import extract_embeddings , POOL_NSP , POOL_MAX
model_path = 'xxx/yyy/uncased_L-12_H-768_A-12'
texts = [
( 'all work and no play' , 'makes jack a dull boy' ),
( 'makes jack a dull boy' , 'all work and no play' ),
]
embeddings = extract_embeddings ( model_path , texts , output_layer_num = 4 , poolings = [ POOL_NSP , POOL_MAX ])
Não há recursos de token nos resultados. As saídas de NSP
e max-pooling serão concatenadas com a forma final (768 x 4 x 2,)
.
O segundo argumento na função auxiliar é um gerador. Para extrair recursos do arquivo:
import codecs
from keras_bert import extract_embeddings
model_path = 'xxx/yyy/uncased_L-12_H-768_A-12'
with codecs . open ( 'xxx.txt' , 'r' , 'utf8' ) as reader :
texts = map ( lambda x : x . strip (), reader )
embeddings = extract_embeddings ( model_path , texts )