Forked from danijar/blog_tensorflow_sequence_classification.py
Created
December 8, 2016 14:27
-
-
Save chrisHuxi/633c0271ab3cd69eaef374b9779d8174 to your computer and use it in GitHub Desktop.
TensorFlow Sequence Classification
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Working example for my blog post at: | |
| # http://danijar.com/introduction-to-recurrent-networks-in-tensorflow/ | |
| import functools | |
| import sets | |
| import tensorflow as tf | |
| from tensorflow.models.rnn import rnn_cell | |
| from tensorflow.models.rnn import rnn | |
| def lazy_property(function): | |
| attribute = '_' + function.__name__ | |
| @property | |
| @functools.wraps(function) | |
| def wrapper(self): | |
| if not hasattr(self, attribute): | |
| setattr(self, attribute, function(self)) | |
| return getattr(self, attribute) | |
| return wrapper | |
| class SequenceClassification: | |
| def __init__(self, data, target, dropout, num_hidden=200, num_layers=3): | |
| self.data = data | |
| self.target = target | |
| self.dropout = dropout | |
| self._num_hidden = num_hidden | |
| self._num_layers = num_layers | |
| self.prediction | |
| self.error | |
| self.optimize | |
| @lazy_property | |
| def prediction(self): | |
| # Recurrent network. | |
| network = rnn_cell.GRUCell(self._num_hidden) | |
| network = rnn_cell.DropoutWrapper( | |
| network, output_keep_prob=self.dropout) | |
| network = rnn_cell.MultiRNNCell([network] * self._num_layers) | |
| output, _ = rnn.dynamic_rnn(network, data, dtype=tf.float32) | |
| # Select last output. | |
| output = tf.transpose(output, [1, 0, 2]) | |
| last = tf.gather(output, int(output.get_shape()[0]) - 1) | |
| # Softmax layer. | |
| weight, bias = self._weight_and_bias( | |
| self._num_hidden, int(self.target.get_shape()[1])) | |
| prediction = tf.nn.softmax(tf.matmul(last, weight) + bias) | |
| return prediction | |
| @lazy_property | |
| def cost(self): | |
| cross_entropy = -tf.reduce_sum(self.target * tf.log(self.prediction)) | |
| return cross_entropy | |
| @lazy_property | |
| def optimize(self): | |
| learning_rate = 0.003 | |
| optimizer = tf.train.RMSPropOptimizer(learning_rate) | |
| return optimizer.minimize(self.cost) | |
| @lazy_property | |
| def error(self): | |
| mistakes = tf.not_equal( | |
| tf.argmax(self.target, 1), tf.argmax(self.prediction, 1)) | |
| return tf.reduce_mean(tf.cast(mistakes, tf.float32)) | |
| @staticmethod | |
| def _weight_and_bias(in_size, out_size): | |
| weight = tf.truncated_normal([in_size, out_size], stddev=0.01) | |
| bias = tf.constant(0.1, shape=[out_size]) | |
| return tf.Variable(weight), tf.Variable(bias) | |
| if __name__ == '__main__': | |
| # We treat images as sequences of pixel rows. | |
| train, test = sets.Mnist() | |
| _, rows, row_size = train.data.shape | |
| num_classes = train.target.shape[1] | |
| data = tf.placeholder(tf.float32, [None, rows, row_size]) | |
| target = tf.placeholder(tf.float32, [None, num_classes]) | |
| dropout = tf.placeholder(tf.float32) | |
| model = SequenceClassification(data, target, dropout) | |
| sess = tf.Session() | |
| sess.run(tf.initialize_all_variables()) | |
| for epoch in range(10): | |
| for _ in range(100): | |
| batch = train.sample(10) | |
| sess.run(model.optimize, { | |
| data: batch.data, target: batch.target, dropout: 0.5}) | |
| error = sess.run(model.error, { | |
| data: test.data, target: test.target, dropout: 1}) | |
| print('Epoch {:2d} error {:3.1f}%'.format(epoch + 1, 100 * error)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment