pytorch——LSTM实现情感分类问题

在这里插入图片描述

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2021/8/1 0:23
# @Author  : Liu Lihao
# @File    : LSTM.py

# -*- coding: utf-8 -*-


import torch
from torch import nn, optim
from torchtext.legacy import data, datasets
import numpy as np


print('GPU:', torch.cuda.is_available())

torch.manual_seed(123)  # 为CPU中设置种子,生成随机数
# 设置随机种子可以确保每次生成固定的随机数,这就使得每次实验结果显示一致了,有利于实验的比较和改进。


'''载入数据'''
TEXT = data.Field(tokenize='spacy')
LABEL = data.LabelField(dtype=torch.float)
train_data, test_data = datasets.IMDB.splits(TEXT, LABEL)

print('len of train data:', len(train_data))  # len of train data: 25000
print('len of test data:', len(test_data))  # len of test data: 25000

print(train_data.examples[15].text)
print(train_data.examples[15].label)
'''
text: ['This', 'is', 'just', 'as', 'good', 'as', 'the', 'original', '101', 'if', 'not', 'better', '.', 'Of', 'course', ',', 'Cruella', 'steals', 'the', 'show', 'with', 'her', 'outrageous', 'behaviour', 'and', 'outfits', ',', 'and', 'the', 'movie', 'was', 'probably', 'made', 'because', 'the', 'public', 'wanted', 'to', 'see', 'more', 'of', 'Cruella', '.', 'We', 'see', 'a', 'lot', 'more', 'of', 'her', 'this', 'time', 'round', '.', 'I', 'also', 'like', 'Ioan', 'Gruffudd', 'as', 'Kevin', ',', 'the', 'rather', 'bumbling', 'male', 'lead', '.', 'To', 'use', 'Paris', 'as', 'the', 'climax', 'of', 'the', 'movie', 'was', 'a', 'clever', 'idea', '.', 'The', 'movie', 'is', 'well', 'worth', 'watching', 'whatever', 'your', 'age', ',', 'provided', 'you', 'like', 'animals', '.']
label: pos
'''

# 对文本内容进行编码
TEXT.build_vocab(train_data, max_size=10000, vectors='glove.6B.100d')
LABEL.build_vocab(train_data)


batchsz = 30
device = torch.device('cuda')
train_iterator, test_iterator = data.BucketIterator.splits(
    (train_data, test_data),
    batch_size=batchsz,
    device=device
)


class RNN(nn.Module):

    def __init__(self, vocab_size, embedding_dim, hidden_dim):
        """
        """
        super(RNN, self).__init__()

        # [0-10001] => [100]
        self.embedding = nn.Embedding(vocab_size, embedding_dim)  # 对单词进行编码。
        # 编码vocab_size个单词,每个单词编码为embedding_dim维度的向量
        # [100] => [256]
        self.rnn = nn.LSTM(embedding_dim, hidden_dim, num_layers=2,
                           bidirectional=True, dropout=0.5)  # memory是hidden_dim
        # [256*2] => [1]
        self.fc = nn.Linear(hidden_dim * 2, 1)
        self.dropout = nn.Dropout(0.5)

    def forward(self, x):
        """
        x: [seq_len, b] vs [b, 3, 28, 28]
        """
        # [seq, b, 1] => [seq, b, 100]
        embedding = self.dropout(self.embedding(x))

        # output: [seq, b, hid_dim*2]
        # hidden/h: [num_layers*2, b, hid_dim]
        # cell/c: [num_layers*2, b, hid_di]
        output, (hidden, cell) = self.rnn(embedding)

        # [num_layers*2, b, hid_dim] => 2 of [b, hid_dim] => [b, hid_dim*2]
        hidden = torch.cat([hidden[-2], hidden[-1]], dim=1)

        # [b, hid_dim*2] => [b, 1]
        hidden = self.dropout(hidden)
        out = self.fc(hidden)

        return out


'''构建网络'''
rnn = RNN(len(TEXT.vocab), 100, 256)

pretrained_embedding = TEXT.vocab.vectors
print('pretrained_embedding:', pretrained_embedding.shape)
rnn.embedding.weight.data.copy_(pretrained_embedding)
print('embedding layer inited.')

optimizer = optim.Adam(rnn.parameters(), lr=1e-3)
criteon = nn.BCEWithLogitsLoss().to(device)
rnn.to(device)




def binary_acc(preds, y):
    """
    get accuracy
    """
    preds = torch.round(torch.sigmoid(preds))
    correct = torch.eq(preds, y).float()
    acc = correct.sum() / len(correct)
    return acc


def train(rnn, iterator, optimizer, criteon):
    avg_acc = []
    rnn.train()

    for i, batch in enumerate(iterator):

        # [seq, b] => [b, 1] => [b]
        pred = rnn(batch.text).squeeze(1)
        #
        loss = criteon(pred, batch.label)
        acc = binary_acc(pred, batch.label).item()
        avg_acc.append(acc)

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if i % 10 == 0:
            print(i, acc)

    avg_acc = np.array(avg_acc).mean()
    print('avg acc:', avg_acc)


def eval(rnn, iterator, criteon):
    avg_acc = []

    rnn.eval()

    with torch.no_grad():
        for batch in iterator:
            # [b, 1] => [b]
            pred = rnn(batch.text).squeeze(1)

            #
            loss = criteon(pred, batch.label)

            acc = binary_acc(pred, batch.label).item()
            avg_acc.append(acc)

    avg_acc = np.array(avg_acc).mean()

    print('>>test:', avg_acc)


for epoch in range(10):
    eval(rnn, test_iterator, criteon)
    train(rnn, train_iterator, optimizer, criteon)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LSTM(Long Short-Term Memory)是一种循环神经网络(RNN)架构,可以在处理序列数据时保留长期的信息。LSTM情感分类是利用LSTM模型对文本进行分类,将文本分为积极、消极或中性情感类别。 下面是一个简单的LSTM情感分类的代码示例: 1. 数据预处理: 在进行LSTM情感分类之前,需要对数据进行预处理。将原始文本转换为数字序列,将每个单词转换为一个唯一的整数标识。 2. 构建LSTM模型: 构建LSTM模型包括以下几个步骤: - 嵌入层:将数字序列转换为词向量。 - LSTM层:包括多个LSTM单元。 - 全连接层:将LSTM输出的向量连接到输出层。 下面是一个简单的LSTM模型代码示例: ``` model = Sequential() model.add(Embedding(vocab_size, 128, input_length=max_len)) model.add(LSTM(128, dropout=0.2, recurrent_dropout=0.2)) model.add(Dense(3, activation='softmax')) ``` 3. 训练模型: 将数据集分成训练集和测试集,然后使用训练集对模型进行训练,调整模型参数以提高准确性。 下面是一个简单的训练代码示例: ``` model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) model.fit(X_train, y_train, epochs=5, batch_size=32) ``` 4. 模型评估: 使用测试集对模型进行评估,计算准确性和损失等指标。 下面是一个简单的评估代码示例: ``` scores = model.evaluate(X_test, y_test, verbose=0) print("Accuracy: %.2f%%" % (scores*100)) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值