首页 > 编程问答 >用于 5 个类别的多标签分类的多任务 bert

用于 5 个类别的多标签分类的多任务 bert

时间:2024-07-24 13:47:06浏览次数:8  
标签:python torch bert-language-model multitasking multilabel-classification

我构建了 5 个基于 BioClinicalBERT 的模型(微调 bert)来预测以下类别的医疗记录标签:

specialties = ["aud","den","oph","oto","psy","tbi"]
clinical_summaries = ["consultation", "hospital_discharge", "operative"]
diagnostics = ["imaging", "lab", "vision", "audio", "psychological", "misc"]
organs = ["abdominal_inguinal_femoral_hernias", "ankle", "artery_and_vein", "back", "bone", "breast", "central_nervous_system", "cranial_nerve", "elbow_and_forearm", "endocrine", "esophageal", "foot", "hand_and_finger", "heart", "hip_and_thigh", "kidney", "knee_and_lower_leg", "male_repro", "muscles", "neck", "nose_and_sinus",  "osteomyelitis", "peripheral_nerves", "rectum_and_anus", "shoulder", "skin", "stomach_and_duodenal", "thyroid_and_parathyroid", "urinary_tract", "wrist"]
diseases = ["amputations", "amyotrophic_lateral_sclerosis", "chronic_fatigue","cold_injury", "diabetes_mellitus", "diabetic_peripheral_neuropathy", "fibromyalgia", "gynecological",  "hairy_cell_leukemia", "headaches", "hemic_and_lymphatic_leukemia", "hepatitis_cirrhosis_and_liver", "hiv", "hypertension", "infectious_diseases", "intestines_nonsurgical", "intestines_surgical", "loss_smell_taste", "multiple_sclerosis", "narcolepsy", "nondegenerative_arthritis", "nutritional_deficiencies", "parkinsons", "peritoneal_adhesions", "persian_gulf_afghanistan_infections", "prostate_cancer", "respiratory", "scars", "seizure_disorders_epilepsy", "sleep_apnea", "systemic_lupus_erythematosus", "tuberculosis"]. 

微调模型是使用以下架构构建的:

# Define the model class
class BioClinicalBERTClass(torch.nn.Module):
    def __init__(self, num_labels):
        super(BioClinicalBERTClass, self).__init__()
        self.bert_model = BertForSequenceClassification.from_pretrained("emilyalsentzer/Bio_ClinicalBERT", num_labels=num_labels)

    def forward(self, input_ids, attention_mask, token_type_ids):
        output = self.bert_model.bert(input_ids=input_ids, attention_mask=attention_mask, token_type_ids=token_type_ids)
        pooled_output = output.pooler_output
        logits = self.bert_model.classifier(pooled_output)
        return logits 

我正在构建一个多任务模型来结合5个微调模型。 我不确定使用具有单一输出的相同架构是否更合适 所有类别的层,或具有特定于任务的输出层的架构,如下所示:

class MultiTaskModel(torch.nn.Module):
    def __init__(self, num_specialties, num_clinical_summaries, num_diagnostics, num_organs, num_diseases):
        super(MultiTaskModel, self).__init__()
        self.shared_base = AutoModel.from_pretrained("emilyalsentzer/Bio_ClinicalBERT")

        # Task-specific output layers
        self.specialties_output = torch.nn.Linear(self.shared_base.config.hidden_size, num_specialties)
        self.clinical_summaries_output = torch.nn.Linear(self.shared_base.config.hidden_size, num_clinical_summaries)
        self.diagnostics_output = torch.nn.Linear(self.shared_base.config.hidden_size, num_diagnostics)
        self.organs_output = torch.nn.Linear(self.shared_base.config.hidden_size, num_organs)
        self.diseases_output = torch.nn.Linear(self.shared_base.config.hidden_size, num_diseases)

    def forward(self, input_ids, attention_mask, token_type_ids):
        shared_output = self.shared_base(input_ids=input_ids, attention_mask=attention_mask, token_type_ids=token_type_ids)
        pooled_output = shared_output.pooler_output

        specialties_logits = self.specialties_output(pooled_output)
        clinical_summaries_logits = self.clinical_summaries_output(pooled_output)
        diagnostics_logits = self.diagnostics_output(pooled_output)
        organs_logits = self.organs_output(pooled_output)
        diseases_logits = self.diseases_output(pooled_output)

        return specialties_logits, clinical_summaries_logits, diagnostics_logits, organs_logits, diseases_logits

