models/dense_net.py
def add_new_kernels_to_layer(self, _input, in_cv, layer, kernel_num,
                                 complementarity=True, kernel_size=3):
        """
        Adds new convolution kernels to a layer within a block:
        creates the kernels, reconstructs the composite function, and
        concatenates outputs to ensure the DenseNet paradigm.

        If required, uses a complementarity mechanism to initialise the new
        kernels: the sign configuration is the opposite of that of the kernels
        with lowest CS, unless that configuration is already taken (in which
        case it must be differnet, but close to the opposite).

        Returns the layer's new output tensor.
        N.B.: This function is meant to be used ONLY in self-constructing mode
            (i.e. when should_self_construct is true).

        Args:
            _input: tensor, the layer's input;
            in_cv: tensor, the input for the layer's convolution;
            layer: `int`, identifier number for this layer (within a block);
            kernel_num: `int`, number of new (square) kernels to be added;
            complementarity: `bool`, whether the complementarity mechanism
                should be used to initialise new kernels or not;
            kernel_size: `int`, size of the kernels (their side).
        """
        with tf.variable_scope("layer_%d" % layer):
            with tf.variable_scope("composite_function"):
                # if using the complementarity mechanism
                if complementarity:
                    # get the sign distribution of all kernels in the layer
                    kernel_signs = []
                    for old_kernel in self.kernels_ref_list[-1][-1]:
                        kernel_signs.append(
                            np.sign(self.sess.run(old_kernel)))
                    # get the ids of the kernels with lowest CS
                    compl_kernels = sorted(
                        range(len(self.kCS_FIFO)),
                        key=lambda i: self.kCS_FIFO[i][-1])[:kernel_num]

                # create and initialise kernel_num new kernels
                in_features = int(in_cv.get_shape()[-1])
                for new_k in range(kernel_num):
                    self.kernel_name_counter += 1
                    self.kernels_ref_list[-1][-1].append(
                        self.weight_variable_msra(
                            [kernel_size, kernel_size, in_features],
                            name='kernel'+str(self.kernel_name_counter)))
                    self.sess.run(tf.variables_initializer(
                        [self.kernels_ref_list[-1][-1][-1]]))

                    # if complementarity, make each new kernel complementary to
                    # one of the previously identified low-CS kernels
                    if complementarity:
                        # get the abs value contents of the new kernel
                        new_k_image = self.sess.run(
                            self.kernels_ref_list[-1][-1][-1])
                        new_k_image = np.absolute(new_k_image)
                        # sign distribution = opposite to the low-CS kernel
                        new_k_signs = -1*kernel_signs[compl_kernels[new_k]]
                        # check if sign distribution already exists
                        new_k_signs_try = new_k_signs
                        sign_distr_exists = True
                        patience = kernel_size*kernel_size*in_features
                        while sign_distr_exists and patience:
                            # compare with each of the distributions
                            sign_distr_exists = False
                            for sign_distr in kernel_signs:
                                sign_distr_exists = sign_distr_exists and (
                                    new_k_signs == sign_distr).all()
                            # if so, switch one of the signs randomly
                            if sign_distr_exists:
                                new_k_signs_try = np.copy(new_k_signs)
                                new_k_signs_try[
                                    np.random.randint(kernel_size)][
                                    np.random.randint(kernel_size)][
                                    np.random.randint(in_features)
                                    ] *= -1
                                patience -= 1
                        # finally, apply the sign distr and add it to the list
                        new_k_image = np.multiply(new_k_image, new_k_signs_try)
                        kernel_signs.append(new_k_signs_try)
                        # assign the new weight values to the kernel
                        self.sess.run(self.kernels_ref_list[-1][-1][-1].assign(
                            new_k_image))

                # reconstruct the composite function from the current kernels
                comp_out, filter_ref = self.reconstruct_composite_function(
                    in_cv, self.kernels_ref_list[-1][-1])
                # save a reference to the composite function's filter
                self.filter_ref_list[-1][-1] = filter_ref
            # concatenate output with layer input to ensure DenseNet paradigm
            if TF_VERSION[0] >= 1 and TF_VERSION[1] >= 0:
                output = tf.concat(axis=3, values=(_input, comp_out))
            else:
                output = tf.concat(3, (_input, comp_out))

        # Keep track of kernel CS.
        self.kCS_FIFO.extend([
            deque(maxlen=self.dkCS_softening) for i in range(kernel_num)])
        self.dkCS_FIFO.extend([
            deque(maxlen=self.dkCS_std_window) for i in range(kernel_num)])

        return output

        Adds new convolution kernels to a layer within a block:
        creates the kernels, reconstructs the composite function, and
        concatenates outputs to ensure the DenseNet paradigm.

        If required, uses a complementarity mechanism to initialise the new
        kernels: the sign configuration is the opposite of that of the kernels
        with lowest CS, unless that configuration is already taken (in which
        case it must be differnet, but close to the opposite).

        Returns the layer's new output tensor.
        N.B.: This function is meant to be used ONLY in self-constructing mode
            (i.e. when should_self_construct is true).

        Args:
            _input: tensor, the layer's input;
            in_cv: tensor, the input for the layer's convolution;
            layer: `int`, identifier number for this layer (within a block);
            kernel_num: `int`, number of new (square) kernels to be added;
            complementarity: `bool`, whether the complementarity mechanism
                should be used to initialise new kernels or not;
            kernel_size: `int`, size of the kernels (their side).
        
