<commit_before>from __future__ import division

import tensorflow as tf
import numpy as np
import time
import sklearn

from sklearn.metrics import precision_score, confusion_matrix
from sklearn.metrics import recall_score, f1_score, roc_curve

from dae import DAE_Layer
from os.path import join as pjoin

#from utils import load_data_sets_pretraining, write_csv
from tools.utils import fill_feed_dict, fill_feed_dict_dae
from tools.evaluate import do_eval_summary, evaluation, do_eval
from tools.config import FLAGS
from tools.visualize import make_heatmap
from tensorflow.python.framework.errors import FailedPreconditionError


class Stacked_DAE(object):
    
    def __init__(self, net_shape, session=None, selfish_layers=False):
        """ Stack De-noising Autoencoder (SDAE) initialization 
        
        Args:
            net_shape: The network architecture of the SDAE
            session : The tensorflow session
            selfish_layers: Whether the layers are going to be trained individually
                            or dependent to the direct output of the previous layer
                            (Theoretically: using it is faster, but memory costly)
        Tips:
            Using selfish_layers needs some extra handling.
              * Feed each individual De-noising Autoencoder (DAE) directly.
                    (e.g. feed_dict = {sdae.get_layers[i]._x : input_data})
              * Reassign/Reload the input data-set with the data-set for the next
                layer, obtained by using the genrate_next_dataset() function.
                    (e.g. in this case load_data_sets_pretraining(next_dataset, split_only=False))
        """
        self._sess = session
        self._net_shape = net_shape
        self._nHLayers = len(self._net_shape) - 2
        self._selfish_layers = selfish_layers
        self.loss_summaries = None
        
        if self._selfish_layers:
            self._x = None
            self._y_dataset = {}
        else:
            self._x = tf.placeholder(dtype=tf.float32, shape=(FLAGS.batch_size, self._net_shape[0]), name='dae_input_layer')

        self._dae_layers = []
        self._weights = []
        self._biases = []
        self.weights = []
        self.biases = []
        self._create_network()

    def _create_network(self):
        is_last_layer = False
        for layer in xrange(self._nHLayers + 1):
            with tf.name_scope("Layer_{0}".format(layer)):
                if self._selfish_layers: 
                    x = tf.placeholder(dtype=tf.float32, shape=(FLAGS.batch_size, self._net_shape[layer]), name='dae_input_from_layer_{0}'.format(layer))
                    self._y_dataset[layer] = []
                else:
                    if layer == 0:
                        x = self._x

                    else:
                        x = self._dae_layers[layer-1].clean_activation()
#                         x = self._dae_layers[layer-1].get_representation_y

                if not layer < self._nHLayers:
                    is_last_layer = True
#                 if layer == self._nHLayers:
#                     break

                dae_layer = DAE_Layer(in_data=x, prev_layer_size=self._net_shape[layer],
                                      next_layer_size=self._net_shape[layer+1], nth_layer=layer+1,
                                      last_layer=is_last_layer)
                
                self._dae_layers.append(dae_layer)

    @property
    def session(self):
        return self._sess

    @property
    def get_layers(self):
        return self._dae_layers
    
    @property
    def get_weights(self):
#         if len(self.weights) != self._nHLayers + 1:
        self.weights = []
        for n in xrange(self._nHLayers + 1):
            if self.get_layers[n].get_w:
                try:
                    self.weights.append(self._sess.run(self.get_layers[n].get_w))
                except FailedPreconditionError:
                    break
            else:
                break

        return self.weights

    @property
    def get_biases(self):
#         if len(self.biases) != self._nHLayers + 1:
        self.biases = []
        for n in xrange(self._nHLayers + 1):
            if self.get_layers[n].get_b:
                try:
                    self.biases.append(self._sess.run(self.get_layers[n].get_b))
                except FailedPreconditionError:
                    break
            else:
                break

        return self.biases
    
    def get_activation(self, x, layer, use_fixed=True):
        return self._sess.run(self.get_layers[layer].clean_activation(x_in=x, use_fixed=use_fixed))

    def train(self, cost, layer=None):
