Keras 自编码器

我很久以前曾用Java处理过神经网络,现在我正在尝试学习如何在Python中使用TFLearn和Keras。

我正在尝试构建一个自编码器,但由于我遇到了问题,我展示的代码没有瓶颈特征(这应该会使问题更容易解决)。

在下面的代码中,我创建了网络,数据集(两个随机变量),并在训练后绘制了每个预测变量与其输入之间的相关性图。

网络应该学会输出它接收到的相同输入。

import matplotlib.pyplot as pltimport numpy as npfrom keras.layers import Input, Densefrom keras.models import Modelfrom keras.models import load_modelfrom loaders.nslKddCup99.nslKddCup99Loader import NslKddCup99def buildMyNetwork(inputs, bottleNeck):    inputLayer = Input(shape=(inputs,))    autoencoder = Dense(inputs*2, activation='relu')(inputLayer)    autoencoder = Dense(inputs*2, activation='relu')(autoencoder)    autoencoder = Dense(bottleNeck, activation='relu')(autoencoder)    autoencoder = Dense(inputs*2, activation='relu')(autoencoder)    autoencoder = Dense(inputs*2, activation='relu')(autoencoder)    autoencoder = Dense(inputs, activation='sigmoid')(autoencoder)    autoencoder = Model(input=inputLayer, output=autoencoder)    autoencoder.compile(optimizer='adadelta', loss='mean_squared_error')    return autoencoderdataSize = 1000variables = 2data = np.zeros((dataSize,variables))data[:, 0] = np.random.uniform(0, 0.8, size=dataSize)data[:, 1] = np.random.uniform(0, 0.1, size=dataSize)trainData, testData = data[:900], data[900:]model = buildMyNetwork(variables,2)model.fit(trainData, trainData, nb_epoch=2000)predictions = model.predict(testData)for x in range(variables):    plt.scatter(testData[:, x], predictions[:, x])    plt.show()    plt.close()

尽管有时结果是可以接受的,但很多时候却不是这样,我知道神经网络有权重随机初始化,因此它可能会收敛到不同的解决方案,但我认为这太过分了,我的代码中可能存在一些错误。

有时相关性是可以接受的

其他时候则完全失效

**

更新:

**

感谢Marcin Możejko!

确实那是问题所在,我最初的问题是因为我试图构建一个自编码器,所以为了与标题保持一致,这里有一个自编码器的示例(只是制作了一个更复杂的数据集并更改了激活函数):

import matplotlib.pyplot as pltimport numpy as npfrom keras.layers import Input, Densefrom keras.models import Modelfrom keras.models import load_modelfrom loaders.nslKddCup99.nslKddCup99Loader import NslKddCup99def buildMyNetwork(inputs, bottleNeck):    inputLayer = Input(shape=(inputs,))    autoencoder = Dense(inputs*2, activation='tanh')(inputLayer)    autoencoder = Dense(inputs*2, activation='tanh')(autoencoder)    autoencoder = Dense(bottleNeck, activation='tanh')(autoencoder)    autoencoder = Dense(inputs*2, activation='tanh')(autoencoder)    autoencoder = Dense(inputs*2, activation='tanh')(autoencoder)    autoencoder = Dense(inputs, activation='tanh')(autoencoder)    autoencoder = Model(input=inputLayer, output=autoencoder)    autoencoder.compile(optimizer='adadelta', loss='mean_squared_error')    return autoencoderdataSize = 1000variables = 6data = np.zeros((dataSize,variables))data[:, 0] = np.random.uniform(0, 0.5, size=dataSize)data[:, 1] = np.random.uniform(0, 0.5, size=dataSize)data[:, 2] = data[:, 0] + data[:, 1]data[:, 3] = data[:, 0] * data[:, 1]data[:, 4] = data[:, 0] / data[:, 1]data[:, 5] = data[:, 0] ** data[:, 1]trainData, testData = data[:900], data[900:]model = buildMyNetwork(variables,2)model.fit(trainData, trainData, nb_epoch=2000)predictions = model.predict(testData)for x in range(variables):    plt.scatter(testData[:, x], predictions[:, x])    plt.show()    plt.close()

在这个例子中,我使用了Tanh激活函数,但我尝试了其他函数也同样有效。现在数据集有6个变量,但自编码器的瓶颈只有2个神经元;由于变量2到5是通过组合变量0和1形成的,自编码器只需要传递这两个变量的信息,并在解码阶段学习生成其他变量的函数。上面的例子展示了所有函数都已学习,但有一个除法函数…我还不知道为什么。


回答:

我认为你的情况相对容易解释为什么你的网络可能无法学习恒等函数。让我们来看你的例子:

  1. 你的输入来自2d空间 – 并且由于均匀分布,它并不位于1d0d子流形上。从这里可以很容易看出,为了从你的自编码器中得到恒等函数,每一层都应该能够表示一个范围至少是二维的函数,因为你的最后一层的输出也应该位于2d流形上。
  2. 让我们逐层检查你的网络是否满足所需的条件:

    inputLayer = Input(shape=(2,))autoencoder = Dense(4, activation='relu')(inputLayer)autoencoder = Dense(4, activation='relu')(autoencoder)autoencoder = Dense(2, activation='relu')(autoencoder) # 这里可能有问题

    你可能会看到瓶颈可能导致问题 – 对于这一层来说,满足第一点的条件可能很困难。为了得到二维的输出范围,你需要有权重,这些权重将使所有示例不落入relu的饱和区域(在这种情况下,所有这些样本将在一个单元中被压缩到0 – 这使得范围不可能是“完全”的2d)。所以基本上 – 这种情况不会发生的概率相对较小。此外,反向传播不会将这个单元移到这个区域的概率也不能被忽视。

更新:

在评论中有人问为什么优化器无法阻止或撤销饱和。这是一个重要的relu缺点的例子 – 一旦一个示例落入relu的饱和区域 – 这个示例就不会直接参与给定单元的学习。它可以通过影响前面的单元来影响它 – 但由于0导数 – 这种影响不是直接的。所以基本上,取消一个示例的饱和来自于副作用 – 而不是优化器的直接作用。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注