【NLP】LSTM 唐诗生成器 pytorch 版
admin
2024-04-03 13:13:31
0

参考这篇文章LSTM唐诗生成器Keras版

将相关的 keras 模型代码进行修改,改成对应的 pytorch 模型,现将有区别的部分放在这里。

训练模型

搭建网络

# 把keras 模型改成 pytorch 模型
# 建立LSTM模型
import torch
import torch.nn as nn
import torch.nn.functional as F# 设置 CUDA
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# model = Sequential()
# model.add(Embedding(10000, 128, input_length=20))
# model.add(LSTM(128, return_sequences=True))
# model.add(Dropout(0.2))
# model.add(LSTM(128))
# model.add(Dropout(0.2))
# model.add(Dense(10000, activation='softmax'))# 参考上述的 keras 模型,建立 pytorch 模型# 第二层 LSTM 只取最后一个输出,所以 return_sequences=Falseclass LSTMNet(nn.Module):def __init__(self):super(LSTMNet, self).__init__()self.embedding = nn.Embedding(10000, 128)self.lstm1 = nn.LSTM(input_size=128, hidden_size=128, num_layers=1, batch_first=True)self.dropout1 = nn.Dropout(0.2)self.lstm2 = nn.LSTM(input_size=128, hidden_size=128, num_layers=1, batch_first=True)self.dropout2 = nn.Dropout(0.2)self.fc = nn.Linear(128, 10000)def forward(self, x):x = self.embedding(x) # [batch_size, seq_len, embedding_size]x, _ = self.lstm1(x)  # [batch_size, seq_len, hidden_size]x = self.dropout1(x)  # [batch_size, seq_len, hidden_size]x, _ = self.lstm2(x)  # [batch_size, seq_len, hidden_size]x = self.dropout2(x)  # [batch_size, seq_len, hidden_size]x = x[:, -1, :] #       这里-1的意思是:取最后一个输出 [batch_size, hidden_size]x = self.fc(x)  #       [batch_size, 10000]return x
# 实例化模型
model = LSTMNet().to(device)
model

LSTMNet(
(embedding): Embedding(10000, 128)
(lstm1): LSTM(128, 128, batch_first=True)
(dropout1): Dropout(p=0.2, inplace=False)
(lstm2): LSTM(128, 128, batch_first=True)
(dropout2): Dropout(p=0.2, inplace=False)
(fc): Linear(in_features=128, out_features=10000, bias=True)
)

Pytorch 数据转换

注意:因为 y_train 和 y_test [batch, 1] 最后一个维度是没用的,
所以要把它去掉,变成 [batch] 才能正常给交叉熵损失函数计算

# 先把 x_train, x_test, y_train, y_test 转化为 tensor
x_train = torch.tensor(x_train).to(device)
x_test = torch.tensor(x_test).to(device)
y_train = torch.tensor(y_train).to(device)
y_test = torch.tensor(y_test).to(device)
# 测试样本能否正常输入网络
pred = model(x_train[0:3].to(device))
print(x_train[0:3].shape) # [3, 20] # 3个样本,每个样本20个词
print(pred.shape) # [3, 10000]     #  3个样本,每个样本10000个分类

torch.Size([3, 20])
torch.Size([3, 10000])

# 因为 y_train 和 y_test [batch, 1] 最后一个维度是没用的,
# 所以要把它去掉,变成 [batch] 才能正常给交叉熵损失函数计算
y_train = y_train.squeeze()
y_test = y_test.squeeze()# 转化成 Long
y_train = y_train.long()
y_test = y_test.long()# 查看形状
y_train.shape,y_test.shape

(torch.Size([39405]), torch.Size([16889]))

训练模型

# 训练模型
import torch.optim as optim
from tqdm import tqdm
optimizer = optim.Adam(model.parameters(), lr=0.001)batch_size = 256
epochs = 20# 注意,这里 y_train, y_test 的形状都是 [batch, 1] ,也就是说,并不是 one-hot 编码
# 所以,损失函数用的是 CrossEntropyLossloss_func = nn.CrossEntropyLoss()
for epoch in range(epochs):print('Epoch: ', epoch)for i in tqdm(range(0, len(x_train), batch_size)):x_batch = x_train[i:i+batch_size]y_batch = y_train[i:i+batch_size]pred = model(x_batch)loss = loss_func(pred, y_batch)optimizer.zero_grad()loss.backward()optimizer.step()# 每个 epoch 结束后,计算一下准确率# 训练集准确率pred = model(x_train)pred = torch.argmax(pred, dim=1)acc = (pred == y_train).sum().item() / len(y_train)print('Train acc: ', acc)# 测试集准确率pred = model(x_test)pred = torch.argmax(pred, dim=1)acc = (pred == y_test).sum().item() / len(y_test)print('Test acc: ', acc)

