【问题标题】:Training with Keras/TensorFlow in fp16 / half-precision for RTX cards在 fp16 中使用 Keras/TensorFlow 进行训练/RTX 卡的半精度
【发布时间】:2020-02-21 23:22:19
【问题描述】:

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

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

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”,这让事情变得更加令人困惑......

我真的很感激一些指导。

谢谢!

【问题讨论】:

    标签: tensorflow keras rtx half-precision-float


    【解决方案1】:

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

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

    我没试过,但是在Keras(至少2.2.5)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”。

    【讨论】:

      猜你喜欢
      • 2019-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-02
      • 2021-05-14
      • 1970-01-01
      • 2020-06-04
      • 2020-09-29
      相关资源
      最近更新 更多