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 신기원 이후에 변경되지 않았습니다.