使用Keras / TensorFlow对RTX卡进行fp16 /半精度的培训

时间:2019-10-25 15:20:42

标签: tensorflow keras rtx half-precision-float

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

到目前为止,我发现有类似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:传递给“合并” Op的“输入”的列表中的张量的类型[float16,float32]均不匹配。

在另一篇文章中,我读到我也应该“在SoftMax层之前重播到FP32”,这使事情变得更加令人困惑...

我真的很感谢一些指导。

谢谢!

1 个答案:

答案 0 :(得分:0)

不了解模型体系结构就很难知道dtype不匹配的原因。但是,我认为在合并之前它具有BatchNorm层。

在这种情况下,合并和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”。