- 解决了输出严重依赖输入的问题
- 输入的时候有一个结束标志,输出时指向这个字则表明结束
3、可以解决一个问题,假设传统seq2seq中,字典固定,那么包含陌生字的新的输入,这个陌生字肯定不会出现在输出中了,而ptr-network中仍可以出现,它的字典会随着输入改变
Ptr_Network处理的是以下的问题,输入的样本分为三个部分,part1为随机生成6到10个元素,每个元素值在1到5之间;part2为随机生成6到10个元素,每个元素值在6到10之间;part3为随机生成6到10个元素,每个元素值在1到5之间;x=part1+part2+part3,输出的y为值为6到10之间的起始位置即可,如样本为[1,2,3,2,4,5,7,9,7,10,8,6,0,4,2,5,1],1*17向量,则y输出为两行,一行为初始位置[0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0],一行为终点位置[0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0]
inputs=tf.placeholder (tf.int32,[1024,60]) #输入inputs是一个tensor张量
targets=tf.placeholder(tf.int32, [2,1024,60])#期望输出也是一个tensor张量
init=tf.random_normal_initializer(0,0.5)#返回一个生成具有正态分布的张量初始化器,均值为0,方差为0.5
cell_enc=tf.contrib.rnn.LSTMCell(6,use_peepholes=False,initializer=init)#lstm单元
cell_dec=tf.contrib.rnn.LSTMCell(6,use_peepholes=False,initializer=init)#lstm单元
Encoder
enc_state=cell_enc.zero_state(1024,tf.float32)#初始化隐层状态,即训练过程中的(Ct,ht)
enc_states#保留所有隐层状态
循环遍历j=1:60
input_=inputs[:,j:j+1]
每次处理多个样本相同位置的元素
W_e当然就是共享的权重矩阵啦 1*6
b_e当然就是偏置啦 1024*6
cell_input=tf.nn.elu(tf.matmul(input_,W_e)+b_e)#lstm单元进行处理 #特征处理
#上述权当是预处理输入吧
output,enc_state=cell_enc(cell_input,enc_state)#lstm处理单元,output为ht,enc_state为(ht,Ct)都为1024*6
enc_states.append(enc_state)
Decoder
starting_generation_symbol=tf.constant(20,shape(2014,1),dtype=tf.float32)# 产生一个值为20的张量
dec_state=enc_states[-1]#encoder最后一个隐层状态相当于decoder的第一个隐层状态2*1024*6
ptr_outputs#输出隐层状态
ptr_outputs_dists#输出隐层状态的集合
循环遍历i=0:2
W_d_in当然就是共享的权重矩阵啦 1*6
b_d_in当然就是偏置啦 1024*6
cell_input=tf.nn.elu(tf.matmul(input_,W_e)+b_e)#lstm单元进行处理
#上述权当是预处理输入吧
output,dec_state=cell_enc(cell_input,dec_state)#lstm处理单元,output为htt,dec_state为(ht,Ct)都为1024*6
#下面也是我们要学习的权重矩阵啦
W_1当然就是共享的权重矩阵啦 6*6
W_2当然就是共享的权重矩阵啦 6*6
bias_ptr当然就是偏置啦 1024*6
index_predists #预测的开始位置(位置有两个,起始位置)
dec_portion=tf.matmul(get_last_state(dec_state),W_2) #get_last_state()函数是取隐层状态Ct(即为下图中的di)的,得到1024*6,
v_blend #6*1张量,就是上图中v矩阵啦,也是要学习的
循环遍历j=0:60
enc_portion= tf.matmul(get_lstm_state(enc_states[j]),W_1)#获取encoder过程中的第j的隐层状态Ct(即为上图中的ej),得到1024*6
raw_blend=tf.nn.elu(enc_portion+dec_portion+bias_ptr)#看出来了吧就是上图中的第一个等式,1024*6
scaled_blend=tf.matmul(raw_blend,v_blend)#1024*1
index_predist=tf.reshape(scaled_blend,(1024,))#reshape1024
enc_portions.append(enc_portion)#这个保存W_1*ej的信息1024*6
index_predists.append(index_predist)#当然是保存预测的始位置信息
idx_prediststribution=tf.transpose(tf.stack(index_predists))#stack()增加一维,transpose()转置,1024*60
idx_diststribution=tf.nn.softmax(idx_prediststribution,dim=-1)#就是上图中的第二个公式啦,1024*60
ptr_output_dists.append(idx_diststribution)#保留预测概率矩阵信息吧
idx=tf.argmax(idx_distribution,1)#开始位置下标呗1024
emb=tf.nn.embedding_lookup(tf.transpose(inputs),idx)#在inputs中找到位置1024*1024
ptr_output_raw=tf.diag_part(emb)#取对角元素,这里是起始位置的元素
ptr_output=tf.reshape(ptr_output_raw,(1024,1))#1024*1#输出信息
ptr_outputs.append(ptr_output)#保存信息呗
input_= ptr_output#1024个样本的起始位置作为最终位置的输入
idx_distributions=tf.stack(ptr_output_dists)# 保留预测概率矩阵 loss=tf.sqrt(tf.reduce_mean(tf.pow(idx_distributions-
actual_index_dists,2.0)))#当然是计算loss啦
train=optimizer.minimize(loss)
后面就是产生train和test data的过程,可以忽略。