File size: 4,311 Bytes
ddcd0d7
606bb52
 
ddcd0d7
606bb52
ddcd0d7
606bb52
 
 
ddcd0d7
606bb52
 
 
 
 
ddcd0d7
 
 
 
606bb52
c41d138
606bb52
 
ddcd0d7
 
 
606bb52
ddcd0d7
606bb52
 
 
ddcd0d7
 
 
 
 
 
 
606bb52
 
ddcd0d7
606bb52
ddcd0d7
606bb52
ddcd0d7
606bb52
ddcd0d7
 
606bb52
 
ddcd0d7
 
 
 
 
 
 
 
 
 
606bb52
ddcd0d7
 
 
 
 
 
 
606bb52
ddcd0d7
 
 
 
 
 
 
 
606bb52
 
ddcd0d7
 
 
 
 
 
 
606bb52
ddcd0d7
 
606bb52
ddcd0d7
 
 
 
606bb52
 
 
 
 
ddcd0d7
 
606bb52
 
 
 
 
ddcd0d7
606bb52
 
 
 
ddcd0d7
 
606bb52
 
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# cognitive_net/network.py
import torch
import torch.nn as nn
import torch.optim as optim
import math
from typing import Dict, List, Optional
from .node import CognitiveNode

class DynamicCognitiveNet(nn.Module):
    """Self-organizing neural architecture with structural plasticity"""
    def __init__(self, input_size: int, output_size: int):
        super().__init__()
        self.input_size = input_size
        self.output_size = output_size
        
        # Neural population
        self.input_nodes = nn.ModuleList([
            CognitiveNode(i, 1) for i in range(input_size)
        ])
        self.output_nodes = nn.ModuleList([
            CognitiveNode(input_size + i, 1) for i in range(output_size)
        ])
        
        # Structural configuration
        self.connections: Dict[str, nn.Parameter] = nn.ParameterDict()
        self._init_base_connections()
        
        # Meta-learning components
        self.emotional_state = nn.Parameter(torch.tensor(0.0))
        self.optimizer = optim.AdamW(self.parameters(), lr=0.001)
        self.loss_fn = nn.MSELoss()

    def _init_base_connections(self):
        """Initialize sparse input-output connectivity"""
        for i, in_node in enumerate(self.input_nodes):
            for j, out_node in enumerate(self.output_nodes):
                conn_id = f"{in_node.id}->{out_node.id}"
                self.connections[conn_id] = nn.Parameter(
                    torch.randn(1) * 0.1
                )

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        # Input processing
        activations = {}
        for i, node in enumerate(self.input_nodes):
            activations[node.id] = node(x[i].unsqueeze(0))
        
        # Output integration
        outputs = []
        for out_node in self.output_nodes:
            integrated = []
            for in_node in self.input_nodes:
                conn_id = f"{in_node.id}->{out_node.id}"
                weight = torch.sigmoid(self.connections[conn_id])
                integrated.append(activations[in_node.id] * weight)
            
            if integrated:
                combined = sum(integrated) / math.sqrt(len(integrated))
                outputs.append(out_node(combined))
        
        return torch.cat(outputs)

    def structural_update(self, global_reward: float):
        """Evolutionary architecture modification"""
        # Connection strength adaptation
        for conn_id, weight in self.connections.items():
            if global_reward > 0:
                new_weight = weight + 0.1 * global_reward
            else:
                new_weight = weight * 0.95
            self.connections[conn_id].data = new_weight.clamp(-1, 1)
        
        # Structural neurogenesis
        if global_reward < -0.5:
            new_conn = self._generate_connection()
            if new_conn not in self.connections:
                self.connections[new_conn] = nn.Parameter(
                    torch.randn(1) * 0.1
                )

    def _generate_connection(self) -> str:
        """Create new input-output connection based on activity"""
        input_act = {n.id: np.mean(n.recent_activations) 
                    for n in self.input_nodes if n.recent_activations}
        output_act = {n.id: np.mean(n.recent_activations)
                     for n in self.output_nodes if n.recent_activations}
        
        if not input_act or not output_act:
            return ""
            
        src = min(input_act, key=input_act.get)  # type: ignore
        tgt = min(output_act, key=output_act.get)  # type: ignore
        return f"{src}->{tgt}"

    def train_step(self, x: torch.Tensor, y: torch.Tensor) -> float:
        self.optimizer.zero_grad()
        pred = self(x)
        loss = self.loss_fn(pred, y)
        
        # Structural regularization
        reg_loss = sum(p.abs().mean() for p in self.connections.values())
        total_loss = loss + 0.01 * reg_loss
        
        total_loss.backward()
        self.optimizer.step()
        
        # Emotional state adaptation
        self.emotional_state.data = torch.sigmoid(
            self.emotional_state + (0.5 - loss.item()) * 0.1
        )
        
        # Structural reorganization
        self.structural_update(0.5 - loss.item())
        
        return total_loss.item()