Bert基础(二十)--Bert实战:机器阅读理解任务

一、机器阅读理解任务

1.1 概念理解

机器阅读理解(Machine Reading Comprehension, MRC)就是给定一篇文章,以及基于文章的一个问题,让机器在阅读文章后对问题进行作答。

在机器阅读理解领域,模型的核心能力体现在对给定文档集合P的理解以及对相关问题Q的准确应答,从而输出答案A。MRC任务可根据问题的形式和答案的生成方式,分为以下几种类型:

  1. 完形填空(Cloze-Style):在这种任务中,文章中的某些单词被隐去,模型需基于上下文信息推断出最可能的单词填充空白。这种方法考验模型对语境的理解以及对词汇的准确预测能力。
  2. 多项选择(Multiple-Choice):此任务为模型提供一篇文章和一个问题,模型需从多个备选答案中选择一个最符合问题要求的答案。这种类型的任务评估模型区分不同选项并做出最佳选择的能力。
  3. 片段抽取(Span-Extraction):在此任务中,模型需从给定文章中抽取一个连续的单词序列作为问题的答案。这种方法强调模型对文章细节的理解和定位关键信息的能力。
  4. 自由作答(Free-Answering):与片段抽取不同,自由作答任务要求模型生成一个单词序列作为答案,而不局限于文章中的现有句子。这种方法不仅考察模型的文本理解能力,还考察其生成连贯、准确答案的能力。

本次内容主要针对片段抽取(Span-Extraction)任务进行实战。

例子:

文档P:
“昨天,NASA宣布了一个关于火星上潜在生命迹象的重大发现。这个发现是基于好奇号火星车在盖尔陨石坑的探测结果。好奇号火星车自2012年登陆火星以来,一直在寻找火星上可能存在生命的迹象。NASA表示,这一发现可能是火星上曾经存在微生物生命的证据。”
问题Q:
“好奇号火星车在哪个陨石坑发现了潜在的生命迹象?”
答案A:
“盖尔陨石坑”

在这个例子中,机器阅读理解模型的任务是从给定的文档P中抽取与问题Q相关的连续文本片段作为答案A。模型需要准确地理解文档的内容,并定位到与问题直接相关的信息,即“盖尔陨石坑”。这种任务不仅要求模型理解文本的字面意义,还要求它能够从复杂的信息中抽取和识别关键信息。

1.2 评价指标

  1. 精准匹配度(Exact Match, EM)
    • 计算方法:将预测结果与标准答案进行一对一比对,判断是否完全匹配。
    • 意义:衡量模型输出与真实标签之间的精确一致性,是评估模型准确性的重要指标之一。
    • 优点:直观反映模型预测的准确性,适合于单标签分类任务。
    • 局限性:对于多标签或模糊匹配场景不适用,可能导致评分偏低。
  2. 模糊匹配度(F1)
    • 计算方法:综合考虑精准匹配度和召回率,得到一个平衡的分数。
    • 意义:考虑了模型在所有类别上的表现,适用于多标签分类任务。
    • 优点:能够处理部分匹配的情况,更好地适应实际应用场景。
    • 局限性:可能会掩盖模型在某些类别的性能短板。
  3. EM和F1的关系
    • EM关注的是绝对的正确性,F1关注的是整体的精确性和召回率。
    • 在理想情况下,EM和F1都应该接近1,但实际情况中两者往往无法同时达到最高值。
    • 根据具体任务需求,可以选择不同的评估指标来优化模型性能。

例子:

  1. 评估指标
    • 精准匹配度(Exact Match, EM):计算预测结果与标准答案是否完全匹配。
    • 模糊匹配度(F1):计算预测结果与标准答案之间字级别的匹配程度。
  2. 简单示例
    • 数据
      • 模型预测结果:西湖
      • 真实标签结果:杭州西湖
    • 计算结果
      • EM = 0,P = 2/2 R=2/4 F1 = (2 * 2/2 * 2/4) / (2/2 + 2/4) = 2/3~= 0.66

在评估机器阅读理解模型的性能时,应根据任务类型和目标选择合适的评估指标。精准匹配度适合于单标签任务,而模糊匹配度更适合于多标签任务。同时,需要认识到这些指标的局限性,并结合其他信息来全面评估模型的性能。

二、实战

2.1 加载数据集

在这里插入图片描述

datasets = load_dataset("cmrc2018", cache_dir="data")
datasets
DatasetDict({train: Dataset({features: ['id', 'context', 'question', 'answers'],num_rows: 10142})validation: Dataset({features: ['id', 'context', 'question', 'answers'],num_rows: 3219})test: Dataset({features: ['id', 'context', 'question', 'answers'],num_rows: 1002})
})

查看下数据

