Python中基本神经网络的可视化爱好者集聚的地方!

当前位置:网站首页 > Python中基本神经网络的可视化 > Python中基本神经网络的可视化

​Python中基本神经网络的可视化

发布时间:2019-01-05 08:30:01 | 作者:三角梅树苗批发

Python中基本神经网络的可视化

建立一个神经网络很酷,但是如果你不了解网络实际在做什么,结果并不意味着什么!在本文中,我们将尝试理解一部分MNIST数据库正在寻找的神经网络。

我们将使用的资源

  • Python(3.6.6)
  • Tensorflow(Keras的后端)
  • Matplotlib
  • NumPy的
  • Jupyter笔记本(可选)

注意:这不是了解Keras或设计神经网络的指南。事实上,我们将使用的网络代码实际上并非由我编写,只是修改过。本指南假设您了解神经网络的基础知识。

可以在此处找到原始源代码,并且可以在以下GitHub存储库中找到所有代码和图像:

https://github.com/jarbus/keras-visualization

网络

Python中基本神经网络的可视化

----

这是我们将可视化的3层网络的简化示例。784个节点的输入层代表我们28x28图像中的784个像素,第一个隐藏层由512个节点组成,第二个由256个节点组成,输出层为10,如下面的代码所示。网络通过激活第三层中的单个节点输出它认为看到的任何数字,这对应于0-9之间的数字。

Python中基本神经网络的可视化

什么是MNIST?

该标准与技术改良研究所数据库是成千上万的手写数字28x28图像的数据库,及其相关的标签(0-9)。下面是一些这样的图像的例子:

Python中基本神经网络的可视化

来自MNIST数据库的样本图像

从输入层到节点的第一个隐藏层

我们将检查网络的权重,以试图了解每个层中每个节点正在寻找的图像的哪些部分。在这个例子中,我们将尝试将每个像素的效果转换为我们可视化的任何节点到灰度值,然后将所有像素的集合显示为灰度图像。首先,让我们看看我们网络中的第一个隐藏层,节点数为512.这是再次简化的图像:

Python中基本神经网络的可视化

网络中的每个连接表示左节点将其值乘以权重乘以右节点。每个连接代表不同的权重(尽管两个节点也可以具有相同的权重)。如您所见,每个输入值乘以权重并馈送到第一个隐藏层中的每个节点。换句话说,如果我们的输入图层大小为784(展平的28x28图像),则第一个隐藏层中的每个节点都有784个输入。这导致第一隐藏层的可视化相对容易 - 如果每个权重直接对应于唯一的输入像素,那么我们可以将每个权重显示为像素本身!我们可以使用以下代码实现此目的:

Python中基本神经网络的可视化

model.layers [0]检索我们网络的第一层,而.get_weights()[0]检索权重,然后将其添加到偏差中.get_weights()[1]

不幸的是,我们无法在28x28阵列中拍重量并将其称为可视化。首先,权重可以是负数,这意味着如果我们试图在灰度图像中显示它们,所有负权重将被剪裁为0,并且-5和-0.4的权重意味着非常不同的事物。另外,我们希望我们的权重在0到255之间,将显示8位图像matplotlib的值。为此,我们将使用以下代码规范化我们的值:

Python中基本神经网络的可视化

我们遍历每个节点(长度是图层中的节点数量),规范化所有权重,使最低值为0,最高值为255,然后将它们转换为整数。

然而,权重的归一化不是节点函数的完美表示。例如,权重可能都是负数,这意味着节点永远不会激活,但在归一化之后,它仍会在可视化中显示为0-255之间的各种权重。然而,这仍然表明节点正在寻找什么(或多或少),并且许多节点以这种方式或另一种方式激活,因此规范化仍然提供了一些我们不会有的非常关键的见解,特别是如果权重是非常接近的,很难区分。

在第一层图像上抛出一些matplotlib函数后,我们得到512张图像,其中一小部分可以在下面看到:

Python中基本神经网络的可视化

这一切似乎都是随机噪音,但是当这些节点中的每一个都乘以额外的重量时,我们就开始得到“特征探测器”,我们将在第二个隐藏层探索它们。所以不要认为这些图像是任何事物的代表,而是只有第二层可以有任何意义的数据。说到第二层......

从第一隐藏层到第二隐藏层