我需要有关便捷架构的建议,以便利用单个模型利用 5 个经过训练的模型的微调知识对所有类别执行多标签分类。请提供有关其权重和偏差加载和使用的详细说明,以需要最少的微调,使其了解类别之间的相关性。模型是否应该对新模型做出同等贡献,或者它们对参数的影响是否应该基于预测类别标签的数量?


对于的多标签分类多任务 BERT 模型,具有特定于任务的输出层的架构是更好的选择。这种方法允许模型学习针对每个特定任务的专门表示,从而产生更好的性能。

以下是有关架构的详细说明,包括权重加载和利用预训练模型知识的考虑因素:

class MultiTaskModel(torch.nn.Module):
    def __init__(self, num_specialties, num_clinical_summaries, num_diagnostics, num_organs, num_diseases):
        super(MultiTaskModel, self).__init__()
        self.shared_base = AutoModel.from_pretrained("emilyalsentzer/Bio_ClinicalBERT")

        # 特定于任务的输出层
        self.specialties_output = torch.nn.Linear(self.shared_base.config.hidden_size, num_specialties)
        self.clinical_summaries_output = torch.nn.Linear(self.shared_base.config.hidden_size, num_clinical_summaries)
        self.diagnostics_output = torch.nn.Linear(self.shared_base.config.hidden_size, num_diagnostics)
        self.organs_output = torch.nn.Linear(self.shared_base.config.hidden_size, num_organs)
        self.diseases_output = torch.nn.Linear(self.shared_base.config.hidden_size, num_diseases)

    def forward(self, input_ids, attention_mask, token_type_ids):
        shared_output = self.shared_base(input_ids=input_ids, attention_mask=attention_mask, token_type_ids=token_type_ids)
        pooled_output = shared_output.pooler_output

        specialties_logits = self.specialties_output(pooled_output)
        clinical_summaries_logits = self.clinical_summaries_output(pooled_output)
        diagnostics_logits = self.diagnostics_output(pooled_output)
        organs_logits = self.organs_output(pooled_output)
        diseases_logits = self.diseases_output(pooled_output)

        return specialties_logits, clinical_summaries_logits, diagnostics_logits, organs_logits, diseases_logits

权重加载和使用预训练知识:

  1. 加载共享基础模型:
  2. 使用 AutoModel.from_pretrained("emilyalsentzer/Bio_ClinicalBERT") 初始化 self.shared_base 会加载 BioClinicalBERT 的权重。这为的多任务模型提供了良好的起点,因为它已经针对生物医学文本进行了预训练。

  3. 初始化特定于任务的层:

  4. 特定于任务的输出层( specialties_output clinical_summaries_output 等)将使用 PyTorch 中的默认初始化方法进行初始化。虽然这通常是一个合理的起点,但可以尝试使用不同的初始化技术来潜在地提高性能。

  5. 微调和冻结:

  6. 初始训练: 在训练的初始阶段,冻结共享基础模型的权重( self.shared_base )并仅训练特定于任务的输出层可能是有益的。这使模型能够首先学习将共享表示映射到其各自的输出空间,而不会显着改变共享表示本身。
  7. 解冻和微调: 在初始训练之后,解冻共享基础模型的权重并微调整个模型(包括共享基础和特定于任务的层)。这允许模型微调其对特定任务的表示,同时仍利用其预训练知识。

  8. 学习率:

  9. 考虑对共享基础模型使用较低的学习率,对特定于任务的层使用较高的学习率。这有助于防止对预训练权重进行过于剧烈的更新,同时仍允许特定于任务的层进行有效学习。可以使用 PyTorch 中的 torch.optim.lr_scheduler 来实现此目的。

利用预训练模型的贡献:

  • 预训练模型的贡献不应基于预测类别标签的数量。所有预训练模型都应平等地为共享基础模型 ( self.shared_base ) 做出贡献。这是因为共享基础模型的目标是捕获所有任务通用的底层表示。特定于任务的层随后学习如何专门化这些表示以用于其各自的任务,而不管每个任务的类别数量如何。

其他提示:

  • 损失函数: 由于正在处理多标签分类,因此请使用 torch.nn.BCEWithLogitsLoss (二元交叉熵与 sigmoid)作为的损失函数。此损失函数分别处理每个标签,并允许每个输入属于多个类别。
  • 评估指标: 考虑使用适合多标签分类的指标,例如精确率、召回率、F1 分数和 AUC(曲线下面积)。
  • 实验: 尝试使用不同的超参数设置(例如学习率、批量大小和训练时期)来找到模型的最佳配置。

