Home > Software design >  How to get prediction scores between 0 and 1 (or -1 and 1)?
How to get prediction scores between 0 and 1 (or -1 and 1)?

Time:02-12

I am training a model that adds a couple of layers to the predifined VGGish network (see github repo), so that it can predict the class of input logmel spectrograms extracted from audio files (full code at bottom).

I generate X_train, X_test, y_train, y_test sets from a previous function first and then run the main() codeblock. This predicts the classes of the X_test at line 78 and prints these:

predictions_sigm = logits.eval(feed_dict = {features_input:X_test})
print(predictions) 

Prints:

[[ -9.074987    8.840093   -8.426974 ]
 [ -9.376444    9.13514    -8.79967  ]
 [-10.03653    -7.725624    7.2162223]
 [ -9.650997    9.308293   -8.9559   ]
 [  7.789041   -7.8485446  -9.8974285]
 [  7.7869387  -7.850354   -9.899081 ]
 [-10.4985485  -8.368322    7.558868 ]
 [-10.306433   -8.043555    7.4093537]
 [  7.787068   -7.850254   -9.898217 ]
 [  7.789579   -7.851698   -9.90515  ]
 [  7.787512   -7.8483863  -9.90212  ]
 [ -9.28933     9.058059   -8.713937 ]
 [  7.7886     -7.8486743  -9.901876 ]
 [  7.7899137  -7.8464875  -9.899316 ]
 [-10.434939   -8.171508    7.459009 ]
 [-10.714449   -8.394194    7.642472 ]
 [-10.564347   -8.165948    7.6475844]
 [ -9.63355     9.158067   -8.794765 ]
 [ -9.501944    9.241178   -8.889491 ]]

My main query is how do I get the array to instead print like this, where it returns 0's and 1's or values between -1 to 1 for each prediction, which I can then convert to 0's and 1's:

[[ 0   1   0 ]
 [ 0   1   0 ]
 [ 0   0    1]
 ...
 [ 0   1   0 ]]

I thought this could be done using predictions_sigm = prediction.eval(...) for this line (78) instead of predictions_sigm = logits.eval(...), as it appeared to be named 'prediction' and use sigmoid some how, at line 27 tf.sigmoid(logits, name='prediction'), but using this gives a 'NameError: name 'prediction' is not defined'.

If presented as a range of values, either -11 to 10 or -1 to 0, are their values useful for something?

Full code:

#run using: 
   #python vggish_train_demo.py --num_batches 100
_NUM_CLASSES = 3
batch_size = 10   
    
def main(X):   
  with tf.Graph().as_default(), tf.Session() as sess:
    # Define VGGish.
    embeddings = vggish_slim.define_vggish_slim(training=FLAGS.train_vggish)
    
    # Define a shallow classification model and associated training ops on top
    # of VGGish.
    with tf.variable_scope('mymodel'):
      # Add a fully connected layer with 100 units. Add an activation function
      # to the embeddings since they are pre-activation.
      num_units = 100
      fc = slim.fully_connected(tf.nn.relu(embeddings), num_units)

      # Add a classifier layer at the end, consisting of parallel logistic
      # classifiers, one per class. This allows for multi-class tasks.
      logits = slim.fully_connected(                                      
          fc, _NUM_CLASSES, activation_fn=None, scope='logits')
      tf.sigmoid(logits, name='prediction')

      # Add training ops.
      with tf.variable_scope('train'):
        global_step = tf.train.create_global_step()

        # Labels are assumed to be fed as a batch multi-hot vectors, with
        # a 1 in the position of each positive class label, and 0 elsewhere.
        labels_input = tf.placeholder(
            tf.float32, shape=(None, _NUM_CLASSES), name='labels')

        # Cross-entropy label loss.
        xent = tf.nn.sigmoid_cross_entropy_with_logits(
            logits=logits, labels=labels_input, name='xent') 
        loss = tf.reduce_mean(xent, name='loss_op')
        tf.summary.scalar('loss', loss)

        # We use the same optimizer and hyperparameters as used to train VGGish.
        optimizer = tf.train.AdamOptimizer(
            learning_rate=vggish_params.LEARNING_RATE,
            epsilon=vggish_params.ADAM_EPSILON)
        train_op = optimizer.minimize(loss, global_step=global_step)

    # Initialize all variables in the model, and then load the pre-trained
    # VGGish checkpoint.
    sess.run(tf.global_variables_initializer())         
    vggish_slim.load_vggish_slim_checkpoint(sess, FLAGS.checkpoint)

    # The training loop.
    features_input = sess.graph.get_tensor_by_name(
        vggish_params.INPUT_TENSOR_NAME)
    
    for epoch in range(FLAGS.num_batches):
            epoch_loss = 0
            i=0
            while i < len(X_train):
                start = i
                end = i batch_size
                batch_x = np.array(X_train[start:end])
                batch_y = np.array(y_train[start:end])

                _, c = sess.run([train_op, loss], feed_dict={features_input: batch_x, labels_input: batch_y})
                epoch_loss  = c
                i =batch_size

            print('Epoch', epoch 1, 'completed out of',FLAGS.num_batches,', loss:',epoch_loss)

    correct = tf.equal(tf.argmax(logits, 1), tf.argmax(labels_input, 1))
    print('Accuracy:',accuracy.eval({features_input:X_test, labels_input:y_test}))
    
    predictions = logits.eval(feed_dict = {features_input:X_test}) 
    print(predictions) #shows table of predictions
    
    #Saves csv file of table of predictions for test data
    time = datetime.now().strftime('%H.%M.%S')
    np.savetxt("test_predictions_" time ".csv", predictionsm, delimiter=",") #put 'r"r'C:\Users\bw339\...\test_predictions' to save in a different folder
    
    
