A maior rede de estudos do Brasil

Grátis
Multilayer Perceptron XOR - Decodificador mensagem

Pré-visualização | Página 1 de 2

/*
Author: Eric Prates
Modified: 10/11/2018
Title: Multilayer Perceptron
##############################
Input example: @e*c$&7e3d96&1@6
Output: AUFSCELEGAL
##############################
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#define ENTRADAS 5
#define SAIDAS 1
#define NR_AMOSTRAS 26
#define NR_NEURON_O 12
#define EPOCAS 10000
#define TX_APRENDIZADO 1
#define MOMENTUM 0.1
#define MAX_IN 1.0
#define MAX_OUT 1000.0
#define ZERO_TEST 0
/*
 Dados para o treinamento da rede
 */
int cj_treinamento[NR_AMOSTRAS][ENTRADAS+SAIDAS] = {
 {0,0,0,0,0,65},
 {0,0,0,0,1,66},
 {0,0,0,1,0,67},
 {0,0,1,0,0,68},
 {0,1,0,0,0,69},
 {1,0,0,0,0,70},
 {1,1,0,0,0,71},
 {0,1,1,0,0,72},
 {0,0,1,1,0,73},
 {0,0,0,1,1,74},
 {0,0,1,1,1,75},
 {0,1,1,1,0,76},
 {1,1,1,0,0,77},
 {1,1,1,1,0,78},
 {0,1,1,1,1,79},
 {1,1,1,1,1,80},
 {1,0,0,0,1,81},
 {0,1,0,1,0,82},
 {1,1,0,0,1,83},
 {0,1,1,0,1,84},
 {1,0,0,1,0,85},
 {1,1,0,1,0,86},
 {1,1,0,1,1,87},
 {0,1,0,0,1,88},
 {0,0,1,0,1,89},
 {1,0,1,0,0,90}
};
/*
 Vari�veis globais
 */
double w_e_o[ENTRADAS+1][NR_NEURON_O];
double w_o_s[NR_NEURON_O+1][SAIDAS];
double saida_o[NR_NEURON_O];
double saida_s[SAIDAS];
double delta_saida[SAIDAS];
double gradiente_oculta[NR_NEURON_O];
double delta_oculta[NR_NEURON_O];
double media_erro = 0.0;
/*
 Cabe�alho das fun��es auxiliares
 */
void inicializa_sinapses();
int gera_nr_aleatorios();
void mostrar_sinapses();
double f_sigmoid(double net);
void calcular_saidas(double entradas[ENTRADAS]);
void treinar_RNA();
double calcular_erro(double desejado, double saida);
void menu();
void calcular_delta_saida(double desejado);
void calcular_delta_oculta();
void calcular_gradiente_oculta();
void ajustar_pesos_sinapticos(double entradas[ENTRADAS]);
void gravar_pesos_sinapticos();
void restaurar_pesos_sinapticos();
/*
 Fun��o principal
 */
