RNN + 超参数调优打造电影评论情感分析模型

在自然语言处理(NLP)领域,循环神经网络(RNN) 是处理序列数据的经典利器,尤其擅长捕捉文本中的上下文依赖关系。对于情感分析这类任务——判断一段文字是正面还是负面——RNN 能够逐词“阅读”句子,并基于语义顺序做出判断,因此被广泛应用。

本文从零构建一个 IMDb 电影评论情感分类模型,不仅使用 LSTM(RNN 的改进版本)作为核心结构,还引入 Keras Tuner 实现超参数自动搜索,结合早停机制与 TensorBoard 可视化,打造一个完整、高效、可复现的深度学习实战项目。

✅ 项目特点:

  • 使用 Google Colab 免费 GPU 加速训练
  • 基于 Keras 内置 IMDB 数据集,开箱即用
  • 自动化超参数调优,告别手动“调参炼丹”
  • 输出结构化实验结果,支持后续分析

一、项目背景与数据准备

📚 数据集简介:IMDb 电影评论

我们使用的 IMDb 数据集 包含 50,000 条经过标注的电影评论,每条被标记为“正面”(1)或“负面”(0),是情感分析领域的标准 benchmark 数据集。

目标:训练一个 RNN 模型,自动判断新评论的情感倾向。

🛠️ 环境与依赖

本项目在 Google Colab 中运行,支持免费 GPU 加速(MacBook Air上要跑一个多小时,Colab上不到半个小时,如果自己电脑性能好的话可以在本地跑)。

首先安装 keras-tuner并导入所需库:

# 安装 Keras Tuner
!pip install -q keras-tuner

# 导入基础库
import numpy as np
import pandas as pd
import tensorflow as tf

# 导入 IMDB 数据集
from tensorflow.keras.datasets import imdb

# 定义基础参数
NUM_WORDS = 10000      # 保留最常见的 10000 个词
MAX_LEN = 150          # 每条评论最大长度
TRAIN_SAMPLES = 20000  # 训练样本数
TEST_SAMPLES = 5000    # 测试样本数

# 加载数据
print("📥 正在加载 IMDB 数据集...")
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=NUM_WORDS)

# 截取指定数量样本
x_train, y_train = x_train[:TRAIN_SAMPLES], y_train[:TRAIN_SAMPLES]
x_test, y_test = x_test[:TEST_SAMPLES], y_test[:TEST_SAMPLES]

print(f"✅ 数据加载完成!")
print(f"训练集大小: {len(x_train)} 条评论")
print(f"测试集大小: {len(x_test)} 条评论")

💡 imdb.load_data(num_words=10000) 会自动将文本转换为整数序列(每个词对应一个 ID),极大简化预处理流程。


🧹 数据预处理:统一长度,划分验证集

由于评论长度不一,必须填充或截断至固定长度才能批量训练。我们使用 pad_sequences 将所有序列统一为 MAX_LEN=150

同时,从训练集中划分出 20% 作为验证集,用于超参数搜索时评估模型性能:

# 划分训练集和验证集
from sklearn.model_selection import train_test_split
from tensorflow.keras.preprocessing.sequence import pad_sequences

print("🧹 正在进行数据预处理...")

# 划分:80% 训练,20% 验证
x_train, x_val, y_train, y_val = train_test_split(
    x_train, y_train,
    test_size=0.2,
    random_state=42
)

# 序列填充到统一长度
x_train = pad_sequences(x_train, maxlen=MAX_LEN, padding='post', truncating='post')
x_val = pad_sequences(x_val, maxlen=MAX_LEN, padding='post', truncating='post')
x_test = pad_sequences(x_test, maxlen=MAX_LEN, padding='post', truncating='post')

print(f"✅ 数据预处理完成!")
print(f"训练集形状: {x_train.shape}")
print(f"验证集形状: {x_val.shape}")
print(f"测试集形状: {x_test.shape}")

✅ 输出:

🧹 正在进行数据预处理...
✅ 数据预处理完成!
训练集形状: (16000, 150)
验证集形状: (4000, 150)
测试集形状: (5000, 150)

二、构建可搜索的 RNN 模型

传统建模往往依赖经验“试错”调参,效率低下。我们使用 Keras Tuner,让机器自动探索最优超参数组合。

定义 build_model(hp) 函数,将关键参数设为可调选项:

# 导入建模所需模块
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout, Bidirectional
from tensorflow.keras.optimizers import Adam, RMSprop
import keras_tuner as kt

def build_model(hp):
    """构建带超参数的 RNN 模型"""
    model = Sequential()

    # 嵌入层:将词 ID 映射为向量
    embedding_dim = hp.Choice('embedding_dim', [64, 100, 128], default=128)
    model.add(Embedding(NUM_WORDS, embedding_dim))

    # LSTM 层:支持多层、双向、Dropout
    lstm_layers = hp.Choice('lstm_layers', [1, 2])
    lstm_units = hp.Choice('lstm_units', [64, 128])
    dropout = hp.Float('dropout', 0.2, 0.5, step=0.1)
    use_bidirectional = hp.Boolean('use_bidirectional', default=False)

    for i in range(lstm_layers):
        return_sequences = (i < lstm_layers - 1)
        if use_bidirectional:
            model.add(Bidirectional(
                LSTM(lstm_units, dropout=dropout, return_sequences=return_sequences)
            ))
        else:
            model.add(LSTM(lstm_units, dropout=dropout, return_sequences=return_sequences))

    # 可选全连接层
    if hp.Boolean('use_dense', default=True):
        dense_units = hp.Choice('dense_units', [32, 64])
        model.add(Dense(dense_units, activation='relu'))
        model.add(Dropout(dropout))

    # 输出层:二分类,使用 sigmoid
    model.add(Dense(1, activation='sigmoid'))

    # 优化器与学习率
    lr = hp.Float('learning_rate', 1e-4, 1e-3, sampling='log')
    optimizer_name = hp.Choice('optimizer', ['adam', 'rmsprop'])
    optimizer = Adam(learning_rate=lr) if optimizer_name == 'adam' else RMSprop(learning_rate=lr)

    model.compile(
        optimizer=optimizer,
        loss='binary_crossentropy',
        metrics=['accuracy']
    )

    return model

print("✅ 模型构建函数已定义!")

🔍 超参数搜索空间说明:

参数 可选值 说明
embedding_dim 64, 100, 128 词向量维度
lstm_layers
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值