Esempio n. 1
0
    def __init__(self, layer_idx, is_training, tau, prev_neurons=None):
        rnn_config = get_rnn_config()
        self.train_config = get_train_config()
        self.layer_config = rnn_config['layer_configs'][layer_idx]
        if prev_neurons is None:
            self.w_shape = (rnn_config['layout'][layer_idx - 1],
                            rnn_config['layout'][layer_idx])
        else:
            self.w_shape = (prev_neurons, rnn_config['layout'][layer_idx])
        self.b_shape = (1, self.w_shape[1])
        self.is_training = is_training

        # Activation summaries and specific neurons to gather individual histograms
        self.acts = dict()
        self.act_neurons = np.random.choice(
            range(self.b_shape[1]),
            size=(get_info_config()['tensorboard']['single_acts'], ),
            replace=False)
        if self.train_config['batchnorm'][
                'type'] == 'batch' and 'fc' in self.train_config['batchnorm'][
                    'modes']:
            self.bn_s_x = get_batchnormalizer()
            self.bn_b_x = get_batchnormalizer()

        with tf.variable_scope(self.layer_config['var_scope']):
            var_keys = ['w', 'b']
            self.weights = Weights(var_keys, self.layer_config, self.w_shape,
                                   self.b_shape, tau)
Esempio n. 2
0
    def __init__(self,
                 layer_idx,
                 is_training,
                 tau,
                 bidirectional_inp=False,
                 prev_neurons=None):
        self.rnn_config = get_rnn_config()
        self.train_config = get_train_config()
        self.layer_config = self.rnn_config['layer_configs'][layer_idx]
        if prev_neurons is None:
            if bidirectional_inp:
                self.w_shape = (self.rnn_config['layout'][layer_idx - 1] * 2 +
                                self.rnn_config['layout'][layer_idx],
                                self.rnn_config['layout'][layer_idx])
            else:
                self.w_shape = (self.rnn_config['layout'][layer_idx - 1] +
                                self.rnn_config['layout'][layer_idx],
                                self.rnn_config['layout'][layer_idx])
        else:
            self.w_shape = (prev_neurons +
                            self.rnn_config['layout'][layer_idx],
                            self.rnn_config['layout'][layer_idx])
        self.b_shape = (1, self.w_shape[1])
        self.cell_access_mat = []
        self.is_training = is_training

        # Activation summaries and specific neurons to gather individual histograms
        self.acts = dict()
        self.act_neurons = np.random.choice(
            range(self.b_shape[1]),
            size=(get_info_config()['tensorboard']['single_acts'], ),
            replace=False)

        if self.train_config['batchnorm'][
                'type'] == 'batch' and 'x' in self.train_config['batchnorm'][
                    'modes']:
            self.bn_b_x = []
            self.bn_s_x = []
        if self.train_config['batchnorm'][
                'type'] == 'batch' and 'h' in self.train_config['batchnorm'][
                    'modes']:
            self.bn_b_h = []
            self.bn_s_h = []

        with tf.variable_scope(self.layer_config['var_scope']):
            var_keys = ['wi', 'bi', 'wc', 'bc', 'wo', 'bo']
            self.weights = Weights(var_keys, self.layer_config, self.w_shape,
                                   self.b_shape, tau)
Esempio n. 3
0
    def setUp(self):
        self.layer_lengths = [3, 3, 3]
        self.weights = Weights(self.layer_lengths, 0.1)
        layer_0 = np.array([
            [1, 2, 1, 2],  #2
            [0, 1, -2, 1],  #0
            [2, 2, 0.5, -1]  #2
        ])
        layer_1 = np.array([
            [1, 2, 0, 0],  #5
            [0, 2, 0, 1],  #6
            [0, 2, 1, 0]  #4
        ])
        self.weights.update_layer(0, layer_0)
        self.weights.update_layer(1, layer_1)

        self.sample_x = np.array([[0.1], [0.2], [0.3]])
        self.sample_y = np.array([[2], [3], [2]])
