Java에서 back-propagation ANN의 간단한 구현을 작성하려고하는데 아주 이상한 출력을 얻고 있습니다. ANN은 두 개의 노드 (입력 벡터의 각 값에 하나씩), 네 개의 노드가있는 단일 숨겨진 레이어 (더 이상 사용하지 않으려 고 실험했습니다) 및 3 개의 노드가있는 출력 레이어가있는 입력 레이어가 있습니다. 3 개의 출력 노드는 "one-hot"인코딩을 사용하여 데이터의 세 가지 가능한 분류를 나타냅니다. 2 입력으로하여 2 진수로Java Back-propagation ANN 출력 값
0.020055 0.40759 2
0.020117 0.14934 3
0.020117 0.25128 3
0.020262 1.6068 1
및 정수 원하는 분류 (1-3) 인 :
ANN에 어떤 입력은 다음과 같이 포맷된다.
목록에서 가능한 모든 데이터 조합으로 ANN 훈련 후, 나는 세 개의 출력 노드
0.11237534579646044 0.15172262242962917 0.7906017313009316 2
0.13686775670201043 0.1774606939461421 0.7656339988150088 3
0.13554918638846133 0.1761024282314506 0.766924262279491 3
0.06185317503169881 0.09410559150503017 0.8516964148498476 1
의 출력으로 소수로, 다음과 같이 내가 가진 방법을 볼 수 출력의 모든 각 라인은 "높은"값 (S 자형 함수로 인해 0.95에 가깝다)을 나타내야하고 나머지는 "낮음"(0.05에 가깝다)이어야한다. 다음은
내가 최종 출력 값을 계산하기 위해 쓴 방법 :public static double [] testANN(double [] input, List<BPNode> hiddenLayer, List <BPNode> outputLayer){
double [] outInputs = new double[hiddenLayer.size()];
double [] results = new double[outputLayer.size()];
for(int i = 0; i<hiddenLayer.size(); i++){
BPNode node = hiddenLayer.get(i);
node.inputs = input.clone();
outInputs[i] = node.getOutput();
}
for(int i = 0; i<outputLayer.size(); i++){
BPNode node = outputLayer.get(i);
node.inputs = outInputs.clone();
results[i] = node.getOutput();
}
return results;
}
을 그리고 여기에 역 전파 알고리즘과 인공 신경망을 훈련하는 방법이다 :
public static void trainANN(double [] input, int desired, List<BPNode> hiddenLayer, List <BPNode> outputLayer){
double [] d = new double[outputLayer.size()];
d[0] = desired==1 ? 0.95 :0.05;
d[1] = desired==2 ? 0.95 :0.05;
d[2] = desired==3 ? 0.95 :0.05;
double [] [] weights = new double[outputLayer.size()][hiddenLayer.size()];
double [] output = testANN(input,hiddenLayer,outputLayer);
double [] del = new double[outputLayer.size()];
for(int i = 0; i<outputLayer.size(); i++){
del[i] = (d[i]-output[i])*output[i]*(1-output[i]);
for (int j = 0; j<outputLayer.get(i).weights.length; j++){
weights[i][j] = outputLayer.get(i).weights[j];
outputLayer.get(i).weights[j]+=0.2*del[i]*outputLayer.get(i).inputs[j];
}
}
for(int i = 0; i<hiddenLayer.size(); i++){
double hiddenDel = 0.0;
for(int j = 0; j<outputLayer.size(); j++){
hiddenDel+=(del[j]*weights[j][i]*hiddenLayer.get(i).getOutput()*(1-hiddenLayer.get(i).getOutput()));
}
for(int j = 0; j<hiddenLayer.get(i).weights.length; j++){
hiddenLayer.get(i).weights[j]+=0.2*hiddenDel*input[j];
}
}
}
마지막으로 ANN을 구현하는 데 사용한 Node 클래스는 다음과 같습니다.
public class BPNode {
public double [] inputs = new double[10];
public double [] weights = new double[10];
public BPNode(double [] w){
weights = w;
}
public double getOutput() {
double a = 0;
for(int j = 0; j<inputs.length; j++){
a += (inputs[j] * weights[j]);
}
return sigmoid(a,10.0);
}
private static double sigmoid(double x, double m)
{
return 1/(1 + Math.exp(-x*m));
}
}
모든 가중치가 0.1로 초기화되고 노드가 배열 목록에 배치되었습니다. 도와 주셔서 정말 감사합니다.