当前位置: 首页 > article >正文

深度学习-可调整嵌入维度、隐藏层维度和训练轮数

下面会结合 PyTorch 框架,以 IMDB 影评情感分析任务为例,实现一个可调整嵌入维度、隐藏层维度和训练轮数的深度学习情感分析模型。

1. 安装必要的库

pip install torch torchtext spacy
python -m spacy download en_core_web_sm

2. 代码实现

import torch
import torch.nn as nn
import torch.optim as optim
from torchtext.legacy import data, datasets
import spacy
import random

# 设置随机种子以保证结果可复现
SEED = 1234
random.seed(SEED)
torch.manual_seed(SEED)
torch.backends.cudnn.deterministic = True

# 加载英语分词器
spacy_en = spacy.load('en_core_web_sm')

# 定义分词函数
def tokenize_en(text):
    return [tok.text for tok in spacy_en.tokenizer(text)]

# 定义字段
TEXT = data.Field(tokenize=tokenize_en, lower=True)
LABEL = data.LabelField(dtype=torch.float)

# 加载 IMDB 数据集
train_data, test_data = datasets.IMDB.splits(TEXT, LABEL)

# 划分验证集
train_data, valid_data = train_data.split(random_state=random.seed(SEED))

# 构建词汇表
MAX_VOCAB_SIZE = 25000
TEXT.build_vocab(train_data, max_size=MAX_VOCAB_SIZE)
LABEL.build_vocab(train_data)

# 创建迭代器
BATCH_SIZE = 64
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
train_iterator, valid_iterator, test_iterator = data.BucketIterator.splits(
    (train_data, valid_data, test_data),
    batch_size=BATCH_SIZE,
    device=device)

# 定义模型
class RNN(nn.Module):
    def __init__(self, vocab_size, embedding_dim, hidden_dim, output_dim, n_layers, bidirectional, dropout):
        super().__init__()
        self.embedding = nn.Embedding(vocab_size, embedding_dim)
        self.rnn = nn.LSTM(embedding_dim,
                           hidden_dim,
                           num_layers=n_layers,
                           bidirectional=bidirectional,
                           dropout=dropout)
        self.fc = nn.Linear(hidden_dim * 2 if bidirectional else hidden_dim, output_dim)
        self.dropout = nn.Dropout(dropout)

    def forward(self, text):
        embedded = self.dropout(self.embedding(text))
        output, (hidden, cell) = self.rnn(embedded)
        if self.rnn.bidirectional:
            hidden = self.dropout(torch.cat((hidden[-2, :, :], hidden[-1, :, :]), dim=1))
        else:
            hidden = self.dropout(hidden[-1, :, :])
        return self.fc(hidden.squeeze(0))

# 训练模型
def train(model, iterator, optimizer, criterion):
    model.train()
    epoch_loss = 0
    for batch in iterator:
        optimizer.zero_grad()
        predictions = model(batch.text).squeeze(1)
        loss = criterion(predictions, batch.label)
        loss.backward()
        optimizer.step()
        epoch_loss += loss.item()
    return epoch_loss / len(iterator)

# 评估模型
def evaluate(model, iterator, criterion):
    model.eval()
    epoch_loss = 0
    with torch.no_grad():
        for batch in iterator:
            predictions = model(batch.text).squeeze(1)
            loss = criterion(predictions, batch.label)
            epoch_loss += loss.item()
    return epoch_loss / len(iterator)

