reinizio a metterci mano per completarlo 2
This commit is contained in:
@@ -0,0 +1,153 @@
|
|||||||
|
# AGENTS.md - Agentic Coding Guidelines
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
C-based neural network implementation from scratch for image classification on CIFAR-10 and MNIST datasets.
|
||||||
|
|
||||||
|
## Build Commands
|
||||||
|
|
||||||
|
### Compilation
|
||||||
|
```bash
|
||||||
|
# Main classifier (MNIST) - compiles the single-classifier training program
|
||||||
|
gcc -o classificatore_singolo_mnist classificatore_singolo.c -lm
|
||||||
|
|
||||||
|
# XOR test/demo - simple test to verify neural network works
|
||||||
|
gcc -o codice_ricordo codice_ricordo.c -lm
|
||||||
|
|
||||||
|
# Visualizer (requires Allegro library)
|
||||||
|
gcc -o visualizzatore visualizzatore.c -lalleg -lm
|
||||||
|
|
||||||
|
# Older multi-layer implementation
|
||||||
|
gcc -o rete_neurale rete_neurale.c -lm
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running Tests
|
||||||
|
```bash
|
||||||
|
# Run XOR validation test (quick sanity check for neural network)
|
||||||
|
./codice_ricordo
|
||||||
|
|
||||||
|
# Run full training loop with existing compiled binary
|
||||||
|
./classificatore_singolo_mnist
|
||||||
|
|
||||||
|
# Automated training with pauses (prevents overheating)
|
||||||
|
./addestratore.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running a Single Test
|
||||||
|
```bash
|
||||||
|
# Compile and run XOR test (single test case)
|
||||||
|
gcc -o codice_ricordo codice_ricordo.c -lm && ./codice_ricordo
|
||||||
|
|
||||||
|
# Compile and run classifier with specific category
|
||||||
|
gcc -o classificatore_singolo_mnist classificatore_singolo.c -lm && ./classificatore_singolo_mnist
|
||||||
|
```
|
||||||
|
|
||||||
|
## Code Style Guidelines
|
||||||
|
|
||||||
|
### Language
|
||||||
|
- Use **Italian** for comments and variable names (maintain consistency)
|
||||||
|
- Use **English** for struct/type definitions and technical terms
|
||||||
|
|
||||||
|
### Formatting
|
||||||
|
- Indent with 4 spaces (no tabs)
|
||||||
|
- Opening braces on same line: `if (cond) {`
|
||||||
|
- Always use braces for control structures, even single lines
|
||||||
|
- Line length: ~80-100 characters preferred
|
||||||
|
- One space after keywords (if, for, while, return)
|
||||||
|
- No space between function name and opening parenthesis
|
||||||
|
- Blank line between functions
|
||||||
|
|
||||||
|
### Naming Conventions
|
||||||
|
- Functions: `snake_case` (e.g., `inizializza_rete_neurale`)
|
||||||
|
- Structs: `PascalCase` (e.g., `ReteNeurale`)
|
||||||
|
- Constants: `UPPER_SNAKE_CASE` (e.g., `EPOCHE`)
|
||||||
|
- Global variables: file scope preferred
|
||||||
|
- Types: use `typedef` for structs
|
||||||
|
|
||||||
|
### Types
|
||||||
|
- Use `byte` (typedef for `unsigned char`) for values 0-255
|
||||||
|
- Use `double` for all floating-point calculations
|
||||||
|
- Prefer explicit types over implicit conversions
|
||||||
|
- Use `size_t` for sizes and indices where appropriate
|
||||||
|
|
||||||
|
### Imports
|
||||||
|
- Standard library headers first (`<stdio.h>`, `<stdlib.h>`, `<math.h>`, `<time.h>`)
|
||||||
|
- Project headers after (use `"quotes"`)
|
||||||
|
- No include guards needed for header-only library
|
||||||
|
- Group related includes together
|
||||||
|
|
||||||
|
### Memory Management
|
||||||
|
- Always check `malloc` return values
|
||||||
|
- Free memory in reverse allocation order
|
||||||
|
- Use `perror()` for error messages before exiting
|
||||||
|
- Avoid memory leaks in loops
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
- Check file operations with `if (!file)` pattern
|
||||||
|
- Return `NULL` on failure for functions returning pointers
|
||||||
|
- Exit with `EXIT_FAILURE` on unrecoverable errors
|
||||||
|
- Validate function inputs at entry points
|
||||||
|
|
||||||
|
### Key Constants (from percettroni.h)
|
||||||
|
- `LRE = 0.1` (learning rate - was 1.414, now 0.1)
|
||||||
|
- `soglia_sigmoide = 0.5` (sigmoid threshold for binary classification)
|
||||||
|
- `file_pesi = "rete_pesi.bin"` (model weights file)
|
||||||
|
|
||||||
|
### Dataset Configuration
|
||||||
|
In `percettroni.h`, uncomment the desired dataset section:
|
||||||
|
- XOR: `#include "xor_manager.h"` (for testing - currently active)
|
||||||
|
- MNIST: Uncomment mnist includes and set file paths
|
||||||
|
- CIFAR-10: Uncomment cifar-10 includes and file paths
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
No formal test framework. Use these approaches:
|
||||||
|
1. `codice_ricordo.c` - XOR validation (4 inputs, quick convergence test)
|
||||||
|
2. Visual inspection of weight outputs via `stampa_pesi_rete()`
|
||||||
|
3. Monitor epoch error rates in training output
|
||||||
|
4. Check for memory leaks with valgrind: `valgrind --leak-check=full ./codice_ricordo`
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
- `percettroni.h` - Core neural network (header-only library with implementations)
|
||||||
|
- `classificatore_singolo.c` - Single-category classifier main program
|
||||||
|
- `codice_ricordo.c` - XOR test/demo
|
||||||
|
- `xor_manager.h` - XOR dataset for testing
|
||||||
|
- `mnist/mnist_manager.h` - MNIST dataset loader
|
||||||
|
- `cifar-10/cifar10_manager.h` - CIFAR-10 dataset loader
|
||||||
|
- `rete_pesi.bin` - Saved model weights
|
||||||
|
- `addestratore.sh` - Training automation script
|
||||||
|
|
||||||
|
## Neural Network Architecture
|
||||||
|
- Activation: sigmoid function
|
||||||
|
- Training: backpropagation with gradient descent
|
||||||
|
- Configurable: layer count and perceptrons per layer
|
||||||
|
- Learning rate: controlled via `LRE` constant (default 0.1)
|
||||||
|
- Binary threshold: 0.5 for classification decisions
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
### Adding a New Dataset
|
||||||
|
1. Create manager header (e.g., `custom_manager.h`)
|
||||||
|
2. Define `N_INPUTS` constant for input size
|
||||||
|
3. Implement `get_dataset()` returning `Dataset*`
|
||||||
|
4. Update `percettroni.h` includes and file paths
|
||||||
|
|
||||||
|
### Debugging Tips
|
||||||
|
- Call `stampa_pesi_rete(rete)` to inspect weights
|
||||||
|
- Reference `codice_ricordo.c` for minimal working example
|
||||||
|
- Verify dataset loading before training loop
|
||||||
|
- Check epoch timing to monitor training progress
|
||||||
|
|
||||||
|
### File I/O
|
||||||
|
- Weights saved as binary in `rete_pesi.bin`
|
||||||
|
- Use `salvaReteNeurale()` and `caricaReteNeurale()` for persistence
|
||||||
|
- Dataset files must match expected binary format
|
||||||
|
|
||||||
|
## Performance Notes
|
||||||
|
- Training is CPU-intensive (minutes per epoch expected)
|
||||||
|
- Use `addestratore.sh` with sleep intervals to prevent overheating
|
||||||
|
- Memory allocated dynamically based on network architecture
|
||||||
|
- No GPU acceleration - pure CPU implementation
|
||||||
|
|
||||||
|
## Language Reference
|
||||||
|
Technical terms (English): activation function, gradient descent, sigmoid, neural network, backpropagation
|
||||||
|
|
||||||
|
Italian terms: pesi (weights), bias, livello (layer), percettrone (perceptron), addestramento (training), epoca (epoch), errore (error), classificazione (label/classification), previsione (prediction), istanza (instance)
|
||||||
@@ -63,7 +63,7 @@ void main()
|
|||||||
|
|
||||||
double **gradienti = elabora_gradienti(rete_neurale, gradiente_errore, sigmoidi);
|
double **gradienti = elabora_gradienti(rete_neurale, gradiente_errore, sigmoidi);
|
||||||
|
|
||||||
aggiorna_pesi(&rete_neurale, sigmoidi, gradienti, set.istanze[indice_set]);
|
aggiorna_pesi(rete_neurale, sigmoidi, gradienti, set.istanze[indice_set]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Executable
BIN
Binary file not shown.
+25
-8
@@ -1,17 +1,34 @@
|
|||||||
#include "percettroni.h"
|
#include "percettroni.h"
|
||||||
|
|
||||||
#define EPOCHE 10
|
#define EPOCHE 100000
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
ReteNeurale rete = inizializza_rete_neurale(3, 8, 2);
|
ReteNeurale rete = inizializza_rete_neurale(2, 2, 2);
|
||||||
stampa_pesi_rete(rete);
|
//stampa_pesi_rete(rete);
|
||||||
|
|
||||||
Dataset *xor;
|
Dataset xor = *crea_dataset_xor();
|
||||||
xor = crea_dataset_xor();
|
|
||||||
|
//for(int i = 0; i < xor->size; i++) {
|
||||||
|
// printf("%d\n", xor->istanze[i].classificazione);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//double **sigmoidi;
|
||||||
|
|
||||||
|
/* for(int epoca = 0; epoca < EPOCHE; epoca++) {
|
||||||
|
for(int indice_istanza = 0; indice_istanza < xor->size; indice_istanza++) {
|
||||||
|
sigmoidi = elabora_sigmoidi(rete, xor->istanze[indice_istanza]);
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
for(int epoca = 0; epoca < EPOCHE; epoca++) {
|
for(int epoca = 0; epoca < EPOCHE; epoca++) {
|
||||||
for(int indice_istanza = 0; indice_istanza < xor->size; indice_istanza++) {
|
printf("\nEPOCA %d\n", epoca);
|
||||||
elabora_sigmoidi(rete, xor->istanze[indice_istanza]);
|
if (addestra(&rete, xor))
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//0:0 -> 0
|
||||||
|
/* sigmoidi = elabora_sigmoidi(rete, xor->istanze[0]);
|
||||||
|
|
||||||
|
int previsto = previsione(sigmoidi[rete.size -1][0]);
|
||||||
|
printf("La previsione per la prima istanza: %d\n", previsto); */
|
||||||
}
|
}
|
||||||
+83
-22
@@ -5,27 +5,26 @@
|
|||||||
|
|
||||||
char *file_pesi = "rete_pesi.bin";
|
char *file_pesi = "rete_pesi.bin";
|
||||||
|
|
||||||
//#include "mnist/mnist_manager.h"
|
// #include "mnist/mnist_manager.h"
|
||||||
/* char *file_immagini = "mnist/t10k-images.idx3-ubyte";
|
/* char *file_immagini = "mnist/t10k-images.idx3-ubyte";
|
||||||
char *file_label = "mnist/t10k-labels.idx1-ubyte"; */
|
char *file_label = "mnist/t10k-labels.idx1-ubyte"; */
|
||||||
//char *file_immagini = "mnist/train-images.idx3-ubyte";
|
// char *file_immagini = "mnist/train-images.idx3-ubyte";
|
||||||
//char *file_label = "mnist/train-labels.idx1-ubyte";
|
// char *file_label = "mnist/train-labels.idx1-ubyte";
|
||||||
|
|
||||||
|
// #include "cifar-10/cifar10_manager.h";
|
||||||
//#include "cifar-10/cifar10_manager.h";
|
// char *file_immagini = "cifar-10/data_batch_1.bin";
|
||||||
//char *file_immagini = "cifar-10/data_batch_1.bin";
|
// char *file_immagini = "cifar-10/data_batch_2.bin";
|
||||||
// char *file_immagini = "cifar-10/data_batch_2.bin";
|
// char *file_immagini = "cifar-10/data_batch_3.bin";
|
||||||
// char *file_immagini = "cifar-10/data_batch_3.bin";
|
// char *file_immagini = "cifar-10/data_batch_4.bin";
|
||||||
// char *file_immagini = "cifar-10/data_batch_4.bin";
|
// char *file_immagini = "cifar-10/data_batch_5.bin";
|
||||||
// char *file_immagini = "cifar-10/data_batch_5.bin";
|
// char *file_immagini = "cifar-10/test_batch.bin";
|
||||||
//char *file_immagini = "cifar-10/test_batch.bin";
|
|
||||||
|
|
||||||
#include "xor_manager.h"
|
#include "xor_manager.h"
|
||||||
|
|
||||||
// Siccome il char è un byte che rappresenta il valore tra 0 e 255. Per evitare confusioni definisco il tipo "byte" come in Java
|
// Siccome il char è un byte che rappresenta il valore tra 0 e 255. Per evitare confusioni definisco il tipo "byte" come in Java
|
||||||
typedef unsigned char byte;
|
typedef unsigned char byte;
|
||||||
|
|
||||||
double LRE = 1.414;
|
double LRE = 0.5;
|
||||||
double soglia_sigmoide = 0.5;
|
double soglia_sigmoide = 0.5;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -61,7 +60,7 @@ double **elabora_gradienti(ReteNeurale, double, double **);
|
|||||||
void discesa_gradiente(ReteNeurale, double **, double **);
|
void discesa_gradiente(ReteNeurale, double **, double **);
|
||||||
double calcola_gradiente_disceso(ReteNeurale, int, int, double **);
|
double calcola_gradiente_disceso(ReteNeurale, int, int, double **);
|
||||||
|
|
||||||
void aggiorna_pesi(ReteNeurale*, double**, double**, Istanza);
|
void aggiorna_pesi(ReteNeurale *, double **, double **, Istanza);
|
||||||
void correggi_pesi_percettrone_double(Percettrone *, int, double **, double);
|
void correggi_pesi_percettrone_double(Percettrone *, int, double **, double);
|
||||||
void correggi_pesi_percettrone_byte(Percettrone *, Istanza, double, int);
|
void correggi_pesi_percettrone_byte(Percettrone *, Istanza, double, int);
|
||||||
|
|
||||||
@@ -146,6 +145,7 @@ ReteNeurale inizializza_rete_neurale(int numero_layers, int numero_percettroni_i
|
|||||||
################# PREVISIONI ################################
|
################# PREVISIONI ################################
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Da eseguire a mano 2
|
||||||
double **elabora_gradienti(ReteNeurale rete_neurale, double gradiente_errore, double **sigmoidi)
|
double **elabora_gradienti(ReteNeurale rete_neurale, double gradiente_errore, double **sigmoidi)
|
||||||
{
|
{
|
||||||
double **gradienti = (double **)malloc(sizeof(double *) * rete_neurale.size);
|
double **gradienti = (double **)malloc(sizeof(double *) * rete_neurale.size);
|
||||||
@@ -164,6 +164,7 @@ double **elabora_gradienti(ReteNeurale rete_neurale, double gradiente_errore, do
|
|||||||
return gradienti;
|
return gradienti;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invocata da elabora_sigmoidi()
|
||||||
double sigmoide(Percettrone p, double *valori)
|
double sigmoide(Percettrone p, double *valori)
|
||||||
{
|
{
|
||||||
double sommatoria = 0.0;
|
double sommatoria = 0.0;
|
||||||
@@ -174,32 +175,48 @@ double sigmoide(Percettrone p, double *valori)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sommatoria += p.bias;
|
sommatoria += p.bias;
|
||||||
|
|
||||||
|
//Sigmoide
|
||||||
double risultato = 1.0 / (1.0 + exp(-sommatoria));
|
double risultato = 1.0 / (1.0 + exp(-sommatoria));
|
||||||
|
//ReLU
|
||||||
|
//double risultato = sommatoria > 0 ? sommatoria : 0.0f;
|
||||||
|
|
||||||
// printf(" sommatoria %f -> %f\n",sommatoria, risultato);
|
// printf(" sommatoria %f -> %f\n",sommatoria, risultato);
|
||||||
|
|
||||||
return risultato;
|
return risultato;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invocata da elabora_gradienti()
|
||||||
double derivata_sigmoide(double valore)
|
double derivata_sigmoide(double valore)
|
||||||
{
|
{
|
||||||
return (valore * (1.0 - valore));
|
//Sigmoide
|
||||||
|
double derivata = valore * (1.0 - valore);
|
||||||
|
//ReLU
|
||||||
|
//double derivata = valore > 0 ? 1.0f : 0.0f;
|
||||||
|
|
||||||
|
return derivata;
|
||||||
}
|
}
|
||||||
|
|
||||||
int previsione(double valore)
|
int previsione(double valore)
|
||||||
{
|
{
|
||||||
|
//Sigmoide
|
||||||
if (valore >= soglia_sigmoide)
|
if (valore >= soglia_sigmoide)
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
//ReLU
|
||||||
|
//return valore > 0 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invocata da elabora_gradienti()
|
||||||
void discesa_gradiente(ReteNeurale rete, double **sigmoidi, double **gradienti)
|
void discesa_gradiente(ReteNeurale rete, double **sigmoidi, double **gradienti)
|
||||||
{
|
{
|
||||||
for (int indice_layer = rete.size - 2; indice_layer >= 0; indice_layer--)
|
for (int indice_layer = rete.size - 2; indice_layer >= 0; indice_layer--)
|
||||||
{
|
{
|
||||||
for (int indice_percettrone = 0; indice_percettrone < rete.layers[indice_layer].size; indice_percettrone++)
|
for (int indice_percettrone = 0; indice_percettrone < rete.layers[indice_layer].size; indice_percettrone++)
|
||||||
{
|
{
|
||||||
double derivata_attivazione = sigmoidi[indice_layer][indice_percettrone] * (1.0 - sigmoidi[indice_layer][indice_percettrone]);
|
double derivata_attivazione = derivata_sigmoide(sigmoidi[indice_layer][indice_percettrone]);
|
||||||
double gradiente_disceso = calcola_gradiente_disceso(rete, indice_layer + 1, indice_percettrone, gradienti);
|
double gradiente_disceso = calcola_gradiente_disceso(rete, indice_layer + 1, indice_percettrone, gradienti);
|
||||||
|
|
||||||
gradienti[indice_layer][indice_percettrone] = gradiente_disceso * derivata_attivazione;
|
gradienti[indice_layer][indice_percettrone] = gradiente_disceso * derivata_attivazione;
|
||||||
@@ -207,17 +224,19 @@ void discesa_gradiente(ReteNeurale rete, double **sigmoidi, double **gradienti)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invocata da discesa_gradienti()
|
||||||
double calcola_gradiente_disceso(ReteNeurale rete, int livello, int indice_peso, double **gradienti)
|
double calcola_gradiente_disceso(ReteNeurale rete, int livello, int indice_peso, double **gradienti)
|
||||||
{
|
{
|
||||||
double sommatoria = 0.0;
|
double sommatoria = 0.0;
|
||||||
for (int indice_percettrone = 0; indice_percettrone < rete.layers[livello].size; indice_percettrone++)
|
for (int indice_percettrone = 0; indice_percettrone < rete.layers[livello].size; indice_percettrone++)
|
||||||
{
|
{
|
||||||
sommatoria += (gradienti[livello][indice_peso] * rete.layers[livello].percettroni[indice_percettrone].pesi[indice_peso]);
|
sommatoria += (gradienti[livello][indice_percettrone] * rete.layers[livello].percettroni[indice_percettrone].pesi[indice_peso]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sommatoria;
|
return sommatoria;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Da eseguire a mano 1
|
||||||
double **elabora_sigmoidi(ReteNeurale rete, Istanza istanza)
|
double **elabora_sigmoidi(ReteNeurale rete, Istanza istanza)
|
||||||
{
|
{
|
||||||
double **sigmoidi = (double **)malloc(sizeof(double *) * rete.size);
|
double **sigmoidi = (double **)malloc(sizeof(double *) * rete.size);
|
||||||
@@ -300,13 +319,52 @@ void correggi_pesi_percettrone_byte(Percettrone *p, Istanza input, double gradie
|
|||||||
// Determino il gradiente del peso
|
// Determino il gradiente del peso
|
||||||
double gradiente_peso = gradiente_percettrone * (double)input.dati[indice_peso];
|
double gradiente_peso = gradiente_percettrone * (double)input.dati[indice_peso];
|
||||||
|
|
||||||
// Modifico il peso Qui si impalla perchè per qualche ragione arriva size elevatissimo
|
// Modifico il peso
|
||||||
p->pesi[indice_peso] += (gradiente_peso * LRE);
|
p->pesi[indice_peso] += (gradiente_peso * LRE);
|
||||||
}
|
}
|
||||||
|
|
||||||
p->bias += (gradiente_percettrone * LRE);
|
p->bias += (gradiente_percettrone * LRE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
################### ADDESTRAMENTO #########################
|
||||||
|
*/
|
||||||
|
//Elabora un'epoca. Restituisce 1 se ha dato il 100% di previsioni corrette
|
||||||
|
byte addestra(ReteNeurale *rete_neurale, Dataset set)
|
||||||
|
{
|
||||||
|
int corrette = 0;
|
||||||
|
double errore_totale = 0.0;
|
||||||
|
|
||||||
|
//Per ogni istanza del dataset
|
||||||
|
for (int indice_set = 0; indice_set < set.size; indice_set++)
|
||||||
|
{
|
||||||
|
double **sigmoidi = elabora_sigmoidi(*rete_neurale, set.istanze[indice_set]);
|
||||||
|
|
||||||
|
byte output_corretto = set.istanze[indice_set].classificazione;
|
||||||
|
int previsto = previsione(sigmoidi[rete_neurale->size - 1][0]);
|
||||||
|
printf("\tPrevisto: %d, corretto: %d\n", previsto, output_corretto);
|
||||||
|
if (previsto == output_corretto) {
|
||||||
|
corrette++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Derivata funzione di perdita
|
||||||
|
double gradiente_errore = (output_corretto - sigmoidi[rete_neurale->size - 1][0]);
|
||||||
|
errore_totale += pow(gradiente_errore, 2);
|
||||||
|
|
||||||
|
double **gradienti = elabora_gradienti(*rete_neurale, gradiente_errore, sigmoidi);
|
||||||
|
|
||||||
|
aggiorna_pesi(rete_neurale, sigmoidi, gradienti, set.istanze[indice_set]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Errore: %f, risposte corrette: %d%\n", errore_totale, (corrette * 100) / set.size);
|
||||||
|
|
||||||
|
if(corrette == set.size)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
################# IMPORT EXPORT ################################
|
################# IMPORT EXPORT ################################
|
||||||
*/
|
*/
|
||||||
@@ -399,16 +457,19 @@ ReteNeurale *caricaReteNeurale(const char *filename)
|
|||||||
return rete;
|
return rete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
################ STAMPE ############################
|
################ STAMPE ############################
|
||||||
*/
|
*/
|
||||||
void stampa_pesi_rete(ReteNeurale rete) {
|
void stampa_pesi_rete(ReteNeurale rete)
|
||||||
for(int indice_layer = 0; indice_layer < rete.size; indice_layer++) {
|
{
|
||||||
|
for (int indice_layer = 0; indice_layer < rete.size; indice_layer++)
|
||||||
|
{
|
||||||
printf("\nLivello %d", indice_layer);
|
printf("\nLivello %d", indice_layer);
|
||||||
for(int indice_percettrone = 0; indice_percettrone < rete.layers[indice_layer].size; indice_percettrone++) {
|
for (int indice_percettrone = 0; indice_percettrone < rete.layers[indice_layer].size; indice_percettrone++)
|
||||||
|
{
|
||||||
printf("\n\tPercettrone %d", indice_percettrone);
|
printf("\n\tPercettrone %d", indice_percettrone);
|
||||||
for(int indice_peso = 0; indice_peso < rete.layers[indice_layer].percettroni[indice_percettrone].size; indice_peso++) {
|
for (int indice_peso = 0; indice_peso < rete.layers[indice_layer].percettroni[indice_percettrone].size; indice_peso++)
|
||||||
|
{
|
||||||
printf("\n\t\tPeso %d: %f", indice_peso, rete.layers[indice_layer].percettroni[indice_percettrone].pesi[indice_peso]);
|
printf("\n\t\tPeso %d: %f", indice_peso, rete.layers[indice_layer].percettroni[indice_percettrone].pesi[indice_peso]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user