美文网首页
GPT图解:代码记录-S2S框架

GPT图解:代码记录-S2S框架

作者: 万州客 | 来源:发表于2024-02-21 08:28 被阅读0次

    一,代码

    sentences = [
        ['咖哥 喜欢 小冰','<sos> KaGe likes XiaoBing', 'KaGe likes XiaoBing <eos>'],
        ['我 爱 学习 人工智能','<sos> I love studying AI', 'I love studying AI <eos>'],
        ['深度学习 改变 世界','<sos> DL changed the world', 'DL changed the world <eos>'],
        ['自然 语言 处理 很 强大','<sos> NLP is so powerful', 'NLP is so powerful <eos>'],
        ['神经网络 非常 复杂','<sos> Neural-Nets are complex', 'Neural-Nets are complex <eos>']
    ]
    
    word_list_cn, word_list_en = [], []
    for s in sentences:
        word_list_cn.extend(s[0].split())
        word_list_en.extend(s[1].split())
        word_list_en.extend(s[2].split())
    
    word_list_cn = list(set(word_list_cn))
    word_list_en = list(set(word_list_en))
    
    word2idx_cn = {w: i for i, w in enumerate(word_list_cn)}
    word2idx_en = {w: i for i, w in enumerate(word_list_en)}
    
    idx2word_cn = {i: w for i, w in enumerate(word_list_cn)}
    idx2word_en = {i: w for i, w in enumerate(word_list_en)}
    
    voc_size_cn = len(word_list_cn)
    voc_size_en = len(word_list_en)
    
    print("句子数量: ", len(sentences))
    print("中文词汇表大小: ", voc_size_cn)
    print("英文词汇表大小: ", voc_size_en)
    print("中文词汇到索引的字典: ", word2idx_cn)
    print("英文词汇到索引的字典: ", word2idx_en)
    
    import numpy as np
    import torch
    import random
    
    def make_data(sentences):
        random_sentence = random.choice(sentences)
        encoder_input = np.array([[word2idx_cn[n] for n in random_sentence[0].split()]])
        decoder_input = np.array([[word2idx_en[n] for n in random_sentence[1].split()]])
        target = np.array([[word2idx_en[n] for n in random_sentence[2].split()]])
        encoder_input = torch.LongTensor(encoder_input)
        decoder_input = torch.LongTensor(decoder_input)
        target = torch.LongTensor(target)
        return encoder_input, decoder_input, target
    
    encoder_input, decoder_input, target = make_data(sentences)
    for s in sentences:
        if all([word2idx_cn[w] in encoder_input[0] for w in s[0].split()]):
            original_sentence = s
            break
    
    print("原始句子: ", original_sentence)
    print('编码器输入张量的形状:', encoder_input.shape)
    print('解码器输入张量的形状: ', decoder_input.shape)
    print('目标张量的形状: ', target.shape)
    print('编码器输入张量: ',encoder_input)
    print('解码器输入张量: ', decoder_input)
    print('目标张量: ', target)
    
    import torch.nn as nn
    
    class Encoder(nn.Module):
        def __init__(self, input_size, hidden_size):
            super(Encoder,self).__init__()
            self.hidden_size = hidden_size
            self.embedding = nn.Embedding(input_size, hidden_size)
            self.rnn = nn.RNN(hidden_size, hidden_size,batch_first=True)
    
        def forward(self, inputs, hidden):
            embedded = self.embedding(inputs)
            output, hidden = self.rnn(embedded, hidden)
            return output, hidden
    
    
    class Decoder(nn.Module):
        def __init__(self, hidden_size, output_size):
            super(Decoder,self).__init__()
            self.hidden_size = hidden_size
            self.embedding = nn.Embedding(output_size, hidden_size)
            self.rnn = nn.RNN(hidden_size, hidden_size, batch_first=True)
            self.out = nn.Linear(hidden_size, output_size)
    
        def forward(self, inputs, hidden):
            embedded = self.embedding(inputs)
            output, hidden = self.rnn(embedded, hidden)
            output = self.out(output)
            return output, hidden
    
    n_hidden = 128
    encoder = Encoder(voc_size_cn, n_hidden)
    decoder = Decoder(n_hidden, voc_size_en)
    print('编码器结构: ', encoder)
    print('解码器结构: ', decoder)
    
    class Seq2Seq(nn.Module):
        def __init__(self, encoder, decoder):
            super(Seq2Seq, self).__init__()
            self.encoder = encoder
            self.decoder = decoder
    
        def forward(self, enc_input, hidden, dec_input):
            encoder_input, encoder_hidden = self.encoder(enc_input, hidden)
            decoder_hidden = encoder_hidden
            decoder_output, _ = self.decoder(dec_input, decoder_hidden)
            return decoder_output
    
    model = Seq2Seq(encoder, decoder)
    print('S2S模型结构: ', model)
    
    def train_seq2seq(model, criterion, optimizer, epochs):
        for epoch in range(epochs):
            encoder_input, decoder_input, target = make_data(sentences)
            hidden = torch.zeros(1, encoder_input.size(0), n_hidden)
            optimizer.zero_grad(0)
            output = model(encoder_input, hidden, decoder_input)
            loss = criterion(output.view(-1, voc_size_en), target.view(-1))
            if (epoch+1) % 40 == 0:
                print(f'Epoch: {epoch + 1:04d} cost = {loss:.6f}')
            loss.backward()
            optimizer.step()
    
    epochs = 400
    criterion = nn.CrossEntropyLoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
    train_seq2seq(model, criterion, optimizer, epochs)
    
    def test_seq2seq(model, source_sentence):
        encoder_input = np.array([[word2idx_cn[n] for n in source_sentence.split()]])
        print(word2idx_en)
        decoder_input = np.array([word2idx_en['<sos>']] + [word2idx_en['<eos>']] * (len(encoder_input[0]) -1))
        encoder_input = torch.LongTensor(encoder_input)
        decoder_input = torch.LongTensor(decoder_input).unsqueeze(0)
        hidden = torch.zeros(1, encoder_input.size(0), n_hidden)
        predict = model(encoder_input, hidden, decoder_input)
        predict = predict.data.max(2, keepdim=True)[1]
        print(source_sentence, '->', [idx2word_en[n.item()] for n in predict.squeeze()])
    
    test_seq2seq(model, '咖哥 喜欢 小冰')
    test_seq2seq(model, '自然 语言 处理 很 强大')
    

    二,输出

    D:\Python310\python.exe D:\tmp\GPT\S2S.py 
    句子数量:  5
    中文词汇表大小:  18
    英文词汇表大小:  20
    中文词汇到索引的字典:  {'学习': 0, '非常': 1, '自然': 2, '语言': 3, '爱': 4, '世界': 5, '深度学习': 6, '处理': 7, '很': 8, '改变': 9, '神经网络': 10, '人工智能': 11, '复杂': 12, '咖哥': 13, '我': 14, '喜欢': 15, '小冰': 16, '强大': 17}
    英文词汇到索引的字典:  {'so': 0, 'are': 1, 'studying': 2, 'likes': 3, 'the': 4, 'changed': 5, 'DL': 6, 'AI': 7, 'is': 8, 'powerful': 9, 'love': 10, '<eos>': 11, 'complex': 12, '<sos>': 13, 'world': 14, 'I': 15, 'KaGe': 16, 'NLP': 17, 'Neural-Nets': 18, 'XiaoBing': 19}
    原始句子:  ['咖哥 喜欢 小冰', '<sos> KaGe likes XiaoBing', 'KaGe likes XiaoBing <eos>']
    编码器输入张量的形状: torch.Size([1, 3])
    解码器输入张量的形状:  torch.Size([1, 4])
    目标张量的形状:  torch.Size([1, 4])
    编码器输入张量:  tensor([[13, 15, 16]])
    解码器输入张量:  tensor([[13, 16,  3, 19]])
    目标张量:  tensor([[16,  3, 19, 11]])
    编码器结构:  Encoder(
      (embedding): Embedding(18, 128)
      (rnn): RNN(128, 128, batch_first=True)
    )
    解码器结构:  Decoder(
      (embedding): Embedding(20, 128)
      (rnn): RNN(128, 128, batch_first=True)
      (out): Linear(in_features=128, out_features=20, bias=True)
    )
    S2S模型结构:  Seq2Seq(
      (encoder): Encoder(
        (embedding): Embedding(18, 128)
        (rnn): RNN(128, 128, batch_first=True)
      )
      (decoder): Decoder(
        (embedding): Embedding(20, 128)
        (rnn): RNN(128, 128, batch_first=True)
        (out): Linear(in_features=128, out_features=20, bias=True)
      )
    )
    Epoch: 0040 cost = 0.645620
    Epoch: 0080 cost = 0.061052
    Epoch: 0120 cost = 0.035644
    Epoch: 0160 cost = 0.037087
    Epoch: 0200 cost = 0.019005
    Epoch: 0240 cost = 0.017388
    Epoch: 0280 cost = 0.011249
    Epoch: 0320 cost = 0.010387
    Epoch: 0360 cost = 0.010690
    Epoch: 0400 cost = 0.005080
    {'so': 0, 'are': 1, 'studying': 2, 'likes': 3, 'the': 4, 'changed': 5, 'DL': 6, 'AI': 7, 'is': 8, 'powerful': 9, 'love': 10, '<eos>': 11, 'complex': 12, '<sos>': 13, 'world': 14, 'I': 15, 'KaGe': 16, 'NLP': 17, 'Neural-Nets': 18, 'XiaoBing': 19}
    咖哥 喜欢 小冰 -> ['KaGe', 'likes', 'XiaoBing']
    {'so': 0, 'are': 1, 'studying': 2, 'likes': 3, 'the': 4, 'changed': 5, 'DL': 6, 'AI': 7, 'is': 8, 'powerful': 9, 'love': 10, '<eos>': 11, 'complex': 12, '<sos>': 13, 'world': 14, 'I': 15, 'KaGe': 16, 'NLP': 17, 'Neural-Nets': 18, 'XiaoBing': 19}
    自然 语言 处理 很 强大 -> ['NLP', 'is', 'so', '<eos>', 'Neural-Nets']
    
    Process finished with exit code 0
    
    

    相关文章

      网友评论

          本文标题:GPT图解:代码记录-S2S框架

          本文链接:https://www.haomeiwen.com/subject/dzjundtx.html