Tensorflow如何计算模型的准确性?

时间:2019-04-24 10:51:07

标签: tensorflow keras deep-learning computer-vision tf.keras

我正在按照this教程进行二进制类分类。在定义模型时,其定义如下并引用:

  

应用tf.keras.layers.Dense图层将这些功能转换为每个图像的单个预测。您在这里不需要激活函数,因为此预测将被视为logit或原始预测值。正数表示1类,负数表示0类。

model = tf.keras.Sequential([
  base_model,
  tf.keras.layers.GlobalAveragePooling2D(),
  tf.keras.layers.Dense(1)
])

,然后将其编译为

base_learning_rate = 0.0001
model.compile(optimizer=tf.keras.optimizers.RMSprop(lr=base_learning_rate),
              loss='binary_crossentropy',
              metrics=['accuracy'])

我看到了类似的模型定义here,如下所示:

model = tf.keras.Sequential([
  mobile_net,
  tf.keras.layers.GlobalAveragePooling2D(),
  tf.keras.layers.Dense(len(label_names))])

model.compile(optimizer=tf.train.AdamOptimizer(), 
              loss=tf.keras.losses.sparse_categorical_crossentropy,
              metrics=["accuracy"])

在上述不使用激活函数的情况下,我观​​察到预测值采用任何实际值(不在[0,1]范围内),而不是单个负值。

model = tf.keras.Sequential([
  mobile_net,
  tf.keras.layers.GlobalAveragePooling2D(),
  tf.keras.layers.Dense(1)])

base_learning_rate = 0.0001
model.compile(optimizer=tf.keras.optimizers.RMSprop(lr=base_learning_rate),
              loss='binary_crossentropy',
              metrics=['accuracy'])

np.squeeze(model.predict(test_ds, steps=test_steps_per_epoch))

# array([0.8656062 , 1.1738479 , 1.3243774 , 0.43144074, 1.3459874 ,
       0.8830215 , 0.27673364, 0.61824167, 0.6811296 , 0.31660053,
       0.66832197, 0.9944696 , 1.1472682 , 0.643435  , 1.6108004 ,
       0.46332538, 1.0919437 , 0.9578197 , 1.176657  , 1.1019497 ,
       1.2280573 , 1.3852577 , 1.0576394 , 0.89174306, 0.75531614,
       0.77309614, 0.2964771 , 1.4851328 , 0.52786475, 0.8349319 ,
       0.6725186 , 0.850648  , 1.5454502 , 1.5105858 , 0.8132403 ,
       0.8769205 , 0.8270436 , 0.5637488 , 1.0141921 , 1.7030811 ,
       1.4353518 , 1.4161562 , 1.378978  , 0.501247  , 0.6213258 ,
       0.9437766 , 2.429086  , 1.2481798 , 0.6229276 , 0.37893608,
       1.3877648 , 1.0904361 , 1.0879816 , 0.42403704, 0.79637295,
       2.8160148 , 0.8214861 , 0.8503458 , 0.80563146, 1.4901325 ,
       1.0303755 , 0.77981436, 1.088749  , 0.71522933, 1.3340217 ,
       2.0090134 , 1.0075089 , 0.8950774 , 0.6173111 , 0.7857665 ,
       1.7411164 , 1.3057053 , 0.33380216, 0.76223296, 1.5859761 ,
       0.96682435, 0.6254643 , 1.4843993 , 1.1031054 , 0.6320849 ,
       0.01859415, 0.72086346, 1.1440296 , 0.29395923, 1.5440805 ,
       0.380056  , 1.7602444 , 0.6369114 , 0.7867059 , 1.1418453 ,
       1.8237758 , 0.2560327 , 2.6044023 , 1.5562654 , 0.737739  ,
       0.40826577], dtype=float32)

问题:1

tensorflow如何基于这些值计算精度?因为这些值不是0或1,它用来确定样本是1类还是0类的阈值是什么?


在另一个tutorial中,我看到了在最后一层使用了S型或softmax激活功能。

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation=tf.nn.relu),
    keras.layers.Dense(10, activation=tf.nn.softmax)
])