datasets["train"][1]
{'id': 'TRAIN_186_QUERY_1','context': '范廷颂枢机(,),圣名保禄·若瑟(),是越南罗马天主教枢机。1963年被任为主教;1990年被擢升为天主教河内总教区宗座署理;1994年被擢升为总主教,同年年底被擢升为枢机;2009年2月离世。范廷颂于1919年6月15日在越南宁平省天主教发艳教区出生;童年时接受良好教育后,被一位越南神父带到河内继续其学业。范廷颂于1940年在河内大修道院完成神学学业。范廷颂于1949年6月6日在河内的主教座堂晋铎;及后被派到圣女小德兰孤儿院服务。1950年代,范廷颂在河内堂区创建移民接待中心以收容到河内避战的难民。1954年,法越战争结束,越南民主共和国建都河内,当时很多天主教神职人员逃至越南的南方,但范廷颂仍然留在河内。翌年管理圣若望小修院;惟在1960年因捍卫修院的自由、自治及拒绝政府在修院设政治课的要求而被捕。1963年4月5日,教宗任命范廷颂为天主教北宁教区主教,同年8月15日就任;其牧铭为「我信天主的爱」。由于范廷颂被越南政府软禁差不多30年,因此他无法到所属堂区进行牧灵工作而专注研读等工作。范廷颂除了面对战争、贫困、被当局迫害天主教会等问题外,也秘密恢复修院、创建女修会团体等。1990年,教宗若望保禄二世在同年6月18日擢升范廷颂为天主教河内总教区宗座署理以填补该教区总主教的空缺。1994年3月23日,范廷颂被教宗若望保禄二世擢升为天主教河内总教区总主教并兼天主教谅山教区宗座署理;同年11月26日,若望保禄二世擢升范廷颂为枢机。范廷颂在1995年至2001年期间出任天主教越南主教团主席。2003年4月26日,教宗若望保禄二世任命天主教谅山教区兼天主教高平教区吴光杰主教为天主教河内总教区署理主教;及至2005年2月19日,范廷颂因获批辞去总主教职务而荣休;吴光杰同日真除天主教河内总教区总主教职务。范廷颂于2009年2月22日清晨在河内离世,享年89岁;其葬礼于同月26日上午在天主教河内总教区总主教座堂举行。','question': '1990年,范廷颂担任什么职务?','answers': {'text': ['1990年被擢升为天主教河内总教区宗座署理'], 'answer_start': [41]}}

2.2 数据预处理

接下来是当前整个任务最复杂的内容,因为数据格式我们需要进行处理成下面格式:

在这里插入图片描述

  1. 数据处理格式
    • [CLS]:表示分类标记,用于指示输入数据的类别。
    • Question:问题的文本内容。
    • [SEP]:分隔符,用于区分问题和上下文。
    • Context:问题的上下文信息,即问题所处的环境或背景。
    • [SEP]:分隔符,用于结束上下文的标注。
  2. 如何准确定位答案位置
    • 使用start_positions / end_positions来指示答案在原始文本中的起始和结束位置。
    • 通过offset_mapping映射原始文本到转换后的序列,从而确定答案的位置。
  3. Context过长时的解决策略
    • 策略1:直接截断(例如,当问题长度超过一定阈值时):这种方法简单且易于实现,但可能会导致答案靠后的部分被忽略。
    • 策略2:滑动窗口(例如,通过多个窗口遍历原始文本):这种方法虽然复杂,但可以保留更多的上下文信息,尽管它会丢失一部分原文本。(下篇再讲)
2.2.1 滑动窗口

在这里插入图片描述

但是如果我们直接截断的这种滑动窗口会影响上下文的理解,所以我们一般会让后面加一段前面一段的内容来维系文本的连贯性
在这里插入图片描述

示例:
问题:中国的首都是哪里?
上下文:北京是中国的首都,它是一座历史悠久的城市,有着丰富的文化遗产和现代化的城市景观。
在这个例子中,我们可以将问题标记为“Question”,上下文标记为“Context”。然后使用start_positions / end_positions来定位答案“北京”在原始文本中的起始和结束位置,并将其与问题一起组成一个完整的输入样本供模型学习。

2.2.2 offsets_mapping

在使用transformers库进行文本处理时,offset_mapping 是一个非常重要的概念。它是一个与分词结果相关联的列表,其中每个元素是一个元组,表示一个token在原始文本中的字符级别位置。

demo = datasets["train"].select(range(10))
tokenized_demo = tokenizer(text=demo["question"],text_pair=demo["context"],return_offsets_mapping=True,return_overflowing_tokens=True,stride=128,max_length=384, truncation="only_second", padding="max_length")
print(tokenized_demo["offset_mapping"][25], len(tokenized_demo["offset_mapping"][25]))

在这里插入图片描述
这个个token下面有多个offsets_mapping索引,我们实际找一个看看

demo[8]
{'id': 'TRAIN_54_QUERY_3','context': '安雅·罗素法(,),来自俄罗斯圣彼得堡的模特儿。她是《全美超级模特儿新秀大赛》第十季的亚军。2008年,安雅宣布改回出生时的名字:安雅·罗素法(Anya Rozova),在此之前是使用安雅·冈()。安雅于俄罗斯出生,后来被一个居住在美国夏威夷群岛欧胡岛檀香山的家庭领养。安雅十七岁时曾参与香奈儿、路易·威登及芬迪(Fendi)等品牌的非正式时装秀。2007年,她于瓦伊帕胡高级中学毕业。毕业后,她当了一名售货员。她曾为Russell Tanoue拍摄照片,Russell Tanoue称赞她是「有前途的新面孔」。安雅在半准决赛面试时说她对模特儿行业充满热诚,所以参加全美超级模特儿新秀大赛。她于比赛中表现出色,曾五次首名入围,平均入围顺序更拿下历届以来最优异的成绩(2.64),另外胜出三次小挑战,分别获得与评判尼祖·百克拍照、为柠檬味道的七喜拍摄广告的机会及十万美元、和盖马蒂洛(Gai Mattiolo)设计的晚装。在最后两强中,安雅与另一名参赛者惠妮·汤姆森为范思哲走秀,但评判认为她在台上不够惠妮突出,所以选了惠妮当冠军,安雅屈居亚军(但就整体表现来说,部份网友认为安雅才是第十季名副其实的冠军。)安雅在比赛拿五次第一,也胜出多次小挑战。安雅赛后再次与Russell Tanoue合作,为2008年4月30日出版的MidWeek杂志拍摄封面及内页照。其后她参加了V杂志与Supreme模特儿公司合办的模特儿选拔赛2008。她其后更与Elite签约。最近她与香港的模特儿公司 Style International Management 签约,并在香港发展其模特儿事业。她曾在很多香港的时装杂志中任模特儿,《Jet》、《东方日报》、《Elle》等。','question': '毕业后的安雅·罗素法职业是什么?','answers': {'text': ['售货员'], 'answer_start': [202]}}

