Seq2seq+RNN 的英文翻译

该代码实现了一个基于RNN的seq2seq模型,用于英文翻译任务。模型包含编码器和解码器两部分,其中编码器处理输入序列,解码器以全问号初始化并生成输出序列。训练过程中,通过循环计算每个时间步的交叉熵损失并累加。在翻译函数中,模型加载并应用于给定单词,输出预测的翻译。

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

# !/usr/bin/env Python3
# -*- coding: utf-8 -*-
# @version: v1.0
# @Author   : Meng Li
# @contact: 925762221@qq.com
# @FILE     : torch_seq2seq.py
# @Time     : 2022/6/8 11:11
# @Software : PyCharm
# @site: 
# @Description :
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import torchsummary
from torch.utils.data import Dataset, DataLoader
import numpy as np
import os


class Seq2seq(nn.Module):
    def __init__(self, in_features, hidden_size):
        super().__init__()
        self.in_features = in_features
        self.hidden_size = hidden_size
        self.encoder = nn.RNN(input_size=in_features, hidden_size=hidden_size, dropout=0.5)  # encoder
        self.decoder = nn.RNN(input_size=in_features, hidden_size=hidden_size, dropout=0.5)  # 翻译的解码器
        self.crition = nn.CrossEntropyLoss()
        self.fc = nn.Linear(hidden_size, in_features)

    def forward(self, enc_input, dec_input, dec_output):
        # enc_input.size() : [Batch_size,seq_len,embedding_size] -> [seq_len,Batch_size,embedding_size]
        enc_input = enc_input.permute(1, 0, 2)  # [seq_len,Batch_size,embedding_size]
        dec_input = dec_input.permute(1, 0, 2)  # [seq_len,Batch_size,embedding_size]
        # output:[seq_len,Batch_size,hidden_size]
        seq_len, batch_size, embedding_size = enc_input.size()
        h_0 = torch.rand(1, batch_size, self.hidden_size)
        _, ht = self.encoder(enc_input, h_0)  # en_ht:[num_layers * num_directions,Batch_size,hidden_size]
        de_output, _ = self.decoder(dec_input, ht)  # de_output:[seq_len,Batch_size,in_features]
        output = self.fc(de_output)
        output = output.permute(1, 0, 2)
        loss = 0
        for i in range(len(output)):  # 对seq的每一个输出进行二分类损失计算
            loss += self.crition(output[i], dec_output[i])
        return output, loss


class my_dataset(Dataset):
    def __init__(self, enc_input, dec_input, dec_output):
        super().__init__()
        self.enc_input = enc_input
        self.dec_input = dec_input
        self.dec_output = dec_output

    def __getitem__(self, index):
        return self.enc_input[index], self.dec_input[index], self.dec_output[index]

    def __len__(self):
        return self.enc_input.size(0)


def make_data1(seq_data):
    vocab = [i for i in "SE?abcdefghijklmnopqrstuvwxyz"]
    word2idx = {j: i for i, j in enumerate(vocab)}
    V = np.max([len(j) for i in seq_data for j in i])  # 求最长元素的长度
    enc_input = []
    dec_input = []
    dec_output = []
    for seq in seq_data:
        enc_input.append(np.eye(len(word2idx))[[word2idx[i] for i in seq[0] + (V - len(seq[0])) * "?" + 'E']])
        dec_input.append(np.eye(len(word2idx))[[word2idx[i] for i in 'S' + seq[1] + (V - len(seq[1])) * "?"]])
        dec_output.append([word2idx[i] for i in seq[1] + (V - len(seq[1])) * "?" + 'E'])
    return torch.tensor(enc_input).double(), torch.tensor(dec_input).double(), torch.LongTensor(dec_output).double()