#         with tf.name_scope("Training"):
        # Add a scalar summary for the snapshot loss.
        self.loss_summaries = tf.scalar_summary(cost.op.name, cost)

        if layer is None:
            lr = FLAGS.supervised_learning_rate
        else:
            lr = self.get_layers[layer]._l_rate

        # Create the gradient descent optimizer with the given learning rate.
        optimizer = tf.train.GradientDescentOptimizer(lr)
        
        # Create a variable to track the global step.
        global_step = tf.Variable(0, trainable=False, name='global_step')
        
        # Use the optimizer to apply the gradients that minimize the loss
        # (and also increment the global step counter) as a single training step.
        train_op = optimizer.minimize(cost, global_step=global_step)
        return train_op, global_step

    def calc_last_x(self, X):
        tmp = X
        for layer in self.get_layers:
            tmp = layer.clean_activation(x_in=tmp, use_fixed=False)
#         print(tmp, self._net_shape[-2], self._net_shape[-1])
#         dae_layer = DAE_Layer(in_data=tmp, prev_layer_size=self._net_shape[-2],
#                                       next_layer_size=self._net_shape[-1], nth_layer=len(self._net_shape)-1,
#                                       last_layer=True)
# 
#         self._dae_layers.append(dae_layer)
#         tmp = self.get_layers[-1].clean_activation(x_in=tmp, use_fixed=False)
        
        return tmp

    def add_final_layer(self, input_x):
        last_x = self.calc_last_x(input_x)
        print "Last layer added:", last_x.get_shape()
        return last_x
    
#     def finetune_net(self):
#         last_output = self._x
#         
#         for layer in xrange(self._nHLayers + 1):
#             w = self.get_layers[layer]
    
    def genrate_next_dataset(self, from_dataset, layer):
        """ Generate next data-set
        Note: This function has a meaning only if selfish layers are in use.
        It takes as input the data-set and transforms it using the previously
        trained layer in order to obtain it's output. The output of that layer
        is saved as a data-set to be used as input for the next one.
        
        Args:
            from_dataset: The data-set you want to transform (usually
                            the one that the previous layer is trained on)
            layer : The layer to be used for the data transformation
        Returns:
            numpy array: The new data-set to be used for the next layer
        """
        if self._selfish_layers:<commit_msg>Minor changes in a variable name<commit_after>from __future__ import division

import tensorflow as tf
import numpy as np
import time
import sklearn

from sklearn.metrics import precision_score, confusion_matrix
from sklearn.metrics import recall_score, f1_score, roc_curve

from dae import DAE_Layer
from os.path import join as pjoin

#from utils import load_data_sets_pretraining, write_csv
from tools.utils import fill_feed_dict, fill_feed_dict_dae
from tools.evaluate import do_eval_summary, evaluation, do_eval
from tools.config import FLAGS
from tools.visualize import make_heatmap
from tensorflow.python.framework.errors import FailedPreconditionError


class Stacked_DAE(object):
    
    def __init__(self, net_shape, session=None, selfish_layers=False):
        """ Stack De-noising Autoencoder (SDAE) initialization 
        
        Args:
            net_shape: The network architecture of the SDAE
            session : The tensorflow session
            selfish_layers: Whether the layers are going to be trained individually
                            or dependent to the direct output of the previous layer
                            (Theoretically: using it is faster, but memory costly)
        Tips:
            Using selfish_layers needs some extra handling.
              * Feed each individual De-noising Autoencoder (DAE) directly.
                    (e.g. feed_dict = {sdae.get_layers[i]._x : input_data})
              * Reassign/Reload the input data-set with the data-set for the next
                layer, obtained by using the genrate_next_dataset() function.
                    (e.g. in this case load_data_sets_pretraining(next_dataset, split_only=False))
        """
        self._sess = session
        self._net_shape = net_shape
        self.nHLayers = len(self._net_shape) - 2
        self._selfish_layers = selfish_layers
        self.loss_summaries = None
        
        if self._selfish_layers:
            self._x = None
            self._y_dataset = {}
        else:
            self._x = tf.placeholder(dtype=tf.float32, shape=(FLAGS.batch_size, self._net_shape[0]), name='dae_input_layer')

        self._dae_layers = []
        self._weights = []
        self._biases = []
        self.weights = []
        self.biases = []
        self._create_network()

    def _create_network(self):
        is_last_layer = False
        for layer in xrange(self.nHLayers + 1):
            with tf.name_scope("Layer_{0}".format(layer)):
                if self._selfish_layers: 
                    x = tf.placeholder(dtype=tf.float32, shape=(FLAGS.batch_size, self._net_shape[layer]), name='dae_input_from_layer_{0}'.format(layer))
                    self._y_dataset[layer] = []
                else:
                    if layer == 0:
                        x = self._x

                    else:
                        x = self._dae_layers[layer-1].clean_activation()
