如何获得介于 0 和 1(或 -1 和 1)之间的预测分数?

How to get prediction scores between 0 and 1 (or -1 and 1)?

我正在训练一个模型,该模型将几个层添加到预定义的 VGGish 网络 (see github repo),以便它可以预测从音频文件中提取的输入 logmel 频谱图的 class(完整代码在底部)。

我首先从以前的函数生成 X_train, X_test, y_train, y_test 集,然后 运行 main() 代码块。这预测了第 78 行 X_test 的 classes 并打印了这些:

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

打印:

[[ -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 ]]

我的主要问题是如何让数组像这样打印,其中每个预测的 returns 0 和 1 或 -1 到 1 之间的值,然后我可以将其转换为 0 和1 的:

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

我认为这可以在这一行 (78) 中使用 predictions_sigm = prediction.eval(...) 而不是 predictions_sigm = logits.eval(...) 来完成,因为它似乎被命名为 'prediction' 并以某种方式使用 sigmoid,在行27 tf.sigmoid(logits, name='prediction'),但使用它会出现“NameError: name 'prediction' is not defined”。

如果以值的范围表示,-11 到 10 或 -1 到 0,它们的值是否有用?

完整代码:

#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

为 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

你正在输出 sigmoid 之前的 linear-layer。更改代码如下:

    # 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')

这将确保您输出介于 0 和 1 之间的值。

注意:您的评估未考虑 multi-class 分类,argmax 将 return 最大值的索引,在您的情况下将是单个输出。