使用反向传播的自动编码器



我正试图使用这个实现反向传播算法的资源来实现自动编码器。我使用的是在那里实现的相同的前馈算法,但它给了我一个很大的错误。在自动编码器中,一种S形函数,应用于隐藏部分进行编码,再应用于输出部分进行解码。

def feedForwardPropagation(network, row, output=False):
currentInput = row
if not output:
layer = network[0]
else:
layer = network[1]
layer_output = []
for neuron in layer:
activation = neuron_activation(neuron['weights'], currentInput)
neuron['output'] = neuron_transfer(activation)
layer_output.append(neuron['output'])
currentInput = layer_output
return currentInput
def backPropagationNetworkErrorUpdate(network, expected):
for i in reversed(range(len(network))):
layer = network[i]
errors = list()
if i != len(network) - 1:
# Hidden Layers weight error compute
for j in range(len(layer)):
error = 0.0
for neuron in network[i + 1]:  # It starts with computing weight error of output neuron.
error += (neuron['weights'][j] * neuron['delta'])
errors.append(error)
else:
# Output layer error computer
for j in range(len(layer)):
neuron = layer[j]
error = expected[j] - neuron['output']
errors.append(error)
for j in range(len(layer)):
neuron = layer[j]
transfer = neuron['output'] * (1.0 - neuron['output'])
neuron['delta'] = errors[j] * transfer
def updateWeights(network, row, l_rate, momentum=0.5):
for i in range(len(network)):
inputs = row[:-1]
if i != 0:
inputs = [neuron['output'] for neuron in network[i - 1]]
for neuron in network[i]:
for j in range(len(inputs)):
neuron['velocity'][j] = momentum * neuron['velocity'][j] + l_rate * neuron['delta'] * inputs[j]
neuron['weights'][j] += neuron['velocity'][j]
neuron['velocity'][-1] = momentum * neuron['velocity'][-1] + l_rate * neuron['delta'] * inputs[j]
neuron['weights'][-1] += neuron['velocity'][-1]

def trainNetwork(network, train, l_rate, n_epoch, n_outputs, test_set):
hitrate = list()
errorRate = list()
epoch_step = list()
for epoch in range(n_epoch):
sum_error = 0
np.random.shuffle(train)
for row in train:
outputs = feedForwardPropagation(network, row)
outputs = feedForwardPropagation(network, outputs)
expected = row
sum_error += sum([(expected[i] - outputs[i]) ** 2 for i in range(len(expected))])
backPropagationNetworkErrorUpdate(network, expected)
updateWeights(network, row, l_rate)
if epoch % 10 == 0:
errorRate.append(sum_error)
epoch_step.append(epoch)
log = '>epoch=%d, lrate=%.3f, error=%.3f' % (epoch, l_rate, sum_error)
print(log, n_epoch, len(network[1][0]['weights']) - 1, l_rate)
return epoch_step, errorRate

对于自动编码,我使用一个隐藏层,n个输入和n个输出。我相信我在前馈实现方面出了问题。如有任何建议,我们将不胜感激。

编辑:我尝试在第一层之后计算权重(在前馈方法中继续注释),然后使用trainNetwork方法中注释的sigmoid函数对输出进行解码。然而,在100个时期之后,错误没有改变

问题的特征(比如错误在100个时期内几乎没有变化,并且仍然存在一个大错误)表明,问题可能是(而且可能是)由输入数据的大小顺序以及使用sigmoid作为激活函数的事实引起的。我给你举一个简单的例子:

假设我想要重构值x=100。如果我在单个神经元上用自动编码器训练它,重建的输出将由r = sigmoid(w*x)给出,其中误差是实际输入和重建之间的差,即e = x - r。请注意,由于sigmoid函数的边界在-1和1之间,因此在这种情况下可以得到的最小误差是e = 100-1 = 99。在这种情况下,无论你训练的权重w有多好,r=sigmoid(w*x)都将始终以1为界。

这意味着在这种情况下,sigmoid激活函数无法表示您的数据。要解决此问题,请执行以下操作之一:

  1. 将输入数据缩小或规格化为-1到1之间的大小,或者
  2. 将sigmoid改为另一个激活函数,它实际上可以重建数据的正确顺序大小

希望这能有所帮助。

相关内容

  • 没有找到相关文章

最新更新