跟我学算法-match-LSTM(向唐老师看齐)
对于match-lstm,将hi文本与输出的match-lstm(由si,hi,qi)组合重新输入到LSTM网络中,以端对端的操作理念。
参考的博客:https://blog.csdn.net/laddie132/article/details/79159895 #MATCH-LSTM原理
https://blog.csdn.net/jdbc/article/details/80755576 # 将SQUAD数据集转换为id
https://blog.csdn.net/xbinworld/article/details/54607525 # 注意机制模型
https://blog.csdn.net/appleml/article/details/76607980 #point-net模型
# !/usr/bin/env python3
# -*- coding: utf-8 -*- import tensorflow as tf
import numpy as np
import tensorflow.contrib as contrib # from app.decorator import exe_time class MatchLstm:
# @exe_time
def __init__(self, vocab_size, sentence_size, embedding_size,
word_embedding, initializer=tf.truncated_normal_initializer(stddev=0.1),
session=tf.Session(), num_class=3,
window_size=4, name='MatchLstm', initial_lr=0.001):
# 字典的大小
self._vocab_size = vocab_size
# 句子的大小
self._sentence_size = sentence_size
# 隐含层的大小
self._embedding_size = embedding_size
# 用于构造向量
self._we = word_embedding
# 初始化
self._initializer = initializer
# 名字
self._name = name
# 输出种类
self._num_class = num_class
self._sess = session
# 窗口的大小
self._window_size = window_size
# 学习率
self._initial_lr = initial_lr
# 编码原文和上下文的信息
self._build_inputs_and_vars()
# 构造模型的结构
self._inference()
# 初始化
self._initial_optimizer() def _build_inputs_and_vars(self):
# 文章的内容
self.premises = tf.placeholder(shape=[None, self._sentence_size], dtype=tf.int32,
name='premises')
# 问题
self.hypotheses = tf.placeholder(shape=[None, self._sentence_size], dtype=tf.int32,
name='hypotheses')
# 标签
self.labels = tf.placeholder(shape=[None, self._num_class], dtype=tf.float32,
name='labels')
# 根据输入的大小来获得样本的大小
self._batch_size = tf.shape(self.premises)[0]
# 初始化学习率
self.lr = tf.get_variable(shape=[], dtype=tf.float32, trainable=False,
initializer=tf.constant_initializer(self._initial_lr), name='lr')
# 初始化new_lr
self.new_lr = tf.placeholder(shape=[], dtype=tf.float32,
name='new_lr')
# 将self.new_lr 赋值给self.lr
self.lr_update_op = tf.assign(self.lr, self.new_lr) with tf.variable_scope(self._name):
# self._word_embedding用于进行单词向量化操作
self._word_embedding = tf.get_variable(name='word_embedding',
shape=[self._vocab_size, self._embedding_size],
initializer=tf.constant_initializer(self._we),
trainable=False)
# 对原文进行向量化操作,同时提取答案上下文的向量矩阵作为答案的向量
self._embed_pre = self._embed_inputs(self.premises, self._word_embedding)
# 对问题进行向量化操作
self._embed_hyp = self._embed_inputs(self.hypotheses, self._word_embedding) def _inference(self):
with tf.variable_scope('{}_lstm_s'.format(self._name)):
# 对原文进行了一次LSTM操作
lstm_s = contrib.rnn.BasicLSTMCell(num_units=self._embedding_size, forget_bias=0.0)
pre_length = self._length(self.premises)
h_s, _ = tf.nn.dynamic_rnn(lstm_s, self._embed_pre, sequence_length=pre_length,
dtype=tf.float32)
self.h_s = h_s with tf.variable_scope('{}_lstm_t'.format(self._name)):
# 对问题进行了一次LSTM操作
lstm_t = contrib.rnn.BasicLSTMCell(num_units=self._embedding_size, forget_bias=0.0)
hyp_length = self._length(self.hypotheses)
h_t, _ = tf.nn.dynamic_rnn(lstm_t, self._embed_hyp, sequence_length=hyp_length,
dtype=tf.float32)
self.h_t = h_t
# 构造一个lstm网络
self.lstm_m = contrib.rnn.BasicLSTMCell(num_units=self._embedding_size,
forget_bias=0.0)
# 构造一个可以变化的向量矩阵
h_m_arr = tf.TensorArray(dtype=tf.float32, size=self._batch_size) i = tf.constant(0)
# while_loop,cond作为条件,body做为操作过程
c = lambda x, y: tf.less(x, self._batch_size)
b = lambda x, y: self._match_sent(x, y)
res = tf.while_loop(cond=c, body=b, loop_vars=(i, h_m_arr))
# LSTM的输出结果
self.h_m_tensor = tf.squeeze(res[-1].stack(), axis=[1])
# 进行一次全连接操作,使得最后的输出结果是一维的
with tf.variable_scope('{}_fully_connect'.format(self._name)):
w_fc = tf.get_variable(shape=[self._embedding_size, self._num_class],
initializer=self._initializer, name='w_fc')
b_fc = tf.get_variable(shape=[self._num_class],
initializer=self._initializer, name='b_fc')
self.logits = tf.matmul(self.h_m_tensor, w_fc) + b_fc
# softmax损失函数,直接使用交叉熵损失函数,输出的结果只是一个数
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(labels=self.labels,
logits=self.logits,
name='cross_entropy')
# 把batch_size的样本的损失函数进行加和
cross_entropy_sum = tf.reduce_sum(cross_entropy, name='cross_entropy_sum')
# 加和以后相除,求损失的平均值
self.loss_op = tf.div(cross_entropy_sum, tf.cast(self._batch_size, dtype=tf.float32))
# argmax,求出每个样本中最大的概率值
self.predict_op = tf.arg_max(self.logits, dimension=1) def _match_sent(self, i, h_m_arr):
# 对每一个句子进行操作
h_s_i = self.h_s[i]
h_t_i = self.h_t[i]
# 输入句子的长度
length_s_i = self._length(self.premises[i])
length_t_i = self._length(self.hypotheses[i]) state = self.lstm_m.zero_state(batch_size=1, dtype=tf.float32) k = tf.constant(0)
c = lambda a, x, y, z, s: tf.less(a, length_t_i)
b = lambda a, x, y, z, s: self._match_attention(a, x, y, z, s)
res = tf.while_loop(cond=c, body=b, loop_vars=(k, h_s_i, h_t_i, length_s_i, state))
# 只获取最后一次的输出结果
final_state_h = res[-1].h
# 将其写入到h_m_arr文件中
h_m_arr = h_m_arr.write(i, final_state_h) i = tf.add(i, 1)
return i, h_m_arr def _match_attention(self, k, h_s, h_t, length_s, state): h_t_k = tf.reshape(h_t[k], [1, -1])
h_s_j = tf.slice(h_s, begin=[0, 0], size=[length_s, self._embedding_size]) with tf.variable_scope('{}_attention_w'.format(self._name)):
w_s = tf.get_variable(shape=[self._embedding_size, self._embedding_size],
initializer=self._initializer, name='w_s')
w_t = tf.get_variable(shape=[self._embedding_size, self._embedding_size],
initializer=self._initializer, name='w_t')
w_m = tf.get_variable(shape=[self._embedding_size, self._embedding_size],
initializer=self._initializer, name='w_m')
w_e = tf.get_variable(shape=[self._embedding_size, 1],
initializer=self._initializer, name='w_e') last_m_h = state.h
# sum_h进行全连接操作,通过对原文进行操作,输出一个权重参数
sum_h = tf.matmul(h_s_j, w_s) + tf.matmul(h_t_k, w_t) + tf.matmul(last_m_h, w_m)
# 经过一个激活层然后再与w_e进行相乘
e_kj = tf.matmul(tf.tanh(sum_h), w_e)
# 求得ai,j
a_kj = tf.nn.softmax(e_kj)
# 进行原文的参数加权
alpha_k = tf.matmul(a_kj, h_s_j, transpose_a=True) alpha_k.set_shape([1, self._embedding_size])
# 将context与即将输入的h_t_k组合输入到下一次的LSTM中
m_k = tf.concat([alpha_k, h_t_k], axis=1)
#
with tf.variable_scope('{}_lstm_m'.format(self._name)):
# 输入到LSTM重新进行计算
# state表示的是si
_, new_state = self.lstm_m(inputs=m_k, state=state) k = tf.add(k, 1)
return k, h_s, h_t, length_s, new_state def _embed_inputs(self, inputs, embeddings):
ndim0_tensor_arr = tf.TensorArray(dtype=tf.float32, size=self._batch_size)
i = tf.constant(0)
# tf.less 当x大于self._batch_size时返回为假
c = lambda x, y, z, n: tf.less(x, self._batch_size)
b = lambda x, y, z, n: self._embed_line(x, y, z, n)
# cond为条件,body为内容
res = tf.while_loop(cond=c, body=b,
loop_vars=(i, inputs, embeddings, ndim0_tensor_arr))
ndim0_tensor = res[-1].stack()
ndim0_tensor = tf.reshape(ndim0_tensor, [-1, self._sentence_size, self._embedding_size])
return ndim0_tensor def _embed_line(self, i, inputs, embeddings, ndim0_tensor_arr):
ndim1_list = []
# 对输入的每一句话进行操作
for j in range(self._sentence_size):
# 输入的第一个字符串
word = inputs[i][j]
unk_word = tf.constant(-1)
# tf.squeeze删除所有大小为1的数组(6,1) 变成(6, ?),在构造的向量矩阵中根据word找出位置
f1 = lambda: tf.squeeze(tf.nn.embedding_lookup(params=embeddings, ids=word))
# 如果没有的话使用0向量代替
f2 = lambda: tf.zeros(shape=[self._embedding_size])
# 如果wordunk与word不相等,执行f1,否者执行f2
res_tensor = tf.case([(tf.not_equal(word, unk_word), f1)], default=f2)
# 添加到ndim1_list 向量中
ndim1_list.append(res_tensor)
for j in range(self._sentence_size):
word = inputs[i][j]
unk_word = tf.constant(-1)
# 如果word等于-1代表了提取答案上下文的内容
f1 = lambda: self._ave_vec(ndim1_list, j)
f2 = lambda: ndim1_list[j]
ndim1_list[j] = tf.case([(tf.not_equal(word, unk_word), f2)],
default=f1)
# tf.stack是一个函数拼接
ndim1_tensor = tf.stack(ndim1_list)
ndim0_tensor_arr = ndim0_tensor_arr.write(i, ndim1_tensor)
i = tf.add(i, 1)
return i, inputs, embeddings, ndim0_tensor_arr def _ave_vec(self, embed_list, cur_pos):
"""
生词的词向量为词窗口的词向量平均值
:param embed_list:
:param cur_pos:
:return:
"""
# 根据句子的大小来获取当前词的上下文,self._window_size 表示提取词的大小
left_pos = max(0, cur_pos - self._window_size)
right_pos = min(cur_pos + self._window_size, self._sentence_size)
# 获得上下文的词向量
e_list = embed_list[left_pos:cur_pos] + embed_list[cur_pos + 1:right_pos + 1]
# tf.stack合并词向量
e_tensor = tf.stack(e_list)
# 对上下文的内容使用reduce_mean来替代原来的位置的信息
ave_tensor = tf.reduce_mean(e_tensor, axis=0)
return ave_tensor @staticmethod
def _length(sequence):
mask = tf.sign(tf.abs(sequence))
length = tf.reduce_sum(mask, axis=-1)
return length def _initial_optimizer(self):
with tf.variable_scope('{}_step'.format(self._name)):
# 进行学习率的衰减, 使用Ada,容易找出全局的最优解,且速度快.
self.global_step = tf.get_variable(shape=[],
initializer=tf.constant_initializer(0),
dtype=tf.int32,
name='global_step')
# 根据动量平均跟新参数
self._optimizer = tf.train.AdamOptimizer(learning_rate=self.lr, beta1=0.9, beta2=0.999)
# 缩小loss
self.train_op = self._optimizer.minimize(self.loss_op, global_step=self.global_step) if __name__ == '__main__':
with tf.Session() as sess:
# embedding需要翻译的句子
embedding = np.random.randn(4, 6)
embedding[0] = 0.0
model = MatchLstm(vocab_size=7, sentence_size=5, embedding_size=6,
word_embedding=embedding, session=sess)
model.batch_size = 1
sent1 = [[3, -1, 2, 1, 0],
[4, 5, 1, 0, 0],
[2, 1, 0, 0, 0]] sent2 = [[2, 1, 0, 0, 0],
[3, -1, 2, 1, 0],
[4, 5, 1, 0, 0]] labels = [[1, 0, 0],
[0, 1, 0],
[0, 0, 1]] sess.run(tf.global_variables_initializer())
# 迭代优化
for temp in range(300):
loss, _, step = sess.run([model.loss_op, model.train_op, model.global_step],
feed_dict={model.premises: sent1, model.hypotheses: sent2,
model.labels: labels, model.lr: 0.001})
print(step, loss)
sent1, sent2 = sent2, sent1
# !/usr/bin/env python3
# -*- coding: utf-8 -*- import tensorflow as tf
import numpy as np
import tensorflow.contrib as contrib # from app.decorator import exe_time class MatchLstm:
# @exe_time
def __init__(self, vocab_size, sentence_size, embedding_size,
word_embedding, initializer=tf.truncated_normal_initializer(stddev=0.1),
session=tf.Session(), num_class=,
window_size=, name='MatchLstm', initial_lr=0.001):
# 字典的大小
self._vocab_size = vocab_size
# 句子的大小
self._sentence_size = sentence_size
# 隐含层的大小
self._embedding_size = embedding_size
# 用于构造向量
self._we = word_embedding
# 初始化
self._initializer = initializer
# 名字
self._name = name
# 输出种类
self._num_class = num_class
self._sess = session
# 窗口的大小
self._window_size = window_size
# 学习率
self._initial_lr = initial_lr
# 编码原文和上下文的信息
self._build_inputs_and_vars()
# 构造模型的结构
self._inference()
# 初始化
self._initial_optimizer() def _build_inputs_and_vars(self):
# 文章的内容
self.premises = tf.placeholder(shape=[None, self._sentence_size], dtype=tf.int32,
name='premises')
# 问题
self.hypotheses = tf.placeholder(shape=[None, self._sentence_size], dtype=tf.int32,
name='hypotheses')
# 标签
self.labels = tf.placeholder(shape=[None, self._num_class], dtype=tf.float32,
name='labels')
# 根据输入的大小来获得样本的大小
self._batch_size = tf.shape(self.premises)[]
# 初始化学习率
self.lr = tf.get_variable(shape=[], dtype=tf.float32, trainable=False,
initializer=tf.constant_initializer(self._initial_lr), name='lr')
# 初始化new_lr
self.new_lr = tf.placeholder(shape=[], dtype=tf.float32,
name='new_lr')
# 将self.new_lr 赋值给self.lr
self.lr_update_op = tf.assign(self.lr, self.new_lr) with tf.variable_scope(self._name):
# self._word_embedding用于进行单词向量化操作
self._word_embedding = tf.get_variable(name='word_embedding',
shape=[self._vocab_size, self._embedding_size],
initializer=tf.constant_initializer(self._we),
trainable=False)
# 对原文进行向量化操作,同时提取答案上下文的向量矩阵作为答案的向量
self._embed_pre = self._embed_inputs(self.premises, self._word_embedding)
# 对问题进行向量化操作
self._embed_hyp = self._embed_inputs(self.hypotheses, self._word_embedding) def _inference(self):
with tf.variable_scope('{}_lstm_s'.format(self._name)):
# 对原文进行了一次LSTM操作
lstm_s = contrib.rnn.BasicLSTMCell(num_units=self._embedding_size, forget_bias=0.0)
pre_length = self._length(self.premises)
h_s, _ = tf.nn.dynamic_rnn(lstm_s, self._embed_pre, sequence_length=pre_length,
dtype=tf.float32)
self.h_s = h_s with tf.variable_scope('{}_lstm_t'.format(self._name)):
# 对问题进行了一次LSTM操作
lstm_t = contrib.rnn.BasicLSTMCell(num_units=self._embedding_size, forget_bias=0.0)
hyp_length = self._length(self.hypotheses)
h_t, _ = tf.nn.dynamic_rnn(lstm_t, self._embed_hyp, sequence_length=hyp_length,
dtype=tf.float32)
self.h_t = h_t
# 构造一个lstm网络
self.lstm_m = contrib.rnn.BasicLSTMCell(num_units=self._embedding_size,
forget_bias=0.0)
# 构造一个可以变化的向量矩阵
h_m_arr = tf.TensorArray(dtype=tf.float32, size=self._batch_size) i = tf.constant()
# while_loop,cond作为条件,body做为操作过程
c = lambda x, y: tf.less(x, self._batch_size)
b = lambda x, y: self._match_sent(x, y)
res = tf.while_loop(cond=c, body=b, loop_vars=(i, h_m_arr))
# LSTM的输出结果
self.h_m_tensor = tf.squeeze(res[-].stack(), axis=[])
# 进行一次全连接操作,使得最后的输出结果是一维的
with tf.variable_scope('{}_fully_connect'.format(self._name)):
w_fc = tf.get_variable(shape=[self._embedding_size, self._num_class],
initializer=self._initializer, name='w_fc')
b_fc = tf.get_variable(shape=[self._num_class],
initializer=self._initializer, name='b_fc')
self.logits = tf.matmul(self.h_m_tensor, w_fc) + b_fc
# softmax损失函数,直接使用交叉熵损失函数,输出的结果只是一个数
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(labels=self.labels,
logits=self.logits,
name='cross_entropy')
# 把batch_size的样本的损失函数进行加和
cross_entropy_sum = tf.reduce_sum(cross_entropy, name='cross_entropy_sum')
# 加和以后相除,求损失的平均值
self.loss_op = tf.div(cross_entropy_sum, tf.cast(self._batch_size, dtype=tf.float32))
# argmax,求出每个样本中最大的概率值
self.predict_op = tf.arg_max(self.logits, dimension=) def _match_sent(self, i, h_m_arr):
# 对每一个句子进行操作
h_s_i = self.h_s[i]
h_t_i = self.h_t[i]
# 输入句子的长度
length_s_i = self._length(self.premises[i])
length_t_i = self._length(self.hypotheses[i]) state = self.lstm_m.zero_state(batch_size=, dtype=tf.float32) k = tf.constant()
c = lambda a, x, y, z, s: tf.less(a, length_t_i)
b = lambda a, x, y, z, s: self._match_attention(a, x, y, z, s)
res = tf.while_loop(cond=c, body=b, loop_vars=(k, h_s_i, h_t_i, length_s_i, state))
# 只获取最后一次的输出结果
final_state_h = res[-].h
# 将其写入到h_m_arr文件中
h_m_arr = h_m_arr.write(i, final_state_h) i = tf.add(i, )
return i, h_m_arr def _match_attention(self, k, h_s, h_t, length_s, state): h_t_k = tf.reshape(h_t[k], [, -])
h_s_j = tf.slice(h_s, begin=[, ], size=[length_s, self._embedding_size]) with tf.variable_scope('{}_attention_w'.format(self._name)):
w_s = tf.get_variable(shape=[self._embedding_size, self._embedding_size],
initializer=self._initializer, name='w_s')
w_t = tf.get_variable(shape=[self._embedding_size, self._embedding_size],
initializer=self._initializer, name='w_t')
w_m = tf.get_variable(shape=[self._embedding_size, self._embedding_size],
initializer=self._initializer, name='w_m')
w_e = tf.get_variable(shape=[self._embedding_size, ],
initializer=self._initializer, name='w_e') last_m_h = state.h
# sum_h进行全连接操作,通过对原文进行操作,输出一个权重参数
sum_h = tf.matmul(h_s_j, w_s) + tf.matmul(h_t_k, w_t) + tf.matmul(last_m_h, w_m)
# 经过一个激活层然后再与w_e进行相乘
e_kj = tf.matmul(tf.tanh(sum_h), w_e)
# 求得ai,j
a_kj = tf.nn.softmax(e_kj)
# 进行原文的参数加权
alpha_k = tf.matmul(a_kj, h_s_j, transpose_a=True) alpha_k.set_shape([, self._embedding_size])
# 将context与即将输入的h_t_k组合输入到下一次的LSTM中
m_k = tf.concat([alpha_k, h_t_k], axis=)
#
with tf.variable_scope('{}_lstm_m'.format(self._name)):
# 输入到LSTM重新进行计算
# state表示的是si
_, new_state = self.lstm_m(inputs=m_k, state=state) k = tf.add(k, )
return k, h_s, h_t, length_s, new_state def _embed_inputs(self, inputs, embeddings):
ndim0_tensor_arr = tf.TensorArray(dtype=tf.float32, size=self._batch_size)
i = tf.constant()
# tf.less 当x大于self._batch_size时返回为假
c = lambda x, y, z, n: tf.less(x, self._batch_size)
b = lambda x, y, z, n: self._embed_line(x, y, z, n)
# cond为条件,body为内容
res = tf.while_loop(cond=c, body=b,
loop_vars=(i, inputs, embeddings, ndim0_tensor_arr))
ndim0_tensor = res[-].stack()
ndim0_tensor = tf.reshape(ndim0_tensor, [-, self._sentence_size, self._embedding_size])
return ndim0_tensor def _embed_line(self, i, inputs, embeddings, ndim0_tensor_arr):
ndim1_list = []
# 对输入的每一句话进行操作
for j in range(self._sentence_size):
# 输入的第一个字符串
word = inputs[i][j]
unk_word = tf.constant(-)
# tf.squeeze删除所有大小为1的数组(6,1) 变成(6, ?),在构造的向量矩阵中根据word找出位置
f1 = lambda: tf.squeeze(tf.nn.embedding_lookup(params=embeddings, ids=word))
# 如果没有的话使用0向量代替
f2 = lambda: tf.zeros(shape=[self._embedding_size])
# 如果wordunk与word不相等,执行f1,否者执行f2
res_tensor = tf.case([(tf.not_equal(word, unk_word), f1)], default=f2)
# 添加到ndim1_list 向量中
ndim1_list.append(res_tensor)
for j in range(self._sentence_size):
word = inputs[i][j]
unk_word = tf.constant(-)
# 如果word等于-1代表了提取答案上下文的内容
f1 = lambda: self._ave_vec(ndim1_list, j)
f2 = lambda: ndim1_list[j]
ndim1_list[j] = tf.case([(tf.not_equal(word, unk_word), f2)],
default=f1)
# tf.stack是一个函数拼接
ndim1_tensor = tf.stack(ndim1_list)
ndim0_tensor_arr = ndim0_tensor_arr.write(i, ndim1_tensor)
i = tf.add(i, )
return i, inputs, embeddings, ndim0_tensor_arr def _ave_vec(self, embed_list, cur_pos):
"""
生词的词向量为词窗口的词向量平均值
:param embed_list:
:param cur_pos:
:return:
"""
# 根据句子的大小来获取当前词的上下文,self._window_size 表示提取词的大小
left_pos = max(, cur_pos - self._window_size)
right_pos = min(cur_pos + self._window_size, self._sentence_size)
# 获得上下文的词向量
e_list = embed_list[left_pos:cur_pos] + embed_list[cur_pos + :right_pos + ]
# tf.stack合并词向量
e_tensor = tf.stack(e_list)
# 对上下文的内容使用reduce_mean来替代原来的位置的信息
ave_tensor = tf.reduce_mean(e_tensor, axis=)
return ave_tensor @staticmethod
def _length(sequence):
mask = tf.sign(tf.abs(sequence))
length = tf.reduce_sum(mask, axis=-)
return length def _initial_optimizer(self):
with tf.variable_scope('{}_step'.format(self._name)):
# 进行学习率的衰减, 使用Ada,容易找出全局的最优解,且速度快.
self.global_step = tf.get_variable(shape=[],
initializer=tf.constant_initializer(),
dtype=tf.int32,
name='global_step')
# 根据动量平均跟新参数
self._optimizer = tf.train.AdamOptimizer(learning_rate=self.lr, beta1=0.9, beta2=0.999)
# 缩小loss
self.train_op = self._optimizer.minimize(self.loss_op, global_step=self.global_step) if __name__ == '__main__':
with tf.Session() as sess:
# embedding需要翻译的句子
embedding = np.random.randn(, )
embedding[] = 0.0
model = MatchLstm(vocab_size=, sentence_size=, embedding_size=,
word_embedding=embedding, session=sess)
model.batch_size = 1
sent1 = [[, -, , , ],
[, , , , ],
[, , , , ]] sent2 = [[, , , , ],
[, -, , , ],
[, , , , ]] labels = [[, , ],
[, , ],
[, , ]] sess.run(tf.global_variables_initializer())
# 迭代优化
for temp in range():
loss, _, step = sess.run([model.loss_op, model.train_op, model.global_step],
feed_dict={model.premises: sent1, model.hypotheses: sent2,
model.labels: labels, model.lr: 0.001})
print(step, loss)
sent1, sent2 = sent2, sent1
跟我学算法-match-LSTM(向唐老师看齐)的更多相关文章
- 1164: 零起点学算法71——C语言合法标识符(存在问题)
1164: 零起点学算法71——C语言合法标识符 Time Limit: 1 Sec Memory Limit: 64 MB 64bit IO Format: %lldSubmitted: 10 ...
- 1163: 零起点学算法70——Yes,I can!
1163: 零起点学算法70--Yes,I can! Time Limit: 1 Sec Memory Limit: 64 MB 64bit IO Format: %lldSubmitted: ...
- 1147: 零起点学算法54——Fibonacc
1147: 零起点学算法54--Fibonacc Time Limit: 1 Sec Memory Limit: 64 MB 64bit IO Format: %lldSubmitted: 20 ...
- 1145: 零起点学算法52——数组中删数II
1145: 零起点学算法52--数组中删数II Time Limit: 1 Sec Memory Limit: 64 MB 64bit IO Format: %lldSubmitted: 293 ...
- 1137: 零起点学算法44——多组测试数据输出II
1137: 零起点学算法44--多组测试数据输出II Time Limit: 1 Sec Memory Limit: 64 MB 64bit IO Format: %lldSubmitted: ...
- 1136: 零起点学算法43——多组测试数据输出I
1136: 零起点学算法43--多组测试数据输出I Time Limit: 1 Sec Memory Limit: 128 MB 64bit IO Format: %lldSubmitted: ...
- 1135: 零起点学算法42——多组测试数据(求和)IV
1135: 零起点学算法42--多组测试数据(求和)IV Time Limit: 1 Sec Memory Limit: 64 MB 64bit IO Format: %lldSubmitted ...
- 1134: 零起点学算法41——多组测试数据(a+b)III
1134: 零起点学算法41--多组测试数据(a+b)III Time Limit: 1 Sec Memory Limit: 64 MB 64bit IO Format: %lldSubmitt ...
- 1133: 零起点学算法40——多组测试数据(a+b)II
1133: 零起点学算法40--多组测试数据(a+b)II Time Limit: 1 Sec Memory Limit: 64 MB 64bit IO Format: %lldSubmitte ...
随机推荐
- 51nod-1455-dp/缩小范围
1455 宝石猎人 题目来源: CodeForces 基准时间限制:2 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 苏塞克岛是一个有着30001个小岛的群岛,这 ...
- System.ComponentModel.DataAnnotations 命名空间和RequiredAttribute 类
System.ComponentModel.DataAnnotations 命名空间提供定义 ASP.NET MVC 和 ASP.NET 数据控件的类的特性. RequiredAttribute 指定 ...
- python学习笔记(三)---python关键字及其用法
转载出处:https://www.cnblogs.com/ECJTUACM-873284962/p/7576959.html 前言 最近在学习Java Sockst的时候遇到了一些麻烦事,我觉得我很有 ...
- 【hive】cube和rollup函数
cube 数据立方体(Data Cube),是多维模型的一个形象的说法.(关于多维模型这里不讲述,在数据仓库设计过程中还挺重要的,有兴趣自行查阅) 立方体其本身只有三维,但多维模型不仅限于三维模型,可 ...
- SPDY以及示例
SPDY是Google开发的基于传输控制协议(TCP)的应用层协议 .Google最早是在Chromium中提出的SPDY协议[1].目前已经被用于Google Chrome浏览器中来访问Google ...
- centos7.3安装配置vsftp
首先使用命令查看,系统内是否安装了vsftp [root@instance_290388 down]# rpm -qa |grep vsftp 如果没有安装,使用命令,进行安装 [root@insta ...
- 将Gridview中的数据出到excel或word中
在以下按钮单击事件中实现:private void btnMIME_Click(object sender, System.EventArgs e){dgShow.AllowPaging = fals ...
- FireFox和IE下使用Date来构造新Date对象的BUG
正常方式 我们都知道可以使用new Date()来创建一个Date对象. new Date();//Date {Mon Jun 15 2015 15:53:16 GMT+0800} 也可以用new D ...
- Mac安装并破解OmniGraffle7
这个实际上不算破解,只是找到了可用的序列号 1.下载地址 https://www.omnigroup.com/omnigraffle 2.激活方法 Omnigraffle Pro 7注册码/许可证 名 ...
- Ubuntu配置SSH服务
本文主要解决Ubuntu配置SSH服务的问题 1.1.修改可用的agt源 sudo vim /etc/apt/sources.list 1.2.更新代码包 sudo apt-get update 2. ...