逐帧二进制精度计算的矢量化



我正在定制标准model.fit((方法,以在验证期间计算每个样本的逐帧精度。样本维度是512个时间帧和128个频率仓。到目前为止,我正在通过循环样本的每一帧来计算逐帧二进制精度,但这需要更多的时间(每个样本约7秒(。因此,验证过程需要花费大量时间。如何通过矢量化进程或其他方法来加快进程?

我使用的示例代码如下:

def test_step(self, data):
x, y = data # Unpack the data   x: (8, 512, 128, 1)    y: (8, 512, 6)
for spl in tf.range(1 if tf.shape(x)[0] == None else tf.shape(x)[0]):
val_accuracy_frm = tf.keras.metrics.BinaryAccuracy(name='frame_accuracy')
val_accuracy_frm_auc = tf.keras.metrics.AUC(name='AUC_accuracy')
x_spl = tf.reshape(x[spl], (1, tf.shape(x)[1], tf.shape(x)[2], tf.shape(x)[3]))
y_pred = self(x_spl, training=False) # y_pred : ([4], 1,512, 6)

for frame in tf.range(tf.shape(x)[1]):
for scl in ['8', '4', '2', '1']:  # Note: For ease, '8' is always the smallest resolution scale and is at index 0 (always) followed by '4' --> '2' --> '1'
if scl == '8':
val_accuracy_frm.reset_states()
val_accuracy_frm.update_state(y[spl][frame], y_pred[0][0][frame])
accuracy_8 = val_accuracy_frm.result()
val_accuracy_frm.reset_states()
elif scl == '4':
val_accuracy_frm.reset_states()
val_accuracy_frm.update_state(y[spl][frame], y_pred[1][0][frame])
accuracy_4 = val_accuracy_frm.result()
val_accuracy_frm.reset_states()
elif scl == '2':
val_accuracy_frm.reset_states()
val_accuracy_frm.update_state(y[spl][frame], y_pred[2][0][frame])
accuracy_2 = val_accuracy_frm.result()
val_accuracy_frm.reset_states()
elif scl == '1':
val_accuracy_frm.reset_states()
val_accuracy_frm.update_state(y[spl][frame], y_pred[3][0][frame])
accuracy_1 = val_accuracy_frm.result()
val_accuracy_frm.reset_states()

val_acc['a8'] = tf.reduce_mean((val_acc['a8'], float(accuracy_8)))
val_acc['a4'] = tf.reduce_mean((val_acc['a4'], float(accuracy_4)))
val_acc['a2'] = tf.reduce_mean((val_acc['a2'], float(accuracy_2)))
val_acc['a1'] = tf.reduce_mean((val_acc['a1'], float(accuracy_1)))

# bce_loss(y, y_pred) # Updates the metrics tracking the loss
val_loss_avg.update_state(y, y_pred) # Update the metrics.
val_accuracy.update_state(y, y_pred) # Update the metrics.
return {m.name: m.result() for m in [val_loss_avg, val_accuracy]}

我使用的是4输出模型,批量大小为8,标签总数为6。

假设y_pred是一个4元组,其中每个y_pred[i]的形状都像y一样为(8, 512, 6),我认为您可以这样做:

def test_step(self, data):
x, y = data  # Unpack the data   x: (8, 512, 128, 1)    y: (8, 512, 6)
y_pred = self(x, training=False)  # shape ([4], 8, 512, 6)
val_acc = {}
for key, idx in zip(["a8", "a4", "a2", "a1"], range(4)):
val_acc[key] = tf.keras.metrics.binary_accuracy(y, y_pred[idx])  # shape (8, 512)
val_acc = {k: tf.reduce_mean(val_acc[k]) for k in val_acc}
# ...

val_acc是整个批次a8、a4、a2、a1中每一个的平均精度的dict,您可以将其用于任何用途。

编辑:如果需要每帧度量,只需删除带有reduce_mean的最后一行即可。

最新更新