단일 출력 단위 (바이너리 분류)로 MLP의 간단한 구현을 작성했습니다. 교육용으로 필요하기 때문에 기존 구현을 사용할 수 없습니다. (멀티 레이어 퍼포먼스 구현 : 가벼운 무게
작업 더미 모델을 만들고 관리 기능을 구현했지만 MLP가 수렴하지 않습니다. 실제로 출력 단위에 대한 그래디언트는 높게 유지됩니다. 신 (新) 시대에 걸쳐, 그래서 그것의 무게는 무한대에 접근
내 구현 :.
import numpy as np
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
X = np.loadtxt('synthetic.txt')
t = X[:, 2].astype(np.int)
X = X[:, 0:2]
# Sigmoid activation function for output unit
def logistic(x):
return 1/(1 + np.exp(-x))
# derivative of the tanh activation function for hidden units
def tanh_deriv(x):
return 1 - np.tanh(x)*np.tanh(x)
input_num = 2 # number of units in the input layer
hidden_num = 2 # number of units in the hidden layer
# initialize weights with random values:
weights_hidden = np.array((2 * np.random.random((input_num + 1, hidden_num + 1)) - 1) * 0.25)
weights_out = np.array((2 * np.random.random( hidden_num + 1) - 1) * 0.25)
def predict(x):
global input_num
global hidden_num
global weights_hidden
global weights_out
x = np.append(x.astype(float), 1.0) # input to the hidden layer: features + bias term
a = x.dot(weights_hidden) # activations of the hidden layer
z = np.tanh(a) # output of the hidden layer
q = logistic(z.dot(weights_out)) # input to the output (decision) layer
if q >= 0.5:
return 1
return 0
def train(X, t, learning_rate=0.2, epochs=50):
global input_num
global hidden_num
global weights_hidden
global weights_out
weights_hidden = np.array((2 * np.random.random((input_num + 1, hidden_num + 1)) - 1) * 0.25)
weights_out = np.array((2 * np.random.random( hidden_num + 1) - 1) * 0.25)
for epoch in range(epochs):
gradient_out = 0.0 # gradients for output and hidden layers
gradient_hidden = []
for i in range(X.shape[0]):
# forward propagation
x = np.array(X[i])
x = np.append(x.astype(float), 1.0) # input to the hidden layer: features + bias term
a = x.dot(weights_hidden) # activations of the hidden layer
z = np.tanh(a) # output of the hidden layer
q = z.dot(weights_out) # activations to the output (decision) layer
y = logistic(q) # output of the decision layer
# backpropagation
delta_hidden_s = [] # delta and gradient for a single training sample (hidden layer)
gradient_hidden_s = []
delta_out_s = t[i] - y # delta and gradient for a single training sample (output layer)
gradient_out_s = delta_out_s * z
for j in range(hidden_num + 1):
delta_hidden_s.append(tanh_deriv(a[j]) * (weights_out[j] * delta_out_s))
gradient_hidden_s.append(delta_hidden_s[j] * x)
gradient_out = gradient_out + gradient_out_s # accumulate gradients over training set
gradient_hidden = gradient_hidden + gradient_hidden_s
print "\n#", epoch, "Gradient out: ",gradient_out,
print "\n Weights out: ", weights_out
# Now updating weights
weights_out = weights_out - learning_rate * gradient_out
for j in range(hidden_num + 1):
weights_hidden.T[j] = weights_hidden.T[j] - learning_rate * gradient_hidden[j]
train(X, t, 0.2, 50)
그리고 시대를 통해 출력 부 그라데이션 및 무게의 진화 :
0 Gradient out: [ 11.07640724 -7.20309009 0.24776626]
Weights out: [-0.15397237 0.22232593 0.03162811]
1 Gradient out: [ 23.68791197 -19.6688382 -1.75324703]
Weights out: [-2.36925382 1.66294395 -0.01792515]
2 Gradient out: [ 79.08612305 -65.76066015 -7.70115262]
Weights out: [-7.10683621 5.59671159 0.33272426]
3 Gradient out: [ 99.59798656 -93.90973727 -21.45674943]
Weights out: [-22.92406082 18.74884362 1.87295478]
,
...
49 Gradient out: [ 107.89975864 -105.8654327 -104.69591522]
Weights out: [-1003.67912726 976.87213404 922.38862049]
나는 다른 데이터 세트, 숨겨진 단위의 다양한 수를 시도했다. 나는 가중치 대신 덧셈을 사용하여 가중치를 업데이트하려고 노력했습니다 ... 아무 것도 도움이되지 않습니다 ...
누군가가 틀렸다고 말해 줄 수 있습니까? 미리 감사드립니다.
안녕하세요, 'synthetic.txt'를 첨부 해주세요. 디버그하고 희망하는 부분을 수정 해 보겠습니다. 출력 레이어로 이동하는 바이어스 용어를 추가해야 할 필요가있는 부분을 이미 발견했습니다. 다른 가중치를 업데이트하는 것과는 다른 바이어스 업데이트 메커니즘을 변경합니다. 감사합니다 – Curious
안녕하세요, 사실은 이미 문제를 해결했습니다. 당신 말이 맞아, 나는 숨겨진 계층에서 편견을 놓쳤다. 또한, 제곱 오차 함수의 합에 대한 backpropagation을 다시 작성합니다. 관심을 가져 주셔서 감사합니다. –