这里有英文,我们拿出来进行分词

tokenizer("Russell Tanoue")
{'input_ids': [101, 13481, 30594, 11010, 10112, 102], 'token_type_ids': [0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1]}

对于英文来讲,如果一个单词没有在此表中出现那么它就需要进行分解,一个单词可以分解多次,直到能在此表中找到,进行表示。
我们可以分别对上面的几个input_ids进行解码看看

tokenizer.decode([101, 13481, 30594, 11010, 10112, 102])
'[CLS] Russell Tanoue [SEP]'
tokenizer("Russell Tanoue").word_ids()
[None, 0, 1, 1, 1, None]

可以发现第一个单词Russell在此表中是有的,但是Tanoue被分解成了三个token

我们分别解码看看

tokenizer.decode([101,  30594, 102]),tokenizer.decode([101,  11010, 102]),tokenizer.decode([101,  10112, 102])('[CLS] Tan [SEP]', '[CLS]ou [SEP]', '[CLS]e [SEP]')

也就是Tanoue被分解成了【Tan, ou, e 】

后面处理的难点就是我们需要把Tan, ou, e对应的input_ids:30594, 11010, 10112,进新计数的时候要根据实际的文本计算

也就是Tanoue在原始文本中占一个字符,但是分词后,它占了三个,所以我们在定位答案的起始位置时需要根据一个字符进行定位,但是我们训练处理的时候时使用编码后的input_ids,所以我们就必须把offsets_mapping和原始的内容匹配好才能根据起始位置找到真正的答案。

2.2.3 overflow

