Tensorflow 2.0:当输出是连续的时,如何计算度量?

2024-04-20 01:57:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在使用Tensorflow 2.0处理二进制顺序输入和输出,我一直想知道Tensorflow使用哪种方法来计算这些场景中培训期间的回忆或准确性等指标

我的网络的每个示例由60个时间步组成,每个时间步有300个特性,因此我的预期输出是1和0的(60, 1)数组。假设我有2000个验证样本。在评估每个历元的验证集时,tensorflow是否将2000个样本的所有连接到单个(2000*60=120000, 1)数组中,然后与连接的地面真相标签进行比较,还是单独评估每个(60, 1),然后返回这些值的平均值?有没有办法改变这种行为


Tags: 方法网络示例顺序tensorflow时间场景二进制
1条回答
网友
1楼 · 发布于 2024-04-20 01:57:14

默认情况下,Tensorflow/Keras会批量计算列车数据的度量,而在fit方法中validation_data参数中传递的所有数据上,Tensorflow/Keras会计算相同的度量

这意味着在列车数据拟合期间打印的度量值是在所有批次上计算的分数的平均值。换句话说,对于列车组,keras单独评估每个巴赫,然后返回这些值的平均值。由于验证数据不同,keras获取所有验证样本,然后将它们与“串联”的groundtruth标签进行比较

为了用代码证明这种行为,我提出了一个虚拟示例。我提供了一个定制的回调函数,用于计算在历元结束时传递的所有数据的准确度分数(用于训练和可选的验证)。这有助于我们理解张量流在训练期间的行为

import numpy as np
from sklearn.metrics import accuracy_score
import tensorflow as tf
from tensorflow.keras.layers import *
from tensorflow.keras.models import *
from tensorflow.keras.callbacks import *

class ACC_custom(tf.keras.callbacks.Callback):

    def __init__(self, train, validation=None):
        super(ACC_custom, self).__init__()
        self.validation = validation
        self.train = train

    def on_epoch_end(self, epoch, logs={}):

        logs['ACC_score_train'] = float('-inf')
        X_train, y_train = self.train[0], self.train[1]
        y_pred = (self.model.predict(X_train).ravel()>0.5)+0
        score = accuracy_score(y_train.ravel(), y_pred)       

        if (self.validation):
            logs['ACC_score_val'] = float('-inf')
            X_valid, y_valid = self.validation[0], self.validation[1]
            y_val_pred = (self.model.predict(X_valid).ravel()>0.5)+0
            val_score = accuracy_score(y_valid.ravel(), y_val_pred)
            logs['ACC_score_train'] = np.round(score, 5)
            logs['ACC_score_val'] = np.round(val_score, 5)
        else:
            logs['ACC_score_train'] = np.round(score, 5)

创建虚拟数据

x_train = np.random.uniform(0,1, (1000,60,10))
y_train = np.random.randint(0,2, (1000,60,1))

x_val = np.random.uniform(0,1, (500,60,10))
y_val = np.random.randint(0,2, (500,60,1))

拟合模型

inp = Input(shape=((60,10)), dtype='float32')
x = Dense(32, activation='relu')(inp)
out = Dense(1, activation='sigmoid')(x)
model = Model(inp, out)

es = EarlyStopping(patience=10, verbose=1, min_delta=0.001, 
                   monitor='ACC_score_val', mode='max', restore_best_weights=True)
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
history = model.fit(x_train,y_train, epochs=10, verbose=2,
          callbacks=[ACC_custom(train=(x_train,y_train),validation=(x_val,y_val)),es],
          validation_data=(x_val,y_val))

在下面的图表中,我比较了回调计算的精度和keras计算的精度

plt.plot(history.history['ACC_score_train'], label='accuracy_callback_train')
plt.plot(history.history['accuracy'], label='accuracy_default_train')
plt.legend(); plt.title('train accuracy')

enter image description here

plt.plot(history.history['ACC_score_val'], label='accuracy_callback_valid')
plt.plot(history.history['val_accuracy'], label='accuracy_default_valid')
plt.legend(); plt.title('validation accuracy')

enter image description here

正如我们所看到的,默认方法和回调之间的列车数据(第一个图)的准确性是不同的。这意味着列车数据的准确性是按批次计算的。 我们回调计算的验证精度(第二个图)与默认方法相同!这意味着验证数据的分数计算一次

相关问题 更多 >