if __name__ == '__main__':
  tf.app.run()

#think the 'An exception has occurred, use %tb to see the full traceback.' is a jupyter thing, hopefully won't happen
 #when run in conda or bash

Edit for ahmet hamza emra

def main(X):   
  with tf.Graph().as_default(), tf.Session() as sess:
    # Define VGGish.
    embeddings = vggish_slim.define_vggish_slim(training=FLAGS.train_vggish)
    #embeddings = vggish_slim.define_vggish_slim(features_tensor= X_train, training=FLAGS.train_vggish) #gives an error that arrays are not right type. no idea why as the shpae of X[0] matches what vggish_slim_define() asks for

    #prediction = vggish_slim.define_vggish_slim(X)
    
    
    # Define a shallow classification model and associated training ops on top
    # of VGGish.
    with tf.variable_scope('mymodel'):
      # Add a fully connected layer with 100 units. Add an activation function
      # to the embeddings since they are pre-activation.
      num_units = 100
      fc = slim.fully_connected(tf.nn.relu(embeddings), num_units)

      # Add a classifier layer at the end, consisting of parallel logistic
      # classifiers, one per class. This allows for multi-class tasks.
      #logits = slim.fully_connected(                                      ### logits threw me, would be easier to name this 'end model' or something
       #   fc, _NUM_CLASSES, activation_fn=None, scope='logits')
      #tf.sigmoid(logits, name='prediction')
      
      linear_out= slim.fully_connected(                                      
          fc, _NUM_CLASSES, activation_fn=None, scope='linear_out')
      logits = tf.sigmoid(logits, name='logits')
    
    
    
    
      # Add training ops.
      with tf.variable_scope('train'):
        global_step = tf.train.create_global_step()

        # Labels are assumed to be fed as a batch multi-hot vectors, with
        # a 1 in the position of each positive class label, and 0 elsewhere.
        labels_input = tf.placeholder(
            tf.float32, shape=(None, _NUM_CLASSES), name='labels')

        # Cross-entropy label loss.
        xent = tf.nn.sigmoid_cross_entropy_with_logits(
            logits=logits, labels=labels_input, name='xent')    ###=labels is selecting my 'y', logits is like a precursor to predictions?
        loss = tf.reduce_mean(xent, name='loss_op')
        tf.summary.scalar('loss', loss)

        # We use the same optimizer and hyperparameters as used to train VGGish.
        optimizer = tf.train.AdamOptimizer(
            learning_rate=vggish_params.LEARNING_RATE,
            epsilon=vggish_params.ADAM_EPSILON)
        train_op = optimizer.minimize(loss, global_step=global_step)

    # Initialize all variables in the model, and then load the pre-trained
    # VGGish checkpoint.
    sess.run(tf.global_variables_initializer())         ### this starts the session appaz
    vggish_slim.load_vggish_slim_checkpoint(sess, FLAGS.checkpoint)

    # The training loop.
    features_input = sess.graph.get_tensor_by_name(
        vggish_params.INPUT_TENSOR_NAME)
    
    for epoch in range(FLAGS.num_batches):
            epoch_loss = 0
            i=0
            while i < len(X_train):
                start = i
                end = i batch_size
                batch_x = np.array(X_train[start:end])
                batch_y = np.array(y_train[start:end])

                _, c = sess.run([train_op, loss], feed_dict={features_input: batch_x, labels_input: batch_y})
                epoch_loss  = c
                i =batch_size

            print('Epoch', epoch 1, 'completed out of',FLAGS.num_batches,', loss:',epoch_loss)
    
    #Get accuracy if executed on test data
    correct = tf.equal(tf.argmax(logits, 1), tf.argmax(labels_input, 1)) #This line returns the max value of each array, which we want o be the same (think the prediction/logits is value given to each class with the highest value being the best match)
    accuracy = tf.reduce_mean(tf.cast(correct, 'float')) #changes correct to type: float
    print('Accuracy:',accuracy.eval({features_input:X_test, labels_input:y_test})) #TF is smart so just knows to feed it through the model without us seeming to tell it to. .eval() uses the current session which I guess is my model?
    
    #Save predictions for test data
    predictions_sigm = logits.eval(feed_dict = {features_input:X_test}) #not really _sigm, change back later
    #print(predictions_sigm) #shows table of predictions
    test_preds = pd.DataFrame(predictions_sigm, columns = col_names)  #converts predictions to df
    true_class = np.argmax(y_test, axis = 1)     #This saves the true class
    test_preds['True class'] = true_class        #This adds true class to the df
    print(test_preds)
        
    #Saves csv file of table of predictions for test data. NB. header will not save when using np.text for some reason
    time = datetime.now().strftime('%H.%M.%S')
    #np.savetxt("test_predictions_" time ".csv", test_preds.values, delimiter=",") #put 'r"r'C:\Users\bw339\...\test_predictions' to save in a different folder
    
    
    ##Save model
    #saver = tf.train.Saver()
    #saver.save(sess, 'my-test-model')

    
    
if __name__ == '__main__':
  tf.app.run()

#think the 'An exception has occurred, use %tb to see the full traceback.' is a jupyter thing, hopefully won't happen
 #when run in conda or bash

CodePudding user response:

You are outputing the linear-layer before the sigmoid. Change the code as following:

    # Add a classifier layer at the end, consisting of parallel logistic
    # classifiers, one per class. This allows for multi-class tasks.
    linear_out= slim.fully_connected(                                      
          fc, _NUM_CLASSES, activation_fn=None, scope='linear_out')
    logits = tf.sigmoid(linear_out, name='logits')

This will ensure you output the values between 0 and 1.

Note: Your evaluation is not considering multi-class classification, argmax will return the index of the largest value which in your case will be single output.

  • Related