【自然語言處理】基於雙向LSTM(Bi-LSTM)文本分類的Python實現

前言

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))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章