(self, batch_size, controller_output_size, out_vector_size, mem_hp, initializer=tf.random_normal,
                 initial_stddev=0.1)
:param batch_size: 
        :param controller_output_size: size of the controller output vector. Used for calculating the shape of the 
               interface weight matrix
        :param out_vector_size: size of the output of memory, after being passed through the output weight matrix
        :param mem_hp: hyperparameters for memory, object with attributes word_size, mem_size, num_read_heads 
        :param initial_stddev:
:param batch_size: 
        :param controller_output_size: size of the controller output vector. Used for calculating the shape of the 
               interface weight matrix
        :param out_vector_size: size of the output of memory, after being passed through the output weight matrix
        :param mem_hp: hyperparameters for memory, object with attributes word_size, mem_size, num_read_heads 
        :param initial_stddev:
: param batch_size : : param controller_output_size : size of the controller output vector . Used for calculating the shape of the interface weight matrix : param out_vector_size : size of the output of memory after being passed through the output weight matrix : param mem_hp : hyperparameters for memory object with attributes word_size mem_size num_read_heads : param initial_stddev :
def __init__(self, batch_size, controller_output_size, out_vector_size, mem_hp, initializer=tf.random_normal,
                 initial_stddev=0.1):
        """
        
        :param batch_size: 
        :param controller_output_size: size of the controller output vector. Used for calculating the shape of the 
               interface weight matrix
        :param out_vector_size: size of the output of memory, after being passed through the output weight matrix
        :param mem_hp: hyperparameters for memory, object with attributes word_size, mem_size, num_read_heads 
        :param initial_stddev: 
        """
        self.batch_size = batch_size
        self.controller_output_size = controller_output_size
        self.out_vector_size = out_vector_size

        self.memory_size = mem_hp.mem_size
        self.word_size = mem_hp.word_size
        self.num_read_heads = mem_hp.num_read_heads

        self.interface_vector_size = (self.word_size * self.num_read_heads) + \
                                     5 * self.num_read_heads + 3 * self.word_size + 3

        self.interface_weights = tf.Variable(
            initializer([self.controller_output_size, self.interface_vector_size], stddev=initial_stddev),
            name="interface_weights")
        self.output_weights = tf.Variable(
            initializer([self.num_read_heads, self.word_size, self.out_vector_size], stddev=initial_stddev),
            name="output_weights_memory")

        # Code below is a more-or-less pythonic way to process the individual interface parameters
        r, w = self.num_read_heads, self.word_size
        sizes = [r * w, r, w, 1, w, w, r, 1, 1, 3 * r]
        names = ["r_read_keys", "r_read_strengths", "write_key", "write_strength", "erase_vector", "write_vector",
                 "r_free_gates", "allocation_gate", "write_gate", "r_read_modes"]
        functions = [tf.identity, Memory.oneplus, tf.identity, Memory.oneplus, tf.nn.sigmoid, tf.identity,
                     tf.nn.sigmoid, tf.nn.sigmoid, tf.nn.sigmoid, self.reshape_and_softmax]

        indexes = [[sum(sizes[:i]), sum(sizes[:i + 1])] for i in range(len(sizes))]
        assert len(names) == len(sizes) == len(functions) == len(indexes)
        # Computing the interface dictionary from ordered lists of sizes, vector names and functions, as in the paper
        # self.split_interface is called later with the actual computed interface vector
        self.split_interface = lambda iv: {name: fn(iv[:, i[0]:i[1]]) for name, i, fn in
                                           zip(names, indexes, functions)}
def __init__ ( self , batch_size , controller_output_size , out_vector_size , mem_hp , initializer = tf . random_normal , initial_stddev = 0.1 ) : self . batch_size = batch_size self . controller_output_size = controller_output_size self . out_vector_size = out_vector_size self . memory_size = mem_hp . mem_size self . word_size = mem_hp . word_size self . num_read_heads = mem_hp . num_read_heads self . interface_vector_size = ( self . word_size * self . num_read_heads ) + 5 * self . num_read_heads + 3 * self . word_size + 3 self . interface_weights = tf . Variable ( initializer ( [ self . controller_output_size , self . interface_vector_size ] , stddev = initial_stddev ) , name = "interface_weights" ) self . output_weights = tf . Variable ( initializer ( [ self . num_read_heads , self . word_size , self . out_vector_size ] , stddev = initial_stddev ) , name = "output_weights_memory" ) # Code below is a more-or-less pythonic way to process the individual interface parameters r , w = self . num_read_heads , self . word_size sizes = [ r * w , r , w , 1 , w , w , r , 1 , 1 , 3 * r ] names = [ "r_read_keys" , "r_read_strengths" , "write_key" , "write_strength" , "erase_vector" , "write_vector" , "r_free_gates" , "allocation_gate" , "write_gate" , "r_read_modes" ] functions = [ tf . identity , Memory . oneplus , tf . identity , Memory . oneplus , tf . nn . sigmoid , tf . identity , tf . nn . sigmoid , tf . nn . sigmoid , tf . nn . sigmoid , self . reshape_and_softmax ] indexes = [ [ sum ( sizes [ : i ] ) , sum ( sizes [ : i + 1 ] ) ] for i in range ( len ( sizes ) ) ] assert len ( names ) == len ( sizes ) == len ( functions ) == len ( indexes ) # Computing the interface dictionary from ordered lists of sizes, vector names and functions, as in the paper # self.split_interface is called later with the actual computed interface vector self . split_interface = lambda iv : { name : fn ( iv [ : , i [ 0 ] : i [ 1 ] ] ) for name , i , fn in zip ( names , indexes , functions ) }