第 1 章项目介绍

在电商平台中,商品发布通常是一个繁琐的过程,需要手动录入商品的各项信息,如品牌、品类等。为了提升效率并减轻商家的工作负担,智能商品录入系统应运而生。该系统能够根据商家提供的商品标题,自动预测并填写相关信息,从而加速商品上架过程。
本项目的核心功能是 商品分类预测,通过自动化分析商品标题,实现品类的自动分类,帮助商家快速、准确地完成商品录入。

在这里插入图片描述

第 2 章需求分析

本项目的核心功能是 根据商品标题预测其所属分类,本质上是一个 多分类问题。通过 BERT模型 加上一个多分类任务头,即可实现该功能。此外,项目需要提供接口,以便商品发布系统进行调用。

第 3 章开发环境准备

3.1创建conda环境

终端输入如下命令,创建项目的虚拟环境,并指定Python版本:

conda create -n product-classify python=3.12

激活该虚拟环境:

conda activate product-classify

3.2安装所需依赖

本项目依赖以下软件和库:
pytorch:深度学习框架,用于训练和推理
transformers:Hugging Face 提供的库,用于加载和微调 BERT 等预训练模型。
datasets:用于高效加载和处理大规模数据集。
scikit-learn:用于模型评估。
tensorboard:用于可视化训练过程中的损失、准确率等指标。
tqdm:用于显示训练进度条,方便监控训练过程。
jupyter:用于实验和数据分析。
FastAPI:用于构建和部署API接口。
Uvicorn:FastAPI的服务器,用于高性能地运行FastAPI应用。
安装命令如下:
1)安装pytorch
使用nvidia-smi查看CUDA版本,并根据其版本选择PyTorch版本进行安装:

pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126

2)安装其余依赖
其余依赖安装最新版本即可

pip install transformers datasets scikit-learn tensorboard tqdm jupyter fastapi uvicorn

3.3创建项目

项目结构如下图所示
在这里插入图片描述

第 4 章数据预处理

4.1数据集说明

本项目使用的 商品标题分类数据集 来自 百度AI Studio,该数据集包含了 训练集、验证集 和 测试集。数据结构如下:
在这里插入图片描述

4.2预处理过程

处理过程如下:
1)加载数据:加载训练集、测试集和验证集数据。
2)数据过滤:移除 text_a 或 label 为 None 的数据样本,确保数据完整性。
3)标签处理:提取所有标签,并将标签列转换为 ClassLabel 类型,便于BERT模型处理。
4)分词处理:使用 BERT分词器 对商品标题进行分词,生成 input_ids 和 attention_mask,并将它们作为模型的输入。
5)保存数据集:将处理后的数据集保存为适合模型训练的格式,便于后续使用。
完整代码如下:

# src/preprocess/process.py

import datasets
from datasets import ClassLabel
from transformers import AutoTokenizer

from configuration import config

def process():
    # 读取数据
    dataset_dic = datasets.load_dataset('csv', data_files={
        'train': str(config.RAW_DATA_DIR / 'train.txt'),
        'test': str(config.RAW_DATA_DIR / 'test.txt'),
        'valid': str(config.RAW_DATA_DIR / 'valid.txt')
    }, delimiter='\t')

    # 过滤数据
    dataset_dic = dataset_dic.filter(lambda x: x['text_a'] is not None and x['label'] is not None)

    # 处理类别
    all_labels = sorted(set(dataset_dic['train']['label']))
    dataset_dic = dataset_dic.cast_column('label', ClassLabel(names=all_labels))

    # 加载tokenizer
    tokenizer = AutoTokenizer.from_pretrained(str(config.PRE_TRAINED_DIR / 'bert-base-chinese'))

    def tokenize(example):
        encoded = tokenizer(
            example['text_a'],
            truncation=True,
            padding='max_length',
            max_length=config.SEQ_LEN,
        )
        example['input_ids'] = encoded['input_ids']
        example['attention_mask'] = encoded['attention_mask']
        return example

    # 编码
    dataset_dic = dataset_dic.map(tokenize, batched=True, remove_columns=['text_a'])

    # 保存数据集
    dataset_dic['train'].save_to_disk(str(config.PROCESSED_DATA_DIR / 'train'))
    dataset_dic['test'].save_to_disk(str(config.PROCESSED_DATA_DIR / 'test'))
    dataset_dic['valid'].save_to_disk(str(config.PROCESSED_DATA_DIR / 'valid'))

4.3构建Dataset和Dataloader

在预处理完成后,我们将需要将数据集转换为 PyTorch 中可以使用的 Dataset 和 DataLoader,以便在训练过程中按批次加载数据。
完整代码如下:

# src/preprocess/dataset.py

from enum import StrEnum
from datasets import load_from_disk
from torch.utils.data import DataLoader

from configuration import config

# 数据类型枚举
class DataType(StrEnum):
    TRAIN = 'train'
    TEST = 'test'
    VALID = 'valid'

def get_dataset(type):
    dataset = load_from_disk(str(config.PROCESSED_DATA_DIR / type))
    dataset.set_format('torch', columns=['input_ids', 'attention_mask', 'label'])  # 设置为 torch 格式
    return dataset

def get_dataloader(type=DataType.TRAIN):
    dataset = get_dataset(type)
    return DataLoader(dataset, batch_size=config.BATCH_SIZE, shuffle=True)

第 5 章模型定义

该模型的核心结构包括 BERT编码器 和一个 分类头,如下:
BERT编码器:从预训练的BERT模型中获取商品标题的上下文表示。
分类头:将BERT输出的 [CLS] token 表示通过一个线性层映射到品类空间,实现分类任务。
完整代码如下:

# src/model/classifier.py

from torch import nn
from transformers import AutoModel

from configuration import config

class BertTitleClassifier(nn.Module):
    def __init__(self, freeze_bert=True):
        """
        初始化分类模型。

        :param freeze_bert: 是否冻结 BERT 编码器的参数(默认冻结,仅训练分类器)
        """
        super().__init__()

        # 加载预训练的 BERT 模型
        self.bert = AutoModel.from_pretrained(config.PRE_TRAINED_DIR / 'bert-base-chinese')

        # 定义分类器:将 BERT 输出的 CLS 向量映射到类别空间
        self.classifier = nn.Linear(self.bert.config.hidden_size, config.NUM_CLASSES)

        # 决定是否冻结 BERT 参数(只训练最后的分类层)
        if freeze_bert:
            for param in self.bert.parameters():
                param.requires_grad = False

    def forward(self, input_ids, attention_mask=None):
        """
        前向传播过程。

        :param input_ids: 输入 token 的 id 序列(batch_size, seq_len)
        :param attention_mask: 注意力掩码(同 shape),标识 padding 的位置
        :return: 分类结果的 logits(batch_size, num_classes)
        """
        # 获取 BERT 输出:last_hidden_state 为所有 token 的表示
        outputs = self.bert(input_ids=input_ids, attention_mask=attention_mask)

        # 取 [CLS] token 对应的表示,作为句子的整体表示
        cls_output = outputs.last_hidden_state[:, 0, :]  # shape: (batch_size, hidden_size)

        # 通过线性分类层得到最终 logits
        logits = self.classifier(cls_output)  # shape: (batch_size, num_classes)

        return logits
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