Euh, non.un réseau de neurones c'est des neurones qui sont connectés entre eux par les sorties.
Un réseau de neurones artificiel est un ensemble de neurones artificiels (qui sont des unités de calcul simple) connectés entre eux par des poids. Chaque neurone a un niveau d'activité, qui correspond à la valeur de sortie y = f( produit_scalaire(poids, entrée) ), avec f une fonction mathématique (souvent non-linéaire et dérivable, mais passons).
Le principe d'un réseau, c'est d'avoir une "couche" de neurones, non-connectés entre eux (dans le cas simple), connectée par les poids à une autre couche de neurones. L'entrée d'un réseau génère de l'activité sur la première couche, l'activité générée passe par les poids pour provoquer de l'activité dans la deuxième couche, et ainsi de suite si on rajoute d'autres couches de neurones.
Ça, ok : on a 10 exemples, chaque exemple contient les deux informations d'entrée et l'information de sortie. L'ensemble des exemples correspont au comportement d'une fonction logique ET, sauf pour le cas ((0.5, 0.7), 0.0), mais on peut vouloir apprendre une fonction différente.j'ai réessayé et voilà ce que ça donne:
float dataset[10][3] = { {0.0 , 0.0 , 0.0}, {0.0 , 1.0 , 0.0}, {1.0 , 0.0 , 0.0}, {1.0 , 1.0 , 1.0}, {0.2 , 0.4 , 0.0}, {0.2 , 0.2 , 0.0}, {0.5 , 0.5 , 1.0}, {0.5 , 0.7 , 0.0}, {0.3 , 0.8 , 0.0}, {0.7 , 0.7 , 1.0}, };
Là, pas d'accord : pourquoi tes poids font 10x3 ? Un réseau qui prend deux entrées et renvoie 1 sortie n'a besoin que de deux poids.float poids[10][3];
Je ne comprends pas à quelle valeur tu initialises tes poids. Un simple "rand() % valeur maximale" suffit à mon avis, par contre, les poids peuvent être négatifs, donc ça devrait rentrer en compte dans l'initialisation (pour ne pas biaiser l'apprentissage).void init() { int i; int j; i = 0; j = 0; srand(time(NULL)); for(j = 0; j < 10;j++) for(i = 0;i < 30;i++) poids[j][i]=(float)(rand() / (RAND_MAX + (0.9 / 0.01))); }
Si ta fonction calcule sert à calculer l'activité de tes neurones (la valeur de sortie y), il n'y a pas de raison que le dataset entre en jeu. Pour calculer la sortie de ton neurone, tu fais simplement le produit scalaire entre l'entrée et les poids.int calcul(int num, int num2) { int i; int j = 0; float total=0; for(i=0;i<30;i++) { if(dataset[num][j]==1) { total+=poids[num2][j]; j++; } } return (total>0?1:0); }
Pour deux neurones et deux poids, c'est neurone_sortie = f( poids_1 * neurone_1 + poids_2 * neurone_2 ), mais c'est une bonne habitude d'écrire un code générique avec une boucle.
Ici, c'est presque bon : pourquoi faire * 10.0 à la fin ?float calcule_poids(float valeur, int valeur_desiree, int valeur_obtenue,int valeur_entree) { float result; result = (valeur + (valeur_desiree - valeur_obtenue) * valeur_entree * 10.0); return result; }
Si tu veux simplifier un peu cette fonction, tu peux ne lui faire calculer que la variation du poids, c'est-à-dire "(valeur_desiree - valeur_obtenue) * valeur_entree".
Pourquoi faire un test num==num2 dans l'appel de ta fonction ? Déjà, tu vas renvoyer un booléen qui devrait faire un warning à la compilation, et ça n'a pas vraiment de sens. Ta variable j ne sert pas ici.void apprendre(int num, int num2) { int i; int j; int result; result = calcul(num,num2); while(i < 30) { poids[num2][0] = calcule_poids((float)poids[num2][0],num==num2,result, dataset[num][0]); i++; j++; } }
Je pense que tu n'es pas loin de comprendre, mais il manque un tout petit peu.
Attention, j'ai l'impression que tu as un peu de mal avec la portée des variables. Il vaut mieux déclarer principalement des variables locales, et faire des return/passage en argument pour les informations que tu veux utiliser dans plusieurs fonctions.int main(int argc, char *argv[]) { init(); int i; int j; i = 0; j = 0; for(j = 0; j <7;j++) { for(i=0;i<7;i++) { printf("t: %i ",calcul(i,j)); } printf("\n"); } /*on fait relier tous les poids avec tous les caractères*/ for(j=0;j<7;j++) { for(i=0;i<7;i++) apprendre(i,j); } return (0); }c'est bon ? Si ce n'ai pas bon j'ai rien pigé de tout ça
Dans ton main, tu ne fais qu'apprendre, mais tu ne peux pas savoir si ça a marché sans tester ton réseau ensuite (comment il se comporte - càd que vaut sa sortie - quand on lui envoie de nouvelles entrées)