前言
Github:Github下載地址
RNN在自然語言處理的文本處理上取得了很大的成功。
雙向LSTM可以捕獲上下文的內容,從而使得分類效果更佳。
在本文的這次分類中,本文使用了情感分析的數據集,最終的模型可以將正面情感和負面情感通過雙向LSTM給分類出來。
實現
這次的主要的類是我們的Detection。
class Detection:
def __init__(self, sequence_length, batch_size, vocab_size, emb_dim, hidden_dim = 128):
self.num_emb = vocab_size # vocab size
self.batch_size = batch_size # batch size
self.emb_dim = emb_dim # dimision of embedding
self.hidden_dim = hidden_dim # hidden size
self.sequence_length = sequence_length # sequence length
self.output_dim = 2
with tf.variable_scope('embedding'):
self.g_embeddings = tf.Variable(tf.random_uniform([self.num_emb, self.emb_dim], -1.0, 1.0), name="W_text")
self.x = tf.placeholder(shape=[self.batch_size, self.sequence_length], dtype=tf.int32)
self.inputs= tf.nn.embedding_lookup(self.g_embeddings, self.x) # seq_length x batch_size x emb_dim
self.targets = tf.placeholder(shape=[self.batch_size, self.output_dim], dtype=tf.int64)
self.output_keep_prob = 0.7#to prevent overfit
cell_bw = tf.contrib.rnn.BasicLSTMCell(self.hidden_dim, state_is_tuple=False) # single lstm unit
cell_bw = tf.contrib.rnn.DropoutWrapper(cell_bw, output_keep_prob=self.output_keep_prob)
cell_fw = tf.contrib.rnn.BasicLSTMCell(self.hidden_dim, state_is_tuple=False) # single lstm unit
cell_fw = tf.contrib.rnn.DropoutWrapper(cell_fw, output_keep_prob=self.output_keep_prob)
self.outputs, self.states = tf.nn.bidirectional_dynamic_rnn(cell_bw, cell_fw, self.inputs, dtype=tf.float32)
self.outputs = tf.reshape(self.outputs, shape=[-1, self.sequence_length, self.hidden_dim])
self.outputs = tf.transpose(self.outputs, perm=[1, 0, 2]) # batch_size x seq_length
self.outputs = tf.reduce_mean(self.outputs, 0)
self.outputs = self.outputs[:self.batch_size] + self.outputs[self.batch_size:]
self.logits = tf.layers.dense(self.outputs, self.output_dim, name="softmax")
self.prob = tf.nn.softmax(self.logits, name="softmax_output")
self.accuracy = tf.equal(tf.argmax(self.targets, axis=1), tf.argmax(self.prob, axis=1))
self.loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=self.targets, logits=self.logits))
tvars = tf.trainable_variables()
max_grad_norm = 5
# We clip the gradients to prevent explosion
grads, _ = tf.clip_by_global_norm(tf.gradients(self.loss, tvars), max_grad_norm)
gradients = list(zip(grads, tvars))
self.train_op = tf.train.AdamOptimizer(0.001).apply_gradients(gradients)
def train(self, sess, x_batch, y_batch):
_, loss = sess.run([self.train_op, self.loss], feed_dict={self.x:x_batch, self.targets:y_batch})
return loss
def predict(self, sess, x_batch):
prob = sess.run([self.prob], feed_dict={self.x:x_batch})
return prob
def get_accuracy(self, sess, x_batch, y_batch):
accuracy = sess.run([self.accuracy], feed_dict={self.x: x_batch, self.targets: y_batch})
return (accuracy[0].tolist().count(True) / len(x_batch))