DAY4-BILSTM-tensorflow.nn.bidirectional_dynamic_rnn()

LSTM的全称是Long Short-Term Memory,它是RNN(Recurrent Neural Network)的一种。LSTM由于其设计的特点,非常适合用于对时序数据的建模,如文本数据。BiLSTM是Bi-directional Long Short-Term Memory的缩写,是由前向LSTM与后向LSTM组合而成。两者在自然语言处理任务中都常被用来建模上下文信息。
自然语言处理中情感分类任务是对给定文本进行情感倾向分类的任务,粗略来看可以认为其是分类任务中的一类。对于情感分类任务,目前通常的做法是先对词或者短语进行表示,再通过某种组合方式把句子中词的表示组合成句子的表示。最后,利用句子的表示对句子进行情感分类。
举一个对句子进行褒贬二分类的例子。
句子:我爱中国  (输入)           句子:我不喜欢你(输入)
情感标签:褒义	(输出)				贬义(输出)
根据前后文的意义不同,句子的褒贬也不同。
但是利用LSTM对句子进行建模还存在一个问题:无法编码从后到前的信息。在更细粒度的分类时,如对于强程度的褒义、弱程度的褒义、中性、弱程度的贬义、强程度的贬义的五分类任务需要注意情感词、程度词、否定词之间的交互。举一个例子,“这个餐厅脏得不行,没有隔壁好”,这里的“不行”是对“脏”的程度的一种修饰,通过BiLSTM可以更好的捕捉双向的语义依赖。

ここに画像を挿入説明
ここに画像を挿入説明

あなたが過去のようなコンテキスト情報にアクセスすることができた場合は、将来のコンテキストへの訪問は、多くのタスクのために、このシーケンスの注釈は非常に有用です。例えば、ほとんどの特殊文字の分類では、それは前の手紙のように、この手紙は、非常に参考になる文字を、知って来ているかどうかを知るためにのようにすることができます。同様に、文章中の音素の分類のためにも。

しかし、タイミングのリカレントニューラルネットワーク(RNN)処理シーケンスの標準に、彼らは、コンテキスト情報の未来を見落とす傾向にあります。非常に明白な解決策は、入力とターゲットとの間の遅延を追加することであり、したがって、予測出力と共に時刻情報Mを次のフレームに付加されているネットワークコンテキスト情報を、参加する将来の時間ステップを与えることができます。理論的には、Mは、将来的に利用可能なすべての情報を取得することは非常に大きくなることが、実際にはMが大きすぎると、予測された結果が悪くなることがわかりました。インターネットは本当に異なる入力ベクトル共同モデリング機能の予測知識の減少につながった入力情報記憶の多くを焦点を当てているためです。従って、Mのサイズを手動で調整されます。

双方向リカレントニューラルネットワーク(BRNN)基本的な考え方は、それぞれ、2個のリカレントニューラルネットワーク(RNN)であり、2は出力層に接続されていること、前方と後方のすべてのトレーニング・シーケンスを提案することです。この構造は、出力層配列過去と未来の入力の完全なコンテキスト情報の各々に点を提供します。次の図に示す膨張ニューラルネットワークに沿って双方向サイクル時間です。隠れ層隠れ層に(W1、W3)、その隠された層(のW2に前後入力:6つのユニークな値は、それぞれ、各時間ステップ六の量で重みを用いて繰り返されますW5)、前後層暗黙出力層(W4、W6)へ。なお、:拡大非環式を確保する層の間の暗黙的な情報フローなしの前後。
ここに画像を挿入説明
示しbilstm分解、要約、各ワードは順方向及び逆位相情報である上記画像、アクセスするデータの各ステップは、出力データを得ることができ、各重みパラメータが一意です。

(フォワードパス)前方推定:
二環式ニューラルネットワーク(BRNN)隠された層の場合、前方に一方向ループニューラルネットワーク(RNN)のように投影された、2つの隠し層への入力シーケンスに加えて、反対方向にあり、 2つの隠し層出力層が処理されるまで、すべての入力シーケンス全体が更新されます

後方突起(復路):
双方向リカレントニューラルネットワーク(BRNN)逆伝播時間によって後方突起標準サイクルニューラルネットワーク(RNN)は、すべての計算された出力層δ項目ことを除いて第一と同様であり、そして2つに返さ隠された層の異なる方向

BILSTM対応する機能はtensorflowであります

def bidirectional_dynamic_rnn(
cell_fw, # 前向RNN
cell_bw, # 后向RNN
inputs, # 输入
sequence_length=None,# 输入序列的实际长度(可选,默认为输入序列的最大长度)
initial_state_fw=None,  # 前向的初始化状态(可选)
initial_state_bw=None,  # 后向的初始化状态(可选)
dtype=None, # 初始化和输出的数据类型(可选)
parallel_iterations=None,
swap_memory=False, 
time_major=False,
# 决定了输入输出tensor的格式:如果为true, 向量的形状必须为 `[max_time, batch_size, depth]`. 
# 如果为false, tensor的形状必须为`[batch_size, max_time, depth]`. 默认为false
scope=None
)

