1121古诗生成

 古诗生成的任务构建

导包,主函数get-data,构建word2index,记得给一个unk,index2word直接用list就可以了,然后是后建立数据集,用dataset老三样,init后面要将要用参数传进去,grtitem拿n句话,再将每句话的每个字的index给出来,后return出来这个地方要注意给他变成tensor类型,然后主函数开始实例化,traindataloder中传的参数有dataset和batchsize,这时候还要实例化一下模型,注意模型要传入的参数,还有实例化优化器,进入循环,取到了bach-index,他是一个tensor类型,在这里我们要把moudel中要用到的初始值和标签给表示出来,23个字对23个字,开始构建模型,一个模型中有个init和forward,在init中我们要设置几个参数,相当于继承,rnn模型需要什么参数,都要写好,中间的w就是embedingnum*hiddennum,batchfirst对其影响不大,他内部会自己转换,bidirectrional是双向的意思,这个乘与v的操作就相当于是一个线性层,再继承一下loss,在forward中对数据进行操作,我们给进去的数据是x,他是没有经过embedding的,进来之后进行embedding,然后将其传入rnn模型,这里我们可以看出来,其实我们这个大模型是自己建立的,数据只是进到rnn里面跑一下,需要他的返回值,根据shape我们可以知道rnn_out1是每个字的信息拼起来的,rnn_out2是包含每句话的信息,我们将rnn的

字符级别的输出乘上V,让他得到预测值,让下一个字成为标签,这样就可以计算loss了,这里计算loss的时候是下面调用,下面传的pre是三维的,我们要将其变成二维的,标签也是二维的,就可以算loss了,然后就是优化器等,算法结束,让他开始预测写诗,搞一个自动生成器,建立一个result,然后随机找一个字放到letter中,要排除符号,先将找到的第一个字放到列表中,然后将找到的这个字的index找到,将其放到设备上,这里要记住我们在生成的时候是需要自己去写这个循环的,不然就相当于没用到rnn的记忆,我们将h_0先设为0矩阵,然后开始循环23次,将index和h_0放进去,计算出来的index和h_0更新,根据index2word找到对应的字,然后将它添加到list中

 

import os
import torch.nn as nn
from torch.utils.data import Dataset,DataLoader
import torch
import random

def get_data(file,num=None):
    with open(file,"r",encoding="utf-8") as f:
        all_data = f.read().split("\n")
    if num is None:
        return all_data
    return all_data[:num]

def build_cor(train_text):
    word_2_index = {"UNK":0}
    for p in train_text:
        for w in p:
            if w not in word_2_index:
                word_2_index[w] = len(word_2_index)
    return word_2_index


class PDataset(Dataset):
    def __init__(self,all_text,word_2_index):
        self.all_text = all_text
        self.word_2_index = word_2_index

    def __getitem__(self,index):
        poetry = self.all_text[index]

        poetry_index = [word_2_index.get(i,0) for i in poetry]
        return torch.tensor(poetry_index)


    def __len__(self):
        return len(self.all_text)


class PModel(nn.Module):
    def __init__(self,corpus_len,embedding_num,hidden_num):
        super().__init__()
        self.embedding = nn.Embedding(corpus_len,embedding_num)
        self.rnn = nn.RNN(embedding_num,hidden_num,batch_first=True,num_layers=1,bidirectional=False)#是否为双向的
        self.V = nn.Linear(hidden_num,corpus_len)#这个v是为了去做分类的,所以输出的维度是词表的大小,预测所有的词。

        self.loss_fun = nn.CrossEntropyLoss()#多分类用的交叉熵损失函数

    def forward(self,x,label=None,h_0=None):#这个h0是专门为了预测而做的,因为我们要用历史信息来预测下一个字。训练模型的时候它内部就自己会有。
        batch_emb = self.embedding(x)

        r
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值