Üdv!
Végre sikerült készítenem 1 neuron hálózatot. Bár nagyon sok (magyar is) doksi található ez ügyben az interneten, de több doksiból kellett összeollóznom a tudást, mert egyes részeket elnagyoltak, másokra pedig ráfókuszáltak..
Ezért is büszke vagyok rá!
javaban, netbeans alatt fejlesztettem. 3 rétegből és rétegenként 4 neuronból áll (be lehet állítani). Minden neuron a köv réteg 4 neuronjával van összekapcsolva.
A mostani forrásban inverter kapu funkcióját tanulta meg: 0 bemenetre 1-et, 1 bemenetre 0-t ad vissza.
A XOR osztály Run metódusában tanulja meg ezt 10000-szer. Majd utána megnézzük h mi lesz a kimenet tetszőleges (0 vagy 1 közötti) bemenetre.
A calculate() számítja ki a az adatokat, learning() pedig tanít.
Tudom 1szerű.. de még az elején vagyok. A forrás nem olyan szép mert kizárólag kisérleti jelleggel készítettem:
ui.: Örülnék ha érdeklődők csatlakoznának a projektemhez. (betű)Képfelismerő rendszer lenne a cél... illetve öntanuló amőba progi
/*
* Main.java
*
* Created on 2006. február 13., 17:12
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package xor;
import java.util.Random;
/**
*
* @author Zoli
*/
public class Main {
// Rétegenkénti neuron szám
static int NON = 4;
// rétegek száma
static int NOL = 3;
static float Sigmoid(float X){
if (X < -38) return 0;
else if (X > 38) return 1;
else return (float)(1.0 / (1.0 + (float)Math.exp(-X)));
}
/** Creates a new instance of Main */
public Main() {
}
public void Run(){
XOR Xor = new XOR();
Xor.Run();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Main m = new Main();
m.Run();
}
class XOR{
float TERVEZETT_KI = 0;
float LEARNING_RATE = (float)0.9;
//float LEARNING_RATE = (float)0.025;
Neuron oNeuron[][] = new Neuron[NOL][NON];
public void building(){
for(int i=0; i<NOL; i++)
for(int j=0; j<NON; j++)oNeuron[i][j]=new Neuron(i);
// First layer
for(int i=0; i<NON; i++){
for(int j=0; j<NON; j++)
oNeuron[0][i].nextNeuron[j] = oNeuron[1][j];
}
//
for(int l=1; l<NOL-1; l++){
for (int n=0; n<NON; n++){
for(int w=0; w < NON; w++){
oNeuron[l][n].nextNeuron[w] = oNeuron[l+1][w];
oNeuron[l][n].prevNeuron[w] = oNeuron[l-1][w];
}
}
}
// Last layer
for(int i=0; i<NON; i++){
for(int j=0; j<NON; j++)
oNeuron[NOL-1][i].prevNeuron[j] = oNeuron[NOL-2][j];
}
}
public void calculate(){
for(int l=0; l<NOL; l++){
for(int n=0; n<NON; n++){
oNeuron[l][n].calculate();
if (oNeuron[l][n].nextNeuron[0] !=null)
for(int w = 0; w<NON; w++)oNeuron[l+1][w].inValues[n] = oNeuron[l][n].result;
}
}
}
private void learning(){
// last layer's errors
for(int n=0; n<NON; n++){
oNeuron[NOL-1][n].Error = (float)((TERVEZETT_KI - oNeuron[NOL-1][n].result) * oNeuron[NOL-1][n].result * (1 - oNeuron[NOL-1][n].result));
}
// hidden layer's errors
for(int l=NOL-2; l>-1; l--){
for(int n=0; n<NON; n++){
float sum = 0;
for(int w=0; w<NON; w++){
sum = sum + oNeuron[l+1][w].Error * oNeuron[l+1][w].weights[n];
}
oNeuron[l][n].Error = (float)(oNeuron[l][n].result * (1 - oNeuron[l][n].result) * sum);
}
}
// eddig hiba, most tanulas.. sulyok modositasa
for(int l=NOL-1; l>-1; l--){
for(int n=0; n<NON; n++){
for(int w=0; w<NON; w++){
if (l<NOL-1){
oNeuron[l][n].change[w] = LEARNING_RATE * oNeuron[l][n].Error * oNeuron[l][n].inValues[w] + (float)0.9 * oNeuron[l][n].change[w];
//oNeuron[l][n].change[w] = LEARNING_RATE * oNeuron[l][n].Error * TERVEZETT_KI + (float)0.9 * oNeuron[l][n].change[w];
oNeuron[l][n].weights[w] = oNeuron[l][n].weights[w] + oNeuron[l][n].change[w];
oNeuron[l][n].t_change = LEARNING_RATE * oNeuron[l][n].Error + (float)0.9 * oNeuron[l][n].t_change;
oNeuron[l][n].threshold += oNeuron[l][n].t_change;
}else{
oNeuron[l][n].change[w] = LEARNING_RATE * oNeuron[l][n].Error * oNeuron[l][n].inValues[w] + (float)0.9 * oNeuron[l][n].change[w];
oNeuron[l][n].weights[w] = oNeuron[l][n].weights[w] + oNeuron[l][n].change[w];
oNeuron[l][n].t_change = LEARNING_RATE * oNeuron[l][n].Error + (float)0.9 * oNeuron[l][n].t_change;
oNeuron[l][n].threshold += oNeuron[l][n].t_change;
}
}
}
}
}
public void reset(){
for(int l=0; l<NOL; l++){
for(int n=0; n<NON; n++){
oNeuron[l][n].reset();
}
}
}
public void Run(){
building();
for (int i = 0; i < 10000; i++){
TERVEZETT_KI = (float)0;
for(int n=0; n<NON; n++)for(int k=0; k<NON; k++)oNeuron[0][n].inValues[k] = (float)1;
calculate();
//for (int j=0; j<NON; j++)System.out.println(j+". "+oNeuron[NOL-1][j].result);
learning();
reset();
TERVEZETT_KI = (float)1;
for(int n=0; n<NON; n++)for(int k=0; k<NON; k++)oNeuron[0][n].inValues[k] = (float)0;
calculate();
//for (int j=0; j<NON; j++)System.out.println(j+". "+oNeuron[NOL-1][j].result);
learning();
reset();
}
reset();
for(int n=0; n<NON; n++)for(int k=0; k<NON; k++)oNeuron[0][n].inValues[k] = (float)1;
calculate();
for (int j=0; j<NON; j++)System.out.println(j+". "+oNeuron[NOL-1][j].result);
}
}
final class Neuron {
int id;
public float [] inValues = new float[NON];
public float [] weights = new float[NON];
public float [] change = new float[NON];
public float result;
public float threshold = 0;
public float t_change = 0;
public Neuron [] prevNeuron = new Neuron[NON];
public Neuron [] nextNeuron = new Neuron[NON];
public float Error;
Random random = new Random();
public Neuron(int id){
this.id = id;
//for (int i=0; i<weights.length; i++)weights[i] = (float)(0.2 * (random.nextFloat() - 0.5));//-0.1 - 0.1
for (int i=0; i<weights.length; i++){
weights[i] = random.nextFloat()*2-1;//-0.1 - 0.1
threshold = random.nextFloat()*2-1;
}
}
public void calculate(){
float tmpResult = 0;
for (int i=0; i < weights.length; i++){
tmpResult += inValues[i] * weights[i];
}
result = Sigmoid(tmpResult - threshold);
//tuzel();
}
public void reset(){
for (int i=0; i<weights.length; i++){
//weights[i] = random.nextFloat()*2-1;//-0.1 - 0.1
change[i] = 0;
inValues[i] = 0;
threshold = 0;
t_change = 0;
Error = 0;
}
}
}
}