# 主函数,可调整参数
def main(embedding_dim=100, hidden_dim=256, n_epochs=5):
    # 初始化模型
    INPUT_DIM = len(TEXT.vocab)
    OUTPUT_DIM = 1
    N_LAYERS = 2
    BIDIRECTIONAL = True
    DROPOUT = 0.5

    model = RNN(INPUT_DIM, embedding_dim, hidden_dim, OUTPUT_DIM, N_LAYERS, BIDIRECTIONAL, DROPOUT)
    model = model.to(device)

    # 定义优化器和损失函数
    optimizer = optim.Adam(model.parameters())
    criterion = nn.BCEWithLogitsLoss()
    criterion = criterion.to(device)

    best_valid_loss = float('inf')
    for epoch in range(n_epochs):
        train_loss = train(model, train_iterator, optimizer, criterion)
        valid_loss = evaluate(model, valid_iterator, criterion)
        if valid_loss < best_valid_loss:
            best_valid_loss = valid_loss
            torch.save(model.state_dict(), 'sentiment_model.pt')
        print(f'Epoch: {epoch + 1:02}')
        print(f'\tTrain Loss: {train_loss:.3f}')
        print(f'\t Val. Loss: {valid_loss:.3f}')

    # 在测试集上评估模型
    model.load_state_dict(torch.load('sentiment_model.pt'))
    test_loss = evaluate(model, test_iterator, criterion)
    print(f'Test Loss: {test_loss:.3f}')

if __name__ == "__main__":
    # 可根据需要调整以下参数
    embedding_dim = 200
    hidden_dim = 512
    n_epochs = 10
    main(embedding_dim, hidden_dim, n_epochs)

3. 代码解释

  • 数据预处理:利用 torchtext 加载 IMDB 数据集,借助 spacy 进行分词,构建词汇表并创建数据迭代器。
  • 模型构建:定义了一个基于 LSTM 的循环神经网络 RNN,包含嵌入层、LSTM 层和全连接层。其中嵌入层的维度由 embedding_dim 控制,LSTM 层的隐藏层维度由 hidden_dim 控制。
  • 训练和评估
    • train 函数用于训练模型一个 epoch,并返回该 epoch 的平均损失。
    • evaluate 函数用于评估模型在给定数据集上的损失。
    • main 函数作为主函数,接收 embedding_dimhidden_dimn_epochs 作为参数,初始化模型、优化器和损失函数,进行模型训练,并在验证集上选择最佳模型,最后在测试集上评估模型性能。

4. 注意事项

  • 此代码运行需要一定的计算资源,若有 GPU 可显著加快训练速度。
  • 可以通过修改 main 函数中传入的 embedding_dimhidden_dimn_epochs 参数,来探究不同参数设置对模型性能的影响。例如,增大 embedding_dim 可能会使模型能更好地捕捉词语之间的语义关系,但也会增加模型的训练时间和内存消耗。

http://www.kler.cn/a/539646.html

相关文章:

  • 详解SQLAlchemy的函数relationship
  • 网络防御高级02-综合实验
  • 【03】 区块链分布式网络
  • Docker基础以及单体实战
  • 【Go语言快速上手】第二部分:Go语言进阶
  • 了解传输层TCP协议
  • Chrome 浏览器 支持多账号登录和管理的浏览器容器解决方案
  • 二级C语言题解:迭代求根、字符串加法、字符串拆分
  • ARM Cortex-M3/M4 权威指南 笔记【一】架构
  • PHP 完整表单实例
  • 嵌入式硬件篇---OpenMV串口流和缓冲区
  • 用AI写游戏3——模拟发牌
  • Golang中 var make new
  • vue表格拖拽,可以多个单元格拖拽
  • html 列动态布局
  • 2025年2月份的一次前端面试题记录....
  • 使用Redis解决使用Session登录带来的共享问题
  • 深度学习-利用Tacotron 2 和 WaveGlow 模型 进行语音合成
  • Vue引入外部异步js函数并接收返回值
  • mysql中主键索引和联合索引的原理解析
  • 开源堡垒机 JumpServer 社区版实战教程:基于 Ubuntu 22.04 离线安装 JumpServer 社区版 v4.4.1
  • 变化检测论文阅读合集
  • 激活函数篇 01 —— 激活函数在神经网络的作用
  • vue3+vite+ts项目中使用vue-router
  • OnlyOffice文件转换PDF
  • 【豆包Marscode体验官】揭秘MarsCode AI编辑助手:高效智能编辑新纪元之入门指导与最佳实践