pytorch 实现LSTM

本文通过使用PyTorch框架实现LSTM网络,对IMDb电影评论进行情感分析,详细介绍了从数据预处理到模型训练的全过程,包括词向量加载、文本编码、批次处理及模型评估。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

**

Pytorch基础知识点整理

**
梯度 下降:

#_*_coding:utf-8_*_
from math import pi
import torch
import torch.optim
x = torch.tensor([pi /3,pi /6],requires_grad = True)
optim = torch.optim.SGD([x,],lr = 0.1,momentum=0)

for step in range(11):
    if step:
        optim.zero_grad()#清零
        f.backward()#计算梯度
        optim.step()#更新参数
    f = - ((x.cos() ** 2).sum()) ** 2       #实验下来f函数的定义也可以放在if前面,结果不变
    print('step:{},x = {},f(x) = {}'.format(step,x.tolist(),f))

**

Pytorch实现LSTM

**

#_*_coding:utf-8_*_
import os
import codecs
import string
from nltk.corpus import stopwords
import snowballstemmer
import re
from itertools import chain
from gensim import models
import torch
from torch import nn
import torch.optim as optim
import torch.utils.data.dataloader as dataloader
from torch.autograd import Variable
import time
from sklearn.metrics import accuracy_score

def read_Data(path,seg = 'train'):
    labels = ['pos','neg']
    data = []
    for label in labels:
        files = os.listdir(os.path.join(path,seg,label))
        for file in files:
            file_data = codecs.open(os.path.join(path,seg,label,file),'r','utf-8')
            review = file_data.read().replace('\n','')
            if label == 'pos':
                data.append([review,1])
            elif label == 'neg':
                data.append([review,0])
    return data

train_data = read_Data('/Users/yangyang/Desktop/aclImdb')
test_data = read_Data('/Users/yangyang/Desktop/aclImdb','test')

def tokenizer(text):
    return [token.lower() for token in text.split(' ')]

#全部小写的data [[]]
train_token = []
test_token = []

for text,label in train_data:
    train_token.append(tokenizer(text))
for text,label in test_data:
    test_token.append(tokenizer(text))

#词表去重
vocab = set(chain(*train_token))
vocab_size = len(vocab)

model = models.KeyedVectors.load_word2vec_format('/Users/yangyang/Desktop/glove/word2vec.6B.100d.txt',binary=False,encoding='utf-8')


#给每个词一个特定的编号
word_to_idx = {word:i+1 for i,word in enumerate(vocab)}
word_to_idx['<unk>'] = 0
# idx_to_word = {word_to_idx[k]:k for k,v in word_to_idx}
idx_to_word = {i+1: word for i, word in enumerate(vocab)}
idx_to_word[0] = '<unk>'

#取编码
def encode_samples(data,vocab):
    result = []
    for items in data:
        tmp = []
        for strs in items:
            if strs in word_to_idx:
                tmp.append(word_to_idx[strs])
            else:
                tmp.append(0)
        result.append(tmp)
    return result
#解决长度问题  所有文本的长度统一为max_length
def pad_samples(data,max_length = 500,PAD = 0):
    padded_features = []
    for item in data:
        if len(item) >= max_length:
            pad_item = item[:max_length]
        else:
            pad_item = item
            while(len(pad_item) < max_length):
                pad_item.append(PAD)
        padded_features.append(pad_item)
    return padded_features

train_features = torch.Tensor(pad_samples(encode_samples(train_token,vocab)))
train_labels = torch.Tensor([label for _,label in train_data])
test_features = torch.Tensor(pad_samples(encode_samples(test_data,vocab)))
test_labels = torch.Tensor([label for _,label in test_data])

class LSTM(nn.Module):
    def __init__(self,vocab_size,embed_size,num_hiddens,num_layers,bidirectional,weight,lables,use_gpu,**kwargs):

        super(LSTM,self).__init__(**kwargs)
        self.num_hiddens = num_hiddens
        self.num_layers = num_layers
        self.use_gpu = use_gpu
        self.bidirectional = bidirectional
        self.embedding = nn.Embedding.from_pretrained(weight)
        self.embedding.weight.requires_grad = False
        self.encoder = nn.LSTM(input_size=embed_size,hidden_size=self.num_hiddens,
                               num_layers=num_layers,bidirectional=self.bidirectional
                               ,dropout=0)
        #bidirectional:True则为双向lstm默认为False
        if self.bidirectional:
            self.decoder = nn.Linear(num_hiddens*4,lables)
        else:
            self.decoder = nn.Linear(num_hiddens*2,lables)

    def forward(self, inputs):
        #size(64,500,300)
        embeddings = self.embedding(inputs)
        #permute后(500,64,300)   (batch,seq,input_size)
        #states.size(500,64,200)
        output, hidden = self.encoder(embeddings.permute([1, 0, 2]))
        #states[i] size(64,200)   -> encoding.size(64,400)
        encoding = torch.cat([output[0], output[-1]], dim=1)
        #这里就可以矩阵相乘了
        outputs = self.decoder(encoding)
        return outputs