Adds new convolution kernels to a layer within a block:
creates the kernels, reconstructs the composite function, and
concatenates outputs to ensure the DenseNet paradigm.

If required, uses a complementarity mechanism to initialise the new
kernels: the sign configuration is the opposite of that of the kernels
with lowest CS, unless that configuration is already taken (in which
case it must be differnet, but close to the opposite).

Returns the layer's new output tensor.
N.B.: This function is meant to be used ONLY in self-constructing mode
.
Adds new convolution kernels to a layer within a block : creates the kernels reconstructs the composite function and concatenates outputs to ensure the DenseNet paradigm . If required uses a complementarity mechanism to initialise the new kernels : the sign configuration is the opposite of that of the kernels with lowest CS unless that configuration is already taken ( in which case it must be differnet but close to the opposite ) . Returns the layer ' s new output tensor . N . B . : This function is meant to be used ONLY in self - constructing mode .
def add_new_kernels_to_layer(self, _input, in_cv, layer, kernel_num,
                                 complementarity=True, kernel_size=3):
        with tf.variable_scope("layer_%d" % layer):
            with tf.variable_scope("composite_function"):
                if complementarity:
                    kernel_signs = []
                    for old_kernel in self.kernels_ref_list[-1][-1]:
                        kernel_signs.append(
                            np.sign(self.sess.run(old_kernel)))
                    compl_kernels = sorted(
                        range(len(self.kCS_FIFO)),
                        key=lambda i: self.kCS_FIFO[i][-1])[:kernel_num]
                in_features = int(in_cv.get_shape()[-1])
                for new_k in range(kernel_num):
                    self.kernel_name_counter += 1
                    self.kernels_ref_list[-1][-1].append(
                        self.weight_variable_msra(
                            [kernel_size, kernel_size, in_features],
                            name='kernel'+str(self.kernel_name_counter)))
                    self.sess.run(tf.variables_initializer(
                        [self.kernels_ref_list[-1][-1][-1]]))
                    if complementarity:
                        new_k_image = self.sess.run(
                            self.kernels_ref_list[-1][-1][-1])
                        new_k_image = np.absolute(new_k_image)
                        new_k_signs = -1*kernel_signs[compl_kernels[new_k]]
                        new_k_signs_try = new_k_signs
                        sign_distr_exists = True
                        patience = kernel_size*kernel_size*in_features
                        while sign_distr_exists and patience:
                            sign_distr_exists = False
                            for sign_distr in kernel_signs:
                                sign_distr_exists = sign_distr_exists and (
                                    new_k_signs == sign_distr).all()
                            if sign_distr_exists:
                                new_k_signs_try = np.copy(new_k_signs)
                                new_k_signs_try[
                                    np.random.randint(kernel_size)][
                                    np.random.randint(kernel_size)][
                                    np.random.randint(in_features)
                                    ] *= -1
                                patience -= 1
                        new_k_image = np.multiply(new_k_image, new_k_signs_try)
                        kernel_signs.append(new_k_signs_try)
                        self.sess.run(self.kernels_ref_list[-1][-1][-1].assign(
                            new_k_image))
                comp_out, filter_ref = self.reconstruct_composite_function(
                    in_cv, self.kernels_ref_list[-1][-1])
                self.filter_ref_list[-1][-1] = filter_ref
            if TF_VERSION[0] >= 1 and TF_VERSION[1] >= 0:
                output = tf.concat(axis=3, values=(_input, comp_out))
            else:
                output = tf.concat(3, (_input, comp_out))
        self.kCS_FIFO.extend([
            deque(maxlen=self.dkCS_softening) for i in range(kernel_num)])
        self.dkCS_FIFO.extend([
            deque(maxlen=self.dkCS_std_window) for i in range(kernel_num)])
        return output
