tensorflow-seq2seq-Attention

本文介绍了使用TensorFlow构建Seq2Seq模型的基础知识,包括编码器、解码器的构建,并简述了文本处理过程。文章强调了在处理长文本时,使用双向动态RNN以提升效果。此外,还讨论了Decoder中的Helper类,如TrainingHelper和GreedyEmbeddingHelper,并提到添加注意力机制以提高模型性能。
摘要由CSDN通过智能技术生成

初学tensorflow, 发现网上坑太多了,各种版本的滞后,一下代码这样写,一下代码那样写~~很多都是老的书写方式! 走了许许多多的弯路,所以想整理一下最新的版本来梳理一下,也可以自己未来回顾的时候有个参考!

注: 现在最新版本是 tensorflow1.9 的版本, 我自己安装的是 1.8的! 所以本文代码肯定适用1.8版本!  1.9应该也适用~~并没有多少改动这方面的代码

 

tensorflow是什么么,基础的概念我就不重复了,一点都不懂的请去看基础教程自己学习! 本文主要以seq2seq 做NLP方面的讲解, 如果你也跟我一样是从  普通神经网络--卷积神经网络--循环神经网络的步骤走过来的话, 一些基本概念应该也都能明白

做初级的 NLP 主要分为以下几个步骤:

1. sample 文本数据的处理
2. seq2seq encoder
3. seq2seq decoder
4. train model
5. prediciting
 

本文跳过文本处理的代码阶段,主要讲 encoder decoder的构建方面, 文本方面的处理会稍微带过一下

一、文本处理

首先你需要有一些sample的数据,可能是英文、中文等等各种文本,里面也可能有各种符号等等

比如聊天机器人的文本, 第一行是问,第二行是答, 第三行是问,第四行是答 这样依此类推下去, 你要做的就是讲这个文本进行处理,无论使用 python的基本语法还是用一些python工具模块 nltk 等来处理文本,最终要讲文本处理成  input_source , output_target这样两个大类,  input_source 就是所有问的语句 一行代表一句问.   output_target就是所有答的语句 也是一行一句答. 类似于基本的神经网络里  X,  Y 这样的数据! 当然分好后,你还要对input_source output_target做一些处理 比如取掉一些没用的特殊字符等,就是要保留纯英文(中午)等,还有记得去除每个行尾巴的 '\n'符号

这时候 你经过处理的到了纯净的 input_source, output_target  然后你就要用这两个内容去做 word_to_int   int_to_word这两个方面的转换了 source 和target都要做这方面的转换  然后你的到 input_source_int    output_target_int 类似这样的 纯数字的东西~~ 也是一样的 一行就代表一个sample 一个target 这样的数据就可以 用到 encoder decoder里面了!

文本处理方面不是本文重点,只是讲了大概要做的处理 最终就是讲文本变成 [1,32,4123,4121,53,56,78......] 类似这样的东西 因为每句话的长度大小都不一定,以及一些其他问题 所以这时候就会有 <PAD>, <UNK>,<EOS>,<GO>这些特殊的符号也要加入进来 当然这些特殊的符号也是转换成特定的数字加入到 input_source_int    output_target_int里面来! 详细的操作代码方面,我下回有空了整理一下 专门开一篇文章来介绍如何处理.

二、seq2seq encoder

seq2seq 的原理本文就不介绍了,相信有太多的文章会很详细的介绍,然后画一大堆图以及数学公式来告诉你如何实现, 那些数学公式基本上数学差的人是看不懂的,看懂了也记得不~~~ 所以本文主要从代码方面介绍, 详细的理论方面请google~~~

seq2seq 分为两大部分, 一个是encoder部分 另一个是decoder部分,我们先讲encoder部分:

