Quanta / quanta_sim_v1_no_viz.py
NextGenC's picture
Upload 11 files
8e35b08 verified
raw
history blame contribute delete
8.66 kB
import neat
import numpy as np
import os
import logging
import pickle # En iyi genomu kaydetmek/yüklemek için
import random
import math
import datetime # Log dosyası ismi için
# --- Loglama Ayarları ---
log_filename = f"quanta_log_{datetime.datetime.now():%Y%m%d_%H%M%S}.log"
logging.basicConfig(
level=logging.INFO, # Log seviyesi (INFO, DEBUG, WARNING, ERROR, CRITICAL)
format='%(asctime)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s', # Log formatı
handlers=[
logging.FileHandler(log_filename), # Dosyaya loglama
logging.StreamHandler() # Konsola (ekrana) loglama
]
)
logger = logging.getLogger(__name__)
logger.info("="*50)
logger.info("Quanta Simülatörü Başlatılıyor (Görselleştirme Olmadan)")
logger.info("="*50)
# --- Simülasyon Parametreleri ---
TARGET_PROB_0 = 0.7 # Hedef: %70 olasılıkla 0 üretmek
TARGET_PROB_1 = 1.0 - TARGET_PROB_0 # Hedef: %30 olasılıkla 1 üretmek
NUM_TRIALS_PER_GENOME = 100 # Her genomu değerlendirmek için yapılacak deneme sayısı
MAX_GENERATIONS = 50 # Maksimum evrim nesli (Donanımınıza göre artırılabilir)
FITNESS_THRESHOLD = 0.99 # Evrimin durması için ulaşılması gereken minimum fitness
logger.info(f"Hedef P(0): {TARGET_PROB_0:.2f}, Hedef P(1): {TARGET_PROB_1:.2f}")
logger.info(f"Genom Başına Deneme Sayısı: {NUM_TRIALS_PER_GENOME}")
logger.info(f"Maksimum Nesil Sayısı: {MAX_GENERATIONS}")
logger.info(f"Fitness Eşiği: {FITNESS_THRESHOLD}")
# --- Basit Kuantum Benzeri Davranış (Taklit) ---
# Bu fonksiyon, kuantum ölçümünün olasılıksal sonucunu basitçe taklit eder.
def simulate_simple_qubit_measurement(prob0=TARGET_PROB_0):
if random.random() < prob0:
return 0
else:
return 1
# --- NEAT Fitness Fonksiyonu ---
# Genomları (sinir ağlarını) değerlendirir.
# Hedef: Ağın çıktısı TARGET_PROB_0'a yakın olasılıkla 0 olmalı.
def eval_genomes(genomes, config):
"""
Popülasyondaki tüm genomların fitness değerlerini hesaplar.
"""
for genome_id, genome in genomes:
genome.fitness = 0.0 # Başlangıç fitness'ı sıfırla
try:
net = neat.nn.FeedForwardNetwork.create(genome, config)
except Exception as e:
logger.error(f"Genome {genome_id} için ağ oluşturulamadı: {e}")
genome.fitness = -1.0 # Geçersiz genomları cezalandır
continue
count_0 = 0
# Her genomu N kez test ederek istatistiksel olarak değerlendir
for _ in range(NUM_TRIALS_PER_GENOME):
# Ağ Girdisi: Şimdilik sabit bir değer (1.0) kullanıyoruz.
# Gelecekte bu girdi, simülasyonun durumunu veya kontrol parametrelerini yansıtabilir.
net_input = (1.0,)
try:
output = net.activate(net_input)
# Ağın çıktısını (genellikle 0-1 arası) yorumla
# Çıktı < 0.5 ise 0, >= 0.5 ise 1 kabul edelim
if output[0] < 0.5:
count_0 += 1
except Exception as e:
logger.warning(f"Genome {genome_id} ağ aktivasyonunda hata: {e}")
# Hata durumunda bu denemeyi atla veya penaltı ver
pass # Şimdilik sadece atlıyoruz
# Gözlemlenen olasılıkları hesapla
observed_prob_0 = count_0 / NUM_TRIALS_PER_GENOME
# Fitness Hesaplama: Hedef olasılıklara ne kadar yakın?
# Ortalama Karesel Hata (MSE) benzeri bir yaklaşım, ama ters çevrilmiş.
# Hata ne kadar küçükse, fitness o kadar yüksek olmalı.
error = (observed_prob_0 - TARGET_PROB_0) ** 2
# Fitness = 1 / (hata + epsilon) -> Hata sıfıra yaklaştıkça fitness sonsuza yaklaşır.
# Daha stabil bir fitness için: Fitness = 1.0 - hata (0 ile 1 arasında)
# Veya hedef eşiğe göre normalize edilebilir. Şimdilik basit tutalım:
fitness = max(0.0, 1.0 - math.sqrt(error)) # Hatanın karekökünü 1'den çıkaralım (0-1 arası)
genome.fitness = fitness
# logger.debug(f"Genome {genome_id}: Fitness = {fitness:.4f}, Gözlenen P(0) = {observed_prob_0:.2f}")
# --- NEAT Çalıştırma Fonksiyonu ---
def run_neat(config_file):
"""
NEAT evrimini başlatır ve yönetir.
"""
logger.info(f"NEAT yapılandırması yükleniyor: {config_file}")
try:
config = neat.Config(neat.DefaultGenome, neat.DefaultReproduction,
neat.DefaultSpeciesSet, neat.DefaultStagnation,
config_file)
# Fitness eşiğini config dosyasından değil, koddan alalım
config.fitness_threshold = FITNESS_THRESHOLD
logger.info(f"Yapılandırma yüklendi. Fitness Eşiği: {config.fitness_threshold}")
except Exception as e:
logger.critical(f"Yapılandırma dosyası yüklenemedi veya geçersiz: {config_file} - Hata: {e}")
return None # Hata durumunda None döndür
logger.info("Yeni popülasyon oluşturuluyor...")
p = neat.Population(config)
# İstatistikleri ve loglamayı ayarlama (Sadece konsol çıktısı)
p.add_reporter(neat.StdOutReporter(True))
# Görselleştirme için istatistik toplayıcıya gerek yok.
# stats = neat.StatisticsReporter()
# p.add_reporter(stats)
# Periyodik olarak checkpoint (yedek) alma
checkpoint_prefix = 'neat-checkpoint-'
p.add_reporter(neat.Checkpointer(10, filename_prefix=checkpoint_prefix)) # Her 10 nesilde bir kaydet
logger.info(f"Checkpoint dosyaları '{checkpoint_prefix}*' olarak kaydedilecek.")
logger.info(f"Evrim başlıyor (Maksimum {MAX_GENERATIONS} nesil)...")
try:
winner = p.run(eval_genomes, MAX_GENERATIONS)
logger.info(' ' + "="*20 + " Evrim Tamamlandı " + "="*20)
except Exception as e:
logger.critical(f"Evrim sırasında kritik bir hata oluştu: {e}")
# Belki son checkpoint'ten devam etme mantığı eklenebilir.
return None
# En iyi genomu göster/kaydet
logger.info(f'En iyi genom bulundu:')
logger.info(f' {winner}') # Konsola detaylı genom bilgisini yazdırır
# En iyi genomu dosyaya kaydet (pickle ile)
winner_filename = "winner_genome.pkl"
try:
with open(winner_filename, 'wb') as f:
pickle.dump(winner, f)
logger.info(f"En iyi genom '{winner_filename}' dosyasına başarıyla kaydedildi.")
except Exception as e:
logger.error(f"En iyi genom kaydedilemedi: {e}")
# En iyi genomdan ağı oluştur ve son bir kez test et
logger.info(" " + "="*20 + " En İyi Genom Testi " + "="*20)
if winner:
try:
winner_net = neat.nn.FeedForwardNetwork.create(winner, config)
test_count_0 = 0
test_trials = 1000 # Daha fazla deneme ile güvenilirliği artır
logger.info(f"En iyi ağ {test_trials} kez test ediliyor...")
for _ in range(test_trials):
net_input = (1.0,)
output = winner_net.activate(net_input)
if output[0] < 0.5:
test_count_0 += 1
observed_prob_0 = test_count_0 / test_trials
logger.info(f"Final Test Sonucu: Gözlenen P(0) = {observed_prob_0:.4f} (Hedef: {TARGET_PROB_0:.3f})")
logger.info(f"Final Test Sonucu: Gözlenen P(1) = {1.0 - observed_prob_0:.4f} (Hedef: {TARGET_PROB_1:.3f})")
final_error = (observed_prob_0 - TARGET_PROB_0) ** 2
logger.info(f"Final Test Hatası (Karesel): {final_error:.6f}")
except Exception as e:
logger.error(f"En iyi genom test edilirken hata oluştu: {e}")
else:
logger.warning("Test edilecek bir kazanan genom bulunamadı.")
logger.info("="*50)
logger.info("Quanta Simülatörü Adım 1 (Görselleştirmesiz) tamamlandı.")
logger.info("="*50)
return winner # Kazanan genomu döndür
if __name__ == '__main__':
# Yapılandırma dosyasının yolu (Python betiği ile aynı klasörde olduğunu varsayar)
local_dir = os.path.dirname(__file__)
config_path = os.path.join(local_dir, 'config-feedforward.txt')
if not os.path.exists(config_path):
logger.critical(f"Yapılandırma dosyası bulunamadı: {config_path}")
logger.critical("Lütfen 'config-feedforward.txt' dosyasını Python betiğiyle aynı klasöre koyun.")
else:
# NEAT'i çalıştır
run_neat(config_path)