0

我刚得到一个 RTX 2070 Super,我想尝试使用带有 TensorFlow 后端的 Keras 进行半精度训练。

到目前为止,我发现了类似这样的文章,建议使用此设置:

import keras.backend as K

dtype='float16'
K.set_floatx(dtype)

# default is 1e-7 which is too small for float16.  Without adjusting the epsilon, we will get NaN predictions because of divide by zero problems
K.set_epsilon(1e-4) 

该网络是一个简单的 4 层 CNN,用于音频分类。

我的输入数据是之前生成的 NumPy 3D 数组(使用 LibROSA 提取的音频 MFCC 特征)。该数据是使用 CPU 生成的,我知道这些值保存为 32 位浮点数。

当我尝试使用这些数据训练我的网络时,我收到以下错误:

TypeError:传递给“合并”操作的“输入”的列表中的张量具有不完全匹配的类型 [float16, float32]。

在另一篇文章中,我读到我还应该“在 SoftMax 层之前转换回 FP32”,这让事情变得更加令人困惑......

我真的很感激一些方向。

谢谢!

4

1 回答 1

0

在不了解模型架构的情况下,很难知道 dtype 不匹配的原因。但是,我认为它在 Merge 之前有一个 BatchNorm 层。

在这种情况下,merge 和 softmax 推荐的原因是相同的,在涉及计算统计(均值/方差)的操作期间,最好使用 float32。这是因为使用 float16 时,精度误差可能太大并且会给出不准确的结果,尤其是在除法期间。

我没试过,但是在 Keras(2.2.5 atleast) BatchNormalization 层中,如果使用 Tensorflow 作为后端,方差会转换为 float32。

   if K.backend() != 'cntk':
        sample_size = K.prod([K.shape(inputs)[axis]
                              for axis in reduction_axes])
        sample_size = K.cast(sample_size, dtype=K.dtype(inputs))
        if K.backend() == 'tensorflow' and sample_size.dtype != 'float32':
            sample_size = K.cast(sample_size, dtype='float32')

        # sample variance - unbiased estimator of population variance
        variance *= sample_size / (sample_size - (1.0 + self.epsilon))

也许归一化后的结果张量没有转换回 float16 并导致错误。为了解决这个问题,您可以删除 BatchNorm 进行确认,然后修改您的本地 keras 副本或实施自定义 BatchNorm,在标准化后转换回“float16”。

于 2020-02-06T19:26:34.373 回答