vincentiusyoshuac commited on
Commit
ddcd0d7
·
verified ·
1 Parent(s): b668479

Update network.py

Browse files
Files changed (1) hide show
  1. network.py +67 -82
network.py CHANGED
@@ -1,130 +1,115 @@
 
1
  import torch
2
  import torch.nn as nn
3
- import torch.nn.functional as F
4
- from torch import optim
5
  import math
6
- from typing import Optional
7
-
8
  from .node import CognitiveNode
9
 
10
  class DynamicCognitiveNet(nn.Module):
11
- """Self-organizing cognitive network with structure learning"""
12
  def __init__(self, input_size: int, output_size: int):
13
  super().__init__()
14
  self.input_size = input_size
15
  self.output_size = output_size
16
 
17
- # Initialize core nodes
18
- self.nodes = nn.ModuleDict({
19
- f'input_{i}': CognitiveNode(i, 1) for i in range(input_size)
20
- })
21
  self.output_nodes = nn.ModuleList([
22
  CognitiveNode(input_size + i, 1) for i in range(output_size)
23
  ])
24
 
25
- # Structure learning parameters
26
- self.connection_strength = nn.ParameterDict()
27
- self.init_connections()
28
 
29
- # Emotional context
30
  self.emotional_state = nn.Parameter(torch.tensor(0.0))
31
- self.learning_rate = 0.01
32
-
33
- # Adaptive learning
34
  self.optimizer = optim.AdamW(self.parameters(), lr=0.001)
35
  self.loss_fn = nn.MSELoss()
36
-
37
- def init_connections(self):
38
- """Initialize sparse random connections"""
39
- for i in range(self.input_size):
40
- for out_node in self.output_nodes:
41
- conn_id = f'input_{i}->{out_node.id}'
42
- self.connection_strength[conn_id] = nn.Parameter(
43
  torch.randn(1) * 0.1
44
  )
45
-
46
  def forward(self, x: torch.Tensor) -> torch.Tensor:
47
- # Process inputs
48
  activations = {}
49
- for i in range(self.input_size):
50
- node = self.nodes[f'input_{i}']
51
  activations[node.id] = node(x[i].unsqueeze(0))
52
-
53
- # Propagate through network
54
  outputs = []
55
  for out_node in self.output_nodes:
56
- input_acts = []
57
- for i in range(self.input_size):
58
- conn_id = f'input_{i}->{out_node.id}'
59
- weight = self.connection_strength.get(conn_id, torch.tensor(0.0))
60
- input_acts.append(activations[i] * torch.sigmoid(weight))
61
-
62
- if input_acts:
63
- combined = sum(input_acts) / math.sqrt(len(input_acts))
64
- out_act = out_node(combined.unsqueeze(0))
65
- outputs.append(out_act)
66
-
67
  return torch.cat(outputs)
68
-
69
- def structural_update(self, reward: float):
70
- """Adapt network structure based on performance"""
71
- # Strengthen productive connections
72
- for conn_id, weight in self.connection_strength.items():
73
- if reward > 0:
74
- new_strength = weight + self.learning_rate * reward
75
  else:
76
- new_strength = weight * 0.9
77
- self.connection_strength[conn_id].data = torch.clamp(new_strength, -1, 1)
78
-
79
- # Add new connections if performance is poor
80
- if reward < -0.5 and torch.rand(1).item() < 0.3:
81
- new_conn = self._create_new_connection()
82
- if new_conn:
83
- self.connection_strength[new_conn] = nn.Parameter(
84
  torch.randn(1) * 0.1
85
  )
86
-
87
- def _create_new_connection(self) -> Optional[str]:
88
- """Create new random connection between underutilized nodes"""
89
- # Find least active nodes
90
- node_activations = {
91
- node_id: sum(node.recent_activations.values()) / len(node.recent_activations)
92
- for node_id, node in self.nodes.items()
93
- if node.recent_activations
94
- }
95
 
96
- if not node_activations:
97
- return None
98
-
99
- # Select random underutilized node pair
100
- sorted_nodes = sorted(node_activations.items(), key=lambda x: x[1])
101
- if len(sorted_nodes) < 2:
102
- return None
103
 
104
- source = sorted_nodes[0][0]
105
- target = sorted_nodes[1][0]
106
-
107
- return f"{source}->{target}"
108
-
109
  def train_step(self, x: torch.Tensor, y: torch.Tensor) -> float:
110
- """Execute a single training step"""
111
  self.optimizer.zero_grad()
112
  pred = self(x)
113
  loss = self.loss_fn(pred, y)
114
 
115
- # Add structural regularization
116
- reg_loss = sum(torch.abs(w).mean() for w in self.connection_strength.values())
117
  total_loss = loss + 0.01 * reg_loss
118
 
119
  total_loss.backward()
120
  self.optimizer.step()
121
 
122
- # Update emotional context
123
  self.emotional_state.data = torch.sigmoid(
124
  self.emotional_state + (0.5 - loss.item()) * 0.1
125
  )
