$$$$
画像認識
from collections import defaultdict
import matplotlib.pyplot as plt
import numpy as np
import random
from sklearn.datasets import load_digits
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import StandardScaler
np.random.seed(42)
random.seed(42)
digits = load_digits()
X_raw, y_raw = digits.data, digits.target
total_indices = np.random.choice(len(X_raw), 400, replace=False)
X_400, y_400 = X_raw[total_indices], y_raw[total_indices]
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_400)
train_idx = []
for c in range(10):
c_idxs = np.where(y_400 == c)[0]
train_idx.extend(c_idxs[:1])
test_idx = [i for i in range(400) if i not in train_idx]
X_train, y_train = X_scaled[train_idx], y_400[train_idx]
X_test, y_test = X_scaled[test_idx], y_400[test_idx]
NUM_CLASSES = 10
INPUT_DIM = 64
INIT_CELLS = 350
MAX_CELLS = 4000
MIN_CELLS = 80
THOUGHT_STEPS = 9
DIVISION_THRESHOLD = 0.5
DEATH_THRESHOLD = 0.09
epochs = 30
class VisionMemoryCell:
def __init__(self, cell_id):
self.id = cell_id
self.w_in = np.random.normal(0, 0.3, INPUT_DIM)
self.A = np.ones(NUM_CLASSES) / NUM_CLASSES
self.pos = np.random.uniform(-0.3, 0.2, 3)
self.links = {}
self.visits = 0.0
self.energy = 0.5
self.recent_activity = 0.0
self.role = random.choice(["Explorer", "Storage", "Bridge", "Default"])
if self.role == "Explorer":
self.lr = 0.35
self.a_decay = 0.70
self.div_rate = 1.2
elif self.role == "Storage":
self.lr = 0.08
self.a_decay = 0.998
self.div_rate = 0.8
elif self.role == "Bridge":
self.lr = 0.20
self.a_decay = 0.992
self.div_rate = 1.0
self.pos *= 0.5
else:
self.lr = 0.20
self.a_decay = 0.995
self.div_rate = 1.0
def cosine_similarity(w, x):
return np.dot(w, x) / (np.linalg.norm(w) * np.linalg.norm(x) + 1e-9)
def softmax(x, temp=1.0):
x = np.array(x) / temp
x = x - np.max(x)
e = np.exp(x)
return e / (np.sum(e) + 1e-12)
def update_topology_with_memory(memory_space, radius_connect=1.5, decay=0.92):
for cell in memory_space:
cell.links = {k: v * decay for k, v in cell.links.items() if v * decay > 0.04}
num_cells = len(memory_space)
for i in range(num_cells):
for j in range(i + 1, num_cells):
c1 = memory_space[i]
c2 = memory_space[j]
dist = np.linalg.norm(c1.pos - c2.pos)
if dist < radius_connect:
delta_w = (1.0 - (dist / radius_connect)) * 0.12
c1.links[c2.id] = min(1.0, c1.links.get(c2.id, 0.0) + delta_w)
c2.links[c1.id] = min(1.0, c2.links.get(c1.id, 0.0) + delta_w)
def update_cell_positions_fast(memory_space, path_history, grid_size=1.2):
dt = 0.1
num_cells = len(memory_space)
if num_cells == 0: return
forces = {c.id: np.zeros(3) for c in memory_space}
grid = defaultdict(list)
for cell in memory_space:
grid_key = tuple(np.floor(cell.pos / grid_size).astype(int))
grid[grid_key].append(cell)
for grid_key, cells_in_grid in grid.items():
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
for dz in [-1, 0, 1]:
neighbor_key = (grid_key[0]+dx, grid_key[1]+dy, grid_key[2]+dz)
if neighbor_key not in grid: continue
for c1 in cells_in_grid:
for c2 in grid[neighbor_key]:
if c1.id >= c2.id: continue
direction = c2.pos - c1.pos
distance = np.linalg.norm(direction) + 1e-5
unit_dir = direction / distance
repulsion = 0.03 / (distance ** 2)
sim_A = cosine_similarity(c1.A, c2.A)
bridge_factor = 1.3 if (c1.role == "Bridge" or c2.role == "Bridge") else 1.0
if sim_A > 0.6:
attraction = 0.08 * (sim_A - 0.6) * distance * bridge_factor
force_mag = -repulsion + attraction
else:
force_mag = -(repulsion + 0.05 * (0.6 - sim_A))
forces[c1.id] += unit_dir * force_mag
forces[c2.id] -= unit_dir * force_mag
for path in path_history:
for i in range(len(path) - 1):
u, v = path[i], path[i+1]
if u not in forces or v not in forces: continue
c_u = next((c for c in memory_space if c.id == u), None)
c_v = next((c for c in memory_space if c.id == v), None)
if not c_u or not c_v: continue
dir_uv = c_v.pos - c_u.pos
dist_uv = np.linalg.norm(dir_uv) + 1e-5
forces[u] += (dir_uv / dist_uv) * 0.05 * dist_uv
forces[v] -= (dir_uv / dist_uv) * 0.05 * dist_uv
for cell in memory_space:
cell.pos += forces[cell.id] * dt
cell.pos = np.clip(cell.pos, -4.0, 4.0)
def live_vision_cycle(memory_space, x_64d=None, target_class=None,
sensory_drive=1.0, intrinsic_drive=0.0, learning_gate=1.0):
if len(memory_space) == 0: return np.zeros(NUM_CLASSES), np.zeros(INPUT_DIM), []
id_to_cell = {c.id: c for c in memory_space}
start_probabilities = np.zeros(len(memory_space))
if x_64d is not None and sensory_drive > 0.0:
sims = np.array([cosine_similarity(cell.w_in, x_64d) for cell in memory_space])
start_probabilities += softmax(sims, temp=0.1) * sensory_drive
if intrinsic_drive > 0.0:
activity_weights = np.array([cell.energy * (cell.recent_activity + 0.05) for cell in memory_space])
start_probabilities += (activity_weights / (np.sum(activity_weights) + 1e-12)) * intrinsic_drive
if np.sum(start_probabilities) == 0:
start_probabilities = np.ones(len(memory_space)) / len(memory_space)
start_probabilities /= np.sum(start_probabilities)
current_cell_id = np.random.choice(list(id_to_cell.keys()), p=start_probabilities)
path = [current_cell_id]
collected_signals = [id_to_cell[current_cell_id].A.copy()]
imagined_pixels = [id_to_cell[current_cell_id].w_in.copy()]
for step in range(THOUGHT_STEPS - 1):
current_cell = id_to_cell[current_cell_id]
current_cell.recent_activity += sensory_drive * 1.0
all_ids = list(id_to_cell.keys())
if current_cell.role == "Explorer" and random.random() < 0.25:
current_cell_id = random.choice(all_ids)
path.append(current_cell_id)
collected_signals.append(id_to_cell[current_cell_id].A.copy())
imagined_pixels.append(id_to_cell[current_cell_id].w_in.copy())
continue
candidates = set(np.random.choice(all_ids, min(20, len(all_ids)), replace=False))
candidates.update(current_cell.links.keys())
scores = []
c_ids = []
for cid in candidates:
if cid in path or cid not in id_to_cell: continue
cell = id_to_cell[cid]
score = current_cell.links.get(cid, 0.0) * 3.0
if x_64d is not None:
score += 2.0 * cosine_similarity(cell.w_in, x_64d) * sensory_drive
score += 0.8 * cosine_similarity(current_cell.A, cell.A)
if cell.role == "Bridge":
score *= 2.5
scores.append(score)
c_ids.append(cid)
if not scores: break
probs = softmax(scores, temp=0.3)
current_cell_id = np.random.choice(c_ids, p=probs)
path.append(current_cell_id)
collected_signals.append(id_to_cell[current_cell_id].A.copy())
imagined_pixels.append(id_to_cell[current_cell_id].w_in.copy())
final_perception = np.mean(np.stack(collected_signals), axis=0) if collected_signals else np.zeros(NUM_CLASSES)
final_image = np.mean(np.stack(imagined_pixels), axis=0) if imagined_pixels else np.zeros(INPUT_DIM)
sensory_factor = sensory_drive * learning_gate
inferred_class = np.argmax(final_perception)
target = target_class if target_class is not None else inferred_class
target_vec = np.zeros(NUM_CLASSES)
target_vec[target] = 1.0
base_reward = min(1.0 / (np.linalg.norm(target_vec - final_perception) + 0.15), 2.5) * 1.5
novelty_reward = 0.0
for cid in path:
if cid in id_to_cell and id_to_cell[cid].visits < 4.0:
novelty_reward += 0.10
info_gain = 0.0
if len(collected_signals) > 1:
first_error = np.linalg.norm(target_vec - collected_signals[0])
final_error = np.linalg.norm(target_vec - final_perception)
info_gain = max(0.0, first_error - final_error) * 2.0
reward = base_reward + novelty_reward + info_gain
for cid in path:
if cid in id_to_cell:
for neighbor_id in id_to_cell[cid].links.keys():
if neighbor_id not in path and neighbor_id in id_to_cell:
id_to_cell[neighbor_id].energy *= 0.96
if x_64d is not None and sensory_factor > 0.0:
unique_visited_ids = set(path)
for cid in unique_visited_ids:
if cid not in id_to_cell: continue
cell = id_to_cell[cid]
if random.random() < 0.10:
continue
if cell.role == "Explorer":
noise = np.random.normal(0, 0.12)
dynamic_lr = max(0.05, cell.lr + noise)
else:
noise = np.random.normal(0, 0.05)
dynamic_lr = max(0.01, cell.lr + noise)
cell.visits += sensory_factor
cell.energy = min(1.0, cell.energy + reward * 0.12 * sensory_factor)
cell.w_in += (dynamic_lr * 0.5 * sensory_factor) * (x_64d - cell.w_in)
cell.A += (dynamic_lr * sensory_factor) * target_vec
cell.A *= cell.a_decay
cell.A /= (np.sum(cell.A) + 1e-12)
return final_perception, final_image, path
def evolve_and_prune_space(memory_space):
for cell in memory_space:
cell.energy *= 0.90
cell.recent_activity *= 0.50
if cell.energy < 0.01: cell.energy = 0.01
new_cells = []
current_max_id = max([c.id for c in memory_space]) if memory_space else 0
for cell in memory_space:
if len(memory_space) + len(new_cells) >= MAX_CELLS: break
if cell.energy > (DIVISION_THRESHOLD * (2.0 - cell.div_rate)) and cell.visits > 10:
child = VisionMemoryCell(current_max_id + len(new_cells) + 1)
child.w_in = np.clip(cell.w_in + np.random.normal(0, 0.05, INPUT_DIM), -3.0, 3.0)
child.A = cell.A.copy()
child.pos = cell.pos + np.random.normal(0, 0.1, 3)
child.role = cell.role
child.lr = cell.lr
child.a_decay = cell.a_decay
child.div_rate = cell.div_rate
cell.energy *= 0.3
cell.visits *= 0.5
child.energy = 0.2
new_cells.append(child)
memory_space.extend(new_cells)
survived_space = []
id_map = {}
for cell in memory_space:
if len(survived_space) > MIN_CELLS:
if cell.energy < DEATH_THRESHOLD and cell.visits < 1.0:
continue
id_map[cell.id] = len(survived_space)
cell.id = id_map[cell.id]
survived_space.append(cell)
for cell in survived_space:
cell.links = {id_map[old_id]: w for old_id, w in cell.links.items() if old_id in id_map}
return survived_space
class EnsembleVisionEcosystem:
def __init__(self, n_estimators=3, total_cells=2500):
self.n_estimators = n_estimators
self.models = []
for _ in range(n_estimators):
space = [VisionMemoryCell(i) for i in range(total_cells)]
update_topology_with_memory(space)
self.models.append({'space': space})
def train_cycle(self, X, y, phase="day"):
for model in self.models:
indices = np.random.choice(len(X), len(X), replace=True)
path_history = []
for idx in indices:
s_drive = 1.0 if phase == "day" else 0.3
i_drive = 0.0 if phase == "day" else 0.7
_, _, path = live_vision_cycle(model['space'], x_64d=X[idx], target_class=y[idx],
sensory_drive=s_drive, intrinsic_drive=i_drive)
if path: path_history.append(path)
update_cell_positions_fast(model['space'], path_history)
update_topology_with_memory(model['space'])
def sleep_cycle(self, steps=30):
for model in self.models:
path_history = []
for _ in range(steps):
_, _, path = live_vision_cycle(model['space'], x_64d=None, target_class=None,
sensory_drive=0.0, intrinsic_drive=1.0)
if path: path_history.append(path)
update_cell_positions_fast(model['space'], path_history)
update_topology_with_memory(model['space'])
def evolve(self):
for model in self.models:
model['space'] = evolve_and_prune_space(model['space'])
update_topology_with_memory(model['space'])
def predict(self, X):
y_pred = []
for idx in range(len(X)):
ensemble_perceptions = []
ensemble_confidences = []
for model in self.models:
perception, _, _ = live_vision_cycle(
model['space'], x_64d=X[idx],
sensory_drive=1.0, intrinsic_drive=0.0, learning_gate=0.0
)
confidence = np.max(perception)
ensemble_perceptions.append(perception)
ensemble_confidences.append(confidence)
weighted_perceptions = np.zeros(NUM_CLASSES)
total_conf = sum(ensemble_confidences) + 1e-12
for p, c in zip(ensemble_perceptions, ensemble_confidences):
weighted_perceptions += p * (c / total_conf)
y_pred.append(np.argmax(weighted_perceptions))
return y_pred
print("=== 🌐 構造記憶&細胞社会性を持つ自己組織化認知生態系 起動 ===")
ecosystem = EnsembleVisionEcosystem(n_estimators=3, total_cells=INIT_CELLS)
for cycle in range(epochs):
ecosystem.train_cycle(X_train, y_train, phase="day")
ecosystem.train_cycle(X_train, y_train, phase="evening")
ecosystem.sleep_cycle(steps=30)
ecosystem.evolve()
y_pred = ecosystem.predict(X_test)
acc = accuracy_score(y_test, y_pred)
avg_cells = int(np.mean([len(m['space']) for m in ecosystem.models]))
roles_count = defaultdict(int)
for c in ecosystem.models[0]['space']: roles_count[c.role] += 1
roles_str = ", ".join([f"{k}:{v}" for k, v in roles_count.items()])
print(f"Cycle {cycle+1:02d}/{epochs} | 総細胞数: {avg_cells:>3} | 正解率: {acc:.4f} | 社会組成: [{roles_str}]")
print("\n[Visualizing Evolved Neural Social Topology...]")
fig = plt.figure(figsize=(9, 7))
ax = fig.add_subplot(111, projection='3d')
ax.set_title("Evolved Concept Space: Grid-optimized & Engram-linked")
first_space = ecosystem.models[0]['space']
role_markers = {"Explorer": "o", "Storage": "s", "Bridge": "^", "Default": "D"}
role_colors = {"Explorer": "cyan", "Storage": "orange", "Bridge": "magenta", "Default": "gray"}
for role in ["Explorer", "Storage", "Bridge", "Default"]:
r_cells = [c for c in first_space if c.role == role]
if not r_cells: continue
ax.scatter([c.pos[0] for c in r_cells],
[c.pos[1] for c in r_cells],
[c.pos[2] for c in r_cells],
c=role_colors[role], marker=role_markers[role], s=50, label=role, edgecolors='black', alpha=0.8)
ax.legend()
plt.show()
from collections import defaultdict
import matplotlib.pyplot as plt
import numpy as np
import random
from sklearn.datasets import load_digits
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import StandardScaler
np.random.seed(42)
random.seed(42)
digits = load_digits()
X_raw, y_raw = digits.data, digits.target
total_indices = np.random.choice(len(X_raw), 400, replace=False)
X_400, y_400 = X_raw[total_indices], y_raw[total_indices]
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_400)
train_idx = []
for c in range(10):
c_idxs = np.where(y_400 == c)[0]
train_idx.extend(c_idxs[:1])
test_idx = [i for i in range(400) if i not in train_idx]
X_train, y_train = X_scaled[train_idx], y_400[train_idx]
X_test, y_test = X_scaled[test_idx], y_400[test_idx]
NUM_CLASSES = 10
INPUT_DIM = 64
INIT_CELLS = 350
MAX_CELLS = 4000
MIN_CELLS = 80
THOUGHT_STEPS = 9
DIVISION_THRESHOLD = 0.5
DEATH_THRESHOLD = 0.09
epochs = 30
class VisionMemoryCell:
def __init__(self, cell_id):
self.id = cell_id
self.w_in = np.random.normal(0, 0.3, INPUT_DIM)
self.A = np.ones(NUM_CLASSES) / NUM_CLASSES
self.pos = np.random.uniform(-0.3, 0.2, 3)
self.links = {}
self.visits = 0.0
self.energy = 0.5
self.recent_activity = 0.0
self.role = random.choice(["Explorer", "Storage", "Bridge", "Default"])
if self.role == "Explorer":
self.lr = 0.35
self.a_decay = 0.70
self.div_rate = 1.2
elif self.role == "Storage":
self.lr = 0.08
self.a_decay = 0.998
self.div_rate = 0.8
elif self.role == "Bridge":
self.lr = 0.20
self.a_decay = 0.992
self.div_rate = 1.0
self.pos *= 0.5
else:
self.lr = 0.20
self.a_decay = 0.995
self.div_rate = 1.0
def cosine_similarity(w, x):
return np.dot(w, x) / (np.linalg.norm(w) * np.linalg.norm(x) + 1e-9)
def softmax(x, temp=1.0):
x = np.array(x) / temp
x = x - np.max(x)
e = np.exp(x)
return e / (np.sum(e) + 1e-12)
def update_topology_with_memory(memory_space, radius_connect=1.5, decay=0.92):
for cell in memory_space:
cell.links = {k: v * decay for k, v in cell.links.items() if v * decay > 0.04}
num_cells = len(memory_space)
for i in range(num_cells):
for j in range(i + 1, num_cells):
c1 = memory_space[i]
c2 = memory_space[j]
dist = np.linalg.norm(c1.pos - c2.pos)
if dist < radius_connect:
delta_w = (1.0 - (dist / radius_connect)) * 0.12
c1.links[c2.id] = min(1.0, c1.links.get(c2.id, 0.0) + delta_w)
c2.links[c1.id] = min(1.0, c2.links.get(c1.id, 0.0) + delta_w)
def update_cell_positions_fast(memory_space, path_history, grid_size=1.2):
dt = 0.1
num_cells = len(memory_space)
if num_cells == 0: return
forces = {c.id: np.zeros(3) for c in memory_space}
grid = defaultdict(list)
for cell in memory_space:
grid_key = tuple(np.floor(cell.pos / grid_size).astype(int))
grid[grid_key].append(cell)
for grid_key, cells_in_grid in grid.items():
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
for dz in [-1, 0, 1]:
neighbor_key = (grid_key[0]+dx, grid_key[1]+dy, grid_key[2]+dz)
if neighbor_key not in grid: continue
for c1 in cells_in_grid:
for c2 in grid[neighbor_key]:
if c1.id >= c2.id: continue
direction = c2.pos - c1.pos
distance = np.linalg.norm(direction) + 1e-5
unit_dir = direction / distance
repulsion = 0.03 / (distance ** 2)
sim_A = cosine_similarity(c1.A, c2.A)
bridge_factor = 1.3 if (c1.role == "Bridge" or c2.role == "Bridge") else 1.0
if sim_A > 0.6:
attraction = 0.08 * (sim_A - 0.6) * distance * bridge_factor
force_mag = -repulsion + attraction
else:
force_mag = -(repulsion + 0.05 * (0.6 - sim_A))
forces[c1.id] += unit_dir * force_mag
forces[c2.id] -= unit_dir * force_mag
for path in path_history:
for i in range(len(path) - 1):
u, v = path[i], path[i+1]
if u not in forces or v not in forces: continue
c_u = next((c for c in memory_space if c.id == u), None)
c_v = next((c for c in memory_space if c.id == v), None)
if not c_u or not c_v: continue
dir_uv = c_v.pos - c_u.pos
dist_uv = np.linalg.norm(dir_uv) + 1e-5
forces[u] += (dir_uv / dist_uv) * 0.05 * dist_uv
forces[v] -= (dir_uv / dist_uv) * 0.05 * dist_uv
for cell in memory_space:
cell.pos += forces[cell.id] * dt
cell.pos = np.clip(cell.pos, -4.0, 4.0)
def live_vision_cycle(memory_space, x_64d=None, target_class=None,
sensory_drive=1.0, intrinsic_drive=0.0, learning_gate=1.0):
if len(memory_space) == 0: return np.zeros(NUM_CLASSES), np.zeros(INPUT_DIM), []
id_to_cell = {c.id: c for c in memory_space}
start_probabilities = np.zeros(len(memory_space))
if x_64d is not None and sensory_drive > 0.0:
sims = np.array([cosine_similarity(cell.w_in, x_64d) for cell in memory_space])
start_probabilities += softmax(sims, temp=0.1) * sensory_drive
if intrinsic_drive > 0.0:
activity_weights = np.array([cell.energy * (cell.recent_activity + 0.05) for cell in memory_space])
start_probabilities += (activity_weights / (np.sum(activity_weights) + 1e-12)) * intrinsic_drive
if np.sum(start_probabilities) == 0:
start_probabilities = np.ones(len(memory_space)) / len(memory_space)
start_probabilities /= np.sum(start_probabilities)
current_cell_id = np.random.choice(list(id_to_cell.keys()), p=start_probabilities)
path = [current_cell_id]
collected_signals = [id_to_cell[current_cell_id].A.copy()]
imagined_pixels = [id_to_cell[current_cell_id].w_in.copy()]
for step in range(THOUGHT_STEPS - 1):
current_cell = id_to_cell[current_cell_id]
current_cell.recent_activity += sensory_drive * 1.0
all_ids = list(id_to_cell.keys())
if current_cell.role == "Explorer" and random.random() < 0.25:
current_cell_id = random.choice(all_ids)
path.append(current_cell_id)
collected_signals.append(id_to_cell[current_cell_id].A.copy())
imagined_pixels.append(id_to_cell[current_cell_id].w_in.copy())
continue
candidates = set(np.random.choice(all_ids, min(20, len(all_ids)), replace=False))
candidates.update(current_cell.links.keys())
scores = []
c_ids = []
for cid in candidates:
if cid in path or cid not in id_to_cell: continue
cell = id_to_cell[cid]
score = current_cell.links.get(cid, 0.0) * 3.0
if x_64d is not None:
score += 2.0 * cosine_similarity(cell.w_in, x_64d) * sensory_drive
score += 0.8 * cosine_similarity(current_cell.A, cell.A)
if cell.role == "Bridge":
score *= 2.5
scores.append(score)
c_ids.append(cid)
if not scores: break
probs = softmax(scores, temp=0.3)
current_cell_id = np.random.choice(c_ids, p=probs)
path.append(current_cell_id)
collected_signals.append(id_to_cell[current_cell_id].A.copy())
imagined_pixels.append(id_to_cell[current_cell_id].w_in.copy())
final_perception = np.mean(np.stack(collected_signals), axis=0) if collected_signals else np.zeros(NUM_CLASSES)
final_image = np.mean(np.stack(imagined_pixels), axis=0) if imagined_pixels else np.zeros(INPUT_DIM)
sensory_factor = sensory_drive * learning_gate
inferred_class = np.argmax(final_perception)
target = target_class if target_class is not None else inferred_class
target_vec = np.zeros(NUM_CLASSES)
target_vec[target] = 1.0
base_reward = min(1.0 / (np.linalg.norm(target_vec - final_perception) + 0.15), 2.5) * 1.5
novelty_reward = 0.0
for cid in path:
if cid in id_to_cell and id_to_cell[cid].visits < 4.0:
novelty_reward += 0.10
info_gain = 0.0
if len(collected_signals) > 1:
first_error = np.linalg.norm(target_vec - collected_signals[0])
final_error = np.linalg.norm(target_vec - final_perception)
info_gain = max(0.0, first_error - final_error) * 2.0
reward = base_reward + novelty_reward + info_gain
for cid in path:
if cid in id_to_cell:
for neighbor_id in id_to_cell[cid].links.keys():
if neighbor_id not in path and neighbor_id in id_to_cell:
id_to_cell[neighbor_id].energy *= 0.96
if x_64d is not None and sensory_factor > 0.0:
unique_visited_ids = set(path)
for cid in unique_visited_ids:
if cid not in id_to_cell: continue
cell = id_to_cell[cid]
if random.random() < 0.10:
continue
if cell.role == "Explorer":
noise = np.random.normal(0, 0.12)
dynamic_lr = max(0.05, cell.lr + noise)
else:
noise = np.random.normal(0, 0.05)
dynamic_lr = max(0.01, cell.lr + noise)
cell.visits += sensory_factor
cell.energy = min(1.0, cell.energy + reward * 0.12 * sensory_factor)
cell.w_in += (dynamic_lr * 0.5 * sensory_factor) * (x_64d - cell.w_in)
cell.A += (dynamic_lr * sensory_factor) * target_vec
cell.A *= cell.a_decay
cell.A /= (np.sum(cell.A) + 1e-12)
return final_perception, final_image, path
def evolve_and_prune_space(memory_space):
for cell in memory_space:
cell.energy *= 0.90
cell.recent_activity *= 0.50
if cell.energy < 0.01: cell.energy = 0.01
new_cells = []
current_max_id = max([c.id for c in memory_space]) if memory_space else 0
for cell in memory_space:
if len(memory_space) + len(new_cells) >= MAX_CELLS: break
if cell.energy > (DIVISION_THRESHOLD * (2.0 - cell.div_rate)) and cell.visits > 10:
child = VisionMemoryCell(current_max_id + len(new_cells) + 1)
child.w_in = np.clip(cell.w_in + np.random.normal(0, 0.05, INPUT_DIM), -3.0, 3.0)
child.A = cell.A.copy()
child.pos = cell.pos + np.random.normal(0, 0.1, 3)
child.role = cell.role
child.lr = cell.lr
child.a_decay = cell.a_decay
child.div_rate = cell.div_rate
cell.energy *= 0.3
cell.visits *= 0.5
child.energy = 0.2
new_cells.append(child)
memory_space.extend(new_cells)
survived_space = []
id_map = {}
for cell in memory_space:
if len(survived_space) > MIN_CELLS:
if cell.energy < DEATH_THRESHOLD and cell.visits < 1.0:
continue
id_map[cell.id] = len(survived_space)
cell.id = id_map[cell.id]
survived_space.append(cell)
for cell in survived_space:
cell.links = {id_map[old_id]: w for old_id, w in cell.links.items() if old_id in id_map}
return survived_space
class EnsembleVisionEcosystem:
def __init__(self, n_estimators=3, total_cells=2500):
self.n_estimators = n_estimators
self.models = []
for _ in range(n_estimators):
space = [VisionMemoryCell(i) for i in range(total_cells)]
update_topology_with_memory(space)
self.models.append({'space': space})
def train_cycle(self, X, y, phase="day"):
for model in self.models:
indices = np.random.choice(len(X), len(X), replace=True)
path_history = []
for idx in indices:
s_drive = 1.0 if phase == "day" else 0.3
i_drive = 0.0 if phase == "day" else 0.7
_, _, path = live_vision_cycle(model['space'], x_64d=X[idx], target_class=y[idx],
sensory_drive=s_drive, intrinsic_drive=i_drive)
if path: path_history.append(path)
update_cell_positions_fast(model['space'], path_history)
update_topology_with_memory(model['space'])
def sleep_cycle(self, steps=30):
for model in self.models:
path_history = []
for _ in range(steps):
_, _, path = live_vision_cycle(model['space'], x_64d=None, target_class=None,
sensory_drive=0.0, intrinsic_drive=1.0)
if path: path_history.append(path)
update_cell_positions_fast(model['space'], path_history)
update_topology_with_memory(model['space'])
def evolve(self):
for model in self.models:
model['space'] = evolve_and_prune_space(model['space'])
update_topology_with_memory(model['space'])
def predict(self, X):
y_pred = []
for idx in range(len(X)):
ensemble_perceptions = []
ensemble_confidences = []
for model in self.models:
perception, _, _ = live_vision_cycle(
model['space'], x_64d=X[idx],
sensory_drive=1.0, intrinsic_drive=0.0, learning_gate=0.0
)
confidence = np.max(perception)
ensemble_perceptions.append(perception)
ensemble_confidences.append(confidence)
weighted_perceptions = np.zeros(NUM_CLASSES)
total_conf = sum(ensemble_confidences) + 1e-12
for p, c in zip(ensemble_perceptions, ensemble_confidences):
weighted_perceptions += p * (c / total_conf)
y_pred.append(np.argmax(weighted_perceptions))
return y_pred
print("=== 🌐 構造記憶&細胞社会性を持つ自己組織化認知生態系 起動 ===")
ecosystem = EnsembleVisionEcosystem(n_estimators=3, total_cells=INIT_CELLS)
for cycle in range(epochs):
ecosystem.train_cycle(X_train, y_train, phase="day")
ecosystem.train_cycle(X_train, y_train, phase="evening")
ecosystem.sleep_cycle(steps=30)
ecosystem.evolve()
y_pred = ecosystem.predict(X_test)
acc = accuracy_score(y_test, y_pred)
avg_cells = int(np.mean([len(m['space']) for m in ecosystem.models]))
roles_count = defaultdict(int)
for c in ecosystem.models[0]['space']: roles_count[c.role] += 1
roles_str = ", ".join([f"{k}:{v}" for k, v in roles_count.items()])
print(f"Cycle {cycle+1:02d}/{epochs} | 総細胞数: {avg_cells:>3} | 正解率: {acc:.4f} | 社会組成: [{roles_str}]")
print("\n[Visualizing Evolved Neural Social Topology...]")
fig = plt.figure(figsize=(9, 7))
ax = fig.add_subplot(111, projection='3d')
ax.set_title("Evolved Concept Space: Grid-optimized & Engram-linked")
first_space = ecosystem.models[0]['space']
role_markers = {"Explorer": "o", "Storage": "s", "Bridge": "^", "Default": "D"}
role_colors = {"Explorer": "cyan", "Storage": "orange", "Bridge": "magenta", "Default": "gray"}
for role in ["Explorer", "Storage", "Bridge", "Default"]:
r_cells = [c for c in first_space if c.role == role]
if not r_cells: continue
ax.scatter([c.pos[0] for c in r_cells],
[c.pos[1] for c in r_cells],
[c.pos[2] for c in r_cells],
c=role_colors[role], marker=role_markers[role], s=50, label=role, edgecolors='black', alpha=0.8)
ax.legend()
plt.show()