news 2026/7/13 16:31:40

Python实战:基于Transformer的新闻主题分类模型构建、评估与云端部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python实战:基于Transformer的新闻主题分类模型构建、评估与云端部署

1. 为什么选择Transformer做新闻分类?

新闻文本分类是自然语言处理中的经典任务。过去大家常用RNN、CNN这些传统神经网络,但自从Transformer横空出世,局面就完全改变了。我第一次用Transformer做分类任务时,准确率直接比LSTM提升了8个百分点,当时就惊掉了下巴。

Transformer的核心优势在于它的注意力机制。想象你在读新闻时,不会平均关注每个字,而是会重点看关键词。比如"央行宣布降准"这句话,"央行"和"降准"才是重点。Transformer的self-attention机制正是模拟了这个过程,它能自动学习哪些词更重要。

我用一个简单例子说明注意力机制有多神奇。下面这段财经新闻:

"美联储宣布加息50个基点,导致纳斯达克指数暴跌3.2%"

传统模型可能平均处理每个词,但Transformer会给"美联储"、"加息"、"暴跌"这些词更高权重。这种特性让它特别适合处理新闻文本,因为新闻的关键信息往往集中在少数关键词上。

2. 快速搭建Transformer分类模型

2.1 数据准备

我们先准备一个典型的新闻数据集,包含7个类别:

  • 教育
  • 科技
  • 社会
  • 时政
  • 财经
  • 房产
  • 家居

每个类别1万条数据,共7万条。数据质量很高,已经去除了乱码和特殊符号。我从实际项目经验中发现,数据清洗比模型选择更重要。曾经有个项目因为数据里有大量HTML标签,导致模型效果奇差,清洗后准确率直接涨了15%。

数据预处理主要做三件事:

  1. 中文分词(我用jieba)
  2. 去除停用词
  3. 文本长度统一(设为200个词)
import jieba from keras.preprocessing.text import Tokenizer # 加载停用词 stop_words = pd.read_csv("stopwords.txt")['stopword'].values # 分词函数 def cut_text(text): return " ".join([w for w in jieba.lcut(text) if w not in stop_words]) # 构建词表 tokenizer = Tokenizer(num_words=10000) tokenizer.fit_on_texts(df['cutword'])

2.2 模型构建

我用的是Keras实现的Transformer编码器。相比原始Transformer,做了两点简化:

  1. 只用Encoder部分(分类任务不需要Decoder)
  2. 简化了位置编码的实现
from tensorflow.keras import layers class TransformerEncoder(layers.Layer): def __init__(self, embed_dim, dense_dim, num_heads): super().__init__() self.attention = layers.MultiHeadAttention(num_heads=num_heads, key_dim=embed_dim) self.dense_proj = keras.Sequential([ layers.Dense(dense_dim, activation="relu"), layers.Dense(embed_dim) ]) self.layernorm1 = layers.LayerNormalization() self.layernorm2 = layers.LayerNormalization() def call(self, inputs): attn_output = self.attention(inputs, inputs) proj_input = self.layernorm1(inputs + attn_output) proj_output = self.dense_proj(proj_input) return self.layernorm2(proj_input + proj_output)

完整模型结构如下:

  1. 输入层(最大长度200)
  2. 词嵌入层(维度128)
  3. Transformer编码器(4个头)
  4. 全局池化
  5. 全连接分类层(7个输出)
inputs = layers.Input(shape=(200,)) x = layers.Embedding(10000, 128)(inputs) x = TransformerEncoder(128, 32, 4)(x) x = layers.GlobalMaxPooling1D()(x) outputs = layers.Dense(7, activation="softmax")(x) model = keras.Model(inputs, outputs)

3. 模型训练与调优技巧

3.1 训练配置

我推荐这些超参数设置:

  • Batch Size: 128
  • 初始学习率: 3e-5
  • Epochs: 10
  • 优化器: AdamW(带权重衰减)

关键技巧是使用学习率warmup:前10%的step线性增加学习率,避免初期震荡。我在多个项目中发现这能提升最终准确率1-2个百分点。

from transformers.optimization_tf import AdamWeightDecay optimizer = AdamWeightDecay( learning_rate=3e-5, weight_decay_rate=0.01 ) model.compile(optimizer=optimizer, loss="sparse_categorical_crossentropy", metrics=["accuracy"])

3.2 早停与模型保存

为了防止过拟合,我设置了两个回调:

  1. EarlyStopping(验证loss 3轮不下降就停止)
  2. ModelCheckpoint(只保存最佳模型)
callbacks = [ keras.callbacks.EarlyStopping(patience=3), keras.callbacks.ModelCheckpoint("best_model.h5", save_best_only=True) ] history = model.fit( train_ds, validation_data=val_ds, epochs=10, callbacks=callbacks )

3.3 效果评估

在测试集上,这个模型达到了96.2%的准确率。混淆矩阵显示最容易混淆的是"财经"和"时政"类新闻,这很合理因为它们经常有重叠词汇。

