機器閱讀理解(基於BiDAF實現片段抽取)

2021-02-08 小杜的nlp樂園

機器閱讀理解背景

    機器閱讀理解是自然語言處理中最熱門、最前沿的研究課題之一。閱讀是人們獲得信息的基本手段,沒有閱讀就沒有理解,沒有理解就沒有交流。市面上已有很多聊天機器人產品,但人們發現這些機器人往往答非所問。究其原因,就是目前採用的技術是「文本比對」的黑盒方式,而實際上機器人並不理解人類在和它說什麼。大家知道,人們在交流是有語境的,通過聯想,人們可以方便地理解對方在說什麼,但是讓機器了解語境確實是一件非常困難的事。為了解決這個問題,研究者提出了許多改進的方式,不斷提高模型理解對話與文章的能力。而且,一大批閱讀理解數據集的發布強有力地推動了技術的發展。

    機器閱讀除了研究價值之外,還有很多有意義的應用,比如文本摘要可以省去人們閱讀全文的時間,問答系統可以從海量文檔中精確地找到用戶問題的答案。機器閱讀也是翻譯和對話的基礎,這對計算機輔助人工服務有重大價值。

    在人工智慧浪潮席捲世界的今天,讓計算機學會閱讀有著重要的意義。一方面,閱讀能力涉及人類的核心智能,也是終極人工智慧必不可少的組成部分;另一方面,隨著文本數據的爆炸性增長,利用模型將文本信息的理解自動化可節省大量人力物力成本,在許多行業有著廣泛的應用價值。

    雖然當前機器閱讀理解的能力遠遜於人類,但我們可以利用計算機的超快運算速度和超大存儲能力找到彎道超車的辦法。所謂「熟讀唐詩三百首,不會吟詩也會吟」,而現在的計算機一秒內就可以讀詩千萬首,我們完全有理由期待它能取得突破性的成果。例如,2018年橫空出世的BERT模型融合了大數據和大模型,在機器閱讀理解等多個自然語言處理領域取得可喜的突破。

機器閱讀理解簡介

機器閱讀理解:機器閱讀理解,又稱閱讀理解問答,要求機器閱讀並理解人類自然語言文本,在此基礎上,解答跟文本信息相關的問題。該任務通常被用來衡量機器自然語言理解能力,可以幫助人類從大量文本中快速聚焦相關信息,降低人工信息獲取成本,在文本問答、信息抽取、對話系統等領域具有極強的應用價值。近年來,機器閱讀理解受到工業界和學術界越來越廣泛的關注,是自然語言處理領域的研究熱點之一。

基礎任務:機器閱讀理解基礎任務是根據問題,從非結構化文檔中尋找合適的答案,因此,研究人員通常將機器閱讀理解形式化為一個關於(文檔,問題,答案)三元組的監督學習問題。

任務類型:根據答案的形式,機器閱讀理解任務被細分為完型填空式、多項選擇式、片段抽取式和自由作答式四類,這四類任務從易到難,見證了機器閱讀理解技術的發展。


機器閱讀理解任務:


          MRC四個任務
              對應的數據集