通过遵循这些步骤,可以创建一个利用五个预训练模型的微调知识的多任务模型,并针对所有类别执行多标签分类。请记住,多任务学习是一个迭代过程,并且可能需要对模型架构和训练过程进行一些实验才能获得最佳结果。

标签:python,torch,bert-language-model,multitasking,multilabel-classification
From: 78785658

相关文章

  • Python 类型提示:自引用类型检查
    我认为静态类型确实会让我在Python中的生活更轻松,考虑到我通常使用C语言工作。我创建了一个像这样的类:classnode(object):"""properties,constructor,etc."""defadd_outneighbor(self,neighbor:node)->None:"""d......
  • Python用shp文件裁剪多个遥感影像的方法
      本文介绍基于Python中ArcPy模块,基于矢量数据范围,对大量栅格遥感影像加以批量裁剪掩膜的方法。  首先,话不多说,本文所需要的代码如下所示。#-*-coding:utf-8-*-"""CreatedonTueDec1320:07:482022@author:fkxxgis"""importarcpyfromarcpy.saimport*......
  • 以编程方式删除 Python 源中的类型提示
    我有一些为Python3.5编写的源代码,我想使其在Python3.4下可执行。我使用的3.5中唯一在3.4中不可用的功能是类型提示,因此我想编写一个脚本来完全删除这些功能。乍一看这似乎很容易,我决定编写一些正则表达式这样做,但后来我想到了一些边缘情况,我不确定如何解决像这样的......
  • Python 类型暗示​​一个充满 myclass 对象的双端队列
    使用Python3.6或更高版本,我想输入提示一个返回MyClass对象的函数myfunc我如何提示myqueue是一个deque|||充满MyClass对象?objects?fromcollectionsimportdequeglobal_queue=deque()classMyClass:passdefmyfunc(m......
  • python之名称空间和作用域(关键字:global和nonlocal的使用)
    文章目录前言1、名称空间和作用域1.1引言1.2名称空间1.2.1内置名称空间1.2.2全局名称空间1.2.3局部名称空间1.2.4名称空间的产生和销毁顺序1.3作用域1.3.1全局作用域1.3.2局部作用域1.3.3名字的查找顺序1.4关键字:global1.5关键字:nonlocal前言本篇文章......
  • 用于 isinstance() 检查的 dict_keys 的显式 python3 类型是什么?
    在Python3中,我应该使用什么类型来检查字典键是否属于它?>>>d={1:2}>>>type(d.keys())<class'dict_keys'>所以我很自然地尝试了这个:>>>isinstance(d.keys(),dict_keys)Traceback(mostrecentcalllast):File"<stdin>",......
  • 初学Python时需要认识清楚的几个概念:对象、函数、圆括号给、点取、方括号取
    这是我在自学Python的过程中自己挑选和提炼出来的几个重要的概念,之所以特意介绍这些概念,其中包含了我自己的思维方式和我对Python设计理念的认识,有其独特性和局限性。我希望这篇文章能够给喜爱Python的朋友们带来一些启发。1、对象(Object)对象是Python编程的基本单元。就像音是......
  • 如何接受文件或路径作为python中方法的参数
    我正在尝试编写一个方法,该方法将接受打开的文件myFile=open("myFile.txt")obj.writeTo(myFile)myFile.close()或带有路径的字符串obj.writeTo("myFile.txt")该方法的实现如下:defwriteTo(self,hessianFile):ifisinstance(hessianFile,file):pr......
  • Python,“pathlib.Path.open()”方法和内置函数“open()”不返回“typing.IO”的实例
    我读过一些其他答案,它们似乎与现实生活中发生的事情相矛盾。尝试以下操作:fromtypingimportIOfrompathlibimportPathexample_path=Path(r"D:\Example.txt")withexample_path.open("r")asf:print(isinstance(f,IO))withopen(example_path)a......
  • 【Dison夏令营 Day 28】用 Python 创建恐龙游戏
    谁没有玩过谷歌著名的“恐龙游戏”?也许每个人都玩过这个游戏。今天,在这篇文章中,我们将帮助你用Python开发一个恐龙游戏。本教程将深入讲解每一行代码,并提供参考资料。我们将尽力让读者详细、透彻地理解这个项目。Python版恐龙游戏的任务记录包括图片文档和Python资料......