Epoch: 0
100%|██████████| 154/154 [00:38<00:00, 4.01it/s]
Train acc: 0.10216977540921203
Test acc: 0.10320326839955
Epoch: 1

Epoch: 19
100%|██████████| 154/154 [00:37<00:00, 4.09it/s]
Train acc: 0.20576069026773253
Test acc: 0.17970276511338742

test_string = '白日依山盡,黃河入海流,欲窮千里目,更上一'for i in range(300):# 循环 300 步,每步都要预测一个字test_string_token = tokenizer.texts_to_sequences([test_string[-20:]]) # 取最后20个字test_string_mat = np.array(test_string_token)pred = model(torch.tensor(test_string_mat).to(device)) # pred 的形状是 [1, 10000]pred_argmax = torch.argmax(pred, dim=1).item()         # pred_argmax 的形状是 [1]# 把预测的字转化为文字tokenizer.index_word[pred_argmax]test_string = test_string + tokenizer.index_word[pred_argmax]
print(test_string)

相关内容

热门资讯

亚朵节后价格“跳水”超70% 春节过后,部分热门小城的亚朵酒店房价上演“过山车”行情,房价节前飙升,节后迅速跳水,巨大的价格波动引...
原创 金... 你绝对想不到,同样一克999足金,在深圳水贝批发市场只要1334元,走进周大福门店却变成1545元,...
德兰明海冲击港交所!递表前大手... 又一家储能企业“叩响”了港交所大门。近期,港交所官网显示,中小型用户侧储能企业深圳市德兰明海新能源股...
绿茶集团、猫眼娱乐发布正面盈利... |2026年2月25日 星期三| NO.1绿茶集团发布正面盈利预告 2月24日港股收市后,绿茶集团(...
安宁市的历史文化及名人有哪些 安宁市,这座坐落在彩云之南的城市,宛如一颗璀璨明珠,散发着迷人的历史文化魅力。在这里,岁月留下了深深...
中国央行连续12个月加量续作M... 来源:中国新闻网 中新社北京2月24日电 (陶思阅)中国央行24日发布中期借贷便利(MLF)招标公告...
不是15%?特朗普10%全球关... 据美国海关及边境保卫局(CBP)发布消息,特朗普政府将实施的新全球关税为10%。 第一财经收到的CB...
2026年春节出游人次、消费金... 2026年春节,为期9天的超长假期点燃了全国消费热情,多项核心数据创下历史纪录。 经文化和旅游部数据...
美国联邦存款保险公司(FDIC... 美国联邦存款保险公司(FDIC):美国银行业存款季环比下滑2%。
2026春节AI大战深度复盘:... 主编温静导读:2026年春节,元宝、千问、豆包三大巨头以红包、免单为杠杆,发动了一场规模空前的用户争...
期市节后首日金属板块普涨 白银... 本报记者 王宁 2月24日,春节后的首个交易日,国内期货市场呈现涨多跌少态势。 从板块表现来看,农产...
月跌超10%背后:软件行业,将... 此前一天,2月23日,人工智能公司Anthropic宣布,其Claude Code工具可用于在IBM...
公告精选 |《飞驰人生3》票房... 控制权收购 东阳光(600673.SH):公司正在筹划通过发行股份的方式收购宜昌东数一号投资有限责任...
东阳光:筹划收购东数一号控制权... 上证报中国证券网讯(记者 骆民)东阳光公告,公司正在筹划通过发行股份的方式收购宜昌东数一号投资有限责...
原创 高... 你有没有发现,几年前人人都在拼命买房,而现在,越来越多人开始思考,房子,到底还是不是财富? 这几年,...
这个春节,中国经济热力值拉满 2026年的春节,注定要在中国消费市场上留下浓墨重彩的一笔。 当9天的超长假期遇上持续加码的政策红利...
2026年中国汽车产业十大趋势... 2025年,中国汽车产业在连续17年产销量稳居全球第一的基础上,再次交出了一份充满变革与挑战的答卷。...
2022年天猫烘焙厨电行业趋势... 今天分享的是:2022年天猫烘焙厨电行业趋势白皮书 报告共计:7页 烘焙厨电迎来新变革:从“功能单一...