Bootstrap

羲和小医生0.1

创建一个名为“羲和小医生”的医学类问答机器人,我们使用Python和一些常用的库来实现。这个项目将包括以下几个部分:
数据处理:准备和处理训练数据。
模型训练:使用bert-base-chinese模型进行微调。
GUI开发:使用tkinter库创建图形用户界面。
项目结构

羲和小医生/
│
├── 羲和小医生.py
├── README.md
└── data/
    └── train_data.json

README.md

# 羲和小医生

这是一个基于BERT的医学类问答机器人,旨在帮助用户获取医学相关问题的解答。本项目使用`bert-base-chinese`模型进行微调,并通过`tkinter`库创建了一个简单的图形用户界面(GUI)。

## 目录结构

- `羲和小医生.py`: 主程序文件,包含数据处理、模型训练和GUI开发。
- `README.md`: 项目说明文档。
- `data/`: 存放训练数据的目录。
  - `train_data.json`: 训练数据集。

## 运行环境

- Python 3.7+
- PyTorch 1.7+
- Transformers 4.0+
- Tkinter

## 安装依赖
pip install torch transformers
使用方法
将训练数据集放入data/train_data.json。
运行羲和小医生.py。
python 羲和小医生.py
训练数据格式
训练数据集应为JSON格式,示例如下:
[
    {
        "instruction": "大肠癌能治愈吗?有什么好的治疗方法?",
        "input": "无",
        "output": "根据你的描述属于恶性肿瘤有关,需要增加营养补充维生素微量元素,易消化易吸收饮食,保持心情舒畅注意休息,需要综合治疗放化疗中药调理生物靶向治疗。",
        "history": null
    },
    {
        "instruction": "外阴脂肪瘤怎样治疗",
        "input": "患者 女50岁,外阴一侧有一个3*5厘米瘤子,约六七年了,以前小,不疼不痒,请问怎样治疗、",
        "output": "你说的症状建议去外科就诊,应该通过手术切除治疗配合抗消炎的药物治疗,平时饮食以清淡为主忌辛辣刺激食物,注意卫生。",
        "history": null
    }
]
作者
作者:yehaiwz
邮箱:[email protected]

羲和小医生.py

import json
import torch
from transformers import BertTokenizer, BertForSequenceClassification, Trainer, TrainingArguments
import tkinter as tk
from tkinter import messagebox

# 加载数据
def load_data(file_path):
    with open(file_path, 'r', encoding='utf-8') as f:
        data = json.load(f)
    return data

# 数据预处理
def preprocess_data(data, tokenizer, max_length=128):
    inputs = []
    labels = []
    for item in data:
        instruction = item['instruction']
        input_text = item['input']
        output = item['output']
        text = f"{instruction} {input_text}"
        inputs.append(text)
        labels.append(output)
    encodings = tokenizer(inputs, truncation=True, padding=True, max_length=max_length, return_tensors='pt')
    return encodings, labels

# 自定义数据集
class MedicalDataset(torch.utils.data.Dataset):
    def __init__(self, encodings, labels):
        self.encodings = encodings
        self.labels = labels

    def __getitem__(self, idx):
        item = {key: val[idx] for key, val in self.encodings.items()}
        item['labels'] = self.labels[idx]
        return item

    def __len__(self):
        return len(self.labels)

# 模型训练
def train_model(data, model, tokenizer, output_dir):
    encodings, labels = preprocess_data(data, tokenizer)
    dataset = MedicalDataset(encodings, labels)
    
    training_args = TrainingArguments(
        output_dir=output_dir,
        num_train_epochs=3,
        per_device_train_batch_size=8,
        warmup_steps=500,
        weight_decay=0.01,
        logging_dir='./logs',
        logging_steps=10,
    )
    
    trainer = Trainer(
        model=model,
        args=training_args,
        train_dataset=dataset,
    )
    
    trainer.train()

# 模型推理
def predict(model, tokenizer, instruction, input_text):
    text = f"{instruction} {input_text}"
    inputs = tokenizer(text, return_tensors='pt')
    outputs = model(**inputs)
    logits = outputs.logits
    predicted_label = torch.argmax(logits, dim=-1).item()
    return predicted_label

# GUI
def create_gui(model, tokenizer):
    def on_query():
        instruction = entry_instruction.get()
        input_text = entry_input.get() if var_input.get() == 1 else "无"
        output = predict(model, tokenizer, instruction, input_text)
        entry_output.delete(0, tk.END)
        entry_output.insert(0, output)

    root = tk.Tk()
    root.title("羲和小医生")

    # 问题输入框
    label_instruction = tk.Label(root, text="问题:")
    label_instruction.grid(row=0, column=0, padx=10, pady=10)
    entry_instruction = tk.Entry(root, width=50)
    entry_instruction.grid(row=0, column=1, padx=10, pady=10)

    # 补充输入框
    var_input = tk.IntVar()
    check_input = tk.Checkbutton(root, text="有补充", variable=var_input)
    check_input.grid(row=1, column=0, padx=10, pady=10)
    entry_input = tk.Entry(root, width=50)
    entry_input.grid(row=1, column=1, padx=10, pady=10)

    # 查询按钮
    button_query = tk.Button(root, text="查询", command=on_query)
    button_query.grid(row=2, column=0, columnspan=2, pady=10)

    # 输出框
    label_output = tk.Label(root, text="羲和回答:")
    label_output.grid(row=3, column=0, padx=10, pady=10)
    entry_output = tk.Entry(root, width=50)
    entry_output.grid(row=3, column=1, padx=10, pady=10)

    root.mainloop()

# 主函数
def main():
    data_path = 'data/train_data.json'
    output_dir = 'output'

    data = load_data(data_path)
    tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
    model = BertForSequenceClassification.from_pretrained('bert-base-chinese', num_labels=1)

    train_model(data, model, tokenizer, output_dir)
    create_gui(model, tokenizer)

if __name__ == "__main__":
    main()

说明
数据加载和预处理:load_data函数读取JSON文件中的数据,preprocess_data函数对数据进行预处理,将其转换为模型可以接受的格式。
自定义数据集:MedicalDataset类用于封装预处理后的数据。
模型训练:train_model函数使用Trainer类进行模型训练。
模型推理:predict函数用于根据输入的问题和补充信息生成回答。
GUI开发:create_gui函数使用tkinter库创建图形用户界面,包括输入框、按钮和输出框。
运行羲和小医生.py文件后,将弹出一个窗口,用户可以在窗口中输入问题和补充信息,点击“查询”按钮后,程序将显示模型生成的回答。

;