Pytorch基于 LSTM 的自动写诗

实验环境

  1. Pytorch 1.4.0
  2. conda 4.7.12
  3. Jupyter Notebook 6.0.1
  4. Python 3.7

数据集介绍

chinese-poetry: 最全中文诗歌古典文集数据库
最全的中华古典文集数据库,包含 5.5 万首唐诗、26 万首宋诗、2.1 万首宋词和其他古典文集。诗 人包括唐宋两朝近 1.4 万古诗人,和两宋时期 1.5 千古词人。数据来源于互联网。
实验使用预处理过的二进制文件 tang.npz 作为数据集,含有 57580 首唐诗,每首诗限定在 125 词, 不足 125 词的以 填充。数据集以 npz 文件形式保存,包含三个部分:

  1. data: (57580,125) 的 numpy 数组,总共有 57580 首诗歌,每首诗歌长度为 125 字符 (不足 125 补空格,超过 125 的丢弃),将诗词中的字转化为其在字典中的序号表示
  2. ix2word: 序号到字的映射,每个序号和它对应的词,例如序号 898 对应“雪”
  3. word2ix: 字到序号的映射,每个字和它对应的序号,例如“雪”对应序号是 898

训练过程

数据准备

首先,导入实验所需的库,定义一些宏参数,BATCH_SIZE 表示每个 batch 加载多少个样本、 EPOCHS 表示总共训练批次。如果支持 cuda 就用 gpu 来 run,不支持就用 cpu 来 run。

import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import time
import matplotlib.pyplot as plt
from torch.optim.lr_scheduler import *
from torch.utils.data import DataLoader
from torch.autograd import Variable

BATCH_SIZE = 16
EPOCHS = 4 
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")

我先读取预处理好的数据,再将其转为 Tensor,这次没有使用 Dataset 去封装 data,但是它还是 可以利用 Dataloader 进行多线程加载,因为 data 作为一个 Tensor 对象,自身已经实现了 getitem 和 len 方法。接着构造数据提供器,shuffle=True 设置在每个 epoch 重新打乱数据,保证数据的随机性;还有多线程加载数据。处理好了训练数据。

# 读入预处理的数据
datas = np.load("./tang.npz")
data = datas['data']
ix2word = datas['ix2word'].item()
word2ix = datas['word2ix'].item()
    
# 转为torch.Tensor
data = torch.from_numpy(data)
train_loader = DataLoader(data, batch_size = BATCH_SIZE, shuffle = True, num_workers = 2)

网络配置

定义一个循环神经网络,输入的字词序号经过 nn.Embedding 得到相应词的词向量表示,然后利用 3 层 LSTM 提取词的所有隐藏元信息,再利用隐藏元的信息进行分类,判断输出属于每一个词的概率。 然后通过全连接的输出层将词向量升维回字词序号,全连接输出层所有激活函数都使用 ReLU 函数。

class PoetryModel(nn.Module):
    def __init__(self, vocab_size, embedding_dim, hidden_dim):
        super(PoetryModel, self).__init__()
        self.hidden_dim = hidden_dim
        self.embedding = nn.Embedding(vocab_size, embedding_dim)
        self.lstm = nn.LSTM(embedding_dim, self.hidden_dim, num_layers=3)
        self.classifier=nn.Sequential(
            nn.Linear(self.hidden_dim, 512), 
            nn.ReLU(inplace=True), 
            nn.Linear(512, 2048), 
            nn.ReLU(inplace=True),
            nn.Linear(2048, vocab_size)
        )

    def forward(self, input, hidden = None):
    
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值