我正在定制标准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
的最后一行即可。