You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于文本数据的ResNet实现疑问及18层ResNet定制需求

问题分析与解决方案

现有代码的问题

你提供的代码完全没有实现ResNet的核心逻辑,本质是一个普通的全连接回归网络:

  • 缺少ResNet标志性的残差跳跃连接
  • 处理的是结构化表格数据,不是文本数据
  • 任务是回归(预测年龄),和你需求的分类任务不符

定制化文本ResNet-18实现方案

针对你的需求(18层、4阶段、残差块、文本分类),我们实现适用于文本的1D ResNet-18(文本是序列数据,用1D卷积替代图像的2D卷积),具体如下:

核心设计要点

  • 文本预处理:用Embedding层将文本转为向量序列,再输入ResNet结构
  • ResNet结构:
    • 总层数18:输入层+4阶段×2残差块×2卷积层+全连接层(符合你定义的层数统计)
    • 每个残差块:2个1D卷积层(带BN+ReLU)+ 残差跳跃连接
    • 4个阶段:每个阶段逐步提升通道数,同时下采样缩短序列长度
  • 分类头:全局平均池化后接2个全连接层,输出网站类别概率
  • 优化配置:Adam优化器+分类交叉熵损失,搭配文本分类常用最优超参数

完整代码实现

import numpy as np
import pandas as pd
from sklearn.model_selection import KFold
from sklearn.preprocessing import LabelEncoder
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Dense, Conv1D, BatchNormalization, ReLU, Add, GlobalAveragePooling1D, Embedding
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.losses import CategoricalCrossentropy
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences

class TextResNet18:
    def __init__(self):
        self.n_folds = int(input('输入K折交叉验证数: '))
        self.epochs = int(input('输入训练轮数: '))
        self.kf = KFold(n_splits=self.n_folds, shuffle=True, random_state=42)
        # 文本预处理参数
        self.max_len = 100  # 文本最大长度
        self.vocab_size = 10000  # 词汇表大小
        self.embedding_dim = 128  # 词嵌入维度

    # 定义残差块
    def residual_block(self, x, filters, stride=1):
        # 主路径
        shortcut = x
        x = Conv1D(filters, kernel_size=3, strides=stride, padding='same')(x)
        x = BatchNormalization()(x)
        x = ReLU()(x)
        x = Conv1D(filters, kernel_size=3, strides=1, padding='same')(x)
        x = BatchNormalization()(x)
        
        # 残差连接:如果通道数或步长变化,调整shortcut
        if stride != 1 or shortcut.shape[-1] != filters:
            shortcut = Conv1D(filters, kernel_size=1, strides=stride, padding='same')(shortcut)
            shortcut = BatchNormalization()(shortcut)
        
        x = Add()([x, shortcut])
        x = ReLU()(x)
        return x

    # 构建ResNet-18模型
    def build_model(self, num_classes):
        inputs = Input(shape=(self.max_len,))
        # 词嵌入层
        x = Embedding(input_dim=self.vocab_size, output_dim=self.embedding_dim, input_length=self.max_len)(inputs)
        
        # 初始卷积层
        x = Conv1D(64, kernel_size=7, strides=2, padding='same')(x)
        x = BatchNormalization()(x)
        x = ReLU()(x)
        
        # 4个阶段,每个阶段2个残差块
        # 阶段1:64通道
        x = self.residual_block(x, 64)
        x = self.residual_block(x, 64)
        # 阶段2:128通道,下采样
        x = self.residual_block(x, 128, stride=2)
        x = self.residual_block(x, 128)
        # 阶段3:256通道,下采样
        x = self.residual_block(x, 256, stride=2)
        x = self.residual_block(x, 256)
        # 阶段4:512通道,下采样
        x = self.residual_block(x, 512, stride=2)
        x = self.residual_block(x, 512)
        
        # 全局平均池化+全连接层
        x = GlobalAveragePooling1D()(x)
        x = Dense(256, activation='relu')(x)
        outputs = Dense(num_classes, activation='softmax')(x)
        
        model = Model(inputs=inputs, outputs=outputs)
        # 编译模型
        model.compile(optimizer=Adam(learning_rate=1e-4),
                      loss=CategoricalCrossentropy(),
                      metrics=['accuracy'])
        return model

    # 数据预处理(文本转序列)
    def preprocess_text(self, texts):
        tokenizer = Tokenizer(num_words=self.vocab_size)
        tokenizer.fit_on_texts(texts)
        sequences = tokenizer.texts_to_sequences(texts)
        padded_sequences = pad_sequences(sequences, maxlen=self.max_len)
        return padded_sequences, tokenizer

    # 训练与验证
    def train_and_evaluate(self, texts, labels):
        # 文本预处理
        x, _ = self.preprocess_text(texts)
        # 标签编码
        le = LabelEncoder()
        y = le.fit_transform(labels)
        y = to_categorical(y, num_classes=len(le.classes_))
        
        oos_accuracy = []
        fold = 0
        for train_idx, test_idx in self.kf.split(x):
            fold +=1
            print(f"第 {fold} 折训练")
            x_train, x_test = x[train_idx], x[test_idx]
            y_train, y_test = y[train_idx], y[test_idx]
            
            model = self.build_model(num_classes=len(le.classes_))
            model.fit(x_train, y_train, 
                      validation_data=(x_test, y_test),
                      epochs=self.epochs,
                      batch_size=32,
                      verbose=1)
            
            _, acc = model.evaluate(x_test, y_test, verbose=0)
            oos_accuracy.append(acc)
            print(f"第 {fold} 折测试准确率: {acc:.4f}")
        
        print(f"\n交叉验证平均准确率: {np.mean(oos_accuracy):.4f} ± {np.std(oos_accuracy):.4f}")

# 示例使用(实际使用时替换为你的真实文本数据和标签)
if __name__ == "__main__":
    # 模拟文本数据和网站类别标签
    sample_texts = [
        "Python数据挖掘入门教程",
        "AI在医疗影像诊断中的应用",
        "React前端组件开发实战",
        "AWS云服务器部署指南",
        "机器学习模型评估指标详解"
    ] * 20  # 扩充数据量
    sample_labels = ["技术教程", "AI医疗", "前端开发", "云计算", "机器学习"] * 20
    
    resnet = TextResNet18()
    resnet.train_and_evaluate(sample_texts, sample_labels)

代码说明

  1. 残差块:实现了ResNet核心的跳跃连接,解决深层网络退化问题
  2. 文本适配:用1D卷积处理序列文本,Embedding层将文本转为可训练的向量表示
  3. 超参数设置:Adam学习率设为1e-4(文本分类常用最优值),batch_size=32,可根据数据量灵活调整
  4. 交叉验证:保留了你原有的K折验证逻辑,确保模型泛化性

内容的提问来源于stack exchange,提问作者Python

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 09:35:16