Я пытаюсь использовать bert как вложение слов в этом хранилище bert . У меня проблема с тем, что функции вывода из extract_features.py не соответствуют моему следующему коду:
import tensorflow as tf
from bert import modeling
import collections
import os
import numpy as np
import json
import pdb
import sys
sys.path.insert(0, './bert')
import bert
#from bert import extract_features
from bert import optimization
from bert import tokenization
flags = tf.flags
FLAGS = flags.FLAGS
bert_path = './uncased_L-12_H-768_A-12'
flags.DEFINE_string(
'bert_config_file', os.path.join(bert_path, 'bert_config.json'),
'config json file corresponding to the pre-trained BERT model.'
)
flags.DEFINE_string(
'bert_vocab_file', os.path.join(bert_path,'vocab.txt'),
'the config vocab file',
)
flags.DEFINE_string(
'init_checkpoint', os.path.join(bert_path,'bert_model.ckpt'),
'from a pre-trained BERT get an initial checkpoint',
)
flags.DEFINE_bool("use_tpu", False, "Whether to use TPU or GPU/CPU.")
def convert2Uni(text):
if isinstance(text, str):
return text
elif isinstance(text, bytes):
return text.decode('utf-8','ignore')
else:
print(type(text))
print('####################wrong################')
def load_vocab(vocab_file):
vocab = collections.OrderedDict()
vocab.setdefault('blank', 2)
index = 0
with open(vocab_file) as reader:
# with tf.gfile.GFile(vocab_file, 'r') as reader:
while True:
tmp = reader.readline()
if not tmp:
break
token = convert2Uni(tmp)
token = token.strip()
vocab[token] = index
index+=1
return vocab
def inputs(vectors, maxlen = 25):
length = len(vectors)
if length > maxlen:
return vectors[0:maxlen], [1]*maxlen, [0]*maxlen
else:
input = vectors+[0]*(maxlen-length)
mask = [1]*length + [0]*(maxlen-length)
segment = [1]*maxlen
return input, mask, segment
def response_request(text):
#pdb.set_trace()
tokens=['[CLS]']+tokenizer.tokenize(text)+['[SEP]']
ids=tokenizer.convert_tokens_to_ids(tokens)
#vectors = [dictionary.get('[CLS]')] + [dictionary.get(i) if i in dictionary else dictionary.get('[UNK]') for i in list(text)] + [dictionary.get('[SEP]')]
input, mask, segment = inputs(ids,maxlen=7)
input_ids = np.reshape(np.array(input), [1, -1])
input_mask = np.reshape(np.array(mask), [1, -1])
segment_ids = np.reshape(np.array(segment), [1, -1])
print(input_ids)
embedding = model.get_sequence_output()
rst = sess.run(embedding, feed_dict={'input_ids_p:0':input_ids, 'input_mask_p:0':input_mask, 'segment_ids_p:0':segment_ids})
return rst
dictionary = load_vocab(FLAGS.bert_vocab_file)
init_checkpoint = FLAGS.init_checkpoint
sess = tf.Session()
bert_config = modeling.BertConfig.from_json_file(FLAGS.bert_config_file)
input_ids_p = tf.placeholder(shape=[None, None], dtype = tf.int32, name='input_ids_p')
input_mask_p = tf.placeholder(shape=[None, None], dtype = tf.int32, name='input_mask_p')
segment_ids_p = tf.placeholder(shape=[None, None], dtype = tf.int32, name='segment_ids_p')
model = modeling.BertModel(
config = bert_config,
is_training = FLAGS.use_tpu,
input_ids = input_ids_p,
input_mask = input_mask_p,
token_type_ids = segment_ids_p,
use_one_hot_embeddings = FLAGS.use_tpu,
)
do_lower_case=True
tokenizer=tokenization.FullTokenizer(vocab_file=FLAGS.bert_vocab_file, do_lower_case=do_lower_case)
print('####################################')
tvars = tf.trainable_variables()
(assignment_map,initialized_variable_names) = modeling.get_assignment_map_from_checkpoint(tvars, init_checkpoint)
tf.train.init_from_checkpoint(init_checkpoint, assignment_map)
restore_saver = tf.train.Saver()
#sess.run(tf.global_variables_initializer())
restore_saver.restore(sess, init_checkpoint)
vec1=response_request('they were not poles.')
И я запустил extract_features.py, используя следующую команду:
$BERT_BASE_DIR=./uncased_L-12_H-768_A-12
CUDA_VISIBLE_DEVICES=1 python extract_features.py \
--input_file=./input.txt \
--output_file=./output.jsonl \
--vocab_file=$BERT_BASE_DIR/vocab.txt \
--bert_config_file=$BERT_BASE_DIR/bert_config.json \
--init_checkpoint=$BERT_BASE_DIR/bert_model.ckpt\
--layers=-1\
--max_seq_length=128 \
--batch_size=8
Я проверил простое предложение «они не были полюсами», но я обнаружил, что функция вывода каждого слова (что-то вроде вложения слова) отличается. Например, свойство первого слова "[CLS]" из extract_features.py имеет значение [0,05451696, 0,03971231, -0,47271463, 0,00887229, -0,7232113, ...] , но функция из моего кода [0.1270566, 0.18324886, -0.45625317, 0.04634093, -0.44191134, ...] .
Основное различие между этими двумя способами заключается в том, что один использует sess.run (model.get_sequence_output ()), а другой - функции estimator.predict (). Интересно, что делает выходные данные этих двух способов несовместимыми, и какой из них правильный (или лучше).
Спасибо