import pandas as pd import torch from sklearn.model_selection import train_test_split from sklearn.preprocessing import LabelEncoder from torch.utils.data import Dataset, DataLoader from torch.utils.tensorboard import SummaryWriter from transformers import BertTokenizer, BertForSequenceClassification, AdamW # 训练模型 device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 加载数据 data = pd.read_csv('simplifyweibo_5_moods.csv') # 获取text和label texts = data['text'].tolist() labels = data['label'].tolist() # 将本文标签转换为数值标签 label_encoder = LabelEncoder() labels = label_encoder.fit_transform(labels) # 划分训练集和测试集 train_texts, val_texts, train_labels, val_labels = train_test_split(texts, labels, test_size=0.2, random_state=42) # 加载BERT的分词器 tokenizer = BertTokenizer.from_pretrained('./bert_localpath/') # 对文本进行编码 train_encodings = tokenizer(train_texts, truncation=True, padding=True, max_length=128) val_encodings = tokenizer(val_texts, truncation=True, padding=True, max_length=128) # 创建PyTorch数据集 class WeiboDataset(Dataset): def __init__(self, encodings, labels): self.encodings = encodings self.labels = labels def __getitem__(self, idx): item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()} item['labels'] = torch.tensor(self.labels[idx]) return item def __len__(self): return len(self.labels) train_dataset = WeiboDataset(train_encodings, train_labels) val_dataset = WeiboDataset(val_encodings, val_labels) # 加载BERT模型,设置输出维度为类别数 num_classes = len(label_encoder.classes_) model = BertForSequenceClassification.from_pretrained('./bert_localpath', num_labels=num_classes).to(device) # 创建DataLoader train_dataloader = DataLoader(train_dataset, batch_size=16, shuffle=True) val_dataloader = DataLoader(val_dataset, batch_size=16, shuffle=True) # 定义优化器 optimizer = AdamW(model.parameters(), lr=2e-5) # 创建TensorBoard的SummmaryWriter writer = SummaryWriter('./logs') epochs = 3 for epoch in r
时间: 2025-07-05 15:47:54 浏览: 13
<think>好的,我现在需要帮助用户解决如何使用PyTorch和BERT进行中文情感分类的问题。用户希望得到完整的代码示例,包括数据预处理、模型加载、训练过程和TensorBoard日志记录。首先,我需要回忆相关的知识,确保自己了解BERT模型的基本结构以及如何在PyTorch中微调它。
首先,数据预处理部分。中文文本处理可能需要分词,但BERT有自带的tokenizer,特别是中文BERT模型,比如BERT-Base-Chinese。所以应该使用BertTokenizer来处理文本,将文本转换为input_ids、attention_mask等。数据集的格式通常是CSV或者TSV,包含文本和标签两列。用户可能需要一个示例的数据结构,比如读取CSV文件,创建Dataset类,然后使用DataLoader加载。
接下来是模型加载。用户提到要加载预训练的BERT模型,并适应分类任务。在Hugging Face的transformers库中,可以使用BertForSequenceClassification,并指定num_labels参数,二分类的话就是2。这里需要导入正确的模型和配置,可能需要设置from_pretrained方法,指定模型名称,比如'bert-base-chinese'。
然后是训练过程。需要设置训练循环,包括优化器(比如AdamW)、学习率调度器(如get_linear_schedule_with_warmup)、损失函数(交叉熵损失)。要注意的是,BERT模型通常需要较大的batch size,但根据用户的实际数据可能调整。训练过程中需要将数据移动到GPU上,如果有的话,同时记录损失和准确率到TensorBoard。
关于TensorBoard日志记录,需要使用torch.utils.tensorboard的SummaryWriter,在训练过程中写入损失和准确率等指标,可能还需要记录计算图。
现在需要考虑代码的结构,可能需要分几个部分:导入库、数据预处理、模型定义、训练函数、评估函数、主函数。同时,用户可能需要参数设置,比如epochs、batch_size、learning_rate等。
可能的陷阱包括tokenizer的使用是否正确,比如最大长度、padding和truncation的设置。另外,数据加载器的shuffle设置是否正确,尤其是在训练和验证集之间。还有,模型在训练模式下的dropout和评估模式下的不同行为。
需要确保代码示例的完整性,比如包括如何准备数据集,定义自定义Dataset类,处理数据加载,训练循环中的前向和后向传播,梯度裁剪,以及模型的保存和加载。
此外,用户可能需要了解如何划分数据集为训练集和验证集,使用train_test_split或者其他方法。数据增强可能不在这个示例的范围内,但如果有余力可以提到。
最后,确保代码能够运行,可能需要测试一下,但由于无法实际执行代码,只能依赖文档和常见实践。同时,需要引用用户提供的引用,引用[1]和引用[2]是关于模型加载和推理脚本的示例,应该整合到回答中,比如在模型加载部分引用[1],在推理部分引用[2]。
总结步骤:
1. 导入必要的库(transformers、torch、pandas、Dataset等)
2. 数据预处理:读取数据,创建Dataset,使用tokenizer编码,DataLoader
3. 模型加载:BertForSequenceClassification.from_pretrained,引用[1]
4. 训练配置:优化器、调度器、损失函数
5. 训练循环:迭代epoch,记录损失和准确率到TensorBoard
6. 评估和保存模型
7. 提供推理示例,引用[2]
8. 生成相关问题
需要检查代码是否符合PyTorch的最佳实践,比如使用with torch.no_grad()在评估阶段,梯度清零,模型保存为.pt文件等。
可能还需要处理标签的格式,确保是整数类型,比如0和1,而不是字符串。数据预处理部分可能需要将标签列转换为数值类型。
另外,注意设备管理,自动检测是否有可用的GPU,使用device = 'cuda' if torch.cuda.is_available() else 'cpu'。
现在,将这些思考整合成一个结构化的回答,确保每个部分都涵盖用户的需求,并且代码示例正确无误。</think>以下是一个基于PyTorch和BERT的中文情感分类完整实现方案,包含数据预处理、模型加载、训练过程和TensorBoard日志记录:
### 一、环境准备
```python
import torch
from torch.utils.data import Dataset, DataLoader
from transformers import BertTokenizer, BertForSequenceClassification, AdamW
from sklearn.model_selection import train_test_split
import pandas as pd
from torch.utils.tensorboard import SummaryWriter
```
### 二、数据预处理
```python
class SentimentDataset(Dataset):
def __init__(self, texts, labels, tokenizer, max_len=128):
self.texts = texts
self.labels = labels
self.tokenizer = tokenizer
self.max_len = max_len
def __len__(self):
return len(self.texts)
def __getitem__(self, idx):
text = str(self.texts[idx])
encoding = self.tokenizer.encode_plus(
text,
add_special_tokens=True,
max_length=self.max_len,
padding='max_length',
truncation=True,
return_tensors='pt',
)
return {
'input_ids': encoding['input_ids'].flatten(),
'attention_mask': encoding['attention_mask'].flatten(),
'labels': torch.tensor(self.labels[idx], dtype=torch.long)
}
# 示例数据加载(替换为真实数据)
df = pd.read_csv('data.csv') # 包含text和label两列
train_df, val_df = train_test_split(df, test_size=0.2)
tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
```
### 三、模型加载
```python
model = BertForSequenceClassification.from_pretrained(
'bert-base-chinese',
num_labels=2 # 二分类任务配置[^1]
)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = model.to(device)
```
### 四、训练配置
```python
BATCH_SIZE = 16
EPOCHS = 3
LEARNING_RATE = 2e-5
train_loader = DataLoader(
SentimentDataset(train_df.text.values, train_df.label.values, tokenizer),
batch_size=BATCH_SIZE,
shuffle=True
)
val_loader = DataLoader(
SentimentDataset(val_df.text.values, val_df.label.values, tokenizer),
batch_size=BATCH_SIZE
)
optimizer = AdamW(model.parameters(), lr=LEARNING_RATE)
total_steps = len(train_loader) * EPOCHS
```
### 五、训练过程(含TensorBoard日志)
```python
writer = SummaryWriter('logs/bert-sentiment')
for epoch in range(EPOCHS):
model.train()
total_loss = 0
for batch in train_loader:
optimizer.zero_grad()
inputs = {k: v.to(device) for k, v in batch.items()}
outputs = model(**inputs)
loss = outputs.loss
loss.backward()
optimizer.step()
total_loss += loss.item()
# 记录训练指标
avg_train_loss = total_loss / len(train_loader)
writer.add_scalar('Loss/train', avg_train_loss, epoch)
# 验证过程
model.eval()
correct = 0
total = 0
with torch.no_grad():
for batch in val_loader:
inputs = {k: v.to(device) for k, v in batch.items()}
outputs = model(**inputs)
_, predicted = torch.max(outputs.logits, 1)
total += inputs['labels'].size(0)
correct += (predicted == inputs['labels']).sum().item()
val_acc = correct / total
writer.add_scalar('Accuracy/val', val_acc, epoch)
print(f'Epoch {epoch+1}/{EPOCHS} | Train Loss: {avg_train_loss:.4f} | Val Acc: {val_acc:.4f}')
writer.close()
torch.save(model.state_dict(), 'bert_sentiment.pt')
```
### 六、推理示例
```python
def predict(text, model, tokenizer, device='cuda'):
model.eval()
encoding = tokenizer.encode_plus(
text,
max_length=128,
padding='max_length',
truncation=True,
return_tensors='pt'
)
inputs = {k: v.to(device) for k, v in encoding.items()}
with torch.no_grad():
outputs = model(**inputs)
return torch.softmax(outputs.logits, dim=1).cpu().numpy()
# 使用示例(参考[^2]实现)
text = "这家餐厅的菜品非常美味,服务也很周到!"
prediction = predict(text, model, tokenizer)
print(f"正面概率: {prediction[0][1]:.4f}")
```
阅读全文
相关推荐


















