File size: 4,060 Bytes
d601f7c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | // Memoria a gruppi di neuroni.
//
// Ogni neurone ha un indirizzo (id = strato * n_ff + indice) e appartiene a un gruppo di 128 neuroni
// dello stesso strato. Ogni gruppo ha 128 bit (16 byte) sul disco: un file per strato
// (strato_LL.bin), il gruppo g occupa i byte [16*g, 16*g+16) del file del suo strato.
//
// Salvare un'informazione: il cervello legge il testo, si misura quanto ogni gruppo si accende rispetto
// al normale, e i byte del testo vengono scritti nei gruppi liberi più accesi. La mappa (mappa.txt)
// registra dove sta ogni informazione e la sua "impronta" di attivazione: il navigatore.
// Ricordare: il cervello legge la domanda, il navigatore confronta i gruppi accesi con le impronte,
// va a leggere i bit dei gruppi giusti e ricompone il testo.
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <time.h>
#include "atlas.h"
#include "brain.h"
#include "sbuf.h"
#define MEM_GROUP 128 // neuroni per gruppo (2^7)
#define MEM_SLOT 16 // byte per gruppo = 128 bit
#define MEM_KEY 512 // gruppi nell'impronta di un ricordo
#define MEM_MAX_TEXT 4096
#define MEM_EMB_LAYERS 1 // strati letti dal navigatore (scelto in laboratorio: 12/12 domande giuste)
typedef struct {
int id;
char title[96];
int len; // byte del testo
uint32_t crc; // per verificare la ricostruzione
time_t t;
int n_groups; // gruppi che custodiscono i byte, in ordine
int *groups;
int n_key; // impronta: gruppi più accesi e quanto
int key_g[MEM_KEY];
float key_w[MEM_KEY];
float *emb; // impronta per il navigatore: stato interno sull'ultima parola (normalizzato)
} Memory;
typedef struct {
char dir[1024];
int n_layer, n_ff, per_layer, n_groups;
int *owner; // [n_groups] id del ricordo che occupa il gruppo, 0 = libero
Memory *mems;
int n_mems, cap_mems, next_id;
float *mu; // [n_layer] attività normale di ogni strato
float *bg_mu, *bg_sd; // [n_groups] attività normale di ogni gruppo e sua variabilità
int n_embd, emb_dim; // dimensione dello stato interno e dell'impronta
int emb_layer[MEM_EMB_LAYERS];
float *emb_mu, *emb_sd; // [emb_dim] stato interno normale
} MemoryStore;
bool mem_open(MemoryStore *m, const char *dir, int n_layer, int n_ff, int n_embd);
void mem_set_baseline(MemoryStore *m, const Atlas *a);
// Comportamento normale di ogni gruppo, misurato con la stessa formula del navigatore sui testi dell'atlante.
void mem_set_background(MemoryStore *m, Brain *b, const Atlas *a);
// Il riferimento calcolato da mem_set_background, su disco: rifarlo vuol dire rileggere tutti gli stimoli
// (minuti senza GPU). key è quella della mappa: vale finché modello e stimoli sono gli stessi.
bool mem_background_save(const MemoryStore *m, const char *path, const char *key);
bool mem_background_load(MemoryStore *m, const char *path, const char *key);
void mem_close(MemoryStore *m);
// Quanto si accende ogni gruppo (rispetto al normale) mentre il cervello legge text. vec: [n_groups].
// emb (facoltativo): impronta per il navigatore, emb_dim valori già normalizzati.
bool mem_activation(MemoryStore *m, Brain *b, const char *text, float *vec, float *emb);
int mem_add(MemoryStore *m, Brain *b, const char *title, const char *text, char *err, size_t cap); // id o -1
bool mem_delete(MemoryStore *m, int id);
// Ricompone il testo dai bit dei gruppi. Ritorna una stringa da liberare, NULL se danneggiato.
char *mem_read(MemoryStore *m, const Memory *mem);
// Navigatore: i ricordi più vicini alla domanda (score 0..1). Ritorna quanti (al massimo max).
int mem_recall(MemoryStore *m, const float *qemb, int *ids, float *scores, int max);
Memory *mem_find(MemoryStore *m, int id);
long mem_used_groups(const MemoryStore *m);
void mem_json(MemoryStore *m, SBuf *o);
|