def get_encoder_layer(input_data, source_vocab_size,encoding_embedding_size,rnn_size,source_sequence_length, num_layers):
    encoder_embed_input = tf.contrib.layers.embed_sequence(input_data, source_vocab_size, encoding_embedding_size)

    def get_signle_cell(rnn_size):
        cell = tf.contrib.rnn.LSTMCell(rnn_size)
        return cell

    rnn_cell = tf.contrib.rnn.MultiRNNCell([get_signle_cell(rnn_size) for _ in range(num_layers)])

    encoder_output,encoder_state = tf.nn.dynamic_rnn(rnn_cell,encoder_embed_input,source_sequence_length, dtype=tf.float32)

    return encoder_output, encoder_state

上面这部分代码就是encoder层的全部代码了~~ 各个参数当然是之前定义好的 我这里讲解一下

input_data  就是通过batch的 input_source_int

### 回答1: 以下是一个简单的 self-attention 代码示例,使用 TensorFlow 实现: ```python import tensorflow as tf class SelfAttention(tf.keras.layers.Layer): def __init__(self, units): super(SelfAttention, self).__init__() self.W1 = tf.keras.layers.Dense(units) self.W2 = tf.keras.layers.Dense(units) self.V = tf.keras.layers.Dense(1) def call(self, inputs): # inputs shape: (batch_size, seq_len, embedding_dim) # hidden shape: (batch_size, seq_len, units) hidden = tf.nn.tanh(self.W1(inputs) + self.W2(inputs)) # score shape: (batch_size, seq_len, 1) score = self.V(hidden) # attention_weights shape: (batch_size, seq_len, 1) attention_weights = tf.nn.softmax(score, axis=1) # context_vector shape: (batch_size, units) context_vector = attention_weights * inputs context_vector = tf.reduce_sum(context_vector, axis=1) return context_vector ``` 这个 self-attention 层接受一个形状为 (batch_size, seq_len, embedding_dim) 的输入张量,其中 batch_size 是批量大小,seq_len 是序列长度,embedding_dim 是嵌入维度。它通过两个全连接层 W1 和 W2 将输入映射到一个隐藏表示,然后使用另一个全连接层 V 计算每个时间步的得分。得分通过 softmax 函数进行归一化,得到每个时间步的注意力权重。最后,将注意力权重乘以输入张量,得到上下文向量,作为 self-attention 层的输出。 使用这个 self-attention 层的示例代码: ```python import numpy as np # 创建一个 self-attentionattention_layer = SelfAttention(units=32) # 创建一个输入张量 inputs = tf.keras.Input(shape=(10, 16)) # 在输入张量上应用 self-attention 层 context_vector = attention_layer(inputs) # 创建一个模型 model = tf.keras.Model(inputs=inputs, outputs=context_vector) # 生成一些随机输入数据 x = np.random.randn(32, 10, 16) # 在模型上进行推理 output = model(x) print(output.shape) # 输出 (32, 32) ``` ### 回答2: 自注意力机制(self-attention)是目前在自然语言处理领域广泛应用的一种机制。自注意力机制在BERT、GPT-2等模型中占据了非常重要的位置,因此,掌握自注意力机制的实现方法对进行文本处理任务非常重要。 而在TensorFlow中,实现自注意力机制也非常简单。下面是一个简单的TensorFlow代码示例: ```python import tensorflow as tf class SelfAttention(tf.keras.layers.Layer): def __init__(self, dim, num_heads): super(SelfAttention, self).__init__() # 创建查询、键、值的权重矩阵 self.query_weights = tf.keras.layers.Dense(units=dim) self.key_weights = tf.keras.layers.Dense(units=dim) self.value_weights = tf.keras.layers.Dense(units=dim) # 查询的分组数:即头的数量 self.num_heads = num_heads # 定义multi-head softmax层 self.multihead_softmax = tf.keras.layers.Dense(units=dim) def call(self, inputs): # inputs的shape:(batch_size, seq_len, embedding_size) # 生成查询、键、值 queries = self.query_weights(inputs) keys = self.key_weights(inputs) values = self.value_weights(inputs) # 将最后一维embedding_size分成num_heads份 queries = tf.reshape(queries, shape=(tf.shape(queries)[0], -1, self.num_heads, queries.shape[-1] // self.num_heads)) keys = tf.reshape(keys, shape=(tf.shape(keys)[0], -1, self.num_heads, keys.shape[-1] // self.num_heads)) values = tf.reshape(values, shape=(tf.shape(values)[0], -1, self.num_heads, values.shape[-1] // self.num_heads)) # 经过matmul计算得到attention分布 attention_matmul = tf.matmul(queries, keys, transpose_b=True) attention_score = tf.nn.softmax(attention_matmul / tf.math.sqrt(tf.cast(keys.shape[-1], dtype=tf.float32))) attention_output = tf.matmul(attention_score, values) # 对前两维进行reshape,再经过全连接层得到结果 attention_output = tf.reshape(attention_output, shape=(tf.shape(attention_output)[0], -1, attention_output.shape[-2] * attention_output.shape[-1])) output = self.multihead_softmax(attention_output) return output ``` 以上函数中,我们首先定义了一个SelfAttention类,该类继承了TensorFlow中的keras.layers.Layer类。在该类中,我们定义了查询、键、值的权重矩阵,以及多头softmax层。然后在call函数中,我们将输入进行查询、键、值的计算,然后分成多个头,经过matmul计算得到attention分布,最后将前两维进行reshape后再经过全连接层得到输出。 使用该SelfAttention类时,只需要在定义model时添加该层即可。例如: ```python import tensorflow as tf input = tf.keras.layers.Input(shape=(None, 512)) self_attention = SelfAttention(dim=512, num_heads=8)(input) model = tf.keras.models.Model(input, self_attention) ``` 以上代码示例可以将输入通过定义的SelfAttention层进行处理,然后输出self-attention后的结果。 ### 回答3: Self-attention(自注意力)是一种用于自然语言处理和计算机视觉领域的自监督学习方法,它通过允许模型在输入序列中关注不同位置的信息来实现对序列数据的建模。代码tensorflow实现了自注意力模型,使得开发者可以使用tensorflow库快速部署自注意力应用。 在代码tensorflow中,首先需要定义一个自注意力层。在该层中,输入数据被表示为一个矩阵,我们可以使用矩阵点积和softmax函数来计算每个注意头的输出: ```python class SelfAttention(tf.keras.layers.Layer): def __init__(self, units): super(SelfAttention, self).__init__() self.units = units self.W_q = tf.keras.layers.Dense(units=self.units) self.W_k = tf.keras.layers.Dense(units=self.units) self.W_v = tf.keras.layers.Dense(units=self.units) self.dense = tf.keras.layers.Dense(units=self.units) def call(self, inputs): Q = self.W_q(inputs) #[batch_size, query_length, depth] K = self.W_k(inputs) #[batch_size, key_length, depth] V = self.W_v(inputs) #[batch_size, value_length, depth] #计算分数,通过矩阵相乘 score = tf.matmul(Q, K, transpose_b=True) #缩放得分 depth = tf.cast(tf.shape(K)[-1], tf.float32) scaled_score = score / tf.math.sqrt(depth) #使用softmax函数计算权重 weights = tf.nn.softmax(scaled_score, axis=-1) #计算加权和 attention_output = tf.matmul(weights, V) #拼接所有头的输出 heads = tf.concat(tf.split(attention_output, num_or_size_splits=self.num_heads, axis=-1), axis=0) return self.dense(heads) ``` 然后,我们可以使用定义好的自注意力层来构建一个自注意力模型。该模型使用多头注意力,允许模型同时关注多个位置的信息。 ```python class SelfAttentionModel(tf.keras.Model): def __init__(self, num_heads, units, output_units): super(SelfAttentionModel, self).__init__() self.num_heads = num_heads self.self_attention = SelfAttention(units=units) self.output_layer = tf.keras.layers.Dense(units=output_units, activation='softmax') def call(self, inputs): self_attention_output = self.self_attention(inputs) return self.output_layer(self_attention_output) ``` 最后,我们可以使用tensorflow的训练方法来训练自注意力模型,并在测试集上评估其性能。同时,我们也可以使用训练好的模型来执行不同的自然语言处理和计算机视觉任务。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值