| 36 | |
| 37 | |
| 38 | class LSTMRNN(object): |
| 39 | def __init__(self, n_steps, input_size, output_size, cell_size, batch_size): |
| 40 | self.n_steps = n_steps |
| 41 | self.input_size = input_size |
| 42 | self.output_size = output_size |
| 43 | self.cell_size = cell_size |
| 44 | self.batch_size = batch_size |
| 45 | with tf.name_scope('inputs'): |
| 46 | self.xs = tf.placeholder(tf.float32, [None, n_steps, input_size], name='xs') |
| 47 | self.ys = tf.placeholder(tf.float32, [None, n_steps, output_size], name='ys') |
| 48 | with tf.variable_scope('in_hidden'): |
| 49 | self.add_input_layer() |
| 50 | with tf.variable_scope('LSTM_cell'): |
| 51 | self.add_cell() |
| 52 | with tf.variable_scope('out_hidden'): |
| 53 | self.add_output_layer() |
| 54 | with tf.name_scope('cost'): |
| 55 | self.compute_cost() |
| 56 | with tf.name_scope('train'): |
| 57 | self.train_op = tf.train.AdamOptimizer(LR).minimize(self.cost) |
| 58 | |
| 59 | def add_input_layer(self,): |
| 60 | l_in_x = tf.reshape(self.xs, [-1, self.input_size], name='2_2D') # (batch*n_step, in_size) |
| 61 | # Ws (in_size, cell_size) |
| 62 | Ws_in = self._weight_variable([self.input_size, self.cell_size]) |
| 63 | # bs (cell_size, ) |
| 64 | bs_in = self._bias_variable([self.cell_size,]) |
| 65 | # l_in_y = (batch * n_steps, cell_size) |
| 66 | with tf.name_scope('Wx_plus_b'): |
| 67 | l_in_y = tf.matmul(l_in_x, Ws_in) + bs_in |
| 68 | # reshape l_in_y ==> (batch, n_steps, cell_size) |
| 69 | self.l_in_y = tf.reshape(l_in_y, [-1, self.n_steps, self.cell_size], name='2_3D') |
| 70 | |
| 71 | def add_cell(self): |
| 72 | lstm_cell = tf.contrib.rnn.BasicLSTMCell(self.cell_size, forget_bias=1.0, state_is_tuple=True) |
| 73 | with tf.name_scope('initial_state'): |
| 74 | self.cell_init_state = lstm_cell.zero_state(self.batch_size, dtype=tf.float32) |
| 75 | self.cell_outputs, self.cell_final_state = tf.nn.dynamic_rnn( |
| 76 | lstm_cell, self.l_in_y, initial_state=self.cell_init_state, time_major=False) |
| 77 | |
| 78 | def add_output_layer(self): |
| 79 | # shape = (batch * steps, cell_size) |
| 80 | l_out_x = tf.reshape(self.cell_outputs, [-1, self.cell_size], name='2_2D') |
| 81 | Ws_out = self._weight_variable([self.cell_size, self.output_size]) |
| 82 | bs_out = self._bias_variable([self.output_size, ]) |
| 83 | # shape = (batch * steps, output_size) |
| 84 | with tf.name_scope('Wx_plus_b'): |
| 85 | self.pred = tf.matmul(l_out_x, Ws_out) + bs_out |
| 86 | |
| 87 | def compute_cost(self): |
| 88 | losses = tf.contrib.legacy_seq2seq.sequence_loss_by_example( |
| 89 | [tf.reshape(self.pred, [-1], name='reshape_pred')], |
| 90 | [tf.reshape(self.ys, [-1], name='reshape_target')], |
| 91 | [tf.ones([self.batch_size * self.n_steps], dtype=tf.float32)], |
| 92 | average_across_timesteps=True, |
| 93 | softmax_loss_function=self.ms_error, |
| 94 | name='losses' |
| 95 | ) |