seq2seq简单实现--在输入序列后添加1

import numpy as np
import tensorflow as tf
import functools

#参数设置
PAD = 0
EOS = 1

# embedding parameters
vocab_size = 10  #词典数量 约等于最后输出的数据库
input_embedding_size = 20  #embedding输入层大小 词的向量化的输入数据

# network parameters
encoder_hidden_units = 20
decoder_hidden_units = 20

# training parameters
batch_size = 100
max_batches = 3001 # 训练需要执行的batch的个数
batches_in_epoch = 1000


def gen_batch(inputs, max_seq_length=None):
    '''
    将inputs转换为numpy数组并将所有sequence用0填充到等长。
    参数
    -------
    inputs : (batch_size,seq_len)
    '''
    sequence_lengths = [len(seq) for seq in inputs] #用于获取每个序列的长度
    batch_size = len(inputs) #用于保存矩阵的行数,也就是batch——size
    if max_seq_length is None:
        max_seq_length = max(sequence_lengths)  #使用输入序列的最长序列长度作为长度限制
    # inputs对应的numpy数组,其中batch_size作为axis=0
    inputs_batch_major = np.zeros(shape=[batch_size, max_seq_length], dtype=np.int32) #初始为0随机化数组
    # seq:(seq_len,input_num)
    for i, seq in enumerate(inputs): #enumerate常用于循环中,用于将下标与数据分离 先分离每一行
        # element:input_num
        for j, element in enumerate(seq): #用于分离第二维的数据
            inputs_batch_major[i, j] = element #传入每一个数据
    # 将seq_len作为axis=0 因为后面需要time——step为第一维
    inputs_seq_major = inputs_batch_major.swapaxes(0, 1)
    return inputs_seq_major, max_seq_length #返回随机数列与序列长度

def random_sequences(length_from, length_to, vocab_lower, vocab_upper, batch_size):
    '''
    随机产生batch_size个sequences,
    其中sequences的长度介于[length_from,length_to],
    sequences中的值介于[vocab_lower,vocab_upper]
    '''
    if length_from > length_to: #错误异常判断
        raise ValueError('length_from > length_to')
    def random_length():
        '''
        随机产生介于[length_from,length_to]的整数
        '''
        if length_from == length_to:
            return length_from
        return np.random.randint(length_from, length_to + 1)

    while True:
        yield [np.random.randint(low=vocab_lower,
                              high=vocab_upper,
                              size=random_length()).tolist()  #生成batchsize组数据
            for _ in range(batch_size)
        ]

def next_feed(batches):
    '''
    用于train时,为sess产生feed_dict
    '''
    batch = next(batches) # 产生当前batch的数据
    encoder_inputs_, _ = gen_batch(batch) # 将该batch的数据处理为encoder期望的形式
    # decoder_inputs_是在原始sequence前拼接EOS
    decoder_inputs_, _ = gen_batch(
        [[EOS] + (sequence) for sequence in batch]
    )

    # decoder_targets_是在原始sequence后拼接EOS
    decoder_targets_, _ = gen_batch(
        [(sequence) + [EOS] for sequence in batch]
    )

    return {
        encoder_inputs: encoder_inputs_,
        decoder_inputs: decoder_inputs_,
        decoder_targets: decoder_targets_,
    }

# encoder_inputs:(batch_size,seq_len)
encoder_inputs = tf.placeholder(shape=[None,None], dtype=tf.int32, name='encoder_inputs')
# decoder_inputs:(batch_size,seq_len+1)
decoder_inputs = tf.placeholder(shape=[None,None], dtype=tf.int32, name='decoder_inputs')
# decoder_targets:(batch_size,seq_len+1)
decoder_targets = tf.placeholder(shape=[None,None], dtype=tf.int32, name='decoder_targets')

# embedding  用于将词的ID转化为向量用于输入到RNN中
lookup_table = tf.Variable(tf.random_normal([vocab_size,input_embedding_size],-1.,1.),dtype=tf.float32)
# eocoder_inputs_embedded:(batch_size,seq_len,input_embedding_size)
encoder_inputs_embedded = tf.nn.embedding_lookup(lookup_table,encoder_inputs)
decoder_inputs_embedded = tf.nn.embedding_lookup(lookup_table,decoder_inputs)
"""
函数:
tf.nn.embedding_lookup(

               params,

               ids,

               partition_strategy='mod',

               name=None,

              validate_indices=True,

              max_norm=None

)

参数说明:
params: 表示完整的嵌入张量,或者除了第一维度之外具有相同形状的P个张量的列表,表示经分割的嵌入张量
ids: 一个类型为int32或int64的Tensor,包含要在params中查找的id
partition_strategy: 指定分区策略的字符串,如果len(params)> 1,则相关。当前支持“div”和“mod”。 默认为“mod”
name: 操作名称(可选)
validate_indices:  是否验证收集索引
max_norm: 如果不是None,嵌入值将被l2归一化为max_norm的值

tf.nn.embedding_lookup()函数的用法主要是选取一个张量里面索引对应的元素
tf.nn.embedding_lookup(tensor,id):即tensor就是输入的张量,id 就是张量对应的索引
tf.nn.embedding_lookup()就是根据input_ids中的id,寻找embeddings中的第id行。比如input_ids=[1,3,5],则找出embeddings中第1,3,5行,组成一个tensor返回
embedding_lookup不是简单的查表,id对应的向量是可以训练的,训练参数个数应该是 category num*embedding size,也就是说lookup是一种全连接层

"""
# 定义encoder
encoder_cell = tf.contrib.rnn.LSTMCell(encoder_hidden_units)
encoder_outputs, encoder_final_state = tf.nn.dynamic_rnn(encoder_cell,
                                                         encoder_inputs_embedded,
                                                         dtype=tf.float32,
                                                         time_major=True) # time_major表示输入的axis=0轴为time(或者是seq_len)