#                         x = self._dae_layers[layer-1].get_representation_y

                if not layer < self.nHLayers:
                    is_last_layer = True
#                 if layer == self.nHLayers:
#                     break

                dae_layer = DAE_Layer(in_data=x, prev_layer_size=self._net_shape[layer],
                                      next_layer_size=self._net_shape[layer+1], nth_layer=layer+1,
                                      last_layer=is_last_layer)
                
                self._dae_layers.append(dae_layer)

    @property
    def session(self):
        return self._sess

    @property
    def get_layers(self):
        return self._dae_layers
    
    @property
    def get_weights(self):
#         if len(self.weights) != self.nHLayers + 1:
        self.weights = []
        for n in xrange(self.nHLayers + 1):
            if self.get_layers[n].get_w:
                try:
                    self.weights.append(self._sess.run(self.get_layers[n].get_w))
                except FailedPreconditionError:
                    break
            else:
                break

        return self.weights

    @property
    def get_biases(self):
#         if len(self.biases) != self.nHLayers + 1:
        self.biases = []
        for n in xrange(self.nHLayers + 1):
            if self.get_layers[n].get_b:
                try:
                    self.biases.append(self._sess.run(self.get_layers[n].get_b))
                except FailedPreconditionError:
                    break
            else:
                break

        return self.biases
    
    def get_activation(self, x, layer, use_fixed=True):
        return self._sess.run(self.get_layers[layer].clean_activation(x_in=x, use_fixed=use_fixed))

    def train(self, cost, layer=None):
#         with tf.name_scope("Training"):
        # Add a scalar summary for the snapshot loss.
        self.loss_summaries = tf.scalar_summary(cost.op.name, cost)

        if layer is None:
            lr = FLAGS.supervised_learning_rate
        else:
            lr = self.get_layers[layer]._l_rate

        # Create the gradient descent optimizer with the given learning rate.
        optimizer = tf.train.GradientDescentOptimizer(lr)
        
        # Create a variable to track the global step.
        global_step = tf.Variable(0, trainable=False, name='global_step')
        
        # Use the optimizer to apply the gradients that minimize the loss
        # (and also increment the global step counter) as a single training step.
        train_op = optimizer.minimize(cost, global_step=global_step)
        return train_op, global_step

    def calc_last_x(self, X):
        tmp = X
        for layer in self.get_layers:
            tmp = layer.clean_activation(x_in=tmp, use_fixed=False)
#         print(tmp, self._net_shape[-2], self._net_shape[-1])
#         dae_layer = DAE_Layer(in_data=tmp, prev_layer_size=self._net_shape[-2],
#                                       next_layer_size=self._net_shape[-1], nth_layer=len(self._net_shape)-1,
#                                       last_layer=True)
# 
#         self._dae_layers.append(dae_layer)
#         tmp = self.get_layers[-1].clean_activation(x_in=tmp, use_fixed=False)
        
        return tmp

    def add_final_layer(self, input_x):
        last_x = self.calc_last_x(input_x)
        print "Last layer added:", last_x.get_shape()
        return last_x
    
#     def finetune_net(self):
#         last_output = self._x
#         
#         for layer in xrange(self.nHLayers + 1):
#             w = self.get_layers[layer]
    
    def genrate_next_dataset(self, from_dataset, layer):
        """ Generate next data-set
        Note: This function has a meaning only if selfish layers are in use.
        It takes as input the data-set and transforms it using the previously
        trained layer in order to obtain it's output. The output of that layer
        is saved as a data-set to be used as input for the next one.
        
        Args:
            from_dataset: The data-set you want to transform (usually
                            the one that the previous layer is trained on)
            layer : The layer to be used for the data transformation
        Returns:
            numpy array: The new data-set to be used for the next layer
        """
        if self._selfish_layers:
{'fraction_non_alphanumeric': 0.078773714599945, 'fraction_numerical': 0.0037118504261754192, 'mean_word_length': 1.926186645213194, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4978296', 'n_tokens_mistral': 4227, 'n_tokens_neox': 4050, 'n_words': 1064}