126
 
127
- # Structural updates
128
- self.structural_update(reward=0.5 - loss.item())
129
 
130
  return total_loss.item()
 
1
+ # cognitive_net/network.py
2
  import torch
3
  import torch.nn as nn
4
+ import torch.optim as optim
 
5
  import math
6
+ from typing import Dict, List, Optional
 
7
  from .node import CognitiveNode
8
 
9
  class DynamicCognitiveNet(nn.Module):
10
+ """Self-organizing neural architecture with structural plasticity"""
11
  def __init__(self, input_size: int, output_size: int):
12
  super().__init__()
13
  self.input_size = input_size
14
  self.output_size = output_size
15
 
16
+ # Neural population
17
+ self.input_nodes = nn.ModuleList([
18
+ CognitiveNode(i, 1) for i in range(input_size)
19
+ ])
20
  self.output_nodes = nn.ModuleList([
21
  CognitiveNode(input_size + i, 1) for i in range(output_size)
22
  ])
23
 
24
+ # Structural configuration
25
+ self.connections: Dict[str, nn.Parameter] = nn.ParameterDict()
26
+ self._init_base_connections()
27
 
28
+ # Meta-learning components
29
  self.emotional_state = nn.Parameter(torch.tensor(0.0))
 
 
 
30
  self.optimizer = optim.AdamW(self.parameters(), lr=0.001)
31
  self.loss_fn = nn.MSELoss()
32
+
33
+ def _init_base_connections(self):
34
+ """Initialize sparse input-output connectivity"""
35
+ for i, in_node in enumerate(self.input_nodes):
36
+ for j, out_node in enumerate(self.output_nodes):
37
+ conn_id = f"{in_node.id}->{out_node.id}"
38
+ self.connections[conn_id] = nn.Parameter(
39
  torch.randn(1) * 0.1
40
  )
41
+
42
  def forward(self, x: torch.Tensor) -> torch.Tensor:
43
+ # Input processing
44
  activations = {}
45
+ for i, node in enumerate(self.input_nodes):
 
46
  activations[node.id] = node(x[i].unsqueeze(0))
47
+
48
+ # Output integration
49
  outputs = []
50
  for out_node in self.output_nodes:
51
+ integrated = []
52
+ for in_node in self.input_nodes:
53
+ conn_id = f"{in_node.id}->{out_node.id}"
54
+ weight = torch.sigmoid(self.connections[conn_id])
55
+ integrated.append(activations[in_node.id] * weight)
56
+
57
+ if integrated:
58
+ combined = sum(integrated) / math.sqrt(len(integrated))
59
+ outputs.append(out_node(combined))
60
+
 
61
  return torch.cat(outputs)
62
+
63
+ def structural_update(self, global_reward: float):
64
+ """Evolutionary architecture modification"""
65
+ # Connection strength adaptation
66
+ for conn_id, weight in self.connections.items():
67
+ if global_reward > 0:
68
+ new_weight = weight + 0.1 * global_reward
69
  else:
70
+ new_weight = weight * 0.95
71
+ self.connections[conn_id].data = new_weight.clamp(-1, 1)
72
+
73
+ # Structural neurogenesis
74
+ if global_reward < -0.5:
75
+ new_conn = self._generate_connection()
76
+ if new_conn not in self.connections:
77
+ self.connections[new_conn] = nn.Parameter(
78
  torch.randn(1) * 0.1
79
  )
80
+
81
+ def _generate_connection(self) -> str:
82
+ """Create new input-output connection based on activity"""
83
+ input_act = {n.id: np.mean(n.recent_activations)
84
+ for n in self.input_nodes if n.recent_activations}
85
+ output_act = {n.id: np.mean(n.recent_activations)
86
+ for n in self.output_nodes if n.recent_activations}
 
 
87
 
88
+ if not input_act or not output_act:
89
+ return ""
 
 
 
 
 
90
 
91
+ src = min(input_act, key=input_act.get) # type: ignore
92
+ tgt = min(output_act, key=output_act.get) # type: ignore
93
+ return f"{src}->{tgt}"
94
+
 
95
  def train_step(self, x: torch.Tensor, y: torch.Tensor) -> float:
 
96
  self.optimizer.zero_grad()
97
  pred = self(x)
98
  loss = self.loss_fn(pred, y)
99
 
100
+ # Structural regularization
101
+ reg_loss = sum(p.abs().mean() for p in self.connections.values())
102
  total_loss = loss + 0.01 * reg_loss
103
 
104
  total_loss.backward()
105
  self.optimizer.step()
106
 
107
+ # Emotional state adaptation
108
  self.emotional_state.data = torch.sigmoid(
109
  self.emotional_state + (0.5 - loss.item()) * 0.1
110
  )
111
 
112
+ # Structural reorganization
113
+ self.structural_update(0.5 - loss.item())
114
 
115
  return total_loss.item()