def train():
    vocab = [i for i in "SE?abcdefghijklmnopqrstuvwxyz"]
    word2idx = {j: i for i, j in enumerate(vocab)}
    idx2word = {i: j for i, j in enumerate(vocab)}
    seq_data = [['man', 'women'], ['black', 'white'], ['king', 'queen'], ['girl', 'boy'], ['up', 'down'],
                ['high', 'low']]
    enc_input, dec_input, dec_output = make_data(seq_data)
    batch_size = 3
    in_features = 29
    hidden_size = 128

    train_data = my_dataset(enc_input, dec_input, dec_output)
    train_iter = DataLoader(train_data, batch_size, shuffle=True)

    net = Seq2seq(in_features, hidden_size)
    net.train()
    learning_rate = 0.001
    optimizer = optim.Adam(net.parameters(), lr=learning_rate)
    loss = 0

    for i in range(1000):
        for en_input, de_input, de_output in train_iter:
            output, loss = net(en_input, de_input, de_output)
            pre = torch.argmax(output, 2)
            # pre_ques = [[idx2word[j] for j in i] for i in en_input.numpy()]
            pre_ret = [[idx2word[j] for j in i] for i in pre.detach().numpy()]
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
        if i % 100 == 0:
            print("step {0} loss {1}".format(i, loss))
    torch.save(net, "translate.pt")


def make_data(seq_data):
    enc_input_all, dec_input_all, dec_output_all = [], [], []
    vocab = [i for i in "SE?abcdefghijklmnopqrstuvwxyz"]
    word2idx = {j: i for i, j in enumerate(vocab)}
    V = np.max([len(j) for i in seq_data for j in i])  # 求最长元素的长度
    for seq in seq_data:
        for i in range(2):
            seq[i] = seq[i] + '?' * (V - len(seq[i]))  # 'man??', 'women'

        enc_input = [word2idx[n] for n in (seq[0] + 'E')]
        dec_input = [word2idx[i] for i in [i for i in len(enc_input) * '?']]
        dec_output = [word2idx[n] for n in (seq[1] + 'E')]

        enc_input_all.append(np.eye(len(vocab))[enc_input])
        dec_input_all.append(np.eye(len(vocab))[dec_input])
        dec_output_all.append(dec_output)  # not one-hot

    # make tensor
    return torch.Tensor(enc_input_all), torch.Tensor(dec_input_all), torch.LongTensor(dec_output_all)


def translate(word):
    vocab = [i for i in "SE?abcdefghijklmnopqrstuvwxyz"]
    idx2word = {i: j for i, j in enumerate(vocab)}
    V = 5
    x, y, z = make_data([[word, "?" * V]])
    if not os.path.exists("translate.pt"):
        train()
    net = torch.load("translate.pt")
    pre, loss = net(x, y, z)
    pre = torch.argmax(pre, 2)[0]
    pre_word = [idx2word[i] for i in pre.numpy()]
    pre_word = "".join([i.replace("?", "") for i in pre_word])
    print(word, "->  ", pre_word[:pre_word.index('E')])


if __name__ == '__main__':
    translate('man')

 

老规矩,还是直接上代码

本代码主要实现了 采用RNN网络,构建seq2seq模型,对英文进行翻译。

seq2seq模型由编码器和解码器两个部分构成,编码器的输出作为隐含层传递到解码器

解码器的输入为随机初始化的,(这里采用全 ‘?’ 作为初始化内容)

解码器的输出为 [batch_size , seq_len , in_features] , 这里需要轮询seq_len个输出,采用交叉熵计算损失并累加。

