Берт: Несоответствие выходных функций из estimator.predict () в extract_features.py и sess.run (model.get_sequence_output ()) - PullRequest
0 голосов
/ 03 июня 2019

Я пытаюсь использовать 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 (). Интересно, что делает выходные данные этих двух способов несовместимыми, и какой из них правильный (или лучше).

Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...