tensorflow - 如何使用 16 位精度浮点

问题描述 投票:0回答:1

问题

float16
可以在 numpy 中使用,但不能在 Tensorflow 2.4.1 中使用,从而导致错误。

float16 是否仅在具有 16 位支持的 GPU 的实例上运行时才可用?

混合精度

如今,大多数模型都使用 float32 数据类型,它需要 32 位 记忆。但是,有两种精度较低的数据类型:float16 和 bfloat16,每个占用 16 位内存。现代的 加速器可以在 16 位数据类型中更快地运行操作,因为它们 拥有专门的硬件来运行 16 位计算和 16 位数据类型 可以更快地从内存中读取。

NVIDIA GPU 在 float16 中运行运算的速度比在 float32 中快,并且 TPU 在 bfloat16 中运行操作的速度比 float32 更快。所以, 应尽可能在这些低精度数据类型上使用 设备。然而,变量和一些计算仍然应该在 float32 出于数字原因,以便模型训练到相同的值 质量。 Keras 混合精度 API 允许您混合使用 float16 或 bfloat16 与 float32,以获得性能 受益于 float16/bfloat16 以及数值稳定性受益于 浮点32。

那么在CPU上测试时,是否需要手动将类型改为float32才能运行?根据[TF2.0]全局更改默认类型,目前没有选项可以更改默认浮点精度。

numpy

import numpy as np
np.arange(12, dtype=np.float16).reshape(3,4)
---
array([[ 0.,  1.,  2.,  3.],
       [ 4.,  5.,  6.,  7.],
       [ 8.,  9., 10., 11.]], dtype=float16)

张量流

import tensorflow as tf
tf.reshape(tf.range(12, dtype=tf.float16), (3,4))
---
NotFoundError                             Traceback (most recent call last)
<ipython-input-14-dbaa1413ee5c> in <module>
      1 import tensorflow as tf
----> 2 tf.reshape(tf.range(12, dtype=tf.float16), (3,4))

~/conda/envs/tensorflow/lib/python3.8/site-packages/tensorflow/python/util/dispatch.py in wrapper(*args, **kwargs)
    199     """Call target, and fall back on dispatchers if there is a TypeError."""
    200     try:
--> 201       return target(*args, **kwargs)
    202     except (TypeError, ValueError):
    203       # Note: convert_to_eager_tensor currently raises a ValueError, not a

~/conda/envs/tensorflow/lib/python3.8/site-packages/tensorflow/python/ops/math_ops.py in range(start, limit, delta, dtype, name)
   1875     delta = cast(delta, inferred_dtype)
   1876 
-> 1877     return gen_math_ops._range(start, limit, delta, name=name)
   1878 
   1879 

~/conda/envs/tensorflow/lib/python3.8/site-packages/tensorflow/python/ops/gen_math_ops.py in _range(start, limit, delta, name)
   7190       return _result
   7191     except _core._NotOkStatusException as e:
-> 7192       _ops.raise_from_not_ok_status(e, name)
   7193     except _core._FallbackException:
   7194       pass

~/conda/envs/tensorflow/lib/python3.8/site-packages/tensorflow/python/framework/ops.py in raise_from_not_ok_status(e, name)
   6860   message = e.message + (" name: " + name if name is not None else "")
   6861   # pylint: disable=protected-access
-> 6862   six.raise_from(core._status_to_exception(e.code, message), None)
   6863   # pylint: enable=protected-access
   6864 

~/.local/lib/python3.8/site-packages/six.py in raise_from(value, from_value)

NotFoundError: Could not find device for node: {{node Range}} = Range[Tidx=DT_HALF]
All kernels registered for op Range:
  device='CPU'; Tidx in [DT_INT64]
  device='CPU'; Tidx in [DT_INT32]
  device='CPU'; Tidx in [DT_DOUBLE]
  device='CPU'; Tidx in [DT_FLOAT]
 [Op:Range]

更新

首次使用 float32 创建然后转换为 float16 时可以。请告知为什么会出现错误。

import tensorflow as tf
a = tf.reshape(tf.range(12, dtype=tf.float32), (3,4))
print(f"a.dtype is {a.dtype}")

tf.cast(a, tf.float16)
---
a.dtype is <dtype: 'float32'>

<tf.Tensor: shape=(3, 4), dtype=float16, numpy=
array([[ 0.,  1.,  2.,  3.],
       [ 4.,  5.,  6.,  7.],
       [ 8.,  9., 10., 11.]], dtype=float16)>
python tensorflow keras precision half-precision-float
1个回答
9
投票

用途:

tf.keras.backend.set_floatx('float16')

您将默认一切都是

tf.float16
。例如:

import tensorflow as tf

tf.keras.backend.set_floatx('float16')

dense_layer = tf.keras.layers.Dense(1)

dense_layer.build((4,))

dense_layer.weights
[<tf.Variable 'kernel:0' shape=(4, 1) dtype=float16, numpy=
 array([[-0.4214],
        [-1.031 ],
        [ 1.041 ],
        [-0.6313]], dtype=float16)>,
 <tf.Variable 'bias:0' shape=(1,) dtype=float16, numpy=array([0.], dtype=float16)>]

但不建议这样做:

注意:不建议将其设置为 float16 进行训练,因为这可能会导致数字稳定性问题。相反,可以通过调用 tf.keras.mixed_ precision.experimental.set_policy('mixed_float16') 使用混合精度(混合使用 float16 和 float32)。有关详细信息,请参阅混合精度指南。

阅读文档

© www.soinside.com 2019 - 2024. All rights reserved.