<think>好的,我现在需要帮助用户了解seq2seq和UNet++的模型架构、应用场景以及实现方法。首先,我得先回忆这两个模型的基本结构,然后整理它们的应用领域,最后考虑如何实现它们。同时,用户可能希望得到对比或者结合两者的信息,所以需要明确区分各自的优缺点。 关于seq2seq模型,我记得它主要用于序列到序列的任务,比如机器翻译、文本摘要等。架构上通常由编码器和解码器组成,可能使用RNN、LSTM或者Transformer。需要注意注意力机制的引入对性能的提升。应用场景方面,除了翻译,还有对话系统、时间序列预测等。实现方法可能需要使用TensorFlow或PyTorch,比如使用LSTM层构建编码器和解码器,并训练模型最小化交叉熵损失。 然后是UNet++,主要用于图像分割,尤其是医学图像。模型结构上,它是在原始UNet基础上增加了密集跳跃连接,形成嵌套的U型结构。这种设计能改善梯度流动,提升分割精度。应用场景包括医学影像分析、卫星图像分割等。实现时可能需要使用卷积层、上采样和跳跃连接,代码框架可能是Keras或PyTorch。 接下来要检查用户提供的引用是否有相关的内容。引用[1]提到语义分割模型的选择因素,可能与UNet++的应用相关,可以引用。引用[2]关于逻辑推理的模型,可能不太相关,但如果有涉及架构设计的部分,可能需要参考,但暂时可能不需要引用。用户之前的问题可能涉及模型比较,所以需要明确区分两者的不同领域:一个是序列处理,一个是图像分割。 用户可能需要知道两者的架构差异,比如seq2seq处理变长序列,而UNet++处理二维图像。应用场景完全不同,但都是编码器-解码器结构的变体。可能需要指出它们的共同点和差异,比如都使用了跳跃连接(UNet++)或注意力(某些seq2seq变体)。 在实现方法部分,需要给出简单的代码示例,比如用PyTorch实现seq2seq的编码器-解码器结构,以及UNet++的模型搭建。但要注意代码的正确性,比如在seq2seq中处理输入序列,处理填充,注意力机制如何实现;在UNet++中如何构建密集跳跃连接,使用卷积块等。 最后生成相关问题,需要围绕架构细节、应用场景、优化方法、与其他模型的比较等方面提问,确保问题能够帮助用户进一步探索这两个模型。 需要确保回答结构清晰,分点说明,使用正确的LaTeX格式,行内公式用$...$,独立公式用$$...$$。同时检查是否有需要引用的地方,比如引用[1]提到的语义分割模型选择因素可以关联到UNet++的应用场景部分。</think>### Seq2Seq模型 **模型架构** Seq2Seq(Sequence-to-Sequence)由编码器(Encoder)和解码器(Decoder)组成,最初基于RNN/LSTM[^1]。其数学表示为: $$ h_t = f_{\text{enc}}(x_t, h_{t-1}), \quad s_i = f_{\text{dec}}(y_{i-1}, s_{i-1}, c) $$ 其中$h_t$为编码器隐藏状态,$s_i$为解码器状态,$c$为上下文向量(常通过注意力机制生成)。 **应用场景** - 机器翻译(如英译中) - 文本摘要生成 - 语音识别与生成 - 时间序列预测(需调整解码逻辑) **实现方法** 使用PyTorch的简化实现: ```python import torch.nn as nn class Seq2Seq(nn.Module): def __init__(self, input_dim, hidden_dim): super().__init__() self.encoder = nn.LSTM(input_dim, hidden_dim) self.decoder = nn.LSTM(hidden_dim, hidden_dim) self.fc = nn.Linear(hidden_dim, input_dim) ``` --- ### UNet++模型 **模型架构** UNet++通过密集跳跃连接改进原始UNet,形成嵌套解码路径[^1]: $$ X^{i,j} = \begin{cases} \mathcal{H}(X^{i-1,j}) & i=0 \\ \mathcal{H}([[X^{k,j}]_{k=0}^{i-1}], \mathcal{U}(X^{i+1,j-1})]) & i>0 \end{cases} $$ 其中$\mathcal{H}$为卷积块,$\mathcal{U}$为上采样操作。 **应用场景** - 医学图像分割(如肿瘤边界识别) - 卫星图像语义分割 - 工业缺陷检测 **实现方法** 典型结构包含: 1. 编码器:4-5级下采样 2. 解码器:密集跳跃连接+通道拼接 3. 深度监督:多尺度输出融合 --- ### 核心差异对比 | 特性 | Seq2Seq | UNet++ | |-------------|-----------------------|----------------------| | 输入类型 | 序列数据(文本/时序) | 二维图像 | | 核心组件 | 注意力机制 | 密集跳跃连接 | | 典型任务 | 机器翻译 | 医学图像分割 | | 计算复杂度 | $O(n^2)$(注意力) | $O(h \times w)$ | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值