(11)清空 GPU 缓存,保存处理后的数据,并列出当前工作目录下的文件。具体实现代码如下所示。
# 清空 GPU 缓存
torch.cuda.empty_cache()
# 保存我们的数据
corpus_hidden.set_format(type="pandas")
# 将标签数据添加到数据框中
def label_int2str(row):
return corpus["train"].features["label"].int2str(row)
# 从训练数据集中提取数据并添加标签名称列,然后保存到 pickle 文件
ldf = corpus_hidden["train"][:]
ldf["label_name"] = ldf["label"].apply(label_int2str)
ldf.to_pickle('training.df')
# 从验证数据集中提取数据并添加标签名称列,然后保存到 pickle 文件
ldf = corpus_hidden["validation"][:]
ldf["label_name"] = ldf["label"].apply(label_int2str)
ldf.to_pickle('validation.df')
# 列出当前工作目录下的文件
!ls /working/
对上述代码的具体说明如下:
- torch.cuda.empty_cache():这行代码用于清空 GPU 缓存,以释放显存资源。这在处理大型深度学习模型时很有用,可以避免显存不足的问题。
- corpus_hidden.set_format(type="pandas"):这行代码将数据集的格式设置为 Pandas 格式,以便后续操作。
- label_int2str(row) 函数:这是一个自定义函数,用于将整数形式的标签转换为字符串形式的标签名称。
- 提取并保存训练数据和验证数据:代码使用 corpus_hidden 数据集中的 "train" 和 "validation" 部分,提取数据并添加标签名称列,然后将数据保存为 pickle 文件('training.df' 和 'validation.df')。
- !ls /kaggle/working/:这行代码用于列出当前工作目录下的文件,以检查保存的 pickle 文件是否成功。
执行后会输出:
huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...
To disable this warning, you can either:
- Avoid using `tokenizers` before the fork if possible
- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)
__notebook__.ipynb training.df validation.df
(12)加载隐藏状态数据,提取标签和标签名称,然后将唯一标签的名称存储在列表中。具体实现代码如下所示。
import pandas as pd
import pickle
# 加载隐藏状态数据
# training = pd.read_pickle('/kaggle/input/hiddenstatedata/training.df')
# validation = pd.read_pickle('/kaggle/input/hiddenstatedata/validation.df')
training = pd.read_pickle('training.df')
validation = pd.read_pickle('validation.df')
training.head()
# 提取标签和标签名称
labels = training[['label','label_name']]
label = []
for i in labels.label.unique():
label.append(labels[labels['label'] == i].iloc[[0]]['label_name'].values[0])
label
对上述代码的具体说明如下:
- pd.read_pickle('training.df') 和 pd.read_pickle('validation.df'):这两行代码用于从 pickle 文件中加载训练和验证数据的隐藏状态。数据从之前保存的 pickle 文件中加载到 Pandas 数据帧中。
- labels 数据帧:这一行代码从训练数据中提取了包含 "label" 和 "label_name" 列的数据帧。
- 循环提取唯一标签的名称:在循环中,代码提取了训练数据中唯一标签的名称,并将这些名称存储在名为 "label" 的列表中。
执行后会输出:
['debt collection',
'other financial service',
'student loan',
'prepaid card',
'credit reporting',
'mortgage',
'payday loan',
'credit card',
'bank account or service',
'money transfers',
'virtual currency']
(13)准备机器学习模型所需的训练和验证数据,包括隐藏状态特征和标签。具体实现代码如下所示。
import numpy as np
# 将训练数据集中的隐藏状态转换为 NumPy 数组
X_train = np.stack(training['hidden_state'])
# 将验证数据集中的隐藏状态转换为 NumPy 数组
X_valid = np.stack(validation["hidden_state"])
# 将训练数据集中的标签转换为 NumPy 数组
y_train = np.array(training["label"])
# 将验证数据集中的标签转换为 NumPy 数组
y_valid = np.array(validation["label"])
# 打印训练数据集和验证数据集的形状
print(f'Training Dataset: {X_train.shape}')
print(f'Validation Dataset {X_valid.shape}')
执行后会输出:
Training Dataset: (26100, 768)
Validation Dataset (2901, 768)
(14)使用Scikit-Learn库中的Logistic Regression(逻辑回归)模型来训练一个文本分类模型。具体实现代码如下所示。
from sklearn.linear_model import LogisticRegression as LR
# 创建逻辑回归分类器,设置最大迭代次数(max_iter)为2000以确保模型收敛
lr_clf = LR(max_iter=2000)
# 使用训练数据集(X_train和y_train)训练逻辑回归模型
lr_clf.fit(X_train, y_train)
执行后会输出:
CPU times: user 8min 59s, sys: 39.2 s, total: 9min 38s
Wall time: 5min 5s
LogisticRegression(max_iter=2000)
(15)评估逻辑回归模型在训练数据集和验证数据集上的分类准确度,以了解模型的性能如何。具体实现代码如下所示。
y_preds_train = lr_clf.predict(X_train)
y_preds_valid = lr_clf.predict(X_valid)
print('LogisticRegression:')
print(f'training accuracy: {round(lr_clf.score(X_train, y_train),3)}')
print(f'validation accuracy: {round(lr_clf.score(X_valid, y_valid),3)}')
执行后会输出:
LogisticRegression:
training accuracy: 0.807
validation accuracy: 0.772
(16)保存训练好的逻辑回归模型,然后可视化验证数据集上的混淆矩阵。具体实现代码如下所示。
import joblib
# 保存训练好的逻辑回归模型到文件
filename = 'classifier.joblib.pkl'
_ = joblib.dump(lr_clf, filename, compress=9)
# 加载 sklearn 模型
# lr_clf = joblib.load('/kaggle/input/hiddenstatedata/' + filename)
# lr_clf
import matplotlib.pyplot as plt
from sklearn.metrics import ConfusionMatrixDisplay, confusion_matrix
# 定义函数用于绘制混淆矩阵
def plot_confusion_matrix(y_model, y_true, labels):
cm = confusion_matrix(y_true, y_model, normalize='true') # 计算混淆矩阵并进行标准化
fig, ax = plt.subplots(figsize=(8, 8))
disp = ConfusionMatrixDisplay(confusion_matrix=cm.round(2).copy(), display_labels=labels)
disp.plot(ax=ax, colorbar=False) # 绘制混淆矩阵图
plt.title("Confusion matrix")
plt.xticks(rotation=90) # 旋转X轴标签以更好地显示
plt.tight_layout()
plt.show()
labels = list(training.label_name.value_counts().index) # 获取标签类别
# 绘制验证数据集上的混淆矩阵
plot_confusion_matrix(y_preds_valid, y_valid, labels)
在上述代码中,首先将训练好的逻辑回归模型保存到名为classifier.joblib.pkl的文件中,使用了压缩等级9来减小文件大小。然后调用自定义的函数plot_confusion_matrix来绘制验证数据集上的混淆矩阵。混淆矩阵用于可视化模型在不同类别上的分类性能,帮助了解模型的性能如何。执行效果如图10-35所示。
图10-35 模型在不同类别上的分类性能
(17)清空PyTorch的GPU缓存,并将数据格式更改为PyTorch张量。具体实现代码如下所示。
# 清空GPU缓存
torch.cuda.empty_cache()
# 将数据格式更改为PyTorch张量
corpus_tokenised.set_format("torch",
columns=["input_ids", "attention_mask", "label"])
corpus_tokenised
执行后会输出:
DatasetDict({
train: Dataset({
features: ['text', 'label', '__index_level_0__', 'input_ids', 'attention_mask'],
num_rows: 26100
})
validation: Dataset({
features: ['text', 'label', '__index_level_0__', 'input_ids', 'attention_mask'],
num_rows: 2901
})
})
(18)导入库Hugging Face Transformers中的相关模块,并初始化了一个预训练的文本分类模型。具体实现代码如下所示。
from transformers import AutoModelForSequenceClassification
import torch
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model_ckpt = "distilbert-base-uncased"
model = (AutoModelForSequenceClassification
.from_pretrained(model_ckpt,
num_labels=len(labels))
.to(device))
from sklearn.metrics import accuracy_score, f1_score
def compute_metrics(pred):
labels = pred.label_ids
preds = pred.predictions.argmax(-1)
f1 = f1_score(labels, preds, average="weighted")
acc = accuracy_score(labels, preds)
return {"accuracy": acc, "f1": f1}
(19)使用库Hugging Face Transformers中的Trainer和TrainingArguments模块进行模型训练。具体实现代码如下所示。
from transformers import Trainer, TrainingArguments
# 定义批次大小
bs = 16
# 定义模型名称
model_name = f"{model_ckpt}-finetuned-financial"
# 获取标签列表
labels = corpus_tokenised["train"].features["label"].names
# 训练参数配置
training_args = TrainingArguments(output_dir=model_name, # 输出目录,用于保存模型和训练日志
num_train_epochs=3, # 训练的轮数
learning_rate=2e-5, # 模型的学习率
per_device_train_batch_size=bs, # 训练时的批次大小
per_device_eval_batch_size=bs, # 验证时的批次大小
weight_decay=0.01, # 权重衰减
evaluation_strategy="epoch", # 评估策略,每个epoch进行一次评估
disable_tqdm=False, # 是否禁用进度条
report_to="none", # 报告结果的方式,这里设置为不报告
push_to_hub=False, # 是否上传到模型Hub
log_level="error") # 日志级别,这里设置为错误级别
from transformers import Trainer
# 初始化Trainer,用于训练和评估模型
trainer = Trainer(model=model, # 模型
args=training_args, # 训练参数(上面定义的)
compute_metrics=compute_metrics, # 计算指标的函数
train_dataset=corpus_tokenised["train"], # 训练数据集
eval_dataset=corpus_tokenised["validation"], # 验证数据集
tokenizer=tokenizer) # 分词器
# 开始训练
trainer.train()
# 保存训练后的模型
trainer.save_model()
执行后会输出:
[4896/4896 37:20, Epoch 3/3]
Epoch Training Loss Validation Loss Accuracy F1
1 0.535000 0.528666 0.842468 0.839433
2 0.410300 0.483131 0.858669 0.855979
3 0.312500 0.477747 0.866942 0.864213
CPU times: user 36min 55s, sys: 16.5 s, total: 37min 12s
Wall time: 37min 21s
(20)在验证数据集上进行模型预测,具体实现代码如下所示。
pred_output = trainer.predict(corpus_tokenised["validation"])
pred_output
执行后会输出:
[182/182 00:26]
PredictionOutput(predictions=array([[ 0.4898075 , -1.1539025 , -2.4000468 , ..., 2.664791 ,
-1.7696137 , -1.85924 ],
[ 5.524978 , 1.4433606 , -1.2144918 , ..., -2.0602236 ,
-2.2785227 , -3.1501598 ],
[-0.99464035, 1.410322 , 5.1908035 , ..., -2.1883903 ,
-1.5084958 , -3.9436107 ],
...,
[ 0.8029568 , 2.751484 , -1.0246688 , ..., -2.6813054 ,
0.32632264, -3.8141603 ],
[ 0.27522528, -1.2025931 , -0.14139701, ..., -2.684458 ,
-1.0188793 , -3.16859 ],
[-0.17902231, -1.83018 , -0.8901656 , ..., -3.2526188 ,
0.6185259 , -3.5121055 ]], dtype=float32), label_ids=array([4, 1, 2, ..., 0, 5, 5]), metrics={'test_loss': 0.47774738073349, 'test_accuracy': 0.8669424336435712, 'test_f1': 0.8642125632561599, 'test_runtime': 26.9558, 'test_samples_per_second': 107.621, 'test_steps_per_second': 6.752})
(21)打印输出模型的预测输出和相应的形状,具体实现代码如下所示。
print(f'Output Predition: {pred_output.predictions.shape}')
print(pred_output.predictions)
执行后会输出:
Output Predition: (2901, 11)
[[ 0.4898075 -1.1539025 -2.4000468 ... 2.664791 -1.7696137
-1.85924 ]
[ 5.524978 1.4433606 -1.2144918 ... -2.0602236 -2.2785227
-3.1501598 ]
[-0.99464035 1.410322 5.1908035 ... -2.1883903 -1.5084958
-3.9436107 ]
...
[ 0.8029568 2.751484 -1.0246688 ... -2.6813054 0.32632264
-3.8141603 ]
[ 0.27522528 -1.2025931 -0.14139701 ... -2.684458 -1.0188793
-3.16859 ]
[-0.17902231 -1.83018 -0.8901656 ... -3.2526188 0.6185259
-3.5121055 ]]
(22)解码模型的预测结果并打印出来,即打印模型对验证数据集中每个样本的最终预测类别。具体实现代码如下所示。
import numpy as np
# Decode the predictions greedily using argmax (highest value of all classes)
y_preds = np.argmax(pred_output.predictions,axis=1)
print(f'Output Prediction:{y_preds.shape}')
print(f'Predictions: {y_preds}')
执行后会输出:
Output Prediction:(2901,)
Predictions: [4 0 2 ... 1 5 5]
(23)绘制混淆矩阵的函数调用,展示模型的预测结果与真实标签之间的对比。具体实现代码如下所示。
plot_confusion_matrix(y_preds,y_valid,labels)
执行后会根据 y_preds 和 y_valid 的值绘制混淆矩阵,用来显示模型的性能表现,特别是在不同类别上的表现情况。执行效果如图10-36所示,
图10-36 模型的性能表现混淆矩阵
本篇内容已经完结!
(10-3-04-01)银行消费者投诉处理模型-CSDN博客