Esempio n. 4
0
 def __init__(self,
              layer_lengths,
              learning_rate=.3,
              lmbda=.1,
              numIter=200,
              epsilon=0.125):
     """
     layer_lengths will be an array where each value is the size of that layer
     e.x. [3,4,5] - would have an input layer of size 3, a hidden layer of size 4, 
     and an output layer of size 5.
     Note: These do not include bias terms.
     """
     #initialize weights
     self.weights = Weights(layer_lengths, epsilon)
     self.layer_lengths = layer_lengths
     self.num_layers = len(self.layer_lengths)
     self.learning_rate = learning_rate
     #index of the last layer
     self.L = self.num_layers - 1
     self.lmbda = lmbda
Esempio n. 5
0
class TestSample(unittest.TestCase):
    def setUp(self):
        self.layer_lengths = [3, 3, 3]
        self.weights = Weights(self.layer_lengths, 0.1)
        layer_0 = np.array([
            [1, 2, 1, 2],  #2
            [0, 1, -2, 1],  #0
            [2, 2, 0.5, -1]  #2
        ])
        layer_1 = np.array([
            [1, 2, 0, 0],  #5
            [0, 2, 0, 1],  #6
            [0, 2, 1, 0]  #4
        ])
        self.weights.update_layer(0, layer_0)
        self.weights.update_layer(1, layer_1)

        self.sample_x = np.array([[0.1], [0.2], [0.3]])
        self.sample_y = np.array([[2], [3], [2]])

    def test_get_outcome(self):
        sample = BasicSample(self.weights, self.sample_x, self.sample_y)
        result = sample.get_outcome()
        self.assertAlmostEqual(5, result[0][0])
        self.assertAlmostEqual(6, result[1][0])
        self.assertAlmostEqual(4, result[2][0])

    def test_calc_deltas(self):
        #ds[L] = [[-3][-3][-2]]
        #ds[1] = [[-16][-2][-3]]
        #ds[0] = [[-40][-13.5][-31]]
        #as[L] = [[5][6][4]]
        #as[1] = [[1][2][0][2]]
        #as[0] = [[1][0.1][0.2][0.3]]
        #deltas[1] = [[-3,-6,0,-6][-3,-6,0,-6][-2,-4,0,-4]]
        #deltas[0] = [[-16,-1.6,-3.2,-4.8][-2,-.2,-.4,-.6][-3,-.3,-.6,-.9]]

        sample = BasicSample(self.weights, self.sample_x, self.sample_y)
        deltas = sample.calc_sample_deltas()
        self.assertAlmostEqual(-3, deltas[1][0][0])
        self.assertAlmostEqual(-1.6, deltas[0][0][1])
Esempio n. 6
0
class NeuralNet():
    def __init__(self,
                 layer_lengths,
                 learning_rate=.3,
                 lmbda=.1,
                 numIter=200,
                 epsilon=0.125):
        """
        layer_lengths will be an array where each value is the size of that layer
        e.x. [3,4,5] - would have an input layer of size 3, a hidden layer of size 4, 
        and an output layer of size 5.
        Note: These do not include bias terms.
        """
        #initialize weights
        self.weights = Weights(layer_lengths, epsilon)
        self.layer_lengths = layer_lengths
        self.num_layers = len(self.layer_lengths)
        self.learning_rate = learning_rate
        #index of the last layer
        self.L = self.num_layers - 1
        self.lmbda = lmbda

    def train(self, X, Y, num_iterations):
        """
        where m = X.shape[1] = Y.shape[1] = #samples
        X = self.layer_lengths[0] x m ndarray
        Y = self.layer_lengths[self.L] x m ndarray
        """
        if self.layer_lengths[0] != X.shape[0]:
            print("num features (" + X.shape[0] +
                  ") does not match input layer_lengths[0] (" +
                  self.layer_lengths[0] + ")")
            sys.exit()
        if self.layer_lengths[self.L] != Y.shape[0]:
            print("output layers don't match (" + Y.shape[0] + ") and (" +
                  self.layer_lengths[self.L] + ")")
            sys.exit()
        if X.shape[1] != Y.shape[1]:
            #TODO proper error checking
            print("inequal sample sizes for input and outputs")
            sys.exit()
        for i in range(0, num_iterations):
            print("starting iteration: " + str(i))
            self.train_iteration(X, Y)

    def train_iteration(self, X, Y):
        iteration = Iteration(self.weights, X, Y, self.lmbda)
        partials = iteration.calc_error_partials()

        #TODO some function that takes in theta and dJ/dTheta and gives the new theta
        #for now, do a simple change of dJ/dtheta * learning_rate. Eventually convert
        #to a more sophisticated gradient descent algorithm
        for i in range(0, self.L):
            next_theta = np.subtract(self.weights.get_layer(i),
                                     self.learning_rate * partials[i])
            self.weights.update_layer(i, next_theta)

    def error(self, expected, actual):
        """
        .5 * Sum(i) (expected[i] - actual[i])^2
        """
        diff = np.subtract(expected, actual)
        diff_squared = np.square(diff)
        return 0.5 * np.sum(diff_squared)
