我构建并微调了 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 初始化: 已经为每个单独的任务微调了 BioClinicalBERT 模型。利用这些经过训练的权重来初始化的多任务模型至关重要。可以通过以下方式执行此操作:
```python # 加载预训练模型 pretrained_specialties_model = BioClinicalBERTClass(num_specialties) pretrained_specialties_model.load_state_dict(torch.load("path_to_specialties_model.pth"))
# 初始化多任务模型中的专科层 multitask_model.specialties_output.weight = pretrained_specialties_model.bert_model.classifier.weight multitask_model.specialties_output.bias = pretrained_specialties_model.bert_model.classifier.bias
# 对其他任务(临床摘要、诊断、器官、疾病)重复上述步骤 ```
-
冻结共享层(可选): 在训练的初始阶段,考虑冻结共享的“BioClinicalBERT”层的权重,只训练特定于任务的输出层。这将允许模型适应新的输出结构,同时保留其对医学语言理解的预先训练的知识。完成几轮训练后,可以解冻共享层,并针对所有权重对模型进行微调,以实现最佳性能。
-
加权损失函数: 由于的任务具有不同的标签空间大小,因此在计算总损失期间对每个任务的损失应用权重非常重要。这可以防止模型偏向于主导损失函数的标签较多的任务。可以尝试以下加权方案:
-
反向频率加权: 根据每个任务中标签的倒频率对损失进行加权,从而更加重视数据集中较不频繁的标签。
- 基于性能的加权: 根据每个任务在验证集上的性能动态调整权重,在表现较差的任务上给予更多重视。
先前模型的影响
所有五个经过训练的模型都应该为新的多任务模型做出贡献,但是它们的影响不一定要相等。允许模型在训练过程中学习适当的权重非常重要。这就是加权损失函数发挥作用的地方。通过根据性能或标签频率调整损失贡献,模型可以决定在多大程度上依赖每个先前训练的模型来进行最终预测。
其他技巧
- 学习率调度: 在训练过程中使用学习率调度技术(例如,余弦退火或逐步衰减)可以帮助模型收敛到更优的解。
- 提前停止: 根据验证集上的性能监控模型性能,并在性能开始下降时停止训练,以防止过拟合。
- 实验: 尝试使用不同的损失加权方案、学习率和训练轮数,以找到适合特定数据集和任务的最佳组合。
请记住,构建有效的多任务学习模型需要进行实验和迭代。通过遵循上述准则并尝试不同的策略,可以开发出在所有五个医学文本标记任务中均具有出色性能的模型。
标签:python,pytorch,bert-language-model,multitasking,multilabel-classification From: 78784412