机械学习 – LSTM应用之sequence generation

  • 概述

LSTM在机械学习上面的应用是异常普遍的,从股票剖析,机械翻译 到 语义剖析等等各个方面都有它的用武之地,经由前面的对于LSTM结构的剖析,这一节主要先容一些LSTM的一个小应用,那就是sequence generation。实在sequence generation本事也是对一些应用的统称,例如: 让机械学习音乐后然后让机械凭据学习的模子自己缔造音乐(制作人快要失业啦。。。。),让机械学习某种语言然后让这个学习到的模子自己发生Word来语言,等等。这实在本质是一种one-to-many的LSTM网络结构。这一节内容主要就是解说这一种网络结构的应用。

  • Sequence generation的网络结构剖析

在咱们现实实行而且写代码之前,咱们主要的义务是若何搭建一个sequence generation的网络结构。一个sequence generation的网络结构实在也是分为两个部门,第一部门是encoding (modeling),也就是咱们建模的网络,它是一个many-to-many的网络结构;第二部门是decoding的历程,它是一个one-to-many的结构。那么详细这个网络结构是什么样呢?咱们看看下面的图片

机械学习 - LSTM应用之sequence generation

 

上面的图片展示的就是一个sequence generation从encoding到decoding的全历程和结构。在咱们的这个应用中,咱们的encoding中每一个time step的输入是一个文字,输出则是响应输入的后一个字,这些数据都来自于咱们的training data;等到咱们训练完成后,咱们将训练得来的LSTM cell来构建一个decoding网络,就是咱们只输入一个单词,它凭据咱们的之前学习的model,来自动的展望咱们要说什么话,是不是很cool??固然啦,在encoding阶段,咱们的LSTM详细有若干的time steps,是凭据咱们的input data的shape来决议的;在decoding阶段详细有若干的time step则是由咱们自己来决议的, 咱们需要用一个for loop来决议咱们在decoding阶段的time steps。从上图,咱们也可以很明显的看出在decoding的时刻,咱们只有一个输入X,后面time step的输入则都是前一个time step的输出。上面就是怎么sequence generation的一个整体的结构。那么就下来,咱们就剖析一些它的代码,看看咱们若何用代码来实现上面的网络结构。

  • Sequence generation 代码剖析

 从上面的剖析,咱们可以看出sequence generation是由两个部门组成,那么自然咱们代码也一定得分成两部门来实现上图中的网络结构,那么接下来咱们来看看第一步,就是若何用Python来实现encoding的结构,代码如下所示,咱们看着代码来逐步剖析:

Rust入坑指南:智能指针

#define shared variables
n_a=64 n_values = 78 # dimensions of out single input reshapor = keras.layers.Reshape((1, n_values)) # Used in Step 2.B of djmodel(), below LSTM_cell = keras.layers.LSTM(n_a, return_state = True) # Used in Step 2.C, return_state muset be set densor = keras.layers.Dense(n_values, activation='softmax') # Used in Step 2.D
#multiple inputs (X, a, c), we have to use functional Keras, other than sequential APIs def create_model(Tx, n_a, n_values): """ Implement the model Arguments: Tx -- length of the sequence in a corpus n_a -- the number of activations used in our model n_values -- number of unique values in the music data Returns: model -- a keras instance model with n_a activations """ # Define the input layer and specify the shape X = keras.Input(shape=(Tx, n_values))#input omit the batch_size dimension, X is still 3 dimensiones (with batch_size dimension). # Define the initial hidden state a0 and initial cell state c0 a0 = keras.Input(shape=(n_a,), name='a0') c0 = keras.Input(shape=(n_a,), name='c0') a = a0 c = c0 # Step 1: Create empty list to append the outputs while you iterate outputs = [] # Step 2: Loop for t in range(Tx): # Step 2.A: select the "t"th time step vector from X. x = keras.layers.Lambda(lambda x: X[:,t,:])(X) # Step 2.B: Use reshapor to reshape x to be (1, n_values) (≈1 line) #由于LSTM layer默认的输入的dimension是 (batch_size, Tx, n_values),其中batch_size是省略的, 即是(Tx, n_values)。若是是(Tx,n_values)的话,LSTM()会默认循环Tx次,因而,咱们将它reshape成(1,n_values),它就不会循环了。 x = reshapor(x) # Step 2.C: Perform one step of the LSTM_cell a, _, c = LSTM_cell(x, initial_state=[a,c]) # Step 2.D: Apply densor to the hidden state output of LSTM_Cell out = densor(a) #out's shape is (m,1,n_values) # Step 2.E: add the output to "outputs" outputs.append(out) # Step 3: Create model instance model = keras.Model(inputs=[X,a0,c0],outputs=outputs) return model

