def loss_func(y_true, y_pred):
     out_mu, out_sigma, out_pi = tf.split(y_pred, num_or_size_splits=[num_mixes * output_dim,
                                                                      num_mixes * output_dim,
                                                                      num_mixes],
                                          axis=1, name='mdn_coef_split')
     cat = Categorical(logits=out_pi)
     component_splits = [output_dim] * num_mixes
     mus = tf.split(out_mu, num_or_size_splits=component_splits, axis=1)
     sigs = tf.split(out_sigma, num_or_size_splits=component_splits, axis=1)
     coll = [MultivariateNormalDiag(loc=loc, scale_diag=scale) for loc, scale
             in zip(mus, sigs)]
     mixture = Mixture(cat=cat, components=coll)
     loss = mixture.log_prob(y_true)
     loss = tf.negative(loss)
     loss = tf.reduce_mean(loss)
     return loss
Exemple #2
0
class Model_SF(Model):
    """ Prediction model for single future frame """
    def __init__(self, args):
        super(Model_SF, self).__init__(args)
        self.ckpt_dir = os.path.join(self.args.train_dir, 'sf_ckpt')
        if not args.test and not args.restore_training and not args.train_condition == 'real_time_play':
            if os.path.exists(self.ckpt_dir):
                print("Checkpoint file path :%s already exist..." %
                      self.ckpt_dir)
                print(
                    "Do you want to delete this folder and recreate one? ( \'y\' or \'n\')"
                )
                while True:
                    keyboard_input = raw_input("Enter your choice:\n")
                    if keyboard_input == 'y':
                        shutil.rmtree(self.ckpt_dir)
                        break
                    elif keyboard_input == 'n':
                        break
                    else:
                        print(
                            "Unrecognized response, please enter \'y\' or \'n\'"
                        )
        self.input = tf.placeholder(
            dtype=tf.float32,
            shape=[None, self.args.seq_length, self.args.features_dim],
            name='input_data')
        self.target = tf.placeholder(dtype=tf.float32,
                                     shape=[None, self.args.gaussian_dim],
                                     name='target')
        self.build_model()
        self.initialize()

    def build_model(self):
        net = tl.layers.InputLayer(self.input, name='input_layer')
        with tf.variable_scope('fc1'):
            net = tl.layers.TimeDistributedLayer(
                net,
                layer_class=tl.layers.DenseLayer,
                args={
                    'n_units': 64,
                    'act': tf.nn.elu,
                    'W_init': tf.contrib.layers.variance_scaling_initializer(),
                    'W_init_args': {
                        'regularizer':
                        tf.contrib.layers.l2_regularizer(
                            self.args.weight_decay)
                    },
                    'name': 'fc1_'
                },
                name='time_dense_fc1')
            # net = tl.layers.DropoutLayer(net, keep=self.args.keep_prob, name='fc1_drop')
        with tf.variable_scope('highway'):
            num_highway = 3
            for idx in xrange(num_highway):
                highway_args = {
                    'n_units': 64,
                    'act': tf.nn.elu,
                    'W_init': tf.contrib.layers.variance_scaling_initializer(),
                    'b_init': tf.constant_initializer(value=0.0),
                    'W_init_args': {
                        'regularizer':
                        tf.contrib.layers.l2_regularizer(
                            self.args.weight_decay)
                    },
                    'name': 'highway_%03d_' % idx
                }
                net = tl.layers.TimeDistributedLayer(
                    net,
                    layer_class=utility.Highway,
                    args=highway_args,
                    name='time_dense_highway_%d' % idx)
                # if idx % 8 == 0:
                #     net = tl.layers.DropoutLayer(net, keep=self.args.keep_prob, name='highway_drop_%d' % idx)
        # net = tl.layers.DropoutLayer(net, keep=self.args.keep_prob, name='highway_drop')
        with tf.variable_scope('fc2'):
            net = tl.layers.TimeDistributedLayer(
                net,
                layer_class=tl.layers.DenseLayer,
                args={
                    'n_units': 64,
                    'act': tf.nn.elu,
                    'W_init': tf.contrib.layers.variance_scaling_initializer(),
                    'W_init_args': {
                        'regularizer':
                        tf.contrib.layers.l2_regularizer(
                            self.args.weight_decay)
                    },
                    'name': 'highway_to_fc_'
                },
                name='time_dense_highway_to_fc')
            net = tl.layers.DropoutLayer(net,
                                         keep=self.args.keep_prob,
                                         name='hw_to_fc_drop')
        with tf.variable_scope('RNN'):
            if self.args.rnn_cell == 'lstm':
                rnn_cell_fn = tf.contrib.rnn.BasicLSTMCell
            elif self.args.rnn_cell == 'gru':
                rnn_cell_fn = tf.contrib.rnn.GRUCell
            else:
                raise ValueError(
                    'Unimplemented RNN Cell, should be \'lstm\' or \'gru\'')
            self.rnn_keep_prob = tf.placeholder(tf.float32)
            rnn_layer_name = 'DRNN_layer'
            net = tl.layers.DynamicRNNLayer(layer=net,
                                            cell_fn=rnn_cell_fn,
                                            n_hidden=128,
                                            dropout=(1.0, self.rnn_keep_prob),
                                            n_layer=self.args.num_cells,
                                            return_last=True,
                                            name=rnn_layer_name)
            rnn_weights_params = [
                var for var in net.all_params
                if rnn_layer_name in var.name and 'weights' in var.name
            ]
            self.add_regularization_loss(rnn_weights_params)
        # net = tl.layers.DenseLayer(net,
        #                            n_units=50,
        #                            act=tf.nn.elu,
        #                            W_init=tf.contrib.layers.variance_scaling_initializer(),
        #                            name='fc1')

        # with tf.variable_scope('Highway'):
        #     num_highway = 15
        #     for idx in xrange(num_highway - 1):
        #         net = utility.Highway(net,
        #                               n_units=64,
        #                               act=tf.nn.elu,
        #                               W_init=tf.contrib.layers.variance_scaling_initializer(),
        #                               b_init=tf.constant_initializer(value=0.0),
        #                               W_init_args={'regularizer': tf.contrib.layers.l2_regularizer(self.args.weight_decay)},
        #                               reuse=False,
        #                               name='highway_%d'%idx)
        net = tl.layers.DenseLayer(
            net,
            n_units=64,
            act=tf.nn.elu,
            W_init=tf.contrib.layers.variance_scaling_initializer(),
            W_init_args={
                'regularizer':
                tf.contrib.layers.l2_regularizer(self.args.weight_decay)
            },
            name='fc_3')
        mus_num = self.args.num_mixtures * self.args.gaussian_dim
        sigmas_num = self.args.num_mixtures * self.args.gaussian_dim
        weights_num = self.args.num_mixtures
        num_output = mus_num + sigmas_num + weights_num
        self.net = tl.layers.DenseLayer(
            net,
            n_units=num_output,
            act=tf.identity,
            W_init=tf.contrib.layers.variance_scaling_initializer(),
            W_init_args={
                'regularizer':
                tf.contrib.layers.l2_regularizer(self.args.weight_decay)
            },
            name='nn_output')
        output = self.net.outputs
        with tf.variable_scope('MDN'):
            mus = output[:, :mus_num]
            sigmas = tf.exp(output[:, mus_num:mus_num + sigmas_num])
            self.weight_logits = output[:, mus_num + sigmas_num:]
            self.mus = tf.reshape(
                mus, (-1, self.args.num_mixtures, self.args.gaussian_dim))
            self.sigmas = tf.reshape(
                sigmas, (-1, self.args.num_mixtures, self.args.gaussian_dim))
            self.weights = tf.nn.softmax(self.weight_logits)
            cat = Categorical(logits=self.weight_logits)
            components = [
                MultivariateNormalDiag(mu=mu, diag_stdev=sigma)
                for mu, sigma in zip(
                    tf.unstack(tf.transpose(self.mus, (
                        1, 0,
                        2))), tf.unstack(tf.transpose(self.sigmas, (1, 0, 2))))
            ]
            self.y_mix = Mixture(cat=cat, components=components)
        self.loss = self.get_loss()

    def get_loss(self):
        with tf.variable_scope('Loss'):
            loss = -self.y_mix.log_prob(self.target)
            loss = tf.reduce_mean(loss) + tf.losses.get_total_loss()
        return loss

    def print_stats(self,
                    distances,
                    title=None,
                    draw=True,
                    save_to_file=False):
        if len(distances.shape) == 2:
            distances = np.average(distances, axis=1)
        from scipy import stats
        n, min_max, mean, var, skew, kurt = stats.describe(distances)
        median = np.median(distances)
        first_quartile = np.percentile(distances, 25)
        third_quartile = np.percentile(distances, 75)
        print('\nDistances statistics:')
        print("Minimum: {0:9.4f} Maximum: {1:9.4f}".format(
            min_max[0], min_max[1]))
        print("Mean: {0:9.4f}".format(mean))
        print("Variance: {0:9.4f}".format(var))
        print("Median: {0:9.4f}".format(median))
        print("First quartile: {0:9.4f}".format(first_quartile))
        print("Third quartile: {0:9.4f}".format(third_quartile))
        threshold = 0.01
        percentage_thr = (distances <= threshold).sum() / float(
            distances.size) * 100.0
        percentage_double_thr = (distances <= 2 * threshold).sum() / float(
            distances.size) * 100.0
        percentage_triple_thr = (distances <= 3 * threshold).sum() / float(
            distances.size) * 100.0
        print(
            "Percentage of testing with distance less than {0:.3f}m is: {1:4.2f} %"
            .format(threshold, percentage_thr))
        print(
            "Percentage of testing with distance less than {0:.3f}m is: {1:4.2f} %"
            .format(2 * threshold, percentage_double_thr))
        print(
            "Percentage of testing with distance less than {0:.3f}m is: {1:4.2f} %"
            .format(3 * threshold, percentage_triple_thr))
        if draw:
            try:
                import seaborn as sns
                import matplotlib.pyplot as plt
                sns.set_style("whitegrid")
                plt.figure()
                vio_ax = sns.violinplot(x=distances, cut=0)
                vio_ax.set_xlabel('distances_error')
                if title is not None:
                    plt.title(title)
                plt.figure()
                strip_ax = sns.stripplot(x=distances)
                strip_ax.set_xlabel('distances_error')
                if title is not None:
                    plt.title(title)
            except ImportError:
                pass

        if save_to_file:
            import csv
            filename = os.path.join(self.ckpt_dir, 'error_stats.csv')
            with open(filename, 'a+') as f:
                csv_writer = csv.writer(f,
                                        delimiter=',',
                                        quoting=csv.QUOTE_ALL)
                data = [
                    percentage_thr, percentage_double_thr,
                    percentage_triple_thr
                ]
                csv_writer.writerow(data)