【问题标题】:Autoencoder using Backpropagation使用反向传播的自动编码器
【发布时间】:2018-04-25 18:47:19
【问题描述】:

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

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 个 epoch 后没有改变

【问题讨论】:

    标签: python algorithm neural-network backpropagation autoencoder


    【解决方案1】:

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

    假设我想重建值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 更改为另一个激活函数,它实际上可以重建正确的数据顺序大小。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2018-03-04
      • 1970-01-01
      • 2021-07-18
      • 2018-04-23
      • 2023-03-12
      • 2014-06-02
      • 1970-01-01
      • 1970-01-01
      • 2014-06-22
      相关资源
      最近更新 更多