我构建了 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
权重加载和使用预训练知识:
- 加载共享基础模型:
-
使用
AutoModel.from_pretrained("emilyalsentzer/Bio_ClinicalBERT")
初始化self.shared_base
会加载 BioClinicalBERT 的权重。这为的多任务模型提供了良好的起点,因为它已经针对生物医学文本进行了预训练。 -
初始化特定于任务的层:
-
特定于任务的输出层(
specialties_output
、clinical_summaries_output
等)将使用 PyTorch 中的默认初始化方法进行初始化。虽然这通常是一个合理的起点,但可以尝试使用不同的初始化技术来潜在地提高性能。 -
微调和冻结:
-
初始训练:
在训练的初始阶段,冻结共享基础模型的权重(
self.shared_base
)并仅训练特定于任务的输出层可能是有益的。这使模型能够首先学习将共享表示映射到其各自的输出空间,而不会显着改变共享表示本身。 -
解冻和微调: 在初始训练之后,解冻共享基础模型的权重并微调整个模型(包括共享基础和特定于任务的层)。这允许模型微调其对特定任务的表示,同时仍利用其预训练知识。
-
学习率:
-
考虑对共享基础模型使用较低的学习率,对特定于任务的层使用较高的学习率。这有助于防止对预训练权重进行过于剧烈的更新,同时仍允许特定于任务的层进行有效学习。可以使用 PyTorch 中的
torch.optim.lr_scheduler
来实现此目的。
利用预训练模型的贡献:
-
预训练模型的贡献不应基于预测类别标签的数量。所有预训练模型都应平等地为共享基础模型 (
self.shared_base
) 做出贡献。这是因为共享基础模型的目标是捕获所有任务通用的底层表示。特定于任务的层随后学习如何专门化这些表示以用于其各自的任务,而不管每个任务的类别数量如何。
其他提示:
-
损失函数:
由于正在处理多标签分类,因此请使用
torch.nn.BCEWithLogitsLoss
(二元交叉熵与 sigmoid)作为的损失函数。此损失函数分别处理每个标签,并允许每个输入属于多个类别。 - 评估指标: 考虑使用适合多标签分类的指标,例如精确率、召回率、F1 分数和 AUC(曲线下面积)。
- 实验: 尝试使用不同的超参数设置(例如学习率、批量大小和训练时期)来找到模型的最佳配置。
通过遵循这些步骤,可以创建一个利用五个预训练模型的微调知识的多任务模型,并针对所有类别执行多标签分类。请记住,多任务学习是一个迭代过程,并且可能需要对模型架构和训练过程进行一些实验才能获得最佳结果。
标签:python,torch,bert-language-model,multitasking,multilabel-classification From: 78785658