FractalBrainNet / FractalBrainNet-v2.py
JoseRFJunior's picture
Upload 2 files
f6ded1e verified
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
import math
from typing import Optional, List, Tuple, Dict, Callable
from enum import Enum
class FractalPatternType(Enum):
"""Tipos de padrões fractais suportados pela FractalBrainNet"""
MANDELBROT = "mandelbrot"
SIERPINSKI = "sierpinski"
JULIA = "julia"
CANTOR = "cantor"
DRAGON_CURVE = "dragon_curve"
class FractalPatternGenerator:
"""
Gerador de padrões fractais para definir as regras de conexão
entre neurônios na FractalBrainNet.
"""
@staticmethod
def mandelbrot_connectivity(width: int, height: int, max_iter: int = 100) -> torch.Tensor:
"""
Gera matriz de conectividade baseada no conjunto de Mandelbrot.
Valores mais altos indicam conexões mais fortes.
"""
x = torch.linspace(-2.5, 1.5, width)
y = torch.linspace(-1.5, 1.5, height)
X, Y = torch.meshgrid(x, y, indexing='ij')
c = X + 1j * Y
z = torch.zeros_like(c)
connectivity = torch.zeros(width, height)
for i in range(max_iter):
mask = torch.abs(z) <= 2
z[mask] = z[mask] ** 2 + c[mask]
connectivity[mask] += 1
# Normalizar para [0, 1]
connectivity = connectivity / max_iter
return connectivity
@staticmethod
def sierpinski_connectivity(size: int, iterations: int = 5) -> torch.Tensor:
"""
Gera matriz de conectividade baseada no triângulo de Sierpinski.
"""
pattern = torch.zeros(size, size)
pattern[0, size//2] = 1.0
for _ in range(iterations):
new_pattern = torch.zeros_like(pattern)
for i in range(size-1):
for j in range(size-1):
if pattern[i, j] > 0:
# Regra do triângulo de Sierpinski
if i+1 < size and j > 0:
new_pattern[i+1, j-1] = 1.0
if i+1 < size and j+1 < size:
new_pattern[i+1, j+1] = 1.0
pattern = torch.maximum(pattern, new_pattern)
return pattern
@staticmethod
def julia_connectivity(width: int, height: int, c_real: float = -0.7,
c_imag: float = 0.27015, max_iter: int = 100) -> torch.Tensor:
"""
Gera matriz de conectividade baseada no conjunto de Julia.
"""
x = torch.linspace(-2, 2, width)
y = torch.linspace(-2, 2, height)
X, Y = torch.meshgrid(x, y, indexing='ij')
z = X + 1j * Y
c = complex(c_real, c_imag)
connectivity = torch.zeros(width, height)
for i in range(max_iter):
mask = torch.abs(z) <= 2
z[mask] = z[mask] ** 2 + c
connectivity[mask] += 1
connectivity = connectivity / max_iter
return connectivity
class CerebralDynamicsModule(nn.Module):
"""
Módulo que simula dinâmicas cerebrais através de processamento
distribuído e paralelo, inspirado na organização hierárquica do cérebro.
"""
def __init__(self, channels: int, fractal_pattern: torch.Tensor):
super().__init__()
self.channels = channels
self.fractal_pattern = nn.Parameter(fractal_pattern, requires_grad=False)
# Múltiplas escalas de processamento (simulando diferentes frequências cerebrais)
self.alpha_processing = nn.Conv2d(channels, channels//4, 1) # 8-12 Hz
self.beta_processing = nn.Conv2d(channels, channels//4, 1) # 13-30 Hz
self.gamma_processing = nn.Conv2d(channels, channels//4, 1) # 30-100 Hz
self.theta_processing = nn.Conv2d(channels, channels//4, 1) # 4-8 Hz
# Integração das diferentes escalas
self.integration = nn.Conv2d(channels, channels, 1)
self.normalization = nn.LayerNorm([channels])
def forward(self, x: torch.Tensor) -> torch.Tensor:
batch_size, channels, height, width = x.shape
# Aplicar padrão fractal como máscara de atenção
if self.fractal_pattern.shape[-2:] != (height, width):
fractal_mask = F.interpolate(
self.fractal_pattern.unsqueeze(0).unsqueeze(0),
size=(height, width), mode='bilinear', align_corners=False
).squeeze()
else:
fractal_mask = self.fractal_pattern
# Processamento em múltiplas escalas (simulando bandas de frequência cerebral)
alpha = self.alpha_processing(x) * fractal_mask.unsqueeze(0).unsqueeze(0)
beta = self.beta_processing(x) * (1 - fractal_mask.unsqueeze(0).unsqueeze(0))
gamma = self.gamma_processing(x) * fractal_mask.unsqueeze(0).unsqueeze(0) * 0.5
theta = self.theta_processing(x) * torch.sin(fractal_mask * math.pi).unsqueeze(0).unsqueeze(0)
# Combinar diferentes escalas
combined = torch.cat([alpha, beta, gamma, theta], dim=1)
integrated = self.integration(combined)
# Normalização adaptativa
integrated = integrated.permute(0, 2, 3, 1)
integrated = self.normalization(integrated)
integrated = integrated.permute(0, 3, 1, 2)
return integrated + x # Conexão residual
class FractalNeuralBlock(nn.Module):
"""
Bloco neural fractal que implementa a regra de expansão fractal
com dinâmicas cerebrais integradas.
"""
def __init__(self, level: int, in_channels: int, out_channels: int,
fractal_pattern: torch.Tensor, drop_path_prob: float = 0.1):
super().__init__()
self.level = level
if level == 1:
# Caso base com dinâmicas cerebrais
self.base_conv = nn.Conv2d(in_channels, out_channels, 3, padding=1)
self.cerebral_dynamics = CerebralDynamicsModule(out_channels, fractal_pattern)
self.activation = nn.GELU() # GELU para maior expressividade
self.norm = nn.BatchNorm2d(out_channels)
else:
# Estrutura recursiva fractal
self.deep_branch = nn.Sequential(
FractalNeuralBlock(level-1, in_channels, out_channels, fractal_pattern, drop_path_prob),
FractalNeuralBlock(level-1, out_channels, out_channels, fractal_pattern, drop_path_prob)
)
self.shallow_branch = nn.Sequential(
nn.Conv2d(in_channels, out_channels, 3, padding=1),
CerebralDynamicsModule(out_channels, fractal_pattern),
nn.BatchNorm2d(out_channels),
nn.GELU()
)
# Mecanismo de atenção fractal
self.fractal_attention = nn.Sequential(
nn.Conv2d(out_channels * 2, out_channels // 4, 1),
nn.GELU(),
nn.Conv2d(out_channels // 4, 2, 1),
nn.Sigmoid()
)
self.drop_path = nn.Dropout2d(drop_path_prob) if drop_path_prob > 0 else nn.Identity()
def forward(self, x: torch.Tensor) -> torch.Tensor:
if self.level == 1:
out = self.base_conv(x)
out = self.norm(out)
out = self.cerebral_dynamics(out)
out = self.activation(out)
return self.drop_path(out)
else:
# Processamento em ramos paralelos
deep_out = self.deep_branch(x)
shallow_out = self.shallow_branch(x)
# Mecanismo de atenção para combinar ramos
combined = torch.cat([deep_out, shallow_out], dim=1)
attention_weights = self.fractal_attention(combined)
# Combinar com pesos adaptativos
alpha, beta = attention_weights.chunk(2, dim=1)
result = alpha * deep_out + beta * shallow_out
return self.drop_path(result)
class AdaptiveScaleProcessor(nn.Module):
"""
Processador adaptativo que opera em múltiplas escalas,
simulando a capacidade do cérebro de processar informações
em diferentes níveis de abstração simultaneamente.
"""
def __init__(self, channels: int):
super().__init__()
self.channels = channels
# Diferentes escalas de processamento
self.local_processor = nn.Conv2d(channels, channels, 1)
self.regional_processor = nn.Conv2d(channels, channels, 3, padding=1)
self.global_processor = nn.Conv2d(channels, channels, 5, padding=2)
# Integração adaptativa
self.scale_fusion = nn.Sequential(
nn.Conv2d(channels * 3, channels, 1),
nn.BatchNorm2d(channels),
nn.GELU()
)
def forward(self, x: torch.Tensor) -> torch.Tensor:
local = self.local_processor(x)
regional = self.regional_processor(x)
global_proc = self.global_processor(x)
# Combinar escalas
multi_scale = torch.cat([local, regional, global_proc], dim=1)
fused = self.scale_fusion(multi_scale)
return fused + x
class FractalBrainNet(nn.Module):
"""
FractalBrainNet: Rede neural que combina a profundidade das redes profundas
com a complexidade e elegância dos fractais, capaz de emular dinâmicas cerebrais
através de estruturas hierárquicas e auto-similares.
Baseada no artigo de Jose R. F. Junior (2024).
"""
def __init__(self,
num_classes: int = 10,
in_channels: int = 3,
fractal_levels: List[int] = [2, 3, 4, 5],
base_channels: int = 64,
fractal_pattern_type: FractalPatternType = FractalPatternType.MANDELBROT,
pattern_resolution: int = 32,
drop_path_prob: float = 0.15,
enable_continuous_learning: bool = True):
super().__init__()
self.num_classes = num_classes
self.fractal_levels = fractal_levels
self.enable_continuous_learning = enable_continuous_learning
# Gerar padrão fractal base
self.fractal_pattern = self._generate_fractal_pattern(
fractal_pattern_type, pattern_resolution
)
# Camada de entrada adaptativa
self.stem = nn.Sequential(
nn.Conv2d(in_channels, base_channels, 7, stride=2, padding=3),
nn.BatchNorm2d(base_channels),
nn.GELU(),
AdaptiveScaleProcessor(base_channels)
)
# Blocos fractais neurais hierárquicos
self.fractal_stages = nn.ModuleList()
current_channels = base_channels
for i, level in enumerate(fractal_levels):
# Aumentar canais progressivamente
stage_channels = base_channels * (2 ** min(i, 4))
# Bloco fractal principal
fractal_block = FractalNeuralBlock(
level, current_channels, stage_channels,
self.fractal_pattern, drop_path_prob
)
# Processador multi-escala
scale_processor = AdaptiveScaleProcessor(stage_channels)
# Pooling adaptativo
if i < len(fractal_levels) - 1:
pooling = nn.Sequential(
nn.Conv2d(stage_channels, stage_channels, 3, stride=2, padding=1),
nn.BatchNorm2d(stage_channels),
nn.GELU()
)
else:
pooling = nn.Identity()
self.fractal_stages.append(nn.Sequential(
fractal_block,
scale_processor,
pooling
))
current_channels = stage_channels
# Sistema de atenção global inspirado na atenção cerebral
self.global_attention = nn.MultiheadAttention(
current_channels, num_heads=8, batch_first=True
)
# Cabeça de classificação com aprendizado contínuo
self.adaptive_pool = nn.AdaptiveAvgPool2d((1, 1))
self.classifier = nn.Sequential(
nn.Dropout(0.2),
nn.Linear(current_channels, current_channels // 2),
nn.GELU(),
nn.Dropout(0.1),
nn.Linear(current_channels // 2, num_classes)
)
# Módulo de meta-aprendizado para adaptação contínua
if enable_continuous_learning:
self.meta_learner = nn.Sequential(
nn.Linear(current_channels, current_channels // 4),
nn.GELU(),
nn.Linear(current_channels // 4, current_channels)
)
self._initialize_weights()
def _generate_fractal_pattern(self, pattern_type: FractalPatternType,
resolution: int) -> torch.Tensor:
"""Gera o padrão fractal base para a rede."""
if pattern_type == FractalPatternType.MANDELBROT:
return FractalPatternGenerator.mandelbrot_connectivity(resolution, resolution)
elif pattern_type == FractalPatternType.SIERPINSKI:
return FractalPatternGenerator.sierpinski_connectivity(resolution)
elif pattern_type == FractalPatternType.JULIA:
return FractalPatternGenerator.julia_connectivity(resolution, resolution)
else:
# Padrão padrão (Mandelbrot)
return FractalPatternGenerator.mandelbrot_connectivity(resolution, resolution)
def _initialize_weights(self):
"""Inicialização de pesos inspirada na neuroplasticidade."""
for m in self.modules():
if isinstance(m, nn.Conv2d):
# Inicialização He com variação fractal
nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
if m.bias is not None:
nn.init.constant_(m.bias, 0)
elif isinstance(m, (nn.BatchNorm2d, nn.LayerNorm)):
nn.init.constant_(m.weight, 1.0)
nn.init.constant_(m.bias, 0.0)
elif isinstance(m, nn.Linear):
nn.init.trunc_normal_(m.weight, std=0.02)
if m.bias is not None:
nn.init.constant_(m.bias, 0)
def forward(self, x: torch.Tensor,
return_attention_maps: bool = False) -> torch.Tensor:
"""
Forward pass com processamento hierárquico e dinâmicas cerebrais.
"""
# Extração inicial de características
x = self.stem(x)
attention_maps = []
# Processamento através dos estágios fractais
for stage in self.fractal_stages:
x = stage(x)
if return_attention_maps:
# Capturar mapas de atenção para análise
attention_map = torch.mean(x, dim=1, keepdim=True)
attention_maps.append(attention_map)
# Pooling adaptativo global
pooled = self.adaptive_pool(x)
features = pooled.flatten(1)
# Aplicar atenção global se habilitada
if hasattr(self, 'global_attention'):
# Reformatar para atenção multi-cabeça
attn_input = features.unsqueeze(1)
attended, _ = self.global_attention(attn_input, attn_input, attn_input)
features = attended.squeeze(1)
# Meta-aprendizado para adaptação contínua
if self.enable_continuous_learning and hasattr(self, 'meta_learner'):
meta_features = self.meta_learner(features)
features = features + 0.1 * meta_features # Residual meta-learning
# Classificação final
output = self.classifier(features)
if return_attention_maps:
return output, attention_maps
return output
def analyze_fractal_patterns(self, x: torch.Tensor) -> Dict[str, torch.Tensor]:
"""
Analisa os padrões emergentes gerados pela estrutura fractal,
conforme mencionado na metodologia do artigo.
"""
self.eval()
with torch.no_grad():
_, attention_maps = self.forward(x, return_attention_maps=True)
analysis = {
'fractal_pattern': self.fractal_pattern,
'attention_maps': attention_maps,
'pattern_complexity': self._compute_pattern_complexity(attention_maps),
'hierarchical_organization': self._analyze_hierarchical_organization(attention_maps)
}
return analysis
def _compute_pattern_complexity(self, attention_maps: List[torch.Tensor]) -> List[float]:
"""Computa a complexidade dos padrões emergentes."""
complexities = []
for attention_map in attention_maps:
# Usar entropia como medida de complexidade
flat_map = attention_map.flatten()
prob_dist = F.softmax(flat_map, dim=0)
entropy = -torch.sum(prob_dist * torch.log(prob_dist + 1e-8))
complexities.append(entropy.item())
return complexities
def _analyze_hierarchical_organization(self, attention_maps: List[torch.Tensor]) -> Dict[str, float]:
"""Analisa a organização hierárquica dos padrões."""
if len(attention_maps) < 2:
return {'correlation': 0.0, 'hierarchy_score': 0.0}
# Correlação entre níveis hierárquicos
correlations = []
for i in range(len(attention_maps) - 1):
map1 = attention_maps[i].flatten()
map2 = F.interpolate(attention_maps[i+1], size=attention_maps[i].shape[-2:],
mode='bilinear', align_corners=False).flatten()
correlation = torch.corrcoef(torch.stack([map1, map2]))[0, 1]
correlations.append(correlation.item())
avg_correlation = sum(correlations) / len(correlations)
hierarchy_score = 1.0 - avg_correlation # Maior diversidade = maior hierarquia
return {
'correlation': avg_correlation,
'hierarchy_score': hierarchy_score
}
# Função para criar modelos FractalBrainNet pré-configurados
def create_fractal_brain_net(model_size: str = 'medium',
num_classes: int = 10,
fractal_pattern: FractalPatternType = FractalPatternType.MANDELBROT) -> FractalBrainNet:
"""
Cria modelos FractalBrainNet pré-configurados inspirados no artigo de Jose R. F. Junior.
Args:
model_size: 'small', 'medium', 'large', 'xlarge'
num_classes: número de classes para classificação
fractal_pattern: tipo de padrão fractal a ser usado
"""
configs = {
'small': {
'fractal_levels': [2, 3],
'base_channels': 32,
'pattern_resolution': 16
},
'medium': {
'fractal_levels': [2, 3, 4],
'base_channels': 64,
'pattern_resolution': 32
},
'large': {
'fractal_levels': [2, 3, 4, 5],
'base_channels': 96,
'pattern_resolution': 64
},
'xlarge': {
'fractal_levels': [3, 4, 5, 6],
'base_channels': 128,
'pattern_resolution': 128
}
}
config = configs.get(model_size, configs['medium'])
return FractalBrainNet(
num_classes=num_classes,
fractal_levels=config['fractal_levels'],
base_channels=config['base_channels'],
fractal_pattern_type=fractal_pattern,
pattern_resolution=config['pattern_resolution']
)
# Demonstração e teste
if __name__ == "__main__":
print("=== FractalBrainNet - Implementação Avançada ===")
print("Baseada no artigo de Jose R. F. Junior (2024)")
print()
# Criar modelo com diferentes padrões fractais
models = {
'Mandelbrot': create_fractal_brain_net('medium', 10, FractalPatternType.MANDELBROT),
'Sierpinski': create_fractal_brain_net('medium', 10, FractalPatternType.SIERPINSKI),
'Julia': create_fractal_brain_net('medium', 10, FractalPatternType.JULIA)
}
# Teste com entrada dummy
dummy_input = torch.randn(2, 3, 64, 64)
for name, model in models.items():
print(f"\n=== Modelo com padrão {name} ===")
# Forward pass normal
output = model(dummy_input)
print(f"Output shape: {output.shape}")
# Análise de padrões fractais emergentes
analysis = model.analyze_fractal_patterns(dummy_input)
print(f"Níveis de atenção capturados: {len(analysis['attention_maps'])}")
print(f"Complexidade dos padrões: {analysis['pattern_complexity']}")
print(f"Organização hierárquica: {analysis['hierarchical_organization']}")
# Estatísticas do modelo
total_params = sum(p.numel() for p in model.parameters())
print(f"Parâmetros totais: {total_params:,}")
print("\n=== FractalBrainNet criada com sucesso! ===")
print("Esta implementação incorpora:")
print("- Padrões fractais (Mandelbrot, Sierpinski, Julia)")
print("- Simulação de dinâmicas cerebrais")
print("- Processamento hierárquico e multi-escala")
print("- Mecanismos de atenção inspirados no cérebro")
print("- Capacidade de aprendizado contínuo")
print("- Análise de padrões emergentes")
"""
# Criar modelo com padrão Mandelbrot
model = create_fractal_brain_net('large', num_classes=1000,
fractal_pattern=FractalPatternType.MANDELBROT)
# Forward pass normal
output = model(input_tensor)
# Análise de padrões emergentes
analysis = model.analyze_fractal_patterns(input_tensor)
print("Complexidade dos padrões:", analysis['pattern_complexity'])
print("Organização hierárquica:", analysis['hierarchical_organization'])
"""