for sen in tokenizer.batch_decode(tokenized_demo["input_ids"][:6]):print(sen)
[CLS] 范 廷 颂 是 什 么 时 候 被 任 为 主 教 的 ? [SEP] 范 廷 颂 枢 机 ( , ) , 圣 名 保 禄 · 若 瑟 ( ) , 是 越 南 罗 马 天 主 教 枢 机 。 1963 年 被 任 为 主 教 ; 1990 年 被 擢 升 为 天 主 教 河 内 总 教 区 宗 座 署 理 ; 1994 年 被 擢 升 为 总 主 教 , 同 年 年 底 被 擢 升 为 枢 机 ; 20092 月 离 世 。 范 廷 颂 于 1919615 日 在 越 南 宁 平 省 天 主 教 发 艳 教 区 出 生 ; 童 年 时 接 受 良 好 教 育 后 , 被 一 位 越 南 神 父 带 到 河 内 继 续 其 学 业 。 范 廷 颂 于 1940 年 在 河 内 大 修 道 院 完 成 神 学 学 业 。 范 廷 颂 于 194966 日 在 河 内 的 主 教 座 堂 晋 铎 ; 及 后 被 派 到 圣 女 小 德 兰 孤 儿 院 服 务 。 1950 年 代 , 范 廷 颂 在 河 内 堂 区 创 建 移 民 接 待 中 心 以 收 容 到 河 内 避 战 的 难 民 。 1954 年 , 法 越 战 争 结 束 , 越 南 民 主 共 和 国 建 都 河 内 , 当 时 很 多 天 主 教 神 职 人 员 逃 至 越 南 的 南 方 , 但 范 廷 颂 仍 然 留 在 河 内 。 翌 年 管 理 圣 若 望 小 修 院 ; 惟 在 1960 年 因 捍 卫 修 院 的 自 由 、 自 治 及 拒 绝 政 府 在 修 院 设 政 治 课 的 要 求 而 被 捕 。 196345 日 , 教 宗 任 命 范 廷 颂 为 天 主 教 北 宁 教 区 主 教 , 同 年 815 日 就 任 ; 其 牧 铭 为 「 我 信 [SEP]
[CLS] 范 廷 颂 是 什 么 时 候 被 任 为 主 教 的 ? [SEP] 越 南 民 主 共 和 国 建 都 河 内 , 当 时 很 多 天 主 教 神 职 人 员 逃 至 越 南 的 南 方 , 但 范 廷 颂 仍 然 留 在 河 内 。 翌 年 管 理 圣 若 望 小 修 院 ; 惟 在 1960 年 因 捍 卫 修 院 的 自 由 、 自 治 及 拒 绝 政 府 在 修 院 设 政 治 课 的 要 求 而 被 捕 。 196345 日 , 教 宗 任 命 范 廷 颂 为 天 主 教 北 宁 教 区 主 教 , 同 年 815 日 就 任 ; 其 牧 铭 为 「 我 信 天 主 的 爱 」 。 由 于 范 廷 颂 被 越 南 政 府 软 禁 差 不 多 30 年 , 因 此 他 无 法 到 所 属 堂 区 进 行 牧 灵 工 作 而 专 注 研 读 等 工 作 。 范 廷 颂 除 了 面 对 战 争 、 贫 困 、 被 当 局 迫 害 天 主 教 会 等 问 题 外 , 也 秘 密 恢 复 修 院 、 创 建 女 修 会 团 体 等 。 1990 年 , 教 宗 若 望 保 禄 二 世 在 同 年 618 日 擢 升 范 廷 颂 为 天 主 教 河 内 总 教 区 宗 座 署 理 以 填 补 该 教 区 总 主 教 的 空 缺 。 1994323 日 , 范 廷 颂 被 教 宗 若 望 保 禄 二 世 擢 升 为 天 主 教 河 内 总 教 区 总 主 教 并 兼 天 主 教 谅 山 教 区 宗 座 署 理 ; 同 年 1126 日 , 若 望 保 禄 二 世 擢 升 范 廷 颂 为 枢 机 。 范 廷 颂 在 1995 年 至 2001 年 期 间 出 任 天 主 教 越 南 主 教 团 主 席 。 20034 [SEP]
[CLS] 范 廷 颂 是 什 么 时 候 被 任 为 主 教 的 ? [SEP] 日 擢 升 范 廷 颂 为 天 主 教 河 内 总 教 区 宗 座 署 理 以 填 补 该 教 区 总 主 教 的 空 缺 。 1994323 日 , 范 廷 颂 被 教 宗 若 望 保 禄 二 世 擢 升 为 天 主 教 河 内 总 教 区 总 主 教 并 兼 天 主 教 谅 山 教 区 宗 座 署 理 ; 同 年 1126 日 , 若 望 保 禄 二 世 擢 升 范 廷 颂 为 枢 机 。 范 廷 颂 在 1995 年 至 2001 年 期 间 出 任 天 主 教 越 南 主 教 团 主 席 。 2003426 日 , 教 宗 若 望 保 禄 二 世 任 命 天 主 教 谅 山 教 区 兼 天 主 教 高 平 教 区 吴 光 杰 主 教 为 天 主 教 河 内 总 教 区 署 理 主 教 ; 及 至 2005219 日 , 范 廷 颂 因 获 批 辞 去 总 主 教 职 务 而 荣 休 ; 吴 光 杰 同 日 真 除 天 主 教 河 内 总 教 区 总 主 教 职 务 。 范 廷 颂 于 2009222 日 清 晨 在 河 内 离 世 , 享 年 89 岁 ; 其 葬 礼 于 同 月 26 日 上 午 在 天 主 教 河 内 总 教 区 总 主 教 座 堂 举 行 。 [SEP] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD]
[CLS] 1990 年 , 范 廷 颂 担 任 什 么 职 务 ? [SEP] 范 廷 颂 枢 机 ( , ) , 圣 名 保 禄 · 若 瑟 ( ) , 是 越 南 罗 马 天 主 教 枢 机 。 1963 年 被 任 为 主 教 ; 1990 年 被 擢 升 为 天 主 教 河 内 总 教 区 宗 座 署 理 ; 1994 年 被 擢 升 为 总 主 教 , 同 年 年 底 被 擢 升 为 枢 机 ; 20092 月 离 世 。 范 廷 颂 于 1919615 日 在 越 南 宁 平 省 天 主 教 发 艳 教 区 出 生 ; 童 年 时 接 受 良 好 教 育 后 , 被 一 位 越 南 神 父 带 到 河 内 继 续 其 学 业 。 范 廷 颂 于 1940 年 在 河 内 大 修 道 院 完 成 神 学 学 业 。 范 廷 颂 于 194966 日 在 河 内 的 主 教 座 堂 晋 铎 ; 及 后 被 派 到 圣 女 小 德 兰 孤 儿 院 服 务 。 1950 年 代 , 范 廷 颂 在 河 内 堂 区 创 建 移 民 接 待 中 心 以 收 容 到 河 内 避 战 的 难 民 。 1954 年 , 法 越 战 争 结 束 , 越 南 民 主 共 和 国 建 都 河 内 , 当 时 很 多 天 主 教 神 职 人 员 逃 至 越 南 的 南 方 , 但 范 廷 颂 仍 然 留 在 河 内 。 翌 年 管 理 圣 若 望 小 修 院 ; 惟 在 1960 年 因 捍 卫 修 院 的 自 由 、 自 治 及 拒 绝 政 府 在 修 院 设 政 治 课 的 要 求 而 被 捕 。 196345 日 , 教 宗 任 命 范 廷 颂 为 天 主 教 北 宁 教 区 主 教 , 同 年 815 日 就 任 ; 其 牧 铭 为 「 我 信 天 主 [SEP]
[CLS] 1990 年 , 范 廷 颂 担 任 什 么 职 务 ? [SEP] 民 主 共 和 国 建 都 河 内 , 当 时 很 多 天 主 教 神 职 人 员 逃 至 越 南 的 南 方 , 但 范 廷 颂 仍 然 留 在 河 内 。 翌 年 管 理 圣 若 望 小 修 院 ; 惟 在 1960 年 因 捍 卫 修 院 的 自 由 、 自 治 及 拒 绝 政 府 在 修 院 设 政 治 课 的 要 求 而 被 捕 。 196345 日 , 教 宗 任 命 范 廷 颂 为 天 主 教 北 宁 教 区 主 教 , 同 年 815 日 就 任 ; 其 牧 铭 为 「 我 信 天 主 的 爱 」 。 由 于 范 廷 颂 被 越 南 政 府 软 禁 差 不 多 30 年 , 因 此 他 无 法 到 所 属 堂 区 进 行 牧 灵 工 作 而 专 注 研 读 等 工 作 。 范 廷 颂 除 了 面 对 战 争 、 贫 困 、 被 当 局 迫 害 天 主 教 会 等 问 题 外 , 也 秘 密 恢 复 修 院 、 创 建 女 修 会 团 体 等 。 1990 年 , 教 宗 若 望 保 禄 二 世 在 同 年 618 日 擢 升 范 廷 颂 为 天 主 教 河 内 总 教 区 宗 座 署 理 以 填 补 该 教 区 总 主 教 的 空 缺 。 1994323 日 , 范 廷 颂 被 教 宗 若 望 保 禄 二 世 擢 升 为 天 主 教 河 内 总 教 区 总 主 教 并 兼 天 主 教 谅 山 教 区 宗 座 署 理 ; 同 年 1126 日 , 若 望 保 禄 二 世 擢 升 范 廷 颂 为 枢 机 。 范 廷 颂 在 1995 年 至 2001 年 期 间 出 任 天 主 教 越 南 主 教 团 主 席 。 2003426 日 , [SEP]
[CLS] 1990 年 , 范 廷 颂 担 任 什 么 职 务 ? [SEP] 廷 颂 为 天 主 教 河 内 总 教 区 宗 座 署 理 以 填 补 该 教 区 总 主 教 的 空 缺 。 1994323 日 , 范 廷 颂 被 教 宗 若 望 保 禄 二 世 擢 升 为 天 主 教 河 内 总 教 区 总 主 教 并 兼 天 主 教 谅 山 教 区 宗 座 署 理 ; 同 年 1126 日 , 若 望 保 禄 二 世 擢 升 范 廷 颂 为 枢 机 。 范 廷 颂 在 1995 年 至 2001 年 期 间 出 任 天 主 教 越 南 主 教 团 主 席 。 2003426 日 , 教 宗 若 望 保 禄 二 世 任 命 天 主 教 谅 山 教 区 兼 天 主 教 高 平 教 区 吴 光 杰 主 教 为 天 主 教 河 内 总 教 区 署 理 主 教 ; 及 至 2005219 日 , 范 廷 颂 因 获 批 辞 去 总 主 教 职 务 而 荣 休 ; 吴 光 杰 同 日 真 除 天 主 教 河 内 总 教 区 总 主 教 职 务 。 范 廷 颂 于 2009222 日 清 晨 在 河 内 离 世 , 享 年 89 岁 ; 其 葬 礼 于 同 月 26 日 上 午 在 天 主 教 河 内 总 教 区 总 主 教 座 堂 举 行 。 [SEP] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD] [PAD]