del encoder_outputs # 将encoder的outputs丢弃,只将final_state传递给decoder

# 定义decoder
decoder_cell = tf.contrib.rnn.LSTMCell(decoder_hidden_units)
decoder_outputs,decoder_final_state = tf.nn.dynamic_rnn(decoder_cell,
                                                       decoder_inputs_embedded,
                                                       initial_state=encoder_final_state,
                                                       dtype=tf.float32,
                                                       time_major=True,
                                                       scope="plain_decoder")

# decoder_outputs是一个Tensor
#tf.contrib.layers.linear() = tf.contrib.layers.fully_connected()
decoder_logits = tf.contrib.layers.linear(decoder_outputs, vocab_size) #把输出转化为[batch_size,vocab_size]
decoder_prediction = tf.argmax(decoder_logits, 2)
stepwise_cross_entropy = tf.nn.softmax_cross_entropy_with_logits_v2(
    labels=tf.one_hot(decoder_targets, depth=vocab_size, dtype=tf.float32),
    logits=decoder_logits)

loss = tf.reduce_mean(stepwise_cross_entropy)
#损失值
train_op = tf.train.AdamOptimizer().minimize(loss)
#Adam优化器

batches = random_sequences(length_from=3, length_to=8,
                           vocab_lower=2, vocab_upper=10,
                           batch_size=batch_size)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    loss_track = []
    for batch in range(max_batches):
        fd = functools.partial(next_feed, batches)() #每次循环产生一个batch的数据
        _, l = sess.run([train_op, loss], fd) #通过梯度下降训练,fd为字典
        loss_track.append(l)

        if batch == 0 or batch % batches_in_epoch == 0:
            print('batch {}'.format(batch))
            print('  minibatch loss: {}'.format(sess.run(loss, fd)))
            predict_ = sess.run(decoder_prediction, fd)
            for i, (inp, pred) in enumerate(zip(fd[encoder_inputs].T, predict_.T)):
                print('  sample {}:'.format(i + 1))
                print('    input     > {}'.format(inp))
                print('    predicted > {}'.format(pred))
                if i >= 2:
                    break

版权声明:本文为CSDN博主「BQW_」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/bqw18744018044/article/details/85220584

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Seq2Seq-Attention模型是一种结合了序列序列seq2seq)模型和注意力机制的网络模型。它最早用于机器翻译任务,可以将一个可变长度的输入序列转换为一个固定长度的向量表示,然后再将这个向量表示转换为一个可变长度的输出序列。\[2\] 在传统的seq2seq模型中,当输入序列较长时,往往会丢失一些重要的信息。为了解决这个问题,Attention机制被引入。Attention机制可以使模型在生成输出序列的过程中,对输入序列的不同部分分配不同的注意力权重,从而更关注输入序列中与当前输出相关的部分。这样,模型可以更好地捕捉到输入序列中的重要信息,提高翻译的准确性和流畅性。\[3\] 在Seq2Seq-Attention模型中,注意力机制的引入使得模型能够更好地处理时间序列数据。通过对输入序列中不同时间步的信息进行权,模型可以更好地理解序列中的时序关系,并在生成输出序列时更准确地预测下一个时间步的值。这使得Seq2Seq-Attention模型在时间序列预测任务中表现出色。\[1\] 总结起来,Seq2Seq-Attention模型是一种结合了序列序列模型和注意力机制的网络模型,它可以更好地处理时间序列数据,并在时间序列预测任务中取得较好的效果。 #### 引用[.reference_title] - *1* [keras seq2seq_在Keras中建立具有Luong注意的Seq2Seq LSTM以进行时间序列预测](https://blog.csdn.net/weixin_26752765/article/details/108132790)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Seq2Seq和Attention机制详解](https://blog.csdn.net/vivian_ll/article/details/89227812)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值