train_data = load_json('dataset/train.json')
dev_data = load_json('dataset/dev.json')
test_data = load_json('dataset/test.json')

train_dataset = MedicalNERDataset(train_data, tokenizer, label2id)
dev_dataset = MedicalNERDataset(dev_data, tokenizer, label2id)
test_dataset = MedicalNERDataset(test_data, tokenizer, label2id)

train_loader = DataLoader(train_dataset, batch_size=8, shuffle=True)
dev_loader = DataLoader(dev_dataset, batch_size=8)
test_loader = DataLoader(test_dataset, batch_size=8)import torch
from sklearn.metrics import classification_report

def train_model(model, dataloader, optimizer, device):
    model.train()
    total_loss = 0
    for batch in dataloader:
        inputs, labels = batch
        input_ids, attention_mask = inputs
        input_ids = input_ids.to(device)
        attention_mask = attention_mask.to(device)
        labels = labels.to(device)
        
        optimizer.zero_grad()
        loss = model(input_ids, attention_mask, labels)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
    return total_loss / len(dataloader)

def evaluate_model(model, dataloader, device):
    model.eval()
    all_preds = []
    all_trues = []
    with torch.no_grad():
        for i, batch in enumerate(dataloader):
            inputs, labels = batch
            input_ids, attention_mask = inputs
            input_ids = input_ids.to(device)
            attention_mask = attention_mask.to(device)
            labels = labels.to(device)

            preds = model(input_ids, attention_mask)

            for pred, label, mask in zip(preds, labels, attention_mask):
                active_indices = mask.bool()
                filtered_pred = [p for p, m in zip(pred, active_indices) if m]
                filtered_label = [l.item() for l, m in zip(label, active_indices) if m]

                assert len(filtered_pred) == len(filtered_label), \
                    f"Length mismatch: pred={len(filtered_pred)}, label={len(filtered_label)}"

                all_preds.extend(filtered_pred)
                all_trues.extend(filtered_label)
    return all_preds, all_trues

def get_classification_report(predictions, true_labels):
    y_true = [id2label[label] for label in true_labels]
    y_pred = [id2label[label] for label in predictions]

    report_dict = classification_report(y_true, y_pred, target_names=label2id.keys(), digits=4, output_dict=True)
    return report_dict

def train_and_evaluate_model(model, model_name, train_loader, dev_loader, optimizer, device, num_epochs=5):
    """训练并评估模型"""
    performance_records[model_name] = []
    
    for epoch in range(num_epochs):
        train_loss = train_model(model, train_loader, optimizer, device)
        preds, trues = evaluate_model(model, dev_loader, device)
        report = get_classification_report(preds, trues)
        performance_records[model_name].append(report['weighted avg'])
        
        print(f"Epoch {epoch + 1}/{num_epochs} - Loss: {train_loss:.4f}")torch.save(model_bert_crf.state_dict(), 'bert_crf_model.pth')
torch.save(model_lstm_crf.state_dict(), 'bilstm_crf_model.pth')
torch.save(model_lstm_attn_crf.state_dict(), 'bilstm_attn_crf_model.pth')
print("Models saved successfully!")三个模型训练和评估时是否使用测试集数据，如未使用则用测试集数据对三个模型进行评估并可视化对比