This repository shows an alternative neural network structure to modern ones, inspiring from the brain and it's creativity, workings.
This documentation provides a comprehensive guide to the decentralized neural web architecture implemented in the provided code. The architecture is designed to simulate a neural network with hierarchical memory management, dynamic adaptation, and performance optimization.
The goal of this architecture is to present an alternative to modern neural models, which are often complex and resource-intensive, taking inspiration from our brains, neurons are decentralized organized in layers, allowing them to interact with themselves and change themselves overtime in more than just sates and weights, while also creating a dynamic memory system.
json-c library
for metal macos version metal api
for cuda version cuda
To compile the code, run the following command in the root directory of the project:
For metal version
clang -framework Metal -framework Foundation -I/opt/homebrew/Cellar/json-c/0.17/include -L/opt/homebrew/Cellar/json-c/0.17/lib -ljson-c -o neural_web neural_web.m
For cpu but macOS version
clang -I/opt/homebrew/Cellar/json-c/0.17/include -L/opt/homebrew/Cellar/json-c/0.17/lib -ljson-c -o neural_web neural_webCPU.c
For cpu 86/64 unix version
clang -I/opt/homebrew/Cellar/json-c/0.17/include -L/opt/homebrew/Cellar/json-c/0.17/lib -ljson-c -o neural_web neural_web64.c
For cuda version
nvcc -o neural_web neural_web.cu -I/opt/homebrew/Cellar/json-c/0.17/include -L/opt/homebrew/Cellar/json-c/0.17/lib -ljson-c
JsonC library replace with your own imports in the command if you copied it into the project or aren’t using homebrew or another version of the lib
The architecture consists of several key components:
The memory system is designed to store and manage memories with varying importance. It consists of:
typedef struct {
float vector[MEMORY_VECTOR_SIZE];
float importance;
unsigned int timestamp;
} MemoryEntry;
typedef struct MemoryCluster {
MemoryEntry *entries;
float importance_threshold;
unsigned int size;
unsigned int capacity;
} MemoryCluster;
typedef struct HierarchicalMemory {
MemoryCluster short_term;
MemoryCluster medium_term;
MemoryCluster long_term;
float consolidation_threshold;
float abstraction_threshold;
unsigned int total_capacity;
} HierarchicalMemory;
typedef struct MemorySystem {
HierarchicalMemory hierarchy;
unsigned int head;
unsigned int size;
unsigned int capacity;
MemoryEntry *entries;
} MemorySystem;
Neurons are the basic units of the neural network, and connections define how neurons are interconnected.
typedef struct {
float state;
float output;
unsigned int num_connections;
unsigned int layer_id;
} Neuron;
Dynamic parameters adapt based on the network’s performance and stability.
typedef struct {
float input_noise_scale;
float weight_noise_scale;
float base_adaptation_rate;
float current_adaptation_rate;
float learning_momentum;
float stability_threshold;
float noise_tolerance;
float recovery_rate;
float plasticity;
float homeostatic_factor;
} DynamicParameters;
Performance metrics track the performance of the network.
typedef struct {
double execution_time;
float average_output;
float error_rate;
int batch_size;
float learning_rate;
} PerformanceMetrics;
Optimization techniques are used to improve the network’s performance.
typedef struct {
int optimal_batch_size;
float optimal_learning_rate;
double best_execution_time;
float best_performance_score;
} OptimizationState;
Adaptation metrics track the network’s adaptation to changes.
typedef struct {
float input_noise_resistance;
float weight_noise_resistance;
float adaptation_speed;
float baseline_performance;
float noisy_performance;
} AdaptationMetrics;
The reflection system evaluates the quality of outputs and suggests improvements. It helps in continuously refining the network’s performance by identifying areas that need enhancement.
The self-identification system helps the neural web assess its own state and biases. This allows the AI to form an identity of sorts, enabling it to understand its capabilities and limitations better.
The knowledge filter ensures that only relevant and high-quality information is processed. This component is crucial for maintaining the integrity and efficiency of the neural web by filtering out noise and irrelevant data.
To initialize the neural network and memory system, use the following functions:
MemorySystem *memorySystem = createMemorySystem(MEMORY_BUFFER_SIZE);
Neuron neurons[MAX_NEURONS];
uint connections[MAX_NEURONS * MAX_CONNECTIONS] = {0};
float weights[MAX_NEURONS * MAX_CONNECTIONS] = {0};
float input_tensor[INPUT_SIZE] = {0};
initializeNeurons(neurons, connections, weights, input_tensor);
MemorySystem *createMemorySystem(unsigned int capacity)
: Creates a new memory system.void freeMemorySystem(MemorySystem *system)
: Frees the memory system.void addMemory(MemorySystem *system, Neuron *neurons, float *input_tensor, unsigned int timestamp)
: Adds a memory to the system.void saveMemorySystem(MemorySystem *system, const char *filename)
: Saves the memory system to a file.MemorySystem *loadMemorySystem(const char *filename)
: Loads the memory system from a file.void saveHierarchicalMemory(MemorySystem *system, const char *filename)
: Saves the hierarchical memory to a file.void loadHierarchicalMemory(MemorySystem *system, const char *filename)
: Loads the hierarchical memory from a file.void initializeNeurons(Neuron *neurons, uint *connections, float *weights, float *input_tensor)
: Initializes the neurons.void updateNeuronStates(Neuron *neurons, float *recurrent_weights)
: Updates the neuron states.void updateWeights(float *weights, Neuron *neurons, uint *connections, float learning_rate)
: Updates the weights.DynamicParameters initDynamicParameters()
: Initializes the dynamic parameters.void updateDynamicParameters(DynamicParameters *params, float performance_delta, float stability_measure, float error_rate)
: Updates the dynamic parameters.float calculatePerformanceScore(PerformanceMetrics metrics)
: Calculates the performance score.float computeAverageOutput(Neuron *neurons)
: Computes the average output.float computeErrorRate(Neuron *neurons, float *previous_outputs)
: Computes the error rate.void optimizeParameters(OptimizationState *opt_state, PerformanceMetrics *history, int history_size)
: Optimizes the parameters.void adaptNetworkDynamic(Neuron *neurons, float *weights, DynamicParameters *params, float performance_delta, float *input_tensor)
: Adapts the network with dynamic parameters.This document outlines the core algorithms and mathematical principles behind a decentralized neural network architecture. These mechanisms enable hierarchical memory management, dynamic adaptation, and optimization.
This algorithm calculates the new state of each neuron based on its current state, inputs, and neighboring influences.
new_state = (current_state * decay_factor) + (recurrent_inputs * recurrent_weight) + (neighbor_influences * neighbor_weight)
output = tanh(state * scale)
Adjusts the connections (weights) between neurons using a modified Hebbian learning rule.
delta_w = learning_rate * (pre_activation * post_activation - weight * decay_factor)
new_weight = max(-1.0, min(1.0, weight + delta_w))
Maintains memories in a hierarchical system, adjusting their importance dynamically.
importance = sum(abs(vector[i]) for i in range(vector_size)) / vector_size
new_importance = importance * decay_factor
new_importance = importance * strengthen_factor
Automatically tunes parameters based on performance and stability.
new_adaptation_rate = (momentum * adaptation_rate) + ((1 - momentum) * target_rate)
new_plasticity = plasticity * stability_factor
new_noise_tolerance = max(0.1, noise_tolerance * (1 - error_rate))
Optimizes learning rate and batch size based on network performance.
performance_score = (time_score * 0.4) + (output_score * 0.4) + (error_penalty * 0.2)
new_batch_size = (current_batch_size % max_batch_size) + 1
new_learning_rate = current_learning_rate * (rand() / RAND_MAX) * 0.5 + 0.75
Finds similar memories using cosine similarity.
similarity = (sum(vector1[i] * vector2[i] for i in range(vector_size))) / (sqrt(sum(vector1[i]**2 for i in range(vector_size))) * sqrt(sum(vector2[i]**2 for i in range(vector_size))))
Provides insights by calculating statistics like averages and variances.
average = sum(values) / len(values)
variance = sum((x - average)**2 for x in values) / len(values)
Refines the network by minimizing errors via gradient descent.
loss = sum((y[i] - y_hat[i])**2 for i in range(n)) / n
new_weight = weight - (learning_rate * loss_gradient)
Performs vector operations efficiently.
result[i] = vector1[i] + vector2[i]
result[i] = vector1[i] * vector2[i]
Creates a memory vector by combining various data sources:
memory_vector = [neuron_states, neuron_outputs, input_tensor]
Assesses stability by comparing current and previous neuron states.
stability_measure = 1 - (sum(abs(current_state[i] - previous_state[i]) for i in range(n)) / n)
Combines similar memories to reduce redundancy.
merged_vector = ((importance1 * vector1) + (importance2 * vector2)) / (importance1 + importance2)
merged_importance = max(importance1, importance2) * 1.1
This README file explains the training mechanism of the neural web implemented in the provided main()
function. The training process involves several key components, including Metal device setup, memory system management, neural network initialization, and the main simulation loop for training. Below, we delve into the design reasons behind each component.
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
id<MTLCommandQueue> commandQueue = [device newCommandQueue];
Metal is used for its high performance and low-level access to the GPU, which is crucial for the efficient computation required in neural network training. Setting up the Metal device and command queue ensures that the GPU resources are ready for compute tasks.
MemorySystem *memorySystem = loadMemorySystem("memory_system.dat");
if (memorySystem != NULL) {
loadHierarchicalMemory(memorySystem, "hierarchical_memory.dat");
// Print memory system statistics and samples
} else {
memorySystem = createMemorySystem(MEMORY_BUFFER_SIZE);
}
The memory system is designed to store and manage hierarchical memory structures, which are essential for retaining learned patterns and experiences. This hierarchical approach allows the system to prioritize and manage memories based on their importance and recency, mimicking human memory processes. Loading an existing memory system ensures continuity and prevents the loss of previously learned information, along with the working memory system allowing the model to have a dynamic realtime memory.
MetaController *metaController = initializeMetaController(network_regions);
IntrinsicMotivation *motivation = initializeMotivationSystem();
GoalSystem *goalSystem = initializeGoalSystem(10);
GlobalContextManager *contextManager = initializeGlobalContextManager(MAX_NEURONS);
The meta controller, cognitive system, and goal planning components are initialized using the provided functions. These components are responsible for orchestrating the overall behavior of the neural web. Allowing the model to have a dynamic realtime memory, understand in a way.
Neuron neurons[MAX_NEURONS];
uint connections[MAX_NEURONS * MAX_CONNECTIONS] = {0};
float weights[MAX_NEURONS * MAX_CONNECTIONS] = {0};
float input_tensor[INPUT_SIZE] = {0};
if (memorySystem->size > 0) {
// Initialize neurons from memory
} else {
initializeNeurons(neurons, connections, weights, input_tensor);
}
Initializing the neural network involves setting up neurons, connections, and weights. If the memory system contains existing data, neurons are initialized from the last memory state to leverage previously learned information. This approach ensures that the network can build upon past experiences, enhancing learning efficiency and effectiveness.
The main simulation loop is the core of the training process. It iterates over a predefined number of steps, performing various operations to train the neural network. This loop ensures that the network is continuously learning and adapting based on new inputs and feedback. Key operations include input generation, memory maintenance, forward and backward passes, memory updates, state history updates, performance metrics updates, dynamic parameter adaptation, and pattern matching.
Performance tracking and optimization are crucial for ensuring that the neural network operates efficiently. By periodically optimizing parameters such as learning rate and batch size, the system can adapt to changing conditions and improve overall performance. This dynamic optimization helps in achieving better convergence and accuracy.
updateDynamicParameters(¶ms, performance_delta, stability, performance_history[step].error_rate);
adaptNetworkDynamic(updatedNeurons, weights, ¶ms, performance_delta, input_tensor);
Dynamic parameter adaptation allows the neural network to adjust its parameters in real-time based on performance metrics and network stability. This adaptability ensures that the network can respond to varying inputs and conditions, improving its robustness and flexibility. Parameters such as adaptation rate, input noise scale, and plasticity are adjusted to optimize learning and performance.
Initialization and Setup:
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
id<MTLCommandQueue> commandQueue = [device newCommandQueue];
MemorySystem *memorySystem = loadMemorySystem("memory_system.dat");
if (memorySystem == NULL) {
memorySystem = createMemorySystem(MEMORY_BUFFER_SIZE);
}
Loading and Creating Shaders:
NSString *shaderSource = @"neuron_update.metal";
NSString *sourceCode = [NSString stringWithContentsOfFile:shaderSource encoding:NSUTF8StringEncoding error:&error];
id<MTLLibrary> library = [device newLibraryWithSource:sourceCode options:nil error:&error];
id<MTLFunction> function = [library newFunctionWithName:@"update_neurons"];
id<MTLComputePipelineState> pipelineState = [device newComputePipelineStateWithFunction:function error:&error];
Neural Network Initialization:
Neuron neurons[MAX_NEURONS];
uint connections[MAX_NEURONS * MAX_CONNECTIONS] = {0};
float weights[MAX_NEURONS * MAX_CONNECTIONS] = {0};
id<MTLBuffer> neuronBuffer = [device newBufferWithBytes:neurons length:sizeof(neurons) options:MTLResourceStorageModeShared];
id<MTLBuffer> connectionBuffer = [device newBufferWithBytes:connections length:sizeof(connections) options:MTLResourceStorageModeShared];
id<MTLBuffer> weightBuffer = [device newBufferWithBytes:weights length:sizeof(weights) options:MTLResourceStorageModeShared];
Main Simulation Loop:
for (int step = 0; step < STEPS; step++) {
TaskPrompt current_prompt;
generateTaskPrompt(¤t_prompt, step);
if (step % 10 == 0) {
decayMemorySystem(memorySystem);
mergeSimilarMemories(memorySystem);
}
}
id<MTLCommandBuffer> commandBuffer = [commandQueue commandBuffer];
id<MTLComputeCommandEncoder> forwardEncoder = [commandBuffer computeCommandEncoder];
[forwardEncoder setComputePipelineState:pipelineState];
[forwardEncoder setBuffer:neuronBuffer offset:0 atIndex:0];
[forwardEncoder setBuffer:weightBuffer offset:0 atIndex:1];
[forwardEncoder setBuffer:connectionBuffer offset:0 atIndex:2];
[forwardEncoder dispatchThreads:gridSize threadsPerThreadgroup:threadGroupSize];
[forwardEncoder endEncoding];
Performance Metrics and Optimization:
float loss = computeMSELoss(updatedNeurons, target_outputs, max_neurons);
updateWeights(weights, updatedNeurons, connections, learning_rate);
if (step % OPTIMIZATION_WINDOW == 0 && step > 0) {
optimizeParameters(&opt_state, performance_history, step + 1);
}
Cleanup and Saving State:
saveNetworkStates(stateHistory, STEPS);
saveMemorySystem(memorySystem, "memory_system.dat");
saveHierarchicalMemory(memorySystem, "hierarchical_memory.dat");
saveSystemParameters(system_params, "system_parameters.dat");
freeMemorySystem(memorySystem);
free(stateHistory);
free(system_params);
int main()
Initialization:
Neural Network Setup:
Main Simulation Loop:
Cleanup and Saving State:
Example of the training can be seen in the MacOS/neural_web.m file in int main or if you are not familiar with metal 86\64/neural_web64CPU.c
Note if you modify max_neurons in the example you have to also modify the input_size to be at max greater than the number of max_neurons by 1 or just lesser than the number of max_neurons or it will have an out of bounds error
The model uses reverse pathways and generally doesn’t only do patterns good because it also reverses its outputs and finds more meaning in it and additional pathways to achieve what it is supposed to similar to how humans do, or as how I think humans do.
You can also see an_idea_of_a_neural_web.pdf file for more information about the reasoning behind the model’s structure, mathematics, and the like.
neuron update shader and the code must be in the same directory.
To modify number of neurons change MAX_NEURONS
Only for unix type systems