ROCm上运行情感分析:使用卷积神经网络

113 篇文章 0 订阅
81 篇文章 0 订阅

15.3. 情感分析:使用卷积神经网络 — 动手学深度学习 2.0.0 documentation (d2l.ai)

代码

import torch
from torch import nn
from d2l import torch as d2l

batch_size = 64
train_iter, test_iter, vocab = d2l.load_data_imdb(batch_size)

def corr1d(X, K):
    w = K.shape[0]
    Y = torch.zeros((X.shape[0] - w + 1))
    for i in range(Y.shape[0]):
        Y[i] = (X[i: i + w] * K).sum()
    return Y

X, K = torch.tensor([0, 1, 2, 3, 4, 5, 6]), torch.tensor([1, 2])
corr1d(X, K)

def corr1d_multi_in(X, K):
    # 首先,遍历'X'和'K'的第0维(通道维)。然后,把它们加在一起
    return sum(corr1d(x, k) for x, k in zip(X, K))

X = torch.tensor([[0, 1, 2, 3, 4, 5, 6],
              [1, 2, 3, 4, 5, 6, 7],
              [2, 3, 4, 5, 6, 7, 8]])
K = torch.tensor([[1, 2], [3, 4], [-1, -3]])
corr1d_multi_in(X, K)

class TextCNN(nn.Module):
    def __init__(self, vocab_size, embed_size, kernel_sizes, num_channels,
                 **kwargs):
        super(TextCNN, self).__init__(**kwargs)
        self.embedding = nn.Embedding(vocab_size, embed_size)
        # 这个嵌入层不需要训练
        self.constant_embedding = nn.Embedding(vocab_size, embed_size)
        self.dropout = nn.Dropout(0.5)
        self.decoder = nn.Linear(sum(num_channels), 2)
        # 最大时间汇聚层没有参数,因此可以共享此实例
        self.pool = nn.AdaptiveAvgPool1d(1)
        self.relu = nn.ReLU()
        # 创建多个一维卷积层
        self.convs = nn.ModuleList()
        for c, k in zip(num_channels, kernel_sizes):
            self.convs.append(nn.Conv1d(2 * embed_size, c, k))

    def forward(self, inputs):
        # 沿着向量维度将两个嵌入层连结起来,
        # 每个嵌入层的输出形状都是(批量大小,词元数量,词元向量维度)连结起来
        embeddings = torch.cat((
            self.embedding(inputs), self.constant_embedding(inputs)), dim=2)
        # 根据一维卷积层的输入格式,重新排列张量,以便通道作为第2维
        embeddings = embeddings.permute(0, 2, 1)
        # 每个一维卷积层在最大时间汇聚层合并后,获得的张量形状是(批量大小,通道数,1)
        # 删除最后一个维度并沿通道维度连结
        encoding = torch.cat([
            torch.squeeze(self.relu(self.pool(conv(embeddings))), dim=-1)
            for conv in self.convs], dim=1)
        outputs = self.decoder(self.dropout(encoding))
        return outputs

embed_size, kernel_sizes, nums_channels = 100, [3, 4, 5], [100, 100, 100]
devices = d2l.try_all_gpus()
net = TextCNN(len(vocab), embed_size, kernel_sizes, nums_channels)

def init_weights(m):
    if type(m) in (nn.Linear, nn.Conv1d):
        nn.init.xavier_uniform_(m.weight)

net.apply(init_weights);

glove_embedding = d2l.TokenEmbedding('glove.6b.100d')
embeds = glove_embedding[vocab.idx_to_token]
net.embedding.weight.data.copy_(embeds)
net.constant_embedding.weight.data.copy_(embeds)
net.constant_embedding.weight.requires_grad = False


lr, num_epochs = 0.001, 5
trainer = torch.optim.Adam(net.parameters(), lr=lr)
loss = nn.CrossEntropyLoss(reduction="none")
d2l.train_ch13(net, train_iter, test_iter, loss, trainer, num_epochs, devices)

d2l.predict_sentiment(net, vocab, 'this movie is so great')

d2l.predict_sentiment(net, vocab, 'this movie is so bad')

代码解析

这段代码实现了一个用于情感分析的文本分类模型。它使用了IMDb评论数据集,并应用了一种被称为TextCNN的卷积神经网络架构。下面依次对代码中的各个部分进行解释:
1. 导入相关库:

    import torch
    from torch import nn
    from d2l import torch as d2l

    导入PyTorch库、神经网络模块和`d2l`工具箱,`d2l`工具箱是为了简化实现并提供了辅助函数。
2. 加载数据集:

    batch_size = 64
    train_iter, test_iter, vocab = d2l.load_data_imdb(batch_size)

    加载IMDb电影评论数据集,并将数据分成小批量进行训练,`batch_size`是每批次训练的样本数量。
3. 实现一维互相关操作:

    def corr1d(X, K):
        # 函数实现

    互相关运算在卷积神经网络中使用,它类似于一维卷积。
4. 实现多输入通道的一维互相关操作:
    

    def corr1d_multi_in(X, K):
        # 函数实现

    当输入数据具有多个通道时,将每个通道的互相关运算结果相加起来,以得到最终结果。
5. 定义TextCNN模型:

    class TextCNN(nn.Module):
        def __init__(self, vocab_size, embed_size, kernel_sizes, num_channels):
            # 模型初始化

        def forward(self, inputs):
            # 模型前向传播

    TextCNN模型通过嵌入层(`nn.Embedding`)将单词映射到低维空间,然后使用卷积层(`nn.Conv1d`)提取局部特征,最后通过一个全连接层(`nn.Linear`)进行分类。
6. 初始化模型权重:

    def init_weights(m):
        if type(m) in (nn.Linear, nn.Conv1d):
            nn.init.xavier_uniform_(m.weight)
    net.apply(init_weights)

    通过`apply`函数将初始化操作`init_weights`应用到模型的每个子模块上。
7. 将预训练的词嵌入加载到模型中:

    glove_embedding = d2l.TokenEmbedding('glove.6b.100d')
    embeds = glove_embedding[vocab.idx_to_token]
    net.embedding.weight.data.copy_(embeds)
    net.constant_embedding.weight.data.copy_(embeds)
    net.constant_embedding.weight.requires_grad = False

    使用GloVe预训练的100维词向量来初始化嵌入层,并固定其中一部分的权重(`constant_embedding`)以防止训练过程中被更新。
8. 训练模型:

    lr, num_epochs = 0.001, 5
    trainer = torch.optim.Adam(net.parameters(), lr=lr)
    loss = nn.CrossEntropyLoss(reduction="none")
    d2l.train_ch13(net, train_iter, test_iter, loss, trainer, num_epochs, devices)

    设置优化器、学习率和损失函数,并开始训练。`train_ch13`函数来自`d2l`工具箱,负责模型的训练过程。
9. 使用训练好的模型进行情感预测:

    d2l.predict_sentiment(net, vocab, 'this movie is so great')
    d2l.predict_sentiment(net, vocab, 'this movie is so bad')

    调用预测函数`predict_sentiment`测试模型效果,传入模型、词汇表和待预测的句子,函数会输出句子的情感倾向(正面或负面)。

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

109702008

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值