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

部署运行你感兴趣的模型镜像

下面会结合 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 可能会使模型能更好地捕捉词语之间的语义关系,但也会增加模型的训练时间和内存消耗。

您可能感兴趣的与本文相关的镜像

PyTorch 2.5

PyTorch 2.5

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

### 隐藏层维度嵌入维度的概念 隐藏层维度(Hidden Layer Dimension)是指神经网络中隐藏层节点的数量或其对应的向量空间大小。这一参数决定了模型内部状态的复杂性表达能力[^1]。而嵌入维度(Embedding Dimension)则是指将离散型数据(如单词、字符或其他符号)映射到连续向量空间后的向量长度,用于捕获输入数据的语义特征[^2]。 两者的主要区别在于作用范围功能定位: - 嵌入维度主要用于输入阶段的数据表示优化,目的是将原始稀疏数据(如独热编码)转化为稠密且具有语义意义的低维向量[^3]。 - 隐藏层维度则涉及整个模型架构的设计,在中间处理过程中起到存储传递信息的作用,直接影响模型的学习能力泛化性能[^4]。 --- ### 联系与相互影响 尽管两者的定义不同,但在实际应用中它们之间存在紧密联系: #### 数据流层面 在许多深度学习框架中,嵌入层通常作为模型的第一部分负责初始化输入数据的向量化形式;随后这些向量会被送入后续的隐藏层进一步加工提取高层次抽象特征。因此可以说,合适的嵌入维度会间接影响隐藏层的工作效果——如果嵌入维度过小,则可能丢失重要细节从而限制整体表现;反之过大又可能导致资源浪费甚至引入噪声干扰训练过程稳定性[^5]。 #### 参数规模方面 对于给定任务而言,调整这两项超参都会显著改变最终所需内存消耗及运算时间长短。具体来说,较大的嵌入尺寸意味着更多待更新权重数量同时也增加了每一步前馈操作所需的乘积累加次数;同样道理更深层次结构也会带来额外开销但由于现代硬件加速技术进步使得这种权衡变得更容易管理一些情况下可以通过增加GPU显存利用率来弥补潜在瓶颈问题出现的可能性降低不少程度上缓解了上述矛盾局面的发生概率提升系统运行效率的同时也增强了用户体验满意度水平达到双赢目的实现最佳配置方案设计思路指导原则如下所示代码片段展示了如何利用PyTorch库创建自定义RNN单元并指定相应属性值以便更好地理解相关内容要点所在之处值得注意的是这里仅作为一个简单示例仅供参考价值有限具体情况还需结合实际需求综合考量后再做决策最为稳妥可靠的做法始终遵循科学实验验证规律不断探索尝试直至找到最优解为止才是正道之选。 ```python import torch.nn as nn class CustomRNN(nn.Module): def __init__(self, vocab_size, embedding_dim, hidden_dim): super(CustomRNN, self).__init__() self.embedding = nn.Embedding(vocab_size, embedding_dim) self.rnn = nn.RNN(embedding_dim, hidden_dim) def forward(self, x): embedded = self.embedding(x) output, _ = self.rnn(embedded) return output ``` --- ### 应用场景对比 | **特性/场景** | **嵌入维度适用情况** | **隐藏层维度适用情况** | |-----------------------|---------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------| | 输入数据预处理 | 将文本、图像标签等离散变量转为可被机器学习算法使用的数值形式 | 不直接参与外部数据转换,主要关注于已有张量间的变换 | | 计算成本 | 较高维度可能会提高精度但也伴随更大存储需求 | 更多层数或更高宽度往往需要更强计算力支持 | | 表达能力 | 控制基础单位间关联性的描述精细度 | 影响全局模式识别准确性 | | 特定领域适配性 | 自然语言处理(NLP),计算机视觉(CV)等领域常用 | 广泛应用于各类监督无监督混合学习任务 | 例如,在构建一个基于Transformer的语言模型时,可以选择较小的嵌入维度以减少初始记忆负担,同时维持较大隐藏层维度确保足够的上下文建模能力[^6]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小赖同学啊

感谢上帝的投喂

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值