我常用的评估指标组合:

  1. 准确率(整体效果)
  2. F1分数(处理类别不平衡)
  3. Cohen's Kappa(考虑随机猜测)
from sklearn.metrics import classification_report y_pred = model.predict(test_ds) print(classification_report(y_true, y_pred.argmax(axis=1)))

4. 模型部署实战

4.1 保存完整pipeline

部署时不仅要保存模型,还要保存tokenizer和标签编码器。我推荐用pickle保存这些组件:

import pickle # 保存模型 model.save('news_classifier.h5') # 保存tokenizer with open('tokenizer.pkl', 'wb') as f: pickle.dump(tokenizer, f) # 保存标签编码器 with open('label_encoder.pkl', 'wb') as f: pickle.dump(label_encoder, f)

4.2 Flask API部署

最简单的部署方式是Flask。下面是一个完整的API实现:

from flask import Flask, request, jsonify import tensorflow as tf import pickle app = Flask(__name__) # 加载组件 model = tf.keras.models.load_model('news_classifier.h5') with open('tokenizer.pkl', 'rb') as f: tokenizer = pickle.load(f) with open('label_encoder.pkl', 'rb') as f: label_encoder = pickle.load(f) @app.route('/predict', methods=['POST']) def predict(): text = request.json['text'] # 预处理 seq = tokenizer.texts_to_sequences([text]) padded = tf.keras.preprocessing.sequence.pad_sequences(seq, maxlen=200) # 预测 pred = model.predict(padded) # 返回结果 return jsonify({ 'class': label_encoder.inverse_transform([pred.argmax()])[0], 'prob': float(pred.max()) }) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)

4.3 使用Hugging Face Hub

如果想更专业的部署,可以上传到Hugging Face Model Hub:

from huggingface_hub import push_to_hub_keras push_to_hub_keras( model, "your-username/news-classifier", include_optimizer=False )

上传后就可以用一行代码加载:

model = keras.models.load_from_hub("your-username/news-classifier")

5. 实际应用中的经验分享

在真实项目中,我遇到过几个典型问题:

  1. 长文本处理:新闻有时很长,超过模型最大长度。我的解决方案是先分段,然后对各段预测后投票。

  2. 新词问题:遇到"元宇宙"这种新词时,tokenizer会拆分成未知标记。解决方法是用领域数据微调tokenizer。

  3. 类别不平衡:某些类别样本少。我采用过采样+类别权重组合,效果最好。

  4. 领域迁移:财经新闻模型用在科技新闻上效果下降。这时需要用少量目标领域数据微调。

一个实用的技巧是建立反馈循环:把线上预测不确定的样本(预测概率<0.7)保存下来,定期人工标注后加入训练集。这套方法让我的一个客户项目准确率从92%提升到了96.5%。

最后提醒大家,部署后一定要监控模型表现。我见过最惨的案例是某个新闻APP的分类模型,因为新闻分布变化,半年后准确率从95%跌到了60%都没人发现。建议设置准确率报警,当周环比下降超过5%时触发警告。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/13 16:27:07

服务器产品SRRC认证详解:型号核准申请流程与材料清单

一、SRRC认证概述 SRRC认证&#xff08;无线电发射设备型号核准&#xff09;是依据《中华人民共和国无线电管理条例》设立的无线电发射设备市场准入制度&#xff0c;由工业和信息化部负责实施&#xff0c;面向在中国境内生产、销售和使用的无线电发射设备。 服务器产品是否需要…

作者头像 李华
网站建设 2026/7/13 16:23:25

深入机器人碰撞检测:Oriented Bounding Boxes (OBB)的实现与应用

引言 在现代机器人软件开发中,碰撞检测是确保系统安全性与稳定性的关键技术。无论是工业机器人臂的运动规划、自动驾驶车辆的导航,还是虚拟现实中的交互模拟,避免机械部件或虚拟对象之间的意外碰撞都是至关重要的。碰撞检测的核心在于高效识别和预防潜在冲突,以提升系统的…

作者头像 李华
网站建设 2026/7/13 16:23:10

MXFP4与FP8双量化技术实战:gpt-oss-120b模型优化完整教程

MXFP4与FP8双量化技术实战&#xff1a;gpt-oss-120b模型优化完整教程 【免费下载链接】gpt-oss-120b-w-mxfp4-a-fp8-kv-fp8-fp8attn-no_lmhead_router 项目地址: https://ai.gitcode.com/hf_mirrors/amd/gpt-oss-120b-w-mxfp4-a-fp8-kv-fp8-fp8attn-no_lmhead_router 想…

作者头像 李华
网站建设 2026/7/13 16:21:46

数据结构——算法复杂度顺序表

目录 一 算法效率 1、复杂度的概念 二 时间复杂度 1、大O的渐进表示法 2、时间复杂度计算示例 三 空间复杂度 1、空间复杂度计算示例 四 常见复杂度对比 五 复杂度算法题 1、旋转数组 六 线性表 七 顺序表 1、概念与结构 2、分类 3、动态顺序表实现 4、顺序表算法题 一、算法效…

作者头像 李华