类似地,我将模型定义如下:

model = tf.keras.Sequential([
  mobile_net,
  keras.layers.GlobalAveragePooling2D(),
  keras.layers.Dense(1, activation='sigmoid')
])

model.compile(optimizer=tf.keras.optimizers.RMSprop(lr=0.0001),
              loss='binary_crossentropy',
              metrics=['accuracy'])

和观测值在[0,1]

范围内
np.squeeze(model.predict(test_ds, steps=test_steps_per_epoch))

# array([0.5962706 , 0.41386074, 0.7369955 , 0.4375754 , 0.4081418 ,
       0.5233598 , 0.54559284, 0.58932847, 0.46750832, 0.73593813,
       0.49894634, 0.49055347, 0.37505004, 0.6098627 , 0.5756561 ,
       0.5219231 , 0.37050545, 0.5673407 , 0.5554987 , 0.531324  ,
       0.28257015, 0.74096835, 0.57002604, 0.46783662, 0.7368346 ,
       0.5332815 , 0.5606995 , 0.5541738 , 0.57862717, 0.40553188,
       0.46588784, 0.30736524, 0.43870398, 0.74726176, 0.71659195,
       0.27446586, 0.50352675, 0.43134567, 0.68349624, 0.38074452,
       0.5150338 , 0.7177907 , 0.61012363, 0.63375396, 0.43830383,
       0.5749217 , 0.4520418 , 0.42618847, 0.53284496, 0.55864084,
       0.55283684, 0.56968784, 0.5476512 , 0.47232378, 0.43477964,
       0.424371  , 0.5257551 , 0.4982109 , 0.6054718 , 0.45364827,
       0.5447099 , 0.5589619 , 0.6879043 , 0.43605927, 0.49726096,
       0.5986774 , 0.46806905, 0.45553213, 0.4558573 , 0.2709099 ,
       0.29398417, 0.42126212, 0.4208623 , 0.25966096, 0.5174277 ,
       0.5691663 , 0.6820154 , 0.66986185, 0.29530805, 0.5368336 ,
       0.6704497 , 0.4770817 , 0.58965963, 0.66673934, 0.44505033,
       0.3894297 , 0.53820807, 0.47612685, 0.3273378 , 0.6933465 ,
       0.54334545, 0.49939007, 0.5978731 , 0.49409997, 0.4585469 ,
       0.43943945], dtype=float32)

问题:2

在这种情况下,如何通过张量流计算精度?


问题:3

使用S型激活与不使用最后一层有何区别?当我使用S形函数时,模型的准确性比不使用S形函数时降低了10%。这是巧合还是需要使用激活功能做任何事情。

1 个答案:

答案 0 :(得分:1)

用于计算精度的函数可以在here中找到。根据您的问题,有不同的定义,例如binary_accuracycategorical_accuracy。根据输出形状和损耗自动选择合适的一个(请参见handle_metrics函数here)。基于这些:

1。

这取决于您的型号。在您的第一个示例中,它将使用

def binary_accuracy(y_true, y_pred):
    '''Calculates the mean accuracy rate across all predictions for binary
    classification problems.
    '''
    return K.mean(K.equal(y_true, K.round(y_pred)))

如您所见,它仅对模型预测进行了四舍五入。在第二个示例中,它将使用

def sparse_categorical_accuracy(y_true, y_pred):
    '''Same as categorical_accuracy, but useful when the predictions are for
    sparse targets.
    '''
    return K.mean(K.equal(K.max(y_true, axis=-1),
                          K.cast(K.argmax(y_pred, axis=-1), K.floatx())))

这里没有四舍五入,但是它会检查天气情况,预测最高的类别与带有真实标签的类别相同。

2。

将再次使用binary_accuracy。但是,这些预测将来自于S型激活。

3。

S型激活会改变您的输出。它将确保预测值在0到1之间。因此,准确性会发生变化,例如0变为0.5,因此四舍五入为1。这也会影响训练。通常会使用具有交叉熵的S型激活,因为它期望的是概率。