我们滑动窗口进行分解后,那么答案可能位于任何一个窗口里,所以我们在处理的时候,需要便利每一个窗口;同时答案可能同时出现了多个窗口,因为有数据的重复,而且相似的答案也可能会出现在不同的位置,所以我们后面处理的时候需要进行对比。

def process_func(examples):tokenized_examples = tokenizer(text=examples["question"],text_pair=examples["context"],return_offsets_mapping=True,return_overflowing_tokens=True,stride=128,max_length=384, truncation="only_second", padding="max_length")sample_mapping = tokenized_examples.pop("overflow_to_sample_mapping")start_positions = []end_positions = []example_ids = []for idx, _ in enumerate(sample_mapping):answer = examples["answers"][sample_mapping[idx]]start_char = answer["answer_start"][0]end_char = start_char + len(answer["text"][0])# 定位答案在token中的起始位置和结束位置# 一种策略,我们要拿到context的起始和结束,然后从左右两侧向答案逼近context_start = tokenized_examples.sequence_ids(idx).index(1)context_end = tokenized_examples.sequence_ids(idx).index(None, context_start) - 1offset = tokenized_examples.get("offset_mapping")[idx]# 判断答案是否在context中if offset[context_end][1] < start_char or offset[context_start][0] > end_char:start_token_pos = 0end_token_pos = 0else:token_id = context_startwhile token_id <= context_end and offset[token_id][0] < start_char:token_id += 1start_token_pos = token_idtoken_id = context_endwhile token_id >= context_start and offset[token_id][1] > end_char:token_id -=1end_token_pos = token_idstart_positions.append(start_token_pos)end_positions.append(end_token_pos)example_ids.append(examples["id"][sample_mapping[idx]])tokenized_examples["offset_mapping"][idx] = [(o if tokenized_examples.sequence_ids(idx)[k] == 1 else None)for k, o in enumerate(tokenized_examples["offset_mapping"][idx])]tokenized_examples["example_ids"] = example_idstokenized_examples["start_positions"] = start_positionstokenized_examples["end_positions"] = end_positionsreturn tokenized_examples