def add_new_kernels_to_layer ( self , _input , in_cv , layer , kernel_num , complementarity = True , kernel_size = 3 ) : with tf . variable_scope ( "layer_%d" % layer ) : with tf . variable_scope ( "composite_function" ) : if complementarity : kernel_signs = [ ] for old_kernel in self . kernels_ref_list [ - 1 ] [ - 1 ] : kernel_signs . append ( np . sign ( self . sess . run ( old_kernel ) ) ) compl_kernels = sorted ( range ( len ( self . kCS_FIFO ) ) , key = lambda i : self . kCS_FIFO [ i ] [ - 1 ] ) [ : kernel_num ] in_features = int ( in_cv . get_shape ( ) [ - 1 ] ) for new_k in range ( kernel_num ) : self . kernel_name_counter += 1 self . kernels_ref_list [ - 1 ] [ - 1 ] . append ( self . weight_variable_msra ( [ kernel_size , kernel_size , in_features ] , name = 'kernel' + str ( self . kernel_name_counter ) ) ) self . sess . run ( tf . variables_initializer ( [ self . kernels_ref_list [ - 1 ] [ - 1 ] [ - 1 ] ] ) ) if complementarity : new_k_image = self . sess . run ( self . kernels_ref_list [ - 1 ] [ - 1 ] [ - 1 ] ) new_k_image = np . absolute ( new_k_image ) new_k_signs = - 1 * kernel_signs [ compl_kernels [ new_k ] ] new_k_signs_try = new_k_signs sign_distr_exists = True patience = kernel_size * kernel_size * in_features while sign_distr_exists and patience : sign_distr_exists = False for sign_distr in kernel_signs : sign_distr_exists = sign_distr_exists and ( new_k_signs == sign_distr ) . all ( ) if sign_distr_exists : new_k_signs_try = np . copy ( new_k_signs ) new_k_signs_try [ np . random . randint ( kernel_size ) ] [ np . random . randint ( kernel_size ) ] [ np . random . randint ( in_features ) ] *= - 1 patience -= 1 new_k_image = np . multiply ( new_k_image , new_k_signs_try ) kernel_signs . append ( new_k_signs_try ) self . sess . run ( self . kernels_ref_list [ - 1 ] [ - 1 ] [ - 1 ] . assign ( new_k_image ) ) comp_out , filter_ref = self . reconstruct_composite_function ( in_cv , self . kernels_ref_list [ - 1 ] [ - 1 ] ) self . filter_ref_list [ - 1 ] [ - 1 ] = filter_ref if TF_VERSION [ 0 ] >= 1 and TF_VERSION [ 1 ] >= 0 : output = tf . concat ( axis = 3 , values = ( _input , comp_out ) ) else : output = tf . concat ( 3 , ( _input , comp_out ) ) self . kCS_FIFO . extend ( [ deque ( maxlen = self . dkCS_softening ) for i in range ( kernel_num ) ] ) self . dkCS_FIFO . extend ( [ deque ( maxlen = self . dkCS_std_window ) for i in range ( kernel_num ) ] ) return output
Adds new convolution kernels to a layer within a block:
creates the kernels, reconstructs the composite function, and
concatenates outputs to ensure the DenseNet paradigm.
Adds new convolution kernels to a layer within a block : creates the kernels reconstructs the composite function and concatenates outputs to ensure the DenseNet paradigm .
"""
        Adds new convolution kernels to a layer within a block:
        creates the kernels, reconstructs the composite function, and
        concatenates outputs to ensure the DenseNet paradigm.

        If required, uses a complementarity mechanism to initialise the new
        kernels: the sign configuration is the opposite of that of the kernels
        with lowest CS, unless that configuration is already taken (in which
        case it must be differnet, but close to the opposite).

        Returns the layer's new output tensor.
        N.B.: This function is meant to be used ONLY in self-constructing mode
            (i.e. when should_self_construct is true).

        Args:
            _input: tensor, the layer's input;
            in_cv: tensor, the input for the layer's convolution;
            layer: `int`, identifier number for this layer (within a block);
            kernel_num: `int`, number of new (square) kernels to be added;
            complementarity: `bool`, whether the complementarity mechanism
                should be used to initialise new kernels or not;
            kernel_size: `int`, size of the kernels (their side).
        """ # if using the complementarity mechanism # get the sign distribution of all kernels in the layer # get the ids of the kernels with lowest CS # create and initialise kernel_num new kernels # if complementarity, make each new kernel complementary to # one of the previously identified low-CS kernels # get the abs value contents of the new kernel # sign distribution = opposite to the low-CS kernel # check if sign distribution already exists # compare with each of the distributions # if so, switch one of the signs randomly # finally, apply the sign distr and add it to the list # assign the new weight values to the kernel # reconstruct the composite function from the current kernels # save a reference to the composite function's filter # concatenate output with layer input to ensure DenseNet paradigm # Keep track of kernel CS.
self
_input
tensor, the layer's input.
tensor the layer ' s input .
in_cv
tensor, the input for the layer's convolution.
tensor the input for the layer ' s convolution .
layer
`int`, identifier number for this layer (within a block).
` int ` identifier number for this layer ( within a block ) .
kernel_num
`int`, number of new (square) kernels to be added.
` int ` number of new ( square ) kernels to be added .
complementarity
`bool`, whether the complementarity mechanism
should be used to initialise new kernels or not.
` bool ` whether the complementarity mechanism should be used to initialise new kernels or not .
kernel_size
`int`, size of the kernels (their side).
` int ` size of the kernels ( their side ) .