现有代码如下：import torch
from torch import nn
from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence
from torch.utils.data import DataLoader
import d2lzh as d2l
def load_data(filename):
    with open(filename, 'r', encoding='utf-8') as f:
        corpus = f.read()
    corpus = corpus.replace(' ', ' ').replace('\r', ' ')
    corpus = corpus[:10000]
    idx_to_char = list(set(corpus))
    char_to_idx = {char: i for i, char in enumerate(idx_to_char)}
    corpus_indices = [char_to_idx[char] for char in corpus]
    vocab_size = len(idx_to_char)
    return corpus_indices, char_to_idx, idx_to_char, vocab_size

filename = 'D:/Users/mhdn/Desktop/jaychou_lyrics.txt'
corpus_indices, char_to_idx, idx_to_char, vocab_size = load_data(filename)
def data_iter_consecutive(corpus_indices, batch_size, seq_length):
    num_examples = (len(corpus_indices) - 1) // seq_length
    corpus_indices = torch.tensor(corpus_indices[:num_examples * seq_length])
    corpus_indices = corpus_indices.reshape((batch_size, -1))
    num_batches = corpus_indices.shape[1] // seq_length
    for i in range(0, num_batches * seq_length, seq_length):
        X = corpus_indices[:, i:i+seq_length]
        Y = corpus_indices[:, i+1:i+seq_length+1]
        yield X, Y
    # 处理最后一个batch的情况
    if num_batches * seq_length < corpus_indices.shape[1]:
        X = corpus_indices[:, num_batches * seq_length:]
        Y = corpus_indices[:, num_batches * seq_length + 1:]
        # 如果最后一个batch的大小不足batch_size，丢弃该batch
        if X.shape[1] == seq_length:
            yield X, Y
# 设置超参数
embed_size = 256
hidden_size = 512
num_layers = 2
lr = 1e-2
num_epochs = 100
batch_size = 32
seq_length = 35
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# 创建数据迭代器
data_iter = data_iter_consecutive(corpus_indices, batch_size, seq_length)
# 创建模型
class GRUModel(nn.Module):
    def __init__(self, vocab_size, embed_size, hidden_size, num_layers):
        super(GRUModel, self).__init__()
        self.embedding = nn.Embedding(vocab_size, embed_size)
        self.gru = nn.GRU(embed_size, hidden_size, num_layers)
        self.fc = nn.Linear(hidden_size, vocab_size)
        self.hidden_size = hidden_size
        self.num_layers = num_layers

    def forward(self, inputs, state):
        embeddings = self.embedding(inputs)
        packed_inputs = pack_padded_sequence(embeddings, lengths=[seq_length] * batch_size, enforce_sorted=False)
        packed_outputs, state = self.gru(packed_inputs, state)
        outputs, _ = pad_packed_sequence(packed_outputs)
        outputs = self.fc(outputs.reshape((-1, outputs.shape[-1])))
        return outputs, state

    def begin_state(self, batch_size, device):
        return torch.zeros((self.num_layers, batch_size, self.hidden_size), device=device)

model = GRUModel(vocab_size, embed_size, hidden_size, num_layers)
model = model.to(device)
# 定义损失函数和优化器# 定义损失函数和优化器
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=lr)
# 训练模型
for epoch in range(num_epochs):
    state = model.begin_state(batch_size, device)
    total_loss = 0
    for X, Y in data_iter:
        X = X.to(device)
        Y = Y.to(device)
        state = state.detach()
        outputs, state = model(X, state)
        loss = loss_fn(outputs, Y.reshape(-1))
        optimizer.zero_grad()
        loss.backward()
        d2l.grad_clipping(model.parameters(), 1)
        optimizer.step()
        total_loss += loss.item() * Y.numel()
    perplexity = d2l.math.exp(total_loss / len(corpus_indices))
    print(f'Epoch {epoch + 1}, Perplexity {perplexity:.2f}')。请给出其预测函数以及结果输出