深度神经网络的图像识别精度,浮点数还是双精度数?

Aid*_*aly 5 c++ precision machine-learning neural-network

用于图像识别的神经网络可能非常大。可能有数千个输入/隐藏神经元,数百万个连接会占用大量计算机资源。

虽然浮点数在 c++中通常是 32 位和64 位,但它们在速度上没有太大的性能差异,但使用浮点数可以节省一些内存。

有一个神经网络是什么使用sigmoid作为激活函数,如果我们可以选择神经网络中的哪些变量可以是float或double,哪些可以float来节省内存而不会使神经网络无法执行?

虽然训练/测试数据的输入和输出绝对可以是浮点数,因为它们不需要双精度,因为图像中的颜色只能在 0-255 的范围内,当归一化为 0.0-1.0 比例时,单位值将为 1 / 255 = 0.0039 ~

1.隐藏神经元的输出精度怎么样,让它们也浮动是否安全?

隐藏神经元的输出从前一层神经元输出的总和 * 其与当前正在计算的神经元的连接权重中获取值,然后将总和传递给激活函数(当前为 sigmoid)以获得新的输出。Sum 变量本身可能是双倍的,因为当网络很大时它可能会变成一个非常大的数字。

在此处输入图片说明

2. 连接权重怎么样,它们可以是浮点数吗?

由于 sigmoid,输入和神经元的输出在 0-1.0 的范围内,但允许权重大于此值。


由于激活函数的导数,随机梯度下降反向传播会遇到梯度消失问题,我决定不把它作为梯度变量应该是什么精度的问题,感觉浮点数根本不够精确,特别是当网络很深时.

sas*_*nin 6

\n
    \n
  1. 隐藏神经元的输出精度怎么样,让它们也浮动是否安全?
  2. \n
\n
\n\n

对于大多数神经网络应用来说,到处使用float32通常是安全的首选。GPU目前只支持float32,所以很多从业者到处坚持float32。对于许多应用程序来说,即使16 位浮点值也足够了。一些极端的例子表明,高精度网络只需每个权重 2 位即可训练(https://arxiv.org/abs/1610.00324 )。

\n\n

深度网络的复杂性通常不受计算时间的限制,而是受单个 GPU 上 RAM 数量和内存总线吞吐量的限制。即使您正在使用 CPU,使用较小的数据类型仍然有助于更有效地使用缓存。您很少受到机器数据类型精度的限制。

\n\n
\n

由于图像中的颜色只能在 0-255 范围内,

\n
\n\n

你这样做是错的。当输入数据的规模已知时,您可以强制网络学习它(除非您使用自定义权重初始化过程)。当输入数据标准化为范围 (-1, 1) 或 (0, 1) 并且权重初始化为具有相同尺度的层的平均输出时,通常会获得更好的结果。这是一种流行的初始化技术:http://andyljones.tumblr.com/post/110998971763/an-explanation-of-xavier-initialization

\n\n

如果输入范围为 [0, 255],则平均输入约为 100,权重约为 1,激活势(激活函数的参数)将约为 100\xc3\x97N,其中N 是层输入的数量,可能位于 sigmoid 的“平坦”部分。因此,要么将权重初始化为 ~ 1/(100\xc3\x97N),要么缩放数据并使用任何流行的初始化方法。否则网络将不得不花费大量的训练时间才能将权重达到这个规模。

\n\n
\n

由于激活函数的导数,随机梯度下降反向传播会遇到梯度消失问题,我决定不将其作为梯度变量的精度应该是多少的问题提出来,感觉浮点根本不够精确,特别是当网络很深。

\n
\n\n

这不是机器算术精度的问题,而是每一层输出的规模的问题。在实践中:

\n\n
    \n
  • 预处理输入数据(标准化为 (-1, 1) 范围)
  • \n
  • 如果层数超过 2 层,则不要使用 sigmoid,而应使用修正线性单位
  • \n
  • 仔细初始化权重
  • \n
  • 使用批量归一化
  • \n
\n\n

如果您不熟悉这些概念,此视频应该有助于学习这些概念。

\n