(output_fw、output_bw)の出力は、テンソルであり、逆方向出力セルは、セルからなるフロント出力テンソルタプルを含みます。
time_majorが偽、及びテンソルの形状[BATCH_SIZE、MAX_TIME、深さ] =仮定する。スプライスされるために(出力、2)tf.concat実験で使用しました。
output_states最後の隠れ状態からなるタプルの前面および背面を含む、(output_state_fw、output_state_bw)です。
output_state_fw入力しLSTMStateTupleためoutput_state_bw。
メモリセルと隠された状態を表す(C、H)、のLSTMStateTuple。

import tensorflow as tf

#定义初始变量
class BILstm:
    def __init__(self, step_nums, output_size, keep_prob,cellunit=20):
        self.step_nums = step_nums#时间片
        self.cellunit = cellunit#lstm隐层单元
        self.keep_prob = keep_prob
        self.W_out = tf.Variable(tf.random_normal([cellunit*2,1]),name='w_out')
        self.B_out = tf.Variable(tf.random_normal([1]),name='B_out')
        self.x_ = tf.placeholder(tf.float32,[None,step_nums,output_size])
        self.y_ = tf.placeholder(tf.float32, [None,step_nums])
        self.cost = tf.reduce_mean(tf.square(self.model() - self.y_))  # 损失方程,均方差
        # self.cost = tf.nn.sigmoid_cross_entropy_with_logits(labels=self.y_,logits=self.model())
        self.train_op = tf.train.AdamOptimizer().minimize(self.cost)  # adam优化器
 


        self.saver = tf.train.Saver()


    def model(self):
        with tf.variable_scope('bilstm'):
            #定义双层lstm
            lstm_forward_cell = tf.nn.rnn_cell.BasicLSTMCell(self.cellunit, forget_bias=1.0, state_is_tuple=True)
            lstm_backward_cell = tf.nn.rnn_cell.BasicLSTMCell(self.cellunit, forget_bias=1.0, state_is_tuple=True)

            #dropout
            lstm_forward_cell = tf.nn.rnn_cell.DropoutWrapper(cell=lstm_forward_cell, input_keep_prob=1.0 ,
                                                              )
            lstm_backward_cell = tf.nn.rnn_cell.DropoutWrapper(cell=lstm_backward_cell, input_keep_prob=1.0,
                                                              )
            outputs,states = tf.nn.bidirectional_dynamic_rnn(lstm_forward_cell, lstm_backward_cell , self.x_ , dtype=tf.float32)
        output = tf.reshape(outputs,[-1,self.cellunit*2])

        out = tf.matmul(output, self.W_out) + self.B_out  # 实现全连接层
        out = tf.reshape(out,[-1,self.step_nums])
        return out

    def train(self, train_x, train_y):  # 训练函数
        with tf.Session() as sess:  # 建立会话
            tf.get_variable_scope().reuse_variables()  # 设置变量共享
            sess.run(tf.global_variables_initializer())  # 会话执行变量初始化
            # 迭代次数
            for i in range(2000):
                _, mse = sess.run([self.train_op, self.cost], feed_dict={self.x_: train_x, self.y_: train_y})
                if i % 100 == 0:
                    print(i, mse)
            save_path = self.saver.save(sess, './model')
            print('Model saved to {}'.format(save_path))

    def test(self, test_x):  # 取出模型对数据进行匹配
        with tf.Session() as sess:
            tf.get_variable_scope().reuse_variables()  # 变量共享
            self.saver.restore(sess, './model')  # 存储模型
            output = sess.run(self.model(), feed_dict={self.x_: test_x})
            return output


if __name__ == '__main__':
    predictor = BILstm(output_size=1, step_nums=4, cellunit=10, keep_prob=1.0)
    train_x = [[[1], [2], [4], [5]],
               [[5], [7], [7], [8]],
               [[3], [4], [5], [7]]]
    train_y = [[2, 5, 7, 4],
               [7, 12, 15, 7],
               [4, 8, 11, 5]]
    predictor.train(train_x, train_y)

    test_x = [[[1], [2], [3], [4]],  # 模型训练结果为train[0] = label[1]  train[1] = train[0]+ train[2]
              [[4], [5], [6], [7]]]
    actual_y = [[2, 4, 6, 3],
                [5, 10, 12, 6]]
    pred_y = predictor.test(test_x)

    print("\nlets run some tests!\n")

    for i, x in enumerate(test_x):
        print('when the inputs is {}'.format(x))
        print('the ground truth output should be {}'.format(actual_y[i]))
        print('and the model thinks it is {}\n'.format(pred_y[i]))

公開された17元の記事 ウォンの賞賛1 ビュー3421

おすすめ

転載: blog.csdn.net/weixin_43983570/article/details/105246838