[中文|Englisch]
Implementierung des BERT. Für die Merkmalsextraktion und -vorhersage könnten offizielle vorab trainierte Modelle geladen werden.
pip install keras-bert
In der Feature-Extraktion-Demo sollten Sie in der Lage sein, die gleichen Extraktionsergebnisse wie mit dem offiziellen Modell chinese_L-12_H-768_A-12
zu erhalten. Und in der Vorhersagedemo konnte das fehlende Wort im Satz vorhergesagt werden.
Die Extraktionsdemo zeigt, wie man in ein Modell konvertiert, das auf TPU läuft.
Die Klassifizierungsdemo zeigt, wie das Modell auf einfache Klassifizierungsaufgaben angewendet wird.
Die Klasse Tokenizer
wird zum Aufteilen von Texten und zum Generieren von Indizes verwendet:
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`.
)
Für das Aufwärmen und Abklingen steht AdamWarmup
Optimierer zur Verfügung. Die Lernrate erreicht lr
in Schritten warmpup_steps
und fällt in Schritten decay_steps
auf min_lr
ab. Zur Berechnung der beiden Schritte gibt es eine Hilfsfunktion calc_train_steps
:
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 )
Mehrere Download-URLs wurden hinzugefügt. Sie können den heruntergeladenen und unkomprimierten Pfad eines Prüfpunkts abrufen, indem Sie:
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 )
Sie können die Hilfsfunktion extract_embeddings
verwenden, wenn Sie die Funktionen von Tokens oder Sätzen (ohne weitere Optimierung) benötigen. So extrahieren Sie die Funktionen aller Token:
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 )
Das zurückgegebene Ergebnis ist eine Liste mit der gleichen Länge wie Texte. Jedes Element in der Liste ist ein Numpy-Array, das um die Länge der Eingabe gekürzt wird. Die Formen der Ausgaben in diesem Beispiel sind (7, 768)
und (8, 768)
.
Wenn die Eingaben gepaarte Sätze sind und Sie die Ausgaben von NSP
und Max-Pooling der letzten 4 Schichten benötigen:
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 ])
Die Ergebnisse enthalten keine Token-Funktionen. Die Ausgaben von NSP
und Max-Pooling werden mit der endgültigen Form (768 x 4 x 2,)
verkettet.
Das zweite Argument in der Hilfsfunktion ist ein Generator. So extrahieren Sie Features aus einer Datei:
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 )