上面代码定义了一个名为 process_func 的函数,其目的是对阅读理解任务的数据进行预处理。这个函数接受一个参数 examples,它是一个包含问题和上下文的数据集。函数的目的是将这个数据集转换成一个适合模型处理的格式。
以下是代码的主要步骤:

  1. 使用 tokenizer 对问题和上下文进行分词。这里设置了几个关键参数:
    • return_offsets_mapping=True:返回每个token与原始文本中字符的对应关系。
    • return_overflowing_tokens=True:当文本长度超过模型最大序列长度时,返回分割的token。
    • stride=128:当进行文本分割时,每次移动的字符数。
    • max_length=384:模型能够处理的最大序列长度。
    • truncation="only_second":如果文本过长,只截断上下文。
    • padding="max_length":对序列进行填充以使它们都具有相同的长度。
  2. sample_mapping 被用来处理文本过长被分割的情况。它包含了分割后的部分与原始样本的对应关系。
  3. 初始化 start_positionsend_positionsexample_ids 三个列表,用于存储答案的起始和结束位置以及问题的ID。
  4. 对于每个样本,根据 sample_mapping 找到对应的答案,并计算答案在token中的起始和结束位置。这是通过比较答案的字符位置和token的字符位置来完成的。
  5. 如果答案在上下文中,则通过遍历token的偏移量来找到答案的起始和结束token位置。
  6. 将起始和结束位置以及问题ID添加到对应的列表中。
  7. 更新 tokenized_examples 中的 offset_mapping,确保只有上下文的token的偏移量被保留。
  8. example_idsstart_positionsend_positions 添加到 tokenized_examples 中。
  9. 返回处理后的 tokenized_examples

总的来说,这个函数的主要目的是为机器阅读理解任务准备数据,包括对问题和上下文进行分词,并确定答案在分词后的文本中的位置。这对于训练模型来预测答案在文本中的位置是至关重要的。

tokenied_datasets = datasets.map(process_func, batched=True, remove_columns=datasets["train"].column_names)
tokenied_datasets
DatasetDict({train: Dataset({features: ['input_ids', 'token_type_ids', 'attention_mask', 'offset_mapping', 'example_ids', 'start_positions', 'end_positions'],num_rows: 19069})validation: Dataset({features: ['input_ids', 'token_type_ids', 'attention_mask', 'offset_mapping', 'example_ids', 'start_positions', 'end_positions'],num_rows: 6286})test: Dataset({features: ['input_ids', 'token_type_ids', 'attention_mask', 'offset_mapping', 'example_ids', 'start_positions', 'end_positions'],num_rows: 1971})
})
tokenied_datasets["train"]["example_ids"][:10]
['TRAIN_186_QUERY_0','TRAIN_186_QUERY_0','TRAIN_186_QUERY_0','TRAIN_186_QUERY_1','TRAIN_186_QUERY_1','TRAIN_186_QUERY_1','TRAIN_186_QUERY_2','TRAIN_186_QUERY_2','TRAIN_186_QUERY_2','TRAIN_186_QUERY_3']

‘TRAIN_186_QUERY_0’,
‘TRAIN_186_QUERY_0’,
‘TRAIN_186_QUERY_0’,
表示第一个被分成了三块,把分割的滑动窗口跟原始的记录进行映射

import collectionsexample_to_feature = collections.defaultdict(list)
for idx, example_id in enumerate(tokenied_datasets["train"]["example_ids"][:10]):example_to_feature[example_id].append(idx)
example_to_feature
defaultdict(list,{'TRAIN_186_QUERY_0': [0, 1, 2],'TRAIN_186_QUERY_1': [3, 4, 5],'TRAIN_186_QUERY_2': [6, 7, 8],'TRAIN_186_QUERY_3': [9]})

2.3 创建模型

model = AutoModelForQuestionAnswering.from_pretrained("google-bert/bert-base-multilingual-cased")

2.4 创建评估函数

import numpy as np
import collectionsdef get_result(start_logits, end_logits, exmaples, features):predictions = {}references = {}# example 和 feature的映射example_to_feature = collections.defaultdict(list)for idx, example_id in enumerate(features["example_ids"]):example_to_feature[example_id].append(idx)# 最优答案候选n_best = 20# 最大答案长度max_answer_length = 30for example in exmaples:example_id = example["id"]context = example["context"]answers = []for feature_idx in example_to_feature[example_id]:start_logit = start_logits[feature_idx]end_logit = end_logits[feature_idx]offset = features[feature_idx]["offset_mapping"]start_indexes = np.argsort(start_logit)[::-1][:n_best].tolist()end_indexes = np.argsort(end_logit)[::-1][:n_best].tolist()for start_index in start_indexes:for end_index in end_indexes:if offset[start_index] is None or offset[end_index] is None:continueif end_index < start_index or end_index - start_index + 1 > max_answer_length:continueanswers.append({"text": context[offset[start_index][0]: offset[end_index][1]],"score": start_logit[start_index] + end_logit[end_index]})if len(answers) > 0:best_answer = max(answers, key=lambda x: x["score"])predictions[example_id] = best_answer["text"]else:predictions[example_id] = ""references[example_id] = example["answers"]["text"]return predictions, references

上面代码定义了一个名为 get_result 的函数,其目的是从模型输出的开始和结束logits中提取预测的答案,并将它们与参考答案进行比较。这个函数接受四个参数:start_logitsend_logitsexamplesfeatures。这些参数用于生成预测答案和参考答案的字典,以便进行评估。
以下是代码的主要步骤:

  1. 初始化两个字典:predictions 用于存储预测答案,references 用于存储参考答案。
  2. 建立一个从example_idfeature_idx的映射,以便能够将预测的答案与原始问题和上下文对应起来。
  3. 对于每个问题(example),找到与其相关的特征索引(feature_idx),并使用这些索引来获取对应的开始和结束的logits。
  4. 对于每个特征索引,找到最可能的开始和结束索引,并使用这些索引来提取文本中的答案片段。
  5. 将每个答案片段及其得分存储在一个列表中。
  6. 从这个列表中选择得分最高的答案作为最佳答案,并将其存储在predictions字典中。
  7. 将参考答案存储在references字典中。
  8. 返回predictionsreferences两个字典。