从上面的代码,咱们可以看出,首先咱们得界说一些shared variable,例如a, c的dimension, LSTM_cell, 等等这些,这些变量在咱们的model中无论是encoding照样decoding都是公用的,并不是说一个LSTM layer就含有很多个LSTM_cell,这是错误的明白(虽然咱们图片上面是这么画的,但这是为了利便人人明白才画了很多个LSTM_cell,现实是同一个LSTM_cell, 希望不要误解)。首先咱们构建这个网络需要的参数有,Tx = time_steps; n_a = a,c的vector的dimension;以及n_values = 咱们每一个输入的vector的dimension。由于咱们的网络有三处输入,分别是X, a, c, 以是咱们要先界说这三处输入,而且设定它们的shape, 注意在设定它们的shape的时刻,是不需要有batch_size的;随后咱们来到for loop中,首先提取每一个time step的input value, 即上面代码中Lambda layer所做的事儿,然后由于咱们提取的是每一个time step的值,每一个time step, LSTM只会循环一次,以是咱们照样得把它reshape到(1,n_values); 随后咱们将处理好的input value传递给LSTM_cell,而且返回hidden state a, 和memory cell c, 最后经由一个dense layer盘算咱们的输出,而且将每一步的输出装进outputs这个list中。这就是构建咱们的encoding网络的整个步骤。那么既然咱们剖析了上面encoding的阶段,完成了对咱们LSTM的训练历程而且获得了咱们想要的LSTM, 那么接下来咱们看一看咱们的decoding历程,即若何用训练获得的LSTM来generate(predict)咱们的sequence啦,咱们照样看下面的代码,然后逐步剖析

def sequence_inference_model(LSTM_cell, n_values = 78, n_a = 64, Ty = 100):
    """
    Uses the trained "LSTM_cell" and "densor" from model() to generate a sequence of values.
    
    Arguments:
    LSTM_cell -- the trained "LSTM_cell" from model(), Keras layer object
    densor -- the trained "densor" from model(), Keras layer object
    n_values -- integer, number of unique values
    n_a -- number of units in the LSTM_cell
    Ty -- integer, number of time steps to generate
    
    Returns:
    inference_model -- Keras model instance
    """
    
    # Define the input of your model with a shape (it is a one-to-many structure, the input shape is (1,n_values))
    x0 = keras.Input(shape=(1, n_values)) # Define a0, c0, initial hidden state for the decoder LSTM a0 = keras.Input(shape=(n_a,), name='a0') c0 = keras.Input(shape=(n_a,), name='c0') a = a0 c = c0 x = x0 # Step 1: Create an empty list of "outputs" to later store your predicted values (≈1 line) outputs = [] # Step 2: Loop over Ty and generate a value at every time step for t in range(Ty): # Step 2.A: Perform one step of LSTM_cell a, _, c = LSTM_cell(x, initial_state=[a, c]) # Step 2.B: Apply Dense layer to the hidden state output of the LSTM_cell out = densor(a) # Step 2.C: Append the prediction "out" to "outputs". out.shape = (None, 78)  outputs.append(out) # Step 2.D: Select the next value according to "out", and set "x" to be the one-hot representation of the # selected value, which will be passed as the input to LSTM_cell on the next step. We have provided # the line of code you need to do this. x = keras.layers.Lambda(one_hot)(out) # Step 3: Create model instance with the correct "inputs" and "outputs" inference_model = keras.Model(inputs=[x0, a0, c0], outputs=outputs) return inference_model

inference_model = sequence_inference_model(LSTM_cell, densor, n_values = 78, n_a = 64, Ty = 50)
inference_model.summary()

x_initializer = np.zeros((1, 1, 78))
a_initializer = np.zeros((1, n_a))
c_initializer = np.zeros((1, n_a))

pred = inference_model.predict([x_initializer, a_initializer, c_initializer])

这个inference model就是凭据上面的训练来的LSTM来predict的,它共用了上面训练得来的的LSTM中的参数weights 和bias, 凭据输入的一个词x0来展望后面来输出哪些值,详细输出若干个值也是凭据用户设定的Ty来决议,固然啦,咱们还可以加倍精细化的治理咱们的输出,例如若是遇到EOS,咱们直接住手输出。咱们纵然有了前面的LSTM,然则由于结构的差别,咱们照样得先去构建一个新的inference model,即重新要搭建一个decoding的结构。从decoding的结构咱们可以看出来,咱们的输入照样有三个,即x0,a0,c0。这里有比encoding简朴的地方就是咱们不需要再去reshape那么的输入了,咱们的输入都是尺度的shape,即分别是(batch_size, Tx, n_values), (batch_size, n_a), (batch_size, n_a),咱们直接输入进去而且输入到Lstm和densor中就可以,不需要举行一些shape方面的设置了,其次这里有一点个encoding不一样的,就是需要将每一个time step的输出当做下个time step的输入, 即上面代码中的x=tf.keras.Lambda(one_hot)(out)。 由于这是一个inference model,以是咱们也不需要重新fitting啦,可以直接调用它的predict方式就可以predict啦。

  • 总结

对于sequence generation相关的应用呢,咱们首先要在脑海中找到这个pattern,即它是有2部门组成的,一个encoding,一个decoding;然后用encoding来训练模子,用decoding来predict模子。对于输入的input layer,一定要注意而且明白他们input data的shape,一定要一致性;对于一起share的变量一定要明白,例如LSTM_cell, densor 等,他们都是组成这个LSTM模子的最基本的希望,都是share的,并不是每一个time step都有自力的entity。若是对于以上的步骤和内容都明白的话,对于sequence generation相关的应用就都可以套用上面的模式举行实现,唯一需要改动的就是一下dimension值。

 

原创文章,作者:28x29新闻网,如若转载,请注明出处:https://www.28x29.com/archives/417.html