int main()
{
 srand(time(NULL));
 while (1) {
 menu();
 }
 return 0;
}
void inicializa_sinapses()
{
 int i, j;
 // Inicializa pesos sin�pticos da entrada para a camada oculta
 for (i = 0; i < ENTRADAS+1; i++) {
 for (j =0; j < NR_NEURON_O; j++) {
 #if ZERO_TEST
 w_e_o[i][j] = 0.0;
 #else
 w_e_o[i][j] = gera_nr_aleatorios();
 #endif
 }
 }
 // Inicializa pesos sin�pticos da camada oculta para a sa�da
 for (i = 0; i < NR_NEURON_O+1; i++) {
 for (j =0; j < SAIDAS; j++) {
 #if ZERO_TEST
 w_o_s[i][j] = 0.0;
 #else
 w_o_s[i][j] = gera_nr_aleatorios();
 #endif
 }
 }
}
int gera_nr_aleatorios()
{
 int numeros[2] = {-1, 1};
 // Retorna -1 ou 1
 return (numeros[rand() % 2]);
}
void mostrar_sinapses()
{
 int i, j;
 // Inicializa pesos sin�pticos da entrada para a camada oculta
 for (i = 0; i < ENTRADAS+1; i++) {
 for (j =0; j < NR_NEURON_O; j++) {
 printf("w_e_o[%d][%d]: %f ", i, j, w_e_o[i][j]);
 }
 printf("\n");
 }
 // Inicializa pesos sin�pticos da camada oculta para a sa�da
 for (i = 0; i < NR_NEURON_O+1; i++) {
 for (j =0; j < SAIDAS; j++) {
 printf("w_o_s[%d][%d]: %f ", i, j, w_o_s[i][j]);
 }
 printf("\n");
 }
}
double f_sigmoid(double net)
{
 return 1 / (1 + exp(-net));
 // return tanh(net);
}
void calcular_saidas(double entradas[ENTRADAS])
{
 int i, j;
 // Calcular os nets da entrada para a camada oculta
 for (i = 0; i < NR_NEURON_O; i++) {
 saida_o[i] = 0.0;
 saida_o[i] += w_e_o[0][i] * 1; // Calcula saida para bias
 for (j = 1; j < ENTRADAS+1; j++) {
 saida_o[i] += w_e_o[j][i] * entradas[j-1];
 }
 // Calcular a saida de saida_o[i]
 saida_o[i] = f_sigmoid(saida_o[i]);
 }
 // Calcular os nets da camada oculta para a sa�da
 for (i = 0; i < SAIDAS; i++) {
 saida_s[i] = 0.0;
 saida_s[i] += w_o_s[0][i] * 1; // Calcula saida para bias
 for (j = 1; j < NR_NEURON_O+1; j++) {
 saida_s[i] += w_o_s[j][i] * saida_o[j-1];
 }
 saida_s[i] = f_sigmoid(saida_s[i]);
 }
}
void treinar_RNA()
{
 int i, j;
 double entradas[ENTRADAS];
 for (i = 1; i <= EPOCAS; i++) {
 for (j = 0; j < NR_AMOSTRAS; j++) {
 entradas[0] = cj_treinamento[j][0];
 entradas[1] = cj_treinamento[j][1];
 entradas[2] = cj_treinamento[j][2];
 entradas[3] = cj_treinamento[j][3];
 entradas[4] = cj_treinamento[j][4];
 // entradas[1] = cj_treinamento[j][1];
 // Feedforward
 calcular_saidas(entradas);
 // Backward (backpropagation)
 calcular_delta_saida(cj_treinamento[j][5]/MAX_OUT);
 calcular_gradiente_oculta();
 calcular_delta_oculta();
 ajustar_pesos_sinapticos(entradas);
 }
 }
 // Mostra media dos erros
 // printf("RNA TREINADA - Media dos erros: %lf\n", media_erro);
}
double calcular_erro(double desejado, double saida)
{
 return desejado - saida;
}
void menu()
{
 int opcao;
 double entradas[ENTRADAS];
 printf("Rede Neural Perceptron de Multiplas Camadas\n");
 printf("Problema do OU EXCLUSIVO - XOR\n");
 printf("*******************************************\n\n");
 printf("1.Treinar a rede\n");
 printf("2.Usar a rede\n");
 printf("3.Ver pesos sinapticos\n");
 printf("4.Sair\n");
 printf("Opcao? ");
 scanf("%d", &opcao);
 switch (opcao) {
 case 1: inicializa_sinapses();
 treinar_RNA();
 break;
 case 2:
 {
 char letra;
 // for(int i = 0; i < ENTRADAS; i++) {
 printf("Entrada :");
 scanf(" %c", &letra);
 // }
 char map[26];
 map[0] = '@';
 map[1] = '#';
 map[2] = '$';
 map[3] = '%';
 map[4] = '&';
 map[5] = '*';
 map[6] = '1';
 map[7] = '2';
 map[8] = '3';
 map[9] = '4';
 map[10] = '5';
 map[11] = '6';
 map[12] = '7';
 map[13] = '8';
 map[14] = '9';
 map[15] = '0';
 map[16] = 'a';
 map[17] = 'b';
 map[18] = 'c';
 map[19] = 'd';
 map[20] = 'e';
 map[21] = 'f';
 map[22] = 'g';
 map[23] = 'h';
 map[24] = 'i';
 map[25] = 'j';
 // printf("%d\n", letra);
 for(int i = 0; i < NR_AMOSTRAS; i++) {