隐藏层2(或1,如果从Keras开始计算0层的数据)由256个节点组成,每个节点接收来自第1层中每个节点的数据。但是,该层不接收以形式为一个784值的单个数组,如第一层。而是每个节点接收512个输入,即第一层中节点的激活。如果是这种情况,那么我们如何将512个权重转换为我们的网络在给定的28x28图像中查找的内容的表示?

请记住,这512个输入中的每一个都对应于一组784个权重,代表网络正在寻找的某个28x28图像,如上一节所示。这意味着如果第二隐藏层中的节点接收512个输入,则每个输入表示第一隐藏层中的对应节点正在寻找的28x28图像,其中每个输入接收不同的权重。由于网络中的每个节点只是将每个输入乘以权重,我们可以通过将每个图像乘以其相应的权重来显示这些节点,并将这些加权图像相加以获得该第二个节点的广义28x28可视化!

这个过程相当于一个点积,它乘以两个矩阵乘以它们相加的分量。对于任何给定的层,Keras以一个漂亮的小数组二维数组的形式存储我们的权重。在我们的第一层中,它是784x512数组的形式,数组的每一行代表给定输入节点的所有权重。另外,这就是为什么我们必须通过添加a来转换它以进行可视化 .T到我们的权重矩阵的末尾,将其转换为512x784数组,其中每一行代表一个输出节点。我们可以采用尺寸为784x512的非转置权重矩阵,并将其点(将每个图像乘以其重量并将图像相加)与第二层权重矩阵(大小为512x256),以获得大小为784x256的新权重矩阵,我们可以转置以获得这个大小为256x784的层的最终矩阵,每行代表第二个隐藏层中的节点,每列代表节点使用的每个像素的权重。

Python中基本神经网络的可视化

我们取消转置我们先前计算的矩阵,并将其与第二层的权重点对,得到一个新的矩阵(784x512 * 512x256).T = 256x784

标准化后,我们可以执行相同的matplotlib魔术来绘制这些新图像,看起来像这样:

Python中基本神经网络的可视化

仍然不是我们正在寻找的,但我们可以开始看到网络正在寻找的图像的不同区域。然而,当节点在最后一层拼凑在一起时,真正发生了魔术。

从第二个隐藏层到输出层

我们现在已经实现了256x784的图像矩阵。使用我们用于第二层的相同过程,我们可以转换我们之前使用的图像(再次)获得784x256矩阵,然后我们可以使用我们在第三层中使用的256x10权重矩阵来实现784x10矩阵,然后,我们可以最后一次点到一个10x784矩阵,其中每一行代表我们的第三层寻找的内容。让我们看一下在500个图像上训练网络(因为当使用数千个图像时,可视化程度要低得多):

Python中基本神经网络的可视化

如您所见,我们可以(sorta)确定每个节点试图检测的数字!这不仅有助于查看网络所需的内容,还可以了解它首先如何推断其结果。例如,当网络在60,000张图像上进行训练时,会出现一个有趣的模式:

Python中基本神经网络的可视化

网络得知,对于Keras中使用的大部分MNIST数据集,图像的某些区域仅由一个或两个数字写入。例如,除了9之外,很少有数字到达图像的最右下方,而数字7和9的左下角则是左下角,如下图所示:

Python中基本神经网络的可视化

来自MNIST数据库的样本图像

上面的图像显示朝向底部的线是因为它试图“捕获”底部的任何书写,并且可以消除任何不是7或9的数字。其他数字出现类似的模式,这有助于表明网络不仅需要大量的数据来获得“更准确”的理解,而且它始终是最简单的路线,以实现最高的准确性。

不总是需要多层网络

除了使用两个隐藏层对网络进行可视化之外,我还试图了解在给定相同数据的情况下,没有隐藏层可以实现的网络的可能性。我将上面的模型调整为只有784个输入和10个输出,将像素直接映射到预期的数字。使用相同的过程可视化第一个隐藏层,网络产生了一些令人惊喜的令人惊讶的结果:

Python中基本神经网络的可视化

输出节点0-9在单层网络中可视化

如您所见,尽管设计的设计不如上面提到的多层网络,但这种可视化展示了单个节点的强大功能。该网络非常清楚地了解它认为每个数字“看起来像什么”,与多层设计相比具有(可以说)更准确的理解。这些结果表明,更多节点并不总能转化为更多的理解,并且网络的功能更少与节点数量有关,而更多关于用于训练的设计/数据。

​Python中基本神经网络的可视化文暂时没人评论 来添加一个吧

发表评论

必填

选填

选填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点

随机文章
三角梅树苗批发推荐
热门文章