这个函数的输出可以用于评估模型的性能,例如通过计算F1分数和精确匹配(EM)分数。这些分数可以帮助您了解模型在给定数据集上的表现。

from metirc.cmrc_eval import evaluate_cmrc
def metirc(pred):start_logits, end_logits = pred[0]if start_logits.shape[0] == len(tokenied_datasets["validation"]):p, r = get_result(start_logits, end_logits, datasets["validation"], tokenied_datasets["validation"])else:p, r = get_result(start_logits, end_logits, datasets["test"], tokenied_datasets["test"])return evaluate_cmrc(p, r)

评估代码

2.5 创建训练器

args = TrainingArguments(output_dir="models_for_qa",per_device_train_batch_size=32,per_device_eval_batch_size=32,evaluation_strategy="epoch",save_strategy="epoch",logging_steps=50,num_train_epochs=1,report_to=['tensorboard']
)

2.6 开始训练

trainer = Trainer(model=model,args=args,train_dataset=tokenied_datasets["train"],eval_dataset=tokenied_datasets["validation"],data_collator=DefaultDataCollator(),compute_metrics=metirc
)trainer.train()

在这里插入图片描述

2.7 评估

trainer.evaluate(eval_dataset=tokenied_datasets["test"])
{'eval_loss': 1.1424208879470825,'eval_avg': 49.33014028955766,'eval_f1': 66.72415283460434,'eval_em': 31.936127744510976,'eval_total': 1002,'eval_skip': 0,'eval_runtime': 32.0109,'eval_samples_per_second': 61.573,'eval_steps_per_second': 1.937,'epoch': 1.0}

预测的效果有点差

2.8 预测

from transformers import pipelinepipe = pipeline("question-answering", model=model, tokenizer=tokenizer, device=0)
pipe(question="马云在哪里创建了阿里巴巴?", context="马云在杭州创建了阿里巴巴"){'score': 0.8899545669555664, 'start': 3, 'end': 5, 'answer': '杭州'}

完整代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/5087.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flink checkpoint 源码分析

序言 最近因为工作需要在阅读flink checkpoint处理机制&#xff0c;学习的过程中记录下来&#xff0c;并分享给大家。也算是学习并记录。 目前公司使用的flink版本为1.11。因此以下的分析都是基于1.11版本来的。 在分享前可以简单对flink checkpoint机制做一个大致的了解。 …

《ElementPlus 与 ElementUI 差异集合》el-dialog 显示属性有差异

ElementPlus 用属性 v-model ElementUI 用属性 visible 其实也是 Vue2/Vue3 的差异&#xff1a;v-model 指令在组件上的使用已经被重新设计&#xff0c;替换掉了 v-bind.sync

JENKINS 安装,学习运维从这里开始

Download and deployJenkins – an open source automation server which enables developers around the world to reliably build, test, and deploy their softwarehttps://www.jenkins.io/download/首先点击上面。下载Jenkins 为了学习&#xff0c;从windows开始&#x…

preg_match详解(反向引用和捕获组)

在讲preg_match函数之前&#xff0c;我们先了解一下什么是php可变变量 php可变变量 在PHP中双引号包裹的字符串中可以解析变量&#xff0c;而单引号则不行 也就是在php中&#xff0c;双引号里面如果包含有变量&#xff0c;php解释器会将其替换为变量解释后的结果&#xff1b…

AI系列:大语言模型的RAG(检索增强生成)技术(上)

前言 大型语言模型&#xff08;LLM&#xff09;虽然在生成文本方面表现出色&#xff0c;但仍然存在一些局限性&#xff1a;数据是静态的&#xff0c;而且缺乏垂直细分领域的知识。为了克服这些限制&#xff0c;有时候会进行进一步的模型训练和微调。在实际应用中&#xff0c;我…

基于深度学习检测恶意流量识别框架(80+特征/99%识别率)

基于深度学习检测恶意流量识别框架 目录 基于深度学习检测恶意流量识别框架简要示例a.检测攻击类别b.模型训练结果输出参数c.前端检测页面d.前端训练界面e.前端审计界面&#xff08;后续更新了&#xff09;f.前端自学习界面&#xff08;自学习模式转换&#xff09;f1.自学习模式…

【嵌入式Linux】阻塞与非阻塞IO为何能降低CPU使用率

本文主要记录嵌入式Linux内核中阻塞与非阻塞IO访问的应用&#xff0c;以及解释了为何二者可以降低CPU使用率 阻塞与非阻塞IO为何能降低CPU使用率 0. 授权须知1. 通俗解释2. 场景描述3. 阻塞IO之———等待队列使用详解4. 非阻塞IO之———poll select4.1 poll 访问4.2 selct 访…

华为L410终端及麒麟KOS上如何安装安卓应用

原文链接&#xff1a;华为L410终端及麒麟KOS上如何安装安卓应用 Hello&#xff0c;大家好啊&#xff01;随着移动应用的普及&#xff0c;越来越多的用户希望在个人电脑上运行安卓应用&#xff0c;以便更好地整合工作和生活中的信息。特别是在华为L410终端和麒麟KOS操作系统上&a…

