很久以前,我在Java中使用过神经网络,现在我试图在Python中学习使用TFLearn和Keras。
我试图构建一个自动编码器,但由于我遇到了问题,我向您展示的代码没有瓶颈特性(这应该会使问题更容易)。
在下面的代码中,我创建了网络,数据集(两个随机变量),在训练之后,它绘制出每个预测变量与其输入之间的相关性。
网络应该学习的是输出与接收相同的输入。

import matplotlib.pyplot as plt
import numpy as np
from keras.layers import Input, Dense
from keras.models import Model
from keras.models import load_model
from loaders.nslKddCup99.nslKddCup99Loader import NslKddCup99

def 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 autoencoder


dataSize = 1000
variables = 2
data = 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()

虽然有些时候结果是可以接受的,但很多时候不是,我知道神经网络有权随机初始化,因此它可能会收敛到不同的解,但我认为这太多了,我的代码可能有一些错误。
Sometimes correlation is acceptable
Others is quite lost
**
更新:
**
谢谢马辛莫伊科!
事实上,这就是问题所在,我最初的问题是因为我试图构建一个自动编码器,所以为了与标题保持一致,下面是一个自动编码器的示例(只是创建一个更复杂的数据集并更改激活函数):
import matplotlib.pyplot as plt
import numpy as np
from keras.layers import Input, Dense
from keras.models import Model
from keras.models import load_model
from loaders.nslKddCup99.nslKddCup99Loader import NslKddCup99

def 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 autoencoder


dataSize = 1000
variables = 6
data = 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组合而成,自动编码器只需要传递这两个变量的信息,并学习函数,就可以在解码阶段生成其他变量。
上面的例子显示了所有的函数是如何学习的,除了一个,除法。。。我还不知道为什么。

最佳答案

我认为您的案例相对容易解释为什么您的网络可能无法学习身份功能。让我们看看你的例子:
您的输入来自2d空间-由于均匀分布,它不位于1d0d子流形上。由此很容易看出,为了从自动编码器中获得一个标识函数,每一层都应该能够表示一个范围至少为二维的函数,因为最后一层的输出也应该位于2d流形上。
让我们通过您的网络,检查它是否满足条件需求:

inputLayer = Input(shape=(2,))
autoencoder = Dense(4, activation='relu')(inputLayer)
autoencoder = Dense(4, activation='relu')(autoencoder)
autoencoder = Dense(2, activation='relu')(autoencoder) # Possible problems here

您可能会看到瓶颈可能会导致一个问题-对于这个层,可能很难从第一点满足条件。对于该层-为了获得二维输出范围,您需要有权重,这将使所有示例不落入relu的饱和区域(在这种情况下,所有这些示例将在其中一个单元中被压扁为0-这使得范围不可能“完全”2d)。所以基本上,这种情况不会发生的概率相对较小。同时,不能忽略反向传播不会将该单元移动到该区域的概率。
更新:
在一条评论中,有人问为什么优化器不能阻止或撤消饱和。这是一个重要的relu缺点之一的例子-一旦一个例子落入relu饱和区域-这个例子不会直接参与某个给定单元的学习。它可以通过影响以前的单位来影响它-但是由于0导数-这种影响不是直接的。所以基本上不饱和的例子来自副作用,而不是优化器的直接作用。

关于python - Keras自动编码器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42514960/

10-11 18:14