0

backpropagation 알고리즘을 구현하는 this 리소스를 사용하여 autoencoder를 구현하려고합니다. 거기에 구현 된 동일한 피드 전달 알고리즘을 사용하고 있지만 큰 오류가 발생합니다. Autoencoders에서 Sigmoid 함수는 인코딩을 위해 숨겨지고 디코딩을 위해 다시 출력에 적용됩니다.Backpropagation을 사용하는 Autoencoder

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 개의 출력을 사용합니다. 나는 feedforward 구현에 문제가 있다고 생각한다. 어떤 제안이라도 대단히 감사하겠습니다.

편집 : 첫 번째 레이어 이후에 가중치를 계산하고 (feedforward 메서드에서 주석 처리를 계속 한 다음) trainNetwork 메서드에 주석 처리 된 시그 모이 드 함수를 사용하여 출력을 디코딩하려고했습니다. 그러나 오류가 100 신기원 이후에 변경되지 않았습니다.

답변

1

문제점 (예 : 100 개 에포크 이상으로 오류가 거의 변경되지 않고 큰 오류가 있음)의 특성은 다음과 같은 원인으로 인해 발생할 수 있음을 나타냅니다. 입력 데이터 크기의 순서, 그리고 시그 모이 드를 활성화 함수로 사용한다는 사실 등이 있습니다. 간단한 예제를 드리겠습니다.

x=100 값을 다시 생성한다고 가정합니다. 단일 뉴런에 자동 코드를 사용하여이를 학습하면 재구성 된 출력은 r = sigmoid(w*x)으로 주어지며 실제 입력과 재구성 간의 차이는 즉 e = x - r입니다. 시그 모이 드 함수는 -1과 1 사이에 있기 때문에이 경우 얻을 수있는 최소 오류는 e = 100-1 = 99입니다. 이 경우에는 w의 무게를 얼마나 잘 훈련해도 r=sigmoid(w*x)은 항상 1로 묶입니다.

이것은 시그마 효과 활성화 기능이이 경우 귀하의 데이터를 나타낼 수 없다는 것을 의미합니다. 이 문제를 해결하거나하려면

  1. 저소득층는 -1과 1 사이의 크기로 입력 데이터를 정상화하거나,
  2. 변경 다른 활성화 함수에 S 자, 즉 실제로 순서의 오른쪽 크기를 재구성 할 수 귀하의 데이터 중.

희망이 도움이됩니다.

관련 문제