在线教程|零门槛部署 Llama 3,70B 版本只占 1.07G 存储空间,新用户免费体验 8B 版本

4 月 18 日&#xff0c;Meta 宣布开源 Llama 3&#xff0c;这个号称「迄今为止最好的开源大模型」一经发布&#xff0c;立刻引爆科技圈&#xff01; 发布当天恰逢斯坦福大学教授、AI 顶尖专家吴恩达的生日&#xff0c;作为 AI 开源倡导者&#xff0c;他激动地发文表示&#xff…

亿图图示使用教程

亿图图示是一款强大的图形绘制工具&#xff0c;可以用于创建流程图、思维导图、组织结构图等多种类型的图表。下面是一些基本的使用教程&#xff1a; 下载和安装&#xff1a;首先&#xff0c;你需要在官方网站上下载亿图图示的安装包&#xff0c;然后按照提示进行安装。 新建项…

Tesla P4终于在DL580 Gen9上面跑起来了!

正文共&#xff1a;666 字 11 图&#xff0c;预估阅读时间&#xff1a;1 分钟 跌跌撞撞&#xff0c;从Tesla M4终于走到了Tesla P40&#xff0c;显存从4 GB到8 GB&#xff0c;最后再到24 GB&#xff0c;真是不容易。 回顾一下&#xff0c;Tesla M4是最早开始搞的&#xff0c;经…

CI/CD:基于kubernetes的Gitlab搭建

1. 项目目标 &#xff08;1&#xff09;熟悉使用k8s环境搭建Gitlab &#xff08;2&#xff09;熟练应用Gitlab基本配置 2. 项目准备 2.1. 规划节点 主机名 主机IP 节点规划 k8s-master 10.0.1.1 kube_master k8s-node1 10.0.1.2 kube_node k8s-node2 10.0.1.3 k…

【AI心理咨询测评】一年后,AI心理咨询的路还有多远?——5例AI模型心理咨询能力测评对比

前言 随着GPT横空出世&#xff0c;AI心理健康的市场开始逐渐被开拓。有人联想到线上以GPT作为基础&#xff0c;开发可线上心理咨询的AI&#xff0c;例如国内的聆心智能。然而&#xff0c;这一想法也遭到了无数人的质疑&#xff1a;“连聊天都尚不能很好完成&#xff0c;去做心…

第⑰讲:Ceph集群各组件的配置参数调整

文章目录 1.Ceph集群各组件的配置文件1.1.Ceph各组件配置方式1.2.ceph临时查看、修改配置参数的方法 2.调整Monitor组件的配置参数删除Pool资源池2.1.临时调整配置参数2.2.永久修改配置参数 1.Ceph集群各组件的配置文件 1.1.Ceph各组件配置方式 Ceph集群中各个组件的默认配置…

【Jenkins】持续集成与交付 (一):深入理解什么是持续集成?

🟣【Jenkins】持续集成与交付 (一):深入理解什么是持续集成? 1、软件开发生命周期与持续集成2、 持续集成的流程3、持续集成的好处4、Jenkins的应用实践5、结语💖The Begin💖点点关注,收藏不迷路💖 1、软件开发生命周期与持续集成 软件开发生命周期(SDLC)是指软…

C语言:项目实践(贪吃蛇)

前言&#xff1a; 相信大家都玩过贪吃蛇这款游戏吧&#xff0c;贪吃蛇是久负盛名的游戏&#xff0c;它也和俄罗斯方块&#xff0c;扫雷等游戏位列经典游戏的行列&#xff0c;那贪吃蛇到底是怎么实现的呢&#xff1f; 今天&#xff0c;我就用C语言带着大家一起来实现一下这款游戏…

微软如何打造数字零售力航母系列科普04 - 微软联合Adobe在微软365应用程序中工作时推出新的生成式AI功能

微软和Adobe正在合作&#xff0c;将情境营销见解和工作流程引入微软Copilot&#xff0c;以提供生成的人工智能功能&#xff0c;使营销人员和营销团队能够在自然的工作流程中实现更多目标。 这些新的集成功能将在生产力和协作工具&#xff08;如Outlook、Teams和Word&#xff0…

【事业单位专场】联考、省市统考、单独招考

一、考编概述 1、事业单位类别 事业单位是指由国家出资或委托管理的公共机构&#xff0c;其主要职能是为社会提供公共服务。在中国&#xff0c;事业单位覆盖了科研、教育、文化和卫生等多个领域&#xff0c;并且有着不同的类型。以下是一些主要的分类&#xff1a; 教育事业单…

NLP(10)--TFIDF优劣势及其应用Demo

前言 仅记录学习过程&#xff0c;有问题欢迎讨论 TF*IDF&#xff1a; 优势&#xff1a; 可解释性好 可以清晰地看到关键词 即使预测结果出错&#xff0c;也很容易找到原因 计算速度快 分词本身占耗时最多&#xff0c;其余为简单统计计算 对标注数据依赖小 可以使用无标注语…

【状态机dp 状态压缩 分组】1994. 好子集的数目

本文涉及知识点 动态规划汇总 动态规划 状态机dp 状态压缩 分组 LeetCode1994. 好子集的数目 给你一个整数数组 nums 。如果 nums 的一个子集中&#xff0c;所有元素的乘积可以表示为一个或多个 互不相同的质数 的乘积&#xff0c;那么我们称它为 好子集 。 比方说&#xff…