Build a simple convnet (BN before ReLU).
        Args:
            inputs: a tensor of size [batch_size, height, width, channels]
            mode: string in ['train', 'test']
        Returns:
            the last op containing the predictions
        Note:
            Best score
            Step:  7015 - Epoch: 18/20 - best batch acc: 0.8984 - loss: 1.5656
            Worst score
            Step:  7523 - Epoch: 20/20 - best batch acc: 0.7734 - loss: 1.6874

def model(self, inputs, mode='train'):
        """Build a simple convnet (BN before ReLU).
        Args:
            inputs: a tensor of size [batch_size, height, width, channels]
            mode: string in ['train', 'test']
        Returns:
            the last op containing the predictions
        Note:
            Best score
            Step:  7015 - Epoch: 18/20 - best batch acc: 0.8984 - loss: 1.5656
            Worst score
            Step:  7523 - Epoch: 20/20 - best batch acc: 0.7734 - loss: 1.6874
        """
        # Extract features
        training = (mode == 'train')
        with tf.variable_scope('conv1') as scope:
            conv = tf.layers.conv2d(inputs=inputs, filters=16, kernel_size=[3, 3], padding='SAME')
            bn = tf.layers.batch_normalization(inputs=conv, training=training)
            bn = tf.nn.relu(bn)
            conv = tf.layers.conv2d(inputs=bn, filters=16, kernel_size=[3, 3], padding='SAME')
            bn = tf.layers.batch_normalization(inputs=conv, training=training)
            bn = tf.nn.relu(bn)
            pool = tf.layers.max_pooling2d(bn, pool_size=[2, 2], strides=2, padding='SAME', name=scope.name)

        with tf.variable_scope('conv2') as scope:
            conv = tf.layers.conv2d(inputs=pool, filters=32, kernel_size=[3, 3], padding='SAME')
            bn = tf.layers.batch_normalization(inputs=conv, training=training)
            bn = tf.nn.relu(bn)
            conv = tf.layers.conv2d(inputs=bn, filters=32, kernel_size=[3, 3], padding='SAME')
            bn = tf.layers.batch_normalization(inputs=conv, training=training)
            bn = tf.nn.relu(bn)
            pool = tf.layers.max_pooling2d(bn, pool_size=[2, 2], strides=2, padding='SAME', name=scope.name)

        with tf.variable_scope('conv3') as scope:
            conv = tf.layers.conv2d(inputs=pool, filters=32, kernel_size=[3, 3], padding='SAME')
            bn = tf.layers.batch_normalization(inputs=conv, training=training)
            bn = tf.nn.relu(bn)
            conv = tf.layers.conv2d(inputs=bn, filters=32, kernel_size=[3, 3], padding='SAME')
            bn = tf.layers.batch_normalization(inputs=conv, training=training)
            bn = tf.nn.relu(bn)
            pool = tf.layers.max_pooling2d(bn, pool_size=[2, 2], strides=2, padding='SAME', name=scope.name)

        # Classify
        with tf.variable_scope('fc') as scope:
            flat = tf.layers.flatten(pool)
            fc = tf.layers.dense(inputs=flat, units=32, activation=tf.nn.relu)
            softmax = tf.layers.dense(inputs=fc, units=self.num_classes, activation=tf.nn.softmax)

        return softmax