创建一个名为“羲和小医生”的医学类问答机器人,我们使用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文件后,将弹出一个窗口,用户可以在窗口中输入问题和补充信息,点击“查询”按钮后,程序将显示模型生成的回答。