num_epochs = 5
embed_size = 300
num_hiddens = 100
num_layers = 2
bidirectional = True
batch_size = 64
labels = 2
lr = 0.8
device = torch.device('cuda:0')
use_gpu = True

weight = torch.zeros(vocab_size+1,embed_size)

for i in range(len(model.index2word)):
    try:
        index = word_to_idx[model.index2word[i]]
    except:
        continue
    weight[index,:] = torch.from_numpy(model.get_vector(
        idx_to_word[word_to_idx[model.index2word[i]]]
    ))

net = LSTM(vocab_size=(vocab_size+1),embed_size=embed_size,num_hiddens=num_hiddens,num_layers=num_layers,
           bidirectional=bidirectional,weight=weight,
           lables=labels,use_gpu=use_gpu)
net.to(device)
loss_function = nn.CrossEntropyLoss()
optimizer = optim.SGD(filter(lambda p:p.requires_grad,net.parameters()),lr=lr)


train_set = torch.utils.data.TensorDataset(train_features,train_labels)
test_set = torch.utils.data.TensorDataset(test_features,test_labels)

train_iter = torch.utils.data.DataLoader(train_set,batch_size=batch_size,shuffle=True)
test_iter = torch.utils.data.DataLoader(test_set,batch_size=batch_size,shuffle=False)

for epoch in range(num_epochs):
    start = time.time()
    train_loss,test_losses = 0,0
    train_acc,test_acc = 0,0
    n,m = 0,0
    for feature,label in train_iter:
        n += 1
        net.zero_grad()
        feature = Variable(feature.cuda())
        label = Variable(label.cuda())
        score = net(feature)
        loss = loss_function(score,label)
        loss.backward()
        optimizer.step()

        train_acc += accuracy_score(torch.argmax(score.cpu().data,dim=1),label.cpu())
        train_loss += loss

    with torch.no_grad():
        for test_feature,test_label in test_iter:
            m += 1
            test_feature = test_feature.cuda()
            test_label = test_label.cuda()
            test_score = net(test_feature)
            test_loss = loss_function(test_score,test_label)
            test_acc += accuracy_score(torch.argmax(test_score.cpu().data,dim=1),test_label.cpu())
            test_losses += test_loss

    end = time.time()
    runtime = end - start
print('epoch: %d, train loss: %.4f, train acc: %.2f, test loss: %.4f, test acc: %.2f, time: %.2f' %
          (epoch, train_loss.data / n, train_acc / n, test_losses.data / m, test_acc / m, runtime))

参考博客https://samaelchen.github.io/pytorch_lstm_sentiment/

PyTorch是一个开源机器学习库,它提供了丰富的工具和函数,用于构建和训练深度学习模型。在PyTorch实现LSTM(长短期记忆)模型可以通过以下步骤完成: 1. 导入必要的库和模块: ```python import torch import torch.nn as nn ``` 2. 定义LSTM模型的类: ```python class LSTMModel(nn.Module): def __init__(self, input_size, hidden_size, num_layers, output_size): super(LSTMModel, self).__init__() self.hidden_size = hidden_size self.num_layers = num_layers self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True) self.fc = nn.Linear(hidden_size, output_size) def forward(self, x): h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device) c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device) out, _ = self.lstm(x, (h0, c0)) out = self.fc(out[:, -1, :]) return out ``` 3. 创建LSTM模型实例: ```python input_size = ... # 输入数据的特征维度 hidden_size = ... # LSTM隐含层的特征维度 num_layers = ... # LSTM模型的层数 output_size = ... # 输出结果的维度 model = LSTMModel(input_size, hidden_size, num_layers, output_size) ``` 4. 定义损失函数和优化器: ```python criterion = nn.MSELoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) ``` 5. 训练LSTM模型: ```python epochs = ... # 训练的轮数 for epoch in range(epochs): # 前向传播 outputs = model(inputs) loss = criterion(outputs, labels) # 反向传播和优化 optimizer.zero_grad() loss.backward() optimizer.step() # 每隔一定步数打印损失值 if (epoch+1) % print_interval == 0: print('Epoch [{}/{}], Loss: {:.4f}'.format(epoch+1, epochs, loss.item())) ``` 通过以上步骤,我们就可以在PyTorch实现一个简单的LSTM模型,并对其进行训练。当然,具体的实现方式还可以根据具体的任务需求做一些调整和改进。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值