2017-10-11 2 views
1

J'ai un modèle DNN feedforward avec plusieurs couches pour effectuer une classification binaire. La couche de sortie est 1 unité sigmoïde et la fonction de perte binary_crossentropy. Comme prévisions je m'attends à un vecteur avec des zéros/uns. Pour cela, je contourne les prédictions et les défigure. Ensuite, j'utilise les fonctions de score de sklearn pour calculer (f1score, rocauc, precision, recall, mcc). Le problème est que j'obtiens un vecteur de prédiction qui ne correspond pas à un codage à chaud unique comme je le prétends. Bien que si j'utilise une fonction de perte mse cela fonctionne comme prétendu.Courbe de classification binaire Keras sortie à zéro/un

=> fonction de création de modèle:

def create_DNN_model(self, verbose=True): 
     print("Creating DNN model") 
     fundamental_parameters = ['dropout', 'output_activation', 'optimization', 'learning_rate', 
           'units_in_input_layer', 
           'units_in_hidden_layers', 'nb_epoch', 'batch_size'] 
     for param in fundamental_parameters: 
      if self.parameters[param] == None: 
       print("Parameter not set: " + param) 
       return 
     self.print_parameter_values() 
     model = Sequential() 
     # Input layer 
     model.add(Dense(self.parameters['units_in_input_layer'], input_dim=self.feature_number, activation='relu')) 
     model.add(BatchNormalization()) 
     model.add(Dropout(self.parameters['dropout'])) 
     # constructing all hidden layers 
     for layer in self.parameters['units_in_hidden_layers']: 
      model.add(Dense(layer, activation='relu')) 
      model.add(BatchNormalization()) 
      model.add(Dropout(self.parameters['dropout'])) 
     # constructing the final layer 
     model.add(Dense(1)) 
     model.add(Activation(self.parameters['output_activation'])) 
     if self.parameters['optimization'] == 'SGD': 
      optim = SGD() 
      optim.lr.set_value(self.parameters['learning_rate']) 
     elif self.parameters['optimization'] == 'RMSprop': 
      optim = RMSprop() 
      optim.lr.set_value(self.parameters['learning_rate']) 
     elif self.parameters['optimization'] == 'Adam': 
      optim = Adam() 
     elif self.parameters['optimization'] == 'Adadelta': 
      optim = Adadelta() 
     model.add(BatchNormalization()) 
     model.compile(loss='binary_crossentropy', optimizer=optim, metrics=[matthews_correlation]) 
     if self.verbose == 1: str(model.summary()) 
     print("DNN model sucessfully created") 
     return model 

=> la fonction d'évaluation:

def evaluate_model(self, X_test, y_test): 
     print("Evaluating model with hold out test set.") 
     y_pred = self.model.predict(X_test) 
     y_pred = [float(np.round(x)) for x in y_pred] 
     y_pred = np.ravel(y_pred) 
     scores = dict() 
     scores['roc_auc'] = roc_auc_score(y_test, y_pred) 
     scores['accuracy'] = accuracy_score(y_test, y_pred) 
     scores['f1_score'] = f1_score(y_test, y_pred) 
     scores['mcc'] = matthews_corrcoef(y_test, y_pred) 
     scores['precision'] = precision_score(y_test, y_pred) 
     scores['recall'] = recall_score(y_test, y_pred) 
     scores['log_loss'] = log_loss(y_test, y_pred) 
     for metric, score in scores.items(): 
      print(metric + ': ' + str(score)) 
     return scores 

=> le vecteur prédit 'y_pred':

[-1. -1. 2. -0. 2. -1. -1. -1. 2. -1. -1. 2. -1. 2. -1. 2. -1. -1. 2. -1. 2. -1. -1. 2. -1. 2. 2. 2. -1. -1. 2. 2. 2. 2. -1. -1. 2. 2. 2. -1. 2. 2. -1. 2. -1. -1. -1. 1. -1. -1. -1.] 

Merci à l'avance.

+1

Vous utilisez l'activation linéaire (par défaut) dans le calque de sortie, alors que vous devriez utiliser sigmoïde. Devrait aider. –

+0

Vous avez absolument raison. Merci beaucoup. – lmpeixoto

+0

Je suis content que ça a marché, je n'étais pas sûr que ça suffise. Je vais le mettre comme une réponse. –

Répondre

0

Vous utilisez l'activation linéaire (par défaut) dans le calque de sortie, alors que vous devriez utiliser sigmoïde.