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可以更好的捕捉双向的语义依赖。

Aquí Insertar imagen Descripción
Aquí Insertar imagen Descripción

Si puede acceder a información de contexto como el pasado, una visita al contexto futuro, esta secuencia de anotación para muchas tareas son muy útiles. Por ejemplo, en la clasificación más especial de caracteres, que puede ser como saber si esta carta que la letra anterior, para llegar a conocer las cartas, que serán muy útiles. Del mismo modo, para la clasificación de los fonemas en la frase también.

Sin embargo, debido a la norma de red neuronal recurrente secuencia de procesamiento (RNN) en el tiempo, tienden a pasar por alto el futuro de la información contextual. Una solución muy evidente es la de añadir un retardo entre la entrada y la diana, y por lo tanto puede dar algunos pasos de tiempo futuro para unirse a la información de contexto de la red, que se añade a la trama siguiente a la información de tiempo M junto con la salida predicha. En teoría, M puede ser muy grande para capturar toda la información disponible en el futuro, pero en realidad descubierto que si M es demasiado grande, los resultados predichos será pobre. Esto se debe a que el Internet es realmente centrando una gran cantidad de memoria de información de entrada, lo que dio lugar a la disminución de los conocimientos previsible de las diferentes vectores de entrada capacidades de modelado conjunta. Por lo tanto, el tamaño de M se ajusta manualmente.

Bidireccional recurrente de red neuronal (BrNN) La idea básica es la de proponer cada secuencia de entrenamiento hacia adelante y hacia atrás, respectivamente, son dos de red neuronal recurrente (RNN), y que los dos están conectados a una capa de salida. Esta estructura proporciona un punto para cada una de la información de contexto completo de pasado y futuro de entrada de secuencia la capa de salida. La siguiente figura muestra la expansión es un tiempo de ciclo de dos vías a lo largo de la red neuronal. Seis valor único se repite usando los pesos en cada paso de tiempo, seis pesos respectivamente: hacia adelante y hacia atrás de entrada para la capa oculta (w1, w3), su capa oculta a la capa oculta (w2 de, w5), hacia adelante y hacia atrás capa a la capa de salida (w4, w6) implícita. Se hace notar que: la adelante y hacia atrás sin flujo de información implícita entre las capas, que aseguran una vista acíclico expandido.
Aquí Insertar imagen Descripción
La imagen de arriba muestra la descomposición bilstm, resumen, cada palabra es la información de fase de avance y retroceso, es decir, cada paso de los datos para el acceso puede obtener datos de salida, y cada parámetro de peso es único .

Estimación hacia adelante (pase hacia adelante):
Para la red neural bi-cíclico (BrNN) oculto capa, hacia delante proyecta como bucle unidireccional de red neural (RNN), además de la secuencia de entrada a las dos capas ocultas son en direcciones opuestas, dos capas ocultas hasta que se procesa la capa de salida todo toda la secuencia de entrada se actualiza

proyecciones hacia atrás (pase hacia atrás):
Bidireccional recurrentes Redes Neuronales (BrNN) proyecciones hacia atrás red neural ciclo estándar (RNN) por el tiempo de propagación hacia atrás es similar a la primera excepto que el tema todo capa de salida calculado δ, y luego regresó a los dos capa oculta diferentes direcciones

BILSTM función correspondiente está en 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
)

salidas de (output_fw, output_bw), es un tensor y una celda de salida hacia atrás comprende una tupla tensor de salida frontal que consiste en la célula.
Supongamos time_major = FALSE, y la forma de la tensor [batch_size, MAX_TIEMPO, profundidad]. Se utiliza en la tf.concat experimentos (salidas, 2) a empalmar.
output_states es (output_state_fw, output_state_bw), que comprende la parte delantera y trasera de la tupla que consiste en el último estado oculto.
escriba output_state_fw y output_state_bw para LSTMStateTuple.
LSTMStateTuple de (c, h), lo que representa la celda de memoria y el estado oculto.

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]))

Publicado 17 artículos originales · ganado elogios 1 · vistas 3421

Supongo que te gusta

Origin blog.csdn.net/weixin_43983570/article/details/105246838
Recomendado
Clasificación