完型填空(loze text)
CNN &Daily Mail,CBT(The Children's Book Test),LAM-BADA dataset,Who-did-What,CLOTH,CliCR
多項選擇(Multiple Choice)
MCText,RACE
片段抽取(Span Extraction)
SQuAD,NewsQA,TriviaQA,DuoRC
自由作答(Free Answering)
bAbl,MS MARCO,SearchQA,NarrativeQA,DuReader


完型填空:完型填空式任務通常將文檔中的某個實體用佔位符替換,機器閱讀殘缺段落後尋找正確的詞進行補充,使原文完整。這類任務代表的數據集有CNN &Daily Mail,CBT(The Children's Book Test),CMRC2017等,其中CNN &Daily Mail是2015年穀歌發布的首個大型閱讀理解數據集,收集了9.3萬篇CNN和22萬篇Daily Mail新聞稿,通過實體替換技術構造百萬級別的三元組語料庫。


多項選擇:多項選擇數據集為(文檔,問題,候選答案集,答案)四元組形式,機器閱讀文檔和問題後,從候選答案集中挑選正確的答案,如MCText,RACE。RACE數據集源自初高中英語考試試題,包含約2.8萬篇文章和10萬個專家問題,用於測試機器的理解和推理能力。


片段抽取:片段抽取式任務要求從原文中抽取一段連續的句子或短語作為問題的答案,相比於完型填空任務填充單一實體,該任務面臨更大的搜索空間,因此更具有挑戰性。2016年,史丹福大學發布了SQuAD數據集,該數據集包括500多篇WIKI百科文章以及人工構建的10萬多問題。2018年,Rajpurkar等人對SQuAD數據集進一步擴增,在原有基礎上新增5萬多無法回答的對抗性問題,這些問題在原文中都存在似是而非的迷惑性答案,模型不僅僅需要準確應答受原文支持的可回答問題,還需要避免對不可回答問題作出回應。因此,該任務難度更高,更能檢驗機器的閱讀理解能力。


自由作答:與片段抽取式任務不同,自由作答式閱讀理解的答案形式更加靈活,正確答案可能需要從原文進行推理或歸納總結,不限制於是否來自原文句子片段,與現實人類作答習慣更為貼近。代表數據集有CoQA、MS-MARCO、DuReader等,通常涉及到多輪迴答、多跳推理等技術。


各項任務熱度圖:


片段抽取:學者C.Snow在2002年的一篇論文中定義閱讀理解是「通過交互從書面文字中提取與構造文章語義的過程」。而機器閱讀理解的目標是利用人工智慧技術,使計算機具有和人類一樣理解文章的能力。下圖給出了一個機器閱讀理解的樣例。其中,模型需要從文章中的一段原文回答問題。


機器閱讀理解架構:


機器閱讀理解工業架構:


BiDAF:Bidirectional Attention  Flow for Machine Comprehension,出自2017年ICLR的一篇論文

核心內容:這篇論文主要對Attention機製做了改進,為此作者總結了MC任務上過去常用的三類attention

1.Attention Reader:通過動態attention機制從文本中提取相關信息(context vector),再根據該信息給出預測結果。

2.Attention-Sum Reader:只計算一次attention weights,然後直接餵給輸出層做出最後的預測,也就是利用attention機制直接獲取文本中各位置作為答案的概率,和pointer network類似的思想,效果很依賴對query的表示。

3.Multi-hop Attention:計算多次attention

主要貢獻:在此上面的基礎上,作者對注意力機製做出了改進,具體BiDAF attention的特點如下

並沒有把context編碼進固定大小的vector,而是讓vector可以流動,減少早期加權和的信息損失

Memory-less,在每個時刻,僅僅對query和當前時刻的context paragraph進行計算,並不直接依賴上一時刻的attention,這使得後面的attention計算不會受到之前錯誤的attention信息的影響

計算了query-to-context(Q2C)和context-to-query(C2Q)兩個方向的attention信息,認為C2Q和Q2C實際上能夠相互補充。實驗發現模型在開發集上去掉C2Q與去掉Q2C相比,分別下降了12和10個百分點,顯然C2Q這個方向上的attention更為重要


模型架構:分為六層

word-Embedding Layer(詞嵌入層)

Character embedding layer(字符嵌入層)

Contextual embedding layer(上下文嵌入層)

Attention flow layer(注意流程)

Modeling layer(模型層)

Output layer(輸出層)

word-Embedding Layer(詞嵌入層):

論文中使用Glove

Character embedding layer(字符嵌入層):

論文中使用了1D-CNN,主要解決OOV問題

Highway network:

1-t:carry gate

高速神經網絡的作用是調整單詞嵌入和字符嵌入步驟的相對貢獻配比,邏輯是,如果我們處理的是一個像「misunderestimate」這樣的oov詞,會希望增加該詞1D-CNN表示的相對重要性,因為我們知道它的Glove表示可能是一些隨機的胡言亂語。另一方面,當我們處理一個常見而且含義明確的單詞時,如「table」時,我們可能希望Glove和1D-CNN之間的貢獻配比更為平等。


數據集是從維基百科中摘取的一部分,json格式如下圖所示:

一個段落中有context和多個問答實例。


代碼實戰

1.數據預處理

class Preprocessor:        def __init__(self, datasets_fp, max_length=384, stride=128):        self.datasets_fp = datasets_fp        self.max_length = max_length        self.max_clen = 384        self.max_qlen = 128        self.stride = stride        self.charset = set()        self.build_charset()
def build_charset(self):         for fp in self.datasets_fp: self.charset |= self.dataset_info(fp)
self.charset = sorted(list(self.charset)) self.charset = ['[PAD]', '[CLS]', '[SEP]'] + self.charset + ['[UNK]'] #構建索引id idx = list(range(len(self.charset)))        #charset to id self.ch2id = dict(zip(self.charset, idx)) #id to charset self.id2ch = dict(zip(idx, self.charset))
def dataset_info(self, inn): charset = set()        #加載json數據集,pio讀取比原生json讀取速度快 dataset = pio.load(inn) #返回context,問題和答案 for _, context, question, answer, _ in self.iter_cqa(dataset): #取不重複的字符然後取併集 charset |= set(context) | set(question) | set(answer) return charset
def iter_cqa(self, dataset): for data in dataset['data']: for paragraph in data['paragraphs']: context = paragraph['context'] for qa in paragraph['qas']: qid = qa['id'] question = qa['question'] for answer in qa['answers']: text = answer['text'] answer_start = answer['answer_start'] yield qid, context, question, text, answer_start
def encode(self, context, question): question_encode = self.convert2id(question, begin=True, end=True) left_length = self.max_length - len(question_encode) context_encode = self.convert2id(context, maxlen=left_length, end=True) cq_encode = question_encode + context_encode
assert len(cq_encode) == self.max_length
return cq_encode
def convert2id(self, sent, maxlen=None, begin=False, end=False): ch = [ch for ch in sent] ch = ['[CLS]'] * begin + ch
if maxlen is not None: ch = ch[:maxlen - 1 * end] ch += ['[SEP]'] * end ch += ['[PAD]'] * (maxlen - len(ch)) else: ch += ['[SEP]'] * end
ids = list(map(self.get_id, ch))
return ids
def get_id(self, ch): return self.ch2id.get(ch, self.ch2id['[UNK]'])     def get_dataset(self, ds_fp): cs, qs, be = [], [], [] for _, c, q, b, e in self.get_data(ds_fp):             cs.append(c) qs.append(q) be.append((b, e)) return map(np.array, (cs, qs, be))
def get_data(self, ds_fp): dataset = pio.load(ds_fp) for qid, context, question, text, answer_start in self.iter_cqa(dataset): cids = self.get_sent_ids(context, self.max_clen) qids = self.get_sent_ids(question, self.max_qlen)             b, e = answer_start, answer_start + len(text) if e >= len(cids): b = e = 0 yield qid, cids, qids, b, e
def get_sent_ids(self, sent, maxlen):        return self.convert2id(sent, maxlen=maxlen, end=True)


2.BiDAF模型架構

class BiDAF:    def __init__(        self, clen, qlen, emb_size,        max_features=5000,        num_highway_layers=2,        encoder_dropout=0,        num_decoders=2,        decoder_dropout=0,    ):        self.clen = clen        self.qlen = qlen        self.max_features = max_features        self.emb_size = emb_size        self.num_highway_layers = num_highway_layers        self.encoder_dropout = encoder_dropout        self.num_decoders = num_decoders        self.decoder_dropout = decoder_dropout
def build_model(self): cinn = tf.keras.layers.Input(shape=(self.clen,), name='CInn') qinn = tf.keras.layers.Input(shape=(self.qlen,), name='QInn') embedding_layer = tf.keras.layers.Embedding(self.max_features, self.emb_size) cemb = embedding_layer(cinn) qemb = embedding_layer(qinn)
for i in range(self.num_highway_layers): highway_layer = layers.Highway(name=f'Highway{i}') chighway = tf.keras.layers.TimeDistributed(highway_layer, name=f'CHighway{i}') qhighway = tf.keras.layers.TimeDistributed(highway_layer, name=f'QHighway{i}')
cemb = chighway(cemb) qemb = qhighway(qemb)
encoder_layer = tf.keras.layers.Bidirectional( tf.keras.layers.LSTM( self.emb_size, recurrent_dropout=self.encoder_dropout, return_sequences=True, name='RNNEncoder' ), name='BiRNNEncoder' )
cencode = encoder_layer(cemb) qencode = encoder_layer(qemb) similarity_layer = layers.Similarity(name='SimilarityLayer') similarity_matrix = similarity_layer([cencode, qencode])        c2q_att_layer = layers.C2QAttention(name='C2QAttention') q2c_att_layer = layers.Q2CAttention(name='Q2CAttention')
c2q_att = c2q_att_layer(similarity_matrix, qencode) q2c_att = q2c_att_layer(similarity_matrix, cencode)
merged_ctx_layer = layers.MergedContext(name='MergedContext') merged_ctx = merged_ctx_layer(cencode, c2q_att, q2c_att)
modeled_ctx = merged_ctx for i in range(self.num_decoders): decoder_layer = tf.keras.layers.Bidirectional( tf.keras.layers.LSTM( self.emb_size, recurrent_dropout=self.decoder_dropout, return_sequences=True, name=f'RNNDecoder{i}' ), name=f'BiRNNDecoder{i}' ) modeled_ctx = decoder_layer(merged_ctx)
span_begin_layer = layers.SpanBegin(name='SpanBegin') span_begin_prob = span_begin_layer([merged_ctx, modeled_ctx])
span_end_layer = layers.SpanEnd(name='SpanEnd') span_end_prob = span_end_layer([cencode, merged_ctx, modeled_ctx, span_begin_prob])
output_layer = layers.Combine(name='CombineOutputs') out = output_layer([span_begin_prob, span_end_prob])
inn = [cinn, qinn]
self.model = tf.keras.models.Model(inn, out) self.model.summary(line_length=128)
optimizer = tf.keras.optimizers.Adadelta(lr=1e-2) self.model.compile( optimizer=optimizer, loss=negative_avg_log_error, metrics=[accuracy] )      

class Highway(tf.keras.layers.Layer):
def __init__(self, activation='relu', *args, **kwargs): self.activation = activation super().__init__(*args, **kwargs)
def build(self, input_shape): dim = input_shape[-1] bias_init = tf.keras.initializers.Constant(-1) self.dense1 = tf.keras.layers.Dense(dim, bias_initializer=bias_init) self.dense2 = tf.keras.layers.Dense(dim)
self.dense1.build(input_shape) self.dense2.build(input_shape)
super().build(input_shape)
def call(self, x): dim = x.shape[-1]
transform_gate = self.dense1(x) transform_gate = tf.keras.layers.Activation('sigmoid')(transform_gate)
carry_gate = tf.keras.layers.Lambda(lambda x: 1.0 - x, output_shape=(dim,))(transform_gate) transformed_data = self.dense2(x) transformed_data = tf.keras.layers.Activation(self.activation)(transformed_data) transformed_gated = tf.keras.layers.multiply([transform_gate, transformed_data]) identity_gated = tf.keras.layers.multiply([carry_gate, x]) value = tf.keras.layers.add([transformed_gated, identity_gated])
return value
def compute_output_shape(self, input_shape): return input_shape
    def get_config(self) config = super().get_config() config['activation'] = self.activation config['transform_gate_bias'] = self.transform_gate_bias return config

計算context和question相似度

class Similarity(tf.keras.layers.Layer):
def build(self, input_shape): word_vector_dim = input_shape[0][-1] weight_vector_dim = word_vector_dim * 3
self.kernel = self.add_weight( name='SimilarityWeight', shape=(weight_vector_dim, 1), initializer='uniform', trainable=True, )
self.bias = self.add_weight( name='SimilarityBias', shape=(), initializer='ones', trainable=True, )
super().build(input_shape)
def compute_similarity(self, repeated_cvectors, repeated_qvectors): element_wise_multiply = repeated_cvectors * repeated_qvectors
concat = tf.keras.layers.concatenate([ repeated_cvectors, repeated_qvectors, element_wise_multiply ], axis=-1)
dot_product = tf.tensordot(concat, self.kernel, axes=1) dot_product = tf.squeeze(dot_product, axis=-1)
return tf.keras.activations.linear(dot_product + self.bias)
def call(self, inputs): c_vector, q_vector = inputs
n_cwords = c_vector.shape[1] n_qwords = q_vector.shape[1]
cdim_repeat = tf.convert_to_tensor([1, 1, n_qwords, 1]) qdim_repeat = tf.convert_to_tensor([1, n_cwords, 1, 1])
repeated_cvectors = tf.tile(tf.expand_dims(c_vector, axis=2), cdim_repeat) repeated_qvectors = tf.tile(tf.expand_dims(q_vector, axis=1), qdim_repeat)
similarity = self.compute_similarity(repeated_cvectors, repeated_qvectors)
return similarity

注意力流層

class C2QAttention(tf.keras.layers.Layer):
def call(self, similarity, qencode): qencode = tf.expand_dims(qencode, axis=1)
c2q_att = tf.keras.activations.softmax(similarity, axis=-1) c2q_att = tf.expand_dims(c2q_att, axis=-1) c2q_att = tf.math.reduce_sum(c2q_att * qencode, -2)
return c2q_att
class Q2CAttention(tf.keras.layers.Layer):
def call(self, similarity, cencode): max_similarity = tf.math.reduce_max(similarity, axis=-1) c2q_att = tf.keras.activations.softmax(max_similarity) c2q_att = tf.expand_dims(c2q_att, axis=-1)
weighted_sum = tf.math.reduce_sum(c2q_att * cencode, axis=-2) weighted_sum = tf.expand_dims(weighted_sum, 1)
num_repeat = cencode.shape[1]
q2c_att = tf.tile(weighted_sum, [1, num_repeat, 1])
return q2c_att

merge後送入LSTM層

class MergedContext(tf.keras.layers.Layer):
def call(self, cencode, c2q_att, q2c_att): m1 = cencode * c2q_att m2 = cencode * q2c_att
concat = tf.keras.layers.concatenate([ cencode, c2q_att, m1, m2], axis=-1 )
return concat
def compute_output_shape(self, input_shape): shape, _, _ = input_shape return shape[:-1] + (shape[-1] * 4, )

Output layer

class SpanBegin(tf.keras.layers.Layer):
def build(self, input_shape): last_dim = input_shape[0][-1] + input_shape[1][-1] inn_shape_dense1 = input_shape[0][:-1] + (last_dim, ) self.dense1 = tf.keras.layers.Dense(1) self.dense1.build(inn_shape_dense1)
super().build(input_shape)
def call(self, inputs): merged_ctx, modeled_ctx = inputs
span_begin_inn = tf.concat([merged_ctx, modeled_ctx], axis=-1) span_begin_weight = tf.keras.layers.TimeDistributed(self.dense1)(span_begin_inn) span_begin_weight = tf.squeeze(span_begin_weight, axis=-1) span_begin_prob = tf.keras.activations.softmax(span_begin_weight)
return span_begin_prob
def compute_output_shape(self, input_shape): return input_shape[0][:-1]
class SpanEnd(tf.keras.layers.Layer):
def build(self, input_shape): emb_size = input_shape[0][-1] // 2 inn_shape_bilstm = input_shape[0][:-1] + (emb_size * 14, ) inn_shape_dense = input_shape[0][:-1] + (emb_size * 10, )
self.bilstm = tf.keras.layers.Bidirectional( tf.keras.layers.LSTM(emb_size, return_sequences=True)) self.bilstm.build(inn_shape_bilstm)
self.dense = tf.keras.layers.Dense(1) self.dense.build(inn_shape_dense)
super().build(input_shape)
def call(self, inputs): cencode, merged_ctx, modeled_ctx, span_begin_prob = inputs
_span_begin_prob = tf.expand_dims(span_begin_prob, axis=-1) weighted_sum = tf.math.reduce_sum(_span_begin_prob * modeled_ctx, axis=-2)
weighted_ctx = tf.expand_dims(weighted_sum, axis=1) tile_shape = tf.concat([[1], [cencode.shape[1]], [1]], axis=0) weighted_ctx = tf.tile(weighted_ctx, tile_shape) m1 = modeled_ctx * weighted_ctx
span_end_repr = tf.concat([merged_ctx, modeled_ctx, weighted_ctx, m1], axis=-1) span_end_repr = self.bilstm(span_end_repr) span_end_inn = tf.concat([merged_ctx, span_end_repr], axis=-1) span_end_weights = tf.keras.layers.TimeDistributed(self.dense)(span_end_inn) span_end_prob = tf.keras.activations.softmax(tf.squeeze(span_end_weights, axis=-1))
return span_end_prob
def compute_output_shape(self, input_shape): return input_shape[1][:-1]
class Combine(tf.keras.layers.Layer):
def call(self, inputs): return tf.stack(inputs, axis=1)

loss function

def negative_avg_log_error(y_true, y_pred):
def sum_of_log_prob(inputs): y_true, y_pred_start, y_pred_end = inputs
begin_idx = tf.dtypes.cast(y_true[0], dtype=tf.int32) end_idx = tf.dtypes.cast(y_true[1], dtype=tf.int32)
begin_prob = y_pred_start[begin_idx] end_prob = y_pred_end[end_idx]
return tf.math.log(begin_prob) + tf.math.log(end_prob)
y_true = tf.squeeze(y_true) y_pred_start = y_pred[:, 0, :] y_pred_end = y_pred[:, 1, :]
inputs = (y_true, y_pred_start, y_pred_end) batch_prob_sum = tf.map_fn(sum_of_log_prob, inputs, dtype=tf.float32)
return -tf.keras.backend.mean(batch_prob_sum, axis=0, keepdims=True)

accuracy

def accuracy(y_true, y_pred):
def calc_acc(inputs): y_true, y_pred_start, y_pred_end = inputs
begin_idx = tf.dtypes.cast(y_true[0], dtype=tf.int32) end_idx = tf.dtypes.cast(y_true[1], dtype=tf.int32)
start_probability = y_pred_start[begin_idx] end_probability = y_pred_end[end_idx]
return (start_probability + end_probability) / 2.0
y_true = tf.squeeze(y_true) y_pred_start = y_pred[:, 0, :] y_pred_end = y_pred[:, 1, :]
inputs = (y_true, y_pred_start, y_pred_end) acc = tf.map_fn(calc_acc, inputs, dtype=tf.float32)
return tf.math.reduce_mean(acc, axis=0)

訓練模型

bidaf.model.fit(        [train_c, train_q], train_y,        batch_size=16,        epochs=100,        validation_data=([test_c, test_q], test_y)    )

部分訓練流程。。。在1080ti下有點小慢


相關焦點

  • EMNLP 2019 | 基於篇章片段抽取的中文閱讀理解數據集
    該論文提出了一種基於篇章片段抽取的中文閱讀理解數據集,也是由哈工大訊飛聯合實驗室承辦的第二屆「訊飛杯」中文機器閱讀理解評測(CMRC 2018)使用的數據。第二屆CCL「訊飛杯」中文機器閱讀理解評測研討會(CMRC 2018)由中國中文信息學會計算語言學專委會主辦,哈工大訊飛聯合實驗室承辦,科大訊飛股份有限公司冠名,於2018年10月19日在湖南長沙圓滿落幕。
  • 走進機器閱讀理解的世界,飛槳開源升級版 BiDAF模型解讀
    在重要的機器閱讀領域,基於DuReader數據集,飛槳升級並開源了一個經典的閱讀理解模型 —— BiDAF,相較於DuReader原始論文中的基線,在效果上有了大幅提升,驗證集上的ROUGE-L指標由原來的39.29提升至47.68,測試集上的ROUGE-L指標由原來的45.90提升至54.66。1.
  • 機器閱讀理解簡述
    閱讀理解大致可以分為四個任務,即填空型閱讀理解任務、選擇型閱讀理解任務、片段抽取型閱讀理解任務以及自由格式閱讀理解任務。隨著以BERT為代表的預訓練模型的發展,四種閱讀理解任務都有著飛速的發展,主要體現為從關注限定文本到結合外部知識,從關注特定片段到對上下文的全面理解。本文對上述幾種主流的機器閱讀理解任務從任務描述、相關數據集、解決方法等幾方面逐一展開介紹。1.
  • 【賽爾筆記】機器閱讀理解簡述
    閱讀理解大致可以分為四個任務,即填空型閱讀理解任務、選擇型閱讀理解任務、片段抽取型閱讀理解任務以及自由格式閱讀理解任務。隨著以BERT為代表的預訓練模型的發展,四種閱讀理解任務都有著飛速的發展,主要體現為從關注限定文本到結合外部知識,從關注特定片段到對上下文的全面理解。本文對上述幾種主流的機器閱讀理解任務從任務描述、相關數據集、解決方法等幾方面逐一展開介紹。1. 填
  • 賽爾筆記 | 機器閱讀理解簡述
    閱讀理解大致可以分為四個任務,即填空型閱讀理解任務、選擇型閱讀理解任務、片段抽取型閱讀理解任務以及自由格式閱讀理解任務。隨著以BERT為代表的預訓練模型的發展,四種閱讀理解任務都有著飛速的發展,主要體現為從關注限定文本到結合外部知識,從關注特定片段到對上下文的全面理解。本文對上述幾種主流的機器閱讀理解任務從任務描述、相關數據集、解決方法等幾方面逐一展開介紹。1.
  • AI機器閱讀理解已超越人類!
    在自然語言處理技術中,機器閱讀理解是繼語音判斷、語義理解之後最大的挑戰:讓智能體理解全文語境。不只是要處理語音和簡單的語義,而是要理解和關注詞彙、語句、篇章結構、思維邏輯、輔助語句和關鍵句等等元素構成的複雜組織網絡。該任務的起源可追溯到 20 世紀 70 年代,但是受限於小規模數據集和基於規則的傳統方法,使機器閱讀理解系統在當時並不能滿足實際應用的需求。
  • 用Gated Convolutional Networks 做機器閱讀理解
    機器閱讀理解 (Machine Reading Comprehension, MRC) 任務主要是根據給定的文章或文本片段,對某些問題進行回答,比較常見的 MRC 任務包括:完形填空,多項選擇,片段抽取,自由作答等。
  • 30 萬獎金海華 AI 挑戰賽 | 用機器挑戰中文閱讀理解
    這些題目在考驗我們對語言是否有準確、深入的理解。所以,這樣的題目也是我們測試計算機模型的重要手段。因此,自自然語言處理出現之時起,機器閱讀理解也就成了最重要的任務之一。和面向學生的語文考試類似,這項任務要求機器閱讀並理解一段或一篇文字,並在此基礎上,回答與文字相關的問題。
  • 30萬獎金海華AI挑戰賽 | 用機器挑戰中文閱讀理解
    在讀中學小學的時候,我們都沒少為語文考試中的閱讀理解題目傷腦筋。這些題目在考驗我們對語言是否有準確、深入的理解。所以,這樣的題目也是我們測試計算機模型的重要手段。因此,自自然語言處理出現之時起,機器閱讀理解也就成了最重要的任務之一。和面向學生的語文考試類似,這項任務要求機器閱讀並理解一段或一篇文字,並在此基礎上,回答與文字相關的問題。
  • 刷新CoQA榜單:基於對抗訓練和知識蒸餾的機器閱讀理解方案解析
    機器之心發布作者:追一科技 AI Lab研究員 Nicolas近日,在由史丹福大學發起的對話式問答挑戰賽 CoQA (Conversational Question Answering Challenge)中,追一科技AI Lab團隊成為榜單第一[1],刷新了之前微軟等團隊創造的CoQA
  • 科大訊飛認知智能持續突破,機器閱讀理解SQuAD測試勇奪第一!
    SQuAD挑戰賽通過眾包的方式構建了一個大規模的機器閱讀理解數據集(包含10萬個問題),就是將一篇幾百詞左右的短文給人工標註者閱讀,讓標註人員提出最多5個基於文章內容的問題並提供正確答案;短文原文則來源於500多篇維基百科文章。
  • ACL2018: 百度閱讀理解技術新進展,讓機器讀懂文本
    閱讀理解是自然語言處理和人工智慧領域的重要前沿課題,對於提升機器智能水平、使機器具有持續知識獲取能力具有重要價值,近年來受到學術界和工業界的廣泛關注。隨著機器閱讀理解技術的發展,閱讀理解任務也在不斷升級,從早期的「完形填空形式」,發展到基於維基百科的「單文檔閱讀理解」,如以斯坦福 SQuAD 為數據集的任務。
  • Deepmind 最新閱讀理解數據集 NarrativeQA ,讓機器挑戰更複雜閱讀...
    雷鋒網按:自然語言處理始終是實現智能、自然人機互動願景裡一塊重要的技術基石。而機器閱讀理解則可以被視為是自然語言處理領域皇冠上的明珠,也是目前該領域的研究焦點之一。閱讀文檔後,讀者通常不能從記憶中重現整個文本,但經常可以回答關於文檔的潛在敘述元素的問題,如突出的實體,事件,地點以及其相互關係等。因此,測試理解需要創建檢查高層次的抽象的問題,而不是只在一個句子中出現一次的事實。不幸的是,關於文檔的表面問題通常可以使用淺層模式匹配或基於全局顯著性的策略或猜測成功(由人和機器)回答。
  • AI前沿丨機器閱讀理解與問答·Dynamic Co-Attention Networks篇
    ·介紹篇中,我們介紹了機器閱讀理解與問答這一任務。我們以該文章為例,為大家介紹這兩種技術,並看看這篇文章是如何使用這兩種技術來解決機器閱讀理解的。協同注意力Co-Attention是注意力機制的一種變體,以機器閱讀理解為例,注意力機制就很像我們人在做閱讀理解時所使用的一種技巧——帶著問題去閱讀,先看問題,再去文本中有目標地閱讀以尋找答案。
  • 科大訊飛機器閱讀理解技術再次登頂SQuAD挑戰賽
    通過讓機器閱讀汽車說明書及相關的介紹材料,使機器深度理解並掌握對該車型的相關知識;在用戶提出相關問題時,不僅能夠快速反饋給用戶相關章節,並且還能夠利用閱讀理解技術進一步挖掘並反饋更精準的答案,從而減少用戶的閱讀量,提高信息獲取的速度。
  • 機器閱讀理解快速迭代,人機互動場景持續落地
    值得一提的是,在2018年的「機器閱讀理解大賽」中,深思考人工智慧同樣在1600多支國內外參賽隊伍中脫穎而出,排名第三,獲全球大獎。此番再奪大賽桂冠,一方面證明了深思考在全球機器閱讀理解領域的前沿實力;另一方面,大賽在極大地推動閱讀理解技術進步的同時,也將深思考這家以研發為主、不斷布局場景落地的創業型公司更多的展現在全世界面前。
  • 2018機器閱讀理解技術競賽開始報名 百度提供中文閱讀理解數據集
    3月1日,由百度公司、中國中文信息學會(CIPS)、中國計算機學會(CCF)聯手舉辦的「2018機器閱讀理解技術競賽」正式開啟報名通道。本次競賽,百度將提供面向真實應用場景迄今為止規模最大的中文閱讀理解數據集DuReader。
  • 巨穎:閱讀理解進階三部曲——關鍵知識、模型性能提升、產品化落地...
    所謂機器閱讀理解,是指讓機器通過閱讀文本,回答內容相關的問題,其中涉及到的理解、推理、摘要等複雜技術,對機器而言頗具挑戰。主要負責閱讀理解相關項目,為追一 AIForce、坐席助手等產品提供技術支持,在閱讀理解、文本分類、信息抽取等方面有深入的研究和豐富的應用經驗。
  • 李偉:輿情事件等級評估及基於語義理解實現文本精細化分類
    人民網輿情數據中心主任數據分析師李偉分享的主題是:輿情事件等級評估及基於語義理解實現文本精細化分類。輿情事件等級評估輿情事件等級評估,李偉從四個方面進行了闡釋:一是當前輿情行業等級評估主要方法以及存在問題。當前行業內使用的指標主要是熱度值。
  • 思必馳在中文機器閱讀理解公開評測中取得階段性進展
    日前,注重源頭基礎創新的思必馳,其知識服務團隊在多個中文機器閱讀理解公開評測中取得階段性進展。此前,該團隊還入選姑蘇重大創新團隊。  機器閱讀理解(Machine Reading Comprehension)是自然語言處理和人工智慧領域的重要前沿課題,旨在讓機器閱讀並理解非結構化的文本,可以準確地回答和文本內容相關的任何問題。