Esempio n. 7
0
class LSTMLayer:
    def __init__(self,
                 layer_idx,
                 is_training,
                 tau,
                 bidirectional_inp=False,
                 prev_neurons=None):
        self.rnn_config = get_rnn_config()
        self.train_config = get_train_config()
        self.layer_config = self.rnn_config['layer_configs'][layer_idx]
        if prev_neurons is None:
            if bidirectional_inp:
                self.w_shape = (self.rnn_config['layout'][layer_idx - 1] * 2 +
                                self.rnn_config['layout'][layer_idx],
                                self.rnn_config['layout'][layer_idx])
            else:
                self.w_shape = (self.rnn_config['layout'][layer_idx - 1] +
                                self.rnn_config['layout'][layer_idx],
                                self.rnn_config['layout'][layer_idx])
        else:
            self.w_shape = (prev_neurons +
                            self.rnn_config['layout'][layer_idx],
                            self.rnn_config['layout'][layer_idx])
        self.b_shape = (1, self.w_shape[1])
        self.cell_access_mat = []
        self.is_training = is_training

        # Activation summaries and specific neurons to gather individual histograms
        self.acts = dict()
        self.act_neurons = np.random.choice(
            range(self.b_shape[1]),
            size=(get_info_config()['tensorboard']['single_acts'], ),
            replace=False)

        if self.train_config['batchnorm'][
                'type'] == 'batch' and 'x' in self.train_config['batchnorm'][
                    'modes']:
            self.bn_b_x = []
            self.bn_s_x = []
        if self.train_config['batchnorm'][
                'type'] == 'batch' and 'h' in self.train_config['batchnorm'][
                    'modes']:
            self.bn_b_h = []
            self.bn_s_h = []

        with tf.variable_scope(self.layer_config['var_scope']):
            var_keys = ['wi', 'bi', 'wc', 'bc', 'wo', 'bo']
            self.weights = Weights(var_keys, self.layer_config, self.w_shape,
                                   self.b_shape, tau)

    # TODO: Update PFP (currently does not work)
    def create_pfp(self, x_m, x_v, mod_layer_config, init, init_cell=None):
        if init:
            cell_shape = (tf.shape(x_m)[0], self.b_shape[1])
            self.weights.tensor_dict['cs_m'] = tf.zeros(cell_shape)
            self.weights.tensor_dict['cs_v'] = tf.zeros(cell_shape)
            self.weights.tensor_dict['co_m'] = tf.zeros(cell_shape)
            self.weights.tensor_dict['co_v'] = tf.zeros(cell_shape)

        if self.train_config['batchnorm']:
            raise Exception(
                'Batchnorm not implemented for probabilistic forward pass')

        # Vector concatenation (input with recurrent)
        m = tf.concat([x_m, self.weights.tensor_dict['co_m']], axis=1)
        v = tf.concat([x_v, self.weights.tensor_dict['co_v']], axis=1)

        a_i_m, a_i_v = approx_activation(self.weights.var_dict['wi_m'],
                                         self.weights.var_dict['wi_v'],
                                         self.weights.var_dict['bi_m'],
                                         self.weights.var_dict['bi_v'], m, v)
        i_m, i_v = transform_sig_activation(a_i_m, a_i_v)
        a_c_m, a_c_v = approx_activation(self.weights.var_dict['wc_m'],
                                         self.weights.var_dict['wc_v'],
                                         self.weights.var_dict['bc_m'],
                                         self.weights.var_dict['bc_v'], m, v)
        c_m, c_v = transform_tanh_activation(a_c_m, a_c_v)
        a_o_m, a_o_v = approx_activation(self.weights.var_dict['wo_m'],
                                         self.weights.var_dict['wo_v'],
                                         self.weights.var_dict['bo_m'],
                                         self.weights.var_dict['bo_v'], m, v)
        o_m, o_v = transform_sig_activation(a_o_m, a_o_v)

        f_m = 1 - i_m
        f_v = i_v
        f_2nd_mom = tf.square(f_m) + f_v
        i_2nd_mom = tf.square(i_m) + i_v
        self.weights.tensor_dict['cs_v'] = tf.multiply(self.weights.tensor_dict['cs_v'], f_2nd_mom) + tf.multiply(c_v, i_2nd_mom) + \
                                           tf.multiply(tf.square(self.weights.tensor_dict['cs_m']), f_v) + tf.multiply(tf.square(c_m), i_v)
        self.weights.tensor_dict['cs_m'] = tf.multiply(
            f_m, self.weights.tensor_dict['cs_m']) + tf.multiply(i_m, c_m)

        c_tan_m, c_tan_v = transform_tanh_activation(
            self.weights.tensor_dict['cs_m'], self.weights.tensor_dict['cs_v'])
        o_2nd_mom = tf.square(o_m) + o_v
        self.weights.tensor_dict['co_m'] = tf.multiply(c_tan_m, o_m)
        self.weights.tensor_dict['co_v'] = tf.multiply(
            c_tan_v, o_2nd_mom) + tf.multiply(tf.square(c_tan_m), o_v)

        return self.weights.tensor_dict['co_m'], self.weights.tensor_dict[
            'co_v']

    # Local reparametrization trick
    def create_l_sampling_pass(self,
                               x,
                               mod_layer_config,
                               time_idx,
                               init,
                               init_cell=None):
        if init:
            cell_shape = (tf.shape(x)[0], self.b_shape[1])
            if init_cell is not None:
                self.weights.tensor_dict['cs'] = init_cell
            else:
                self.weights.tensor_dict['cs'] = tf.zeros(cell_shape)
            self.weights.tensor_dict['co'] = tf.zeros(cell_shape)

        co = self.weights.tensor_dict['co']
        if self.train_config['batchnorm']['type'] == 'batch':
            bn_idx = min(time_idx, self.train_config['batchnorm']['tau'] - 1)
            if 'x' in self.train_config['batchnorm']['modes']:
                if len(self.bn_b_x) == bn_idx:
                    self.bn_b_x.append(get_batchnormalizer())
                x = self.bn_b_x[bn_idx](x, self.is_training)
            if 'h' in self.train_config['batchnorm']['modes'] and bn_idx > 0:
                if len(self.bn_b_h) == bn_idx - 1:
                    self.bn_b_h.append(get_batchnormalizer())
                co = self.bn_b_h[bn_idx - 1](co, self.is_training)

        x = tf.concat([x, co], axis=1)

        if 'i' in self.rnn_config['act_disc']:
            i = self.weights.sample_activation(
                'wi', 'bi', x, 'sig', init,
                self.train_config['batchnorm']['type'] == 'layer')
        else:
            a_i = self.weights.sample_activation(
                'wi', 'bi', x, None, init,
                self.train_config['batchnorm']['type'] == 'layer')
            i = tf.sigmoid(a_i)
        f = 1. - i

        if 'c' in self.rnn_config['act_disc']:
            c = self.weights.sample_activation(
                'wc', 'bc', x, 'tanh', init,
                self.train_config['batchnorm']['type'] == 'layer')
        else:
            a_c = self.weights.sample_activation(
                'wc', 'bc', x, None, init,
                self.train_config['batchnorm']['type'] == 'layer')
            c = tf.tanh(a_c)

        if 'o' in self.rnn_config['act_disc']:
            o = self.weights.sample_activation(
                'wo', 'bo', x, 'sig', init,
                self.train_config['batchnorm']['type'] == 'layer')
        else:
            a_o = self.weights.sample_activation(
                'wo', 'bo', x, None, init,
                self.train_config['batchnorm']['type'] == 'layer')
            o = tf.sigmoid(a_o)

        self.weights.tensor_dict['cs'] = tf.multiply(
            f, self.weights.tensor_dict['cs']) + tf.multiply(i, c)
        if 'i' in self.rnn_config['act_disc']:
            self.weights.tensor_dict['co'] = tf.multiply(
                self.weights.tensor_dict['cs'], o)
        else:
            self.weights.tensor_dict['co'] = tf.multiply(
                tf.tanh(self.weights.tensor_dict['cs']), o)

        return self.weights.tensor_dict['co'], self.weights.tensor_dict['cs']

    # Global reparametrization trick
    def create_g_sampling_pass(self,
                               x,
                               mod_layer_config,
                               time_idx,
                               init,
                               second_arm_pass=False,
                               data_key=None,
                               init_cell=None):
        #if len(self.rnn_config['act_disc']) != 0:
        #raise Exception('classic reparametrization does not work with discrete activations')

        if init:
            self.weights.create_tensor_samples(second_arm_pass=second_arm_pass,
                                               data_key=data_key)
            cell_shape = (tf.shape(x)[0], self.b_shape[1])
            if init_cell is not None:
                self.weights.tensor_dict['cs'] = init_cell
            else:
                self.weights.tensor_dict['cs'] = tf.zeros(cell_shape)
            self.weights.tensor_dict['co'] = tf.zeros(cell_shape)

        co = self.weights.tensor_dict['co']
        if self.train_config['batchnorm']['type'] == 'batch':
            bn_idx = min(time_idx, self.train_config['batchnorm']['tau'] - 1)
            if 'x' in self.train_config['batchnorm']['modes']:
                if len(self.bn_b_x) == bn_idx:
                    self.bn_b_x.append(get_batchnormalizer())
                x = self.bn_b_x[bn_idx](x, self.is_training)
            if 'h' in self.train_config['batchnorm']['modes'] and bn_idx > 0:
                if len(self.bn_b_h) == bn_idx - 1:
                    self.bn_b_h.append(get_batchnormalizer())
                co = self.bn_b_h[bn_idx - 1](co, self.is_training)

        x = tf.concat([x, co], axis=1)

        i_act = tf.matmul(
            x, self.weights.tensor_dict['wi']) + self.weights.tensor_dict['bi']
        c_act = tf.matmul(
            x, self.weights.tensor_dict['wc']) + self.weights.tensor_dict['bc']
        o_act = tf.matmul(
            x, self.weights.tensor_dict['wo']) + self.weights.tensor_dict['bo']

        if self.train_config['batchnorm']['type'] == 'layer':
            i_act = tf.contrib.layers.layer_norm(i_act)
            c_act = tf.contrib.layers.layer_norm(c_act)
            o_act = tf.contrib.layers.layer_norm(o_act)

        if 'i' in self.rnn_config['act_disc']:
            print(self.rnn_config['act_bins'])
            i = disc_sigmoid(i_act, self.rnn_config['act_bins'])
        else:
            i = tf.sigmoid(i_act)

        f = 1. - i
        if 'c' in self.rnn_config['act_disc']:
            c = disc_tanh(c_act, self.rnn_config['act_bins'])
        else:
            c = tf.tanh(c_act)

        if 'o' in self.rnn_config['act_disc']:
            o = disc_sigmoid(o_act, self.rnn_config['act_bins'])
        else:
            o = tf.sigmoid(o_act)

        self.weights.tensor_dict['cs'] = tf.multiply(
            f, self.weights.tensor_dict['cs']) + tf.multiply(i, c)
        self.weights.tensor_dict['co'] = tf.multiply(
            o, tf.tanh(self.weights.tensor_dict['cs']))
        return self.weights.tensor_dict['co'], self.weights.tensor_dict['cs']

    def create_var_fp(self, x, time_idx, init, init_cell=None):
        if init:
            cell_shape = (tf.shape(x)[0], self.b_shape[1])
            if init_cell is not None:
                self.weights.tensor_dict['cs'] = init_cell
            else:
                self.weights.tensor_dict['cs'] = tf.zeros(cell_shape)
            self.weights.tensor_dict['co'] = tf.zeros(cell_shape)

        co = self.weights.tensor_dict['co']
        if self.train_config['batchnorm']['type'] == 'batch':
            bn_idx = min(time_idx, self.train_config['batchnorm']['tau'] - 1)
            if 'x' in self.train_config['batchnorm']['modes']:
                if len(self.bn_s_x) == bn_idx:
                    self.bn_s_x.append(get_batchnormalizer())
                x = self.bn_s_x[bn_idx](x, self.is_training)
            if 'h' in self.train_config['batchnorm']['modes'] and bn_idx > 0:
                if len(self.bn_s_h) == bn_idx - 1:
                    self.bn_s_h.append(get_batchnormalizer())
                co = self.bn_s_h[bn_idx - 1](co, self.is_training)

        x = tf.concat([x, co], axis=1)
        i_act = tf.matmul(
            x, self.weights.var_dict['wi']) + self.weights.var_dict['bi']
        c_act = tf.matmul(
            x, self.weights.var_dict['wc']) + self.weights.var_dict['bc']
        o_act = tf.matmul(
            x, self.weights.var_dict['wo']) + self.weights.var_dict['bo']

        if self.train_config['batchnorm']['type'] == 'layer':
            i_act = tf.contrib.layers.layer_norm(i_act)
            c_act = tf.contrib.layers.layer_norm(c_act)
            o_act = tf.contrib.layers.layer_norm(o_act)

        if init:
            for act_type, act in zip(['i', 'c', 'o'], [i_act, c_act, o_act]):
                self.acts[act_type] = act
                for neuron_idc in range(len(self.act_neurons)):
                    self.acts[act_type + '_' + str(neuron_idc)] = tf.slice(
                        act, begin=(0, neuron_idc), size=(-1, 1))

        else:
            for act_type, act in zip(['i', 'c', 'o'], [i_act, c_act, o_act]):
                self.acts[act_type] = tf.concat([act, self.acts[act_type]],
                                                axis=0)
                for neuron_idc in range(len(self.act_neurons)):
                    self.acts[act_type + '_' + str(neuron_idc)] = \
                        tf.concat([tf.slice(act, begin=(0, neuron_idc), size=(-1, 1)),
                                   self.acts[act_type + '_' + str(neuron_idc)]], axis=0)

        if 'i' in self.rnn_config['act_disc']:
            i = tf.cast(tf.cast(
                tf.sigmoid(i_act) * self.rnn_config['act_bins'],
                dtype=tf.int32),
                        dtype=tf.float32) / self.rnn_config['act_bins']
            if get_info_config()['cell_access']:
                self.cell_access_mat.append(i)

        else:
            i = tf.sigmoid(i_act)
        f = 1. - i

        if 'c' in self.rnn_config['act_disc']:
            c = tf.cast(tf.cast(
                tf.sigmoid(c_act) * self.rnn_config['act_bins'],
                dtype=tf.int32),
                        dtype=tf.float32) * 2 / self.rnn_config['act_bins'] - 1
        else:
            c = tf.tanh(c_act)

        if 'o' in self.rnn_config['act_disc']:
            o = tf.cast(tf.cast(
                tf.sigmoid(o_act) * self.rnn_config['act_bins'],
                dtype=tf.int32),
                        dtype=tf.float32) / self.rnn_config['act_bins']
        else:
            o = tf.sigmoid(o_act)

        self.weights.tensor_dict['cs'] = tf.multiply(
            f, self.weights.tensor_dict['cs']) + tf.multiply(i, c)
        if 'i' in self.rnn_config['act_disc']:
            self.weights.tensor_dict['co'] = tf.multiply(
                o, self.weights.tensor_dict['cs'])
        else:
            self.weights.tensor_dict['co'] = tf.multiply(
                o, tf.tanh(self.weights.tensor_dict['cs']))
        return self.weights.tensor_dict['co'], self.weights.tensor_dict['cs']
Esempio n. 8
0
class FCLayer:
    def __init__(self, layer_idx, is_training, tau, prev_neurons=None):
        rnn_config = get_rnn_config()
        self.train_config = get_train_config()
        self.layer_config = rnn_config['layer_configs'][layer_idx]
        if prev_neurons is None:
            self.w_shape = (rnn_config['layout'][layer_idx - 1],
                            rnn_config['layout'][layer_idx])
        else:
            self.w_shape = (prev_neurons, rnn_config['layout'][layer_idx])
        self.b_shape = (1, self.w_shape[1])
        self.is_training = is_training

        # Activation summaries and specific neurons to gather individual histograms
        self.acts = dict()
        self.act_neurons = np.random.choice(
            range(self.b_shape[1]),
            size=(get_info_config()['tensorboard']['single_acts'], ),
            replace=False)
        if self.train_config['batchnorm'][
                'type'] == 'batch' and 'fc' in self.train_config['batchnorm'][
                    'modes']:
            self.bn_s_x = get_batchnormalizer()
            self.bn_b_x = get_batchnormalizer()

        with tf.variable_scope(self.layer_config['var_scope']):
            var_keys = ['w', 'b']
            self.weights = Weights(var_keys, self.layer_config, self.w_shape,
                                   self.b_shape, tau)

    def create_pfp(self, x_m, x_v, mod_layer_config, init):
        a_m, a_v = approx_activation(self.weights.var_dict['w_m'],
                                     self.weights.var_dict['w_v'],
                                     self.weights.var_dict['b_m'],
                                     self.weights.var_dict['b_v'], x_m, x_v)
        return a_m, a_v

    def create_l_sampling_pass(self,
                               x,
                               mod_layer_config,
                               time_idx,
                               init,
                               init_cell=None):
        if self.train_config['batchnorm'][
                'type'] == 'batch' and 'fc' in self.train_config['batchnorm'][
                    'modes']:
            x = self.bn_b_x(x, self.is_training)
        return self.weights.sample_activation(
            'w', 'b', x, None, init,
            self.train_config['batchnorm']['type'] == 'layer'), None

    def create_g_sampling_pass(self,
                               x,
                               mod_layer_config,
                               time_idx,
                               init,
                               second_arm_pass=False,
                               data_key=None,
                               init_cell=None):
        if init:
            self.weights.create_tensor_samples(second_arm_pass=second_arm_pass,
                                               data_key=data_key)
        if self.train_config['batchnorm'][
                'type'] == 'batch' and 'fc' in self.train_config['batchnorm'][
                    'modes']:
            x = self.bn_b_x(x, self.is_training)

        act = tf.matmul(x, self.weights.tensor_dict['w'])
        if self.layer_config['bias_enabled']:
            act += self.weights.tensor_dict['b']
        if self.train_config['batchnorm']['type'] == 'layer':
            return tf.contrib.layers.layer_norm(act)
        else:
            return act, None

    def create_var_fp(self, x, time_idx, init, init_cell=None):
        if self.train_config['batchnorm'][
                'type'] == 'batch' and 'fc' in self.train_config['batchnorm'][
                    'modes']:
            x = self.bn_s_x(x, self.is_training)

        act = tf.matmul(x, self.weights.var_dict['w'])
        if self.layer_config['bias_enabled']:
            act += self.weights.var_dict['b']
        if self.train_config['batchnorm']['type'] == 'layer':
            act = tf.contrib.layers.layer_norm(act)

        # Store activations over layer and over single neurons.
        if get_rnn_config()['architecture'] == 'encoder':
            return act, None
        if time_idx == 0:
            self.acts['n'] = act
            for neuron_idc in range(len(self.act_neurons)):
                self.acts['n' + '_' + str(neuron_idc)] = tf.slice(
                    act, begin=(0, neuron_idc), size=(-1, 1))
        else:
            self.acts['n'] = tf.concat([self.acts['n'], act], 0)
            for neuron_idc in range(len(self.act_neurons)):
                self.acts['n' + '_' + str(neuron_idc)] = tf.concat([
                    tf.slice(act, begin=(0, neuron_idc), size=(-1, 1)),
                    self.acts['n_' + str(neuron_idc)]
                ],
                                                                   axis=0)

        return act, None