İçeriğe geç

Kılavuzlar

Eğitim: bir pekiştirmeli öğrenme politikasını değerlendirme

İki tür pekiştirmeli öğrenme sorusu için çalıştırılabilir bir anlatım: çalıştırabildiğiniz bir politikanın bölümler (episode) boyunca ne kadar iyi performans gösterdiği ve gerçek dünyada deneyemediğiniz bir politikanın, yerini alacağı politikanın kaydından (log) değerlendirilerek ne kadar iyi sonuç vereceği. İki örnek de sağlayıcı kimlik bilgisi olmadan yerelde çalışır.

Her alanın ve değerlendiricinin başvurusu Pekiştirmeli öğrenme sayfasıdır; vaka, değerlendirici, metrik, aralık ve kapı terimleri Temel kavramlar sayfasındadır. Bu sayfa onların içinden geçen uygulamalı yoldur.

Oloproof burada neyi yapar, neyi yapmaz

Oloproof ortamınızı çalıştırmaz, bir benzetici barındırmaz ya da bir politika eğitmez. Sisteminiz her bölümü kendi ortamında çalıştırır ve onu bir rl_episode/v1 yapıtı olarak kaydeder; her bölüm metriği bu kayıttan okunur. İkinci kısımda hiçbir şey çalışmaz: test edilen politika yalnızca her eyleme vereceği olasılığı bildirir.

İki soruyu birbirinden ayrı tutun:

SoruElinizdekiKısım
Bu politika bölümler boyunca ne kadar iyi?Çalıştırabildiğiniz bir politika ve ortam1
Bu politika üretimde ne kadar iyi olurdu?Daha eski bir politikanın verdiği kararların, kullandığı olasılıklarla birlikte bir kaydı2

Ön koşullar

  • Python 3.11 ya da üstü ve kurulu Oloproof (pip install oloproof).
  • Paketle birlikte gelen örnek proje. Onu yeni bir dizine kopyalayın:
oloproof init --example rl my-rl

İki proje içerir: episodes/ ve off_policy/. Aşağıdaki her komut bunlardan birinin içinden çalışır ve kanıt onun .oloproof/ dizininde saklanır.

Kısım 1: çalıştırabildiğiniz bir politika

cd my-rl/episodes

Dosyalar

DosyaNedir
env.pyBir ızgara dünyası, iki politika (wander ve plan) ve onları çalıştıran sistemler
data/tasks.jsonlHer biri bir görev olan 24 ızgara: duvarlar, tehlikeler, bir başlangıç ve bir hedef
oloproof.yamlTemel politika wander için paket
candidate.yamlAday politika plan için aynı paket
release.yamlSürüm politikası
comparison.yamlBir adayın temele karşı karşılaması gereken kurallar

Bir bölüm, hedefe ulaşana ya da adımları tükenene kadar her adımda bir hücre ilerler. Her adım -1 kazandırır ve hedefe ulaşmak +10 kazandırır; dolayısıyla bir getiri -30 (30 adım, hedef yok) ile 10 arasındadır. Bir tehlikeye girmenin maliyeti 1'dir: güvenlik kısıtı budur. Politika ne seçerse seçsin, her on hareketten biri rastgele bir yöne kayar; bu yüzden aynı politika aynı ızgarada farklı sonuçlar alabilir.

Bir bölümü kaydetmek

Sistem bölümü kendisi çalıştırır ve kaydı vaka kaydedicisine verir:

@system(name="grid-agent", version="wander-v1", records=("rl_episode/v1",))
def run_baseline(task):
    return _run(task, wander)


def _run(task, policy):
    recorder = current_case()
    record = episode(task, policy, seed=task["seed"] * 1000 + recorder.replicate)
    recorder.rl_episode(record)
    return {"success": record["success"], "steps": len(record["steps"])}

Kayıt her adımın ödülünü ve maliyetini, bölümün hedefe ulaşıp ulaşmadığını (success) ve onu adım sınırının bitirip bitirmediğini (truncated) listeler.

Görev başına birkaç bölüm

oloproof.yaml, replicates: 5 bildirir; bu yüzden her görev beş bölüm çalıştırır. current_case().replicate hangisi olduğunu söyler (0'dan 4'e) ve ortam bölümün tohumunu ondan türetir: aynı görevin aynı bölümü her zaman aynı şekilde yeniden oynanır ve ikinci bir çalıştırma, saklanan bölümleri yeniden çalıştırmak yerine yeniden kullanır.

Birim görev olarak kalır. Her kriter, her görevin beş bölümü üzerindeki kendi ortalamasının 24 görev üzerindeki ortalamasıdır; bu yüzden aralık 120 bölümü değil, 24 görevi sayar. Bölümleri saymak, bir ızgaranın beş bölümünü beş bağımsız ızgaraymış gibi göstermek olurdu.

Değerlendiriciler:

evaluators:
  - {type: episode_return, return_range: [-30, 10]}
  - {type: episode_success}
  - {type: episode_cost_within, budget: 0, criterion: hazard_free}
metrics:
  - {id: solved_every_time, type: every_replicate, criterion: episode_success}

return_range zorunludur: ortalama bir getiri üzerindeki aralık yalnızca her getirinin içinde bulunduğu bir aralık içinde geçerlidir ve onun dışındaki bir getiri çalıştırmayı durdurur. solved_every_time bir görevi yalnızca beş bölümünün hepsi hedefe ulaştığında sayar.

Temeli çalıştırın

oloproof run
Gate: BLOCK (exit 3)
                                        Decisions
┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Rule          ┃ Metric          ┃ State                 ┃ Reasons                     ┃
┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ success-floor │ episode_success │ INSUFFICIENT_EVIDENCE │ interval_overlaps_threshold │
│ safety-floor  │ hazard_free     │ INSUFFICIENT_EVIDENCE │ interval_overlaps_threshold │
└───────────────┴─────────────────┴───────────────────────┴─────────────────────────────┘
                                                           Metrics
┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Metric            ┃ Estimate ┃ Interval        ┃ N                                                                         ┃
┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ episode_return    │ -10.51   │ [-16.44, -5.11] │ mean of 24 observed · 0 missing · 0 excluded                              │
│ episode_success   │ 76.7%    │ [55.4%, 89.6%]  │ 24 cases observed · 0 missing · 0 excluded · 5 replicates each · 14 flaky │
│ hazard_free       │ 29.2%    │ [10.3%, 54.0%]  │ 24 cases observed · 0 missing · 0 excluded · 5 replicates each · 9 flaky  │
│ solved_every_time │ 37.5%    │ [18.7%, 59.5%]  │ 9 / 24 observed · 0 missing · 0 excluded · 5 replicates each · 14 flaky   │
└───────────────────┴──────────┴─────────────────┴───────────────────────────────────────────────────────────────────────────┘
Cache: execution 0 hit/120 miss; judgment 0 hit/360 miss

Satır satır okuyun:

  • Gezinen politika bölümlerin %76.7'sinde hedefe ulaşır, ancak aralık %55.4'ten %89.6'ya uzanır; bu yüzden %75 tabanı ne aşılmış ne de kaçırılmıştır: INSUFFICIENT_EVIDENCE.
  • 24 görevden yalnızca 9'unu beş bölümünün her birinde çözer. "Genellikle çalışır" ve "her seferinde çalışır" farklı iddialardır ve gözetimsiz çalışacak bir ajanın ikincisine ihtiyacı vardır.
  • 14 görev kararsızdır (flaky): başarıları birebir aynı bölümler arasında değişti. Görev başına tek bölüm bunu gösteremezdi.
  • Bölümlerin %29.2'sinde tehlikelerden kaçınır. Aralığın üst ucu olan %54.0, %50 tabanının üstündedir; bu yüzden bu zayıf kayıt bile politikanın güvensiz olduğunu henüz kanıtlamaz.

Tek bir göreve bakın:

oloproof inspect RUN_ID --case grid_03
output: {
  "success": false,
  "steps": 30
}
judgments:
  episode_return: score -30
  episode_success: failed
  hazard_free: passed

grid_03 görevinin ilk bölümünde adımlar tükendi: getiri -30, hedef yok, girilen tehlike yok.

Adayı çalıştırın

oloproof run --config candidate.yaml
│ success-floor │ episode_success │ PASS                  │ lower_bound_meets_minimum   │
│ safety-floor  │ hazard_free     │ INSUFFICIENT_EVIDENCE │ interval_overlaps_threshold │
│ episode_return    │ 0.42     │ [-5.78, 2.59]   │ mean of 24 observed · 0 missing · 0 excluded                             │
│ episode_success   │ 100.0%   │ [79.9%, 100.0%] │ 24 cases observed · 0 missing · 0 excluded · 5 replicates each           │
│ hazard_free       │ 57.5%    │ [29.3%, 81.5%]  │ 24 cases observed · 0 missing · 0 excluded · 5 replicates each · 6 flaky │
│ solved_every_time │ 100.0%   │ [85.7%, 100.0%] │ 24 / 24 observed · 0 missing · 0 excluded · 5 replicates each            │

Planlayıcı her bölümde hedefe ulaşır; bu yüzden başarı tabanı geçer. Yine de tehlikelere girer: bazı ızgaralarda güvenli yol yoktur ve kaygan zemin onu başkalarına iter. %57.5'lik güvenlik oranı tabanın üstündedir, ancak 24 görev bunun %50'nin üstünde olduğunu henüz gösteremez.

İki politikayı karşılaştırın

oloproof compare CANDIDATE_RUN_ID BASELINE_RUN_ID --policy comparison.yaml
episode_return: +10.92 [+0.21, +17.74] · 24 paired · 0 missing · 0 excluded
episode_success: +23.3 points [-3.2, +44.6] · 24 paired · 0 missing · 0 excluded
hazard_free: +28.3 points [-2.4, +54.7] · 24 paired · 0 missing · 0 excluded
solved_every_time: +62.5 points [+24.3, +87.7] · 24 paired · 0 missing · 0 excluded
Decisions
  return-better  episode_return  superiority  PASS  difference_above_zero
  safety-no-worse  hazard_free  non-inferiority, margin 5.0 points  PASS  lower_bound_above_margin
Gate: ALLOW (exit 0)

Karşılaştırma her görevi kendisiyle eşleştirir; her taraf beş bölüm üzerindeki ortalaması değerindedir. Getiri farkı getirinin kendi birimindedir: planlayıcı bölüm başına yaklaşık 10.9 daha fazla, en az 0.21 daha fazla kazanır. Aynı ızgaralarda eşleştirildiğinde, 5 puanlık bir marj planlayıcının daha az güvenli olmadığını göstermeye yeter; oysa iki çalıştırmadan hiçbiri tek başına kendi güvenlik tabanını karara bağlayamamıştı.

Kısım 2: bir kayıttan değerlendirilen bir politika

cd ../off_policy

Bir destek masası her talebi küçük ya da büyük bir modele yönlendirir. Mevcut yönlendirici küçük modeli zamanın %70'inde, büyük olanı %30'unda, rastgele seçer. Yeni bir kural yazdınız: teknik talepler ve uzun fatura talepleri büyük modele gider. Onu henüz gerçek talepler üzerinde deneyemezsiniz, ama eski yönlendiricinin kaydı onun yerine yanıt verebilir. Politika dışı (off-policy) değerlendirme budur.

Kayıt ve dosyaları

DosyaNedir
data/decisions.jsonlMevcut yönlendiricinin verdiği 600 karar
make_log.pyO kaydı yazan benzetim; nasıl yapıldığını görebilmeniz için
router.pyYeni kural, test edilen sistem
oloproof.yamlPaket
release.yamlSürüm politikası

Kaydın her satırı tek bir karardır:

{"id":"t001","input":{"topic":"technical","length":"short"},"expected":{"action":"small","logging_probabilities":{"small":0.7,"large":0.3},"reward":1}}

input yönlendiricinin gördüğü, action seçtiği, logging_probabilities o anda her modele verdiği olasılık ve reward talebin çözülüp çözülmediğidir. Yeni kural yalnızca kendi olasılıklarıyla yanıt verir:

@system(name="ticket-router", version="by-topic-v1")
def route_by_topic(ticket):
    large = ticket["topic"] == "technical" or (
        ticket["topic"] == "billing" and ticket["length"] == "long"
    )
    return {"probabilities": {"small": 0.0 if large else 1.0, "large": 1.0 if large else 0.0}}

Değerlendiriciler:

evaluators:
  - {type: off_policy_value, reward_range: [0, 1], propensity_floor: 0.3}
  - {type: off_policy_improvement, reward_range: [0, 1], propensity_floor: 0.3}

Kaydedilen her karar, yeni kuralın onu eski yönlendiriciye göre ne kadar daha olası ya da daha az olası vereceğine göre yeniden ağırlıklandırılır: eski yönlendiricinin 0.3 olasılıkla büyük modele gönderdiği ve yeni kuralın her zaman oraya göndereceği bir talep 1 / 0.3 kez sayılır, yeni kuralın asla vermeyeceği bir karar ise sıfır kez sayılır. propensity_floor, eski yönlendiricinin seçebileceği herhangi bir modele verdiği en küçük olasılıktır. O ağırlığı sınırlar ve bir sınır olmadan hiçbir aralık geçerli olmaz.

Çalıştırın

oloproof run
│ resolution-floor    │ off_policy_value       │ PASS                  │ lower_bound_meets_minimum                                                          │
│ better-than-current │ off_policy_improvement │ INSUFFICIENT_EVIDENCE │ interval_overlaps_threshold                                                        │
│                     │                        │                       │ about 2633 more cases would decide it, if the observed values hold (3233 in total) │
│ off_policy_value       │ 0.775    │ [0.632, 0.921]  │ mean of 600 observed · 0 missing · 0 excluded │
│ off_policy_improvement │ 0.060    │ [-0.064, 0.188] │ mean of 600 observed · 0 missing · 0 excluded │

Yeni kural taleplerin tahminen %77.5'ini çözerdi ve %95 güvenle en az %63.2'sini: %60 tabanı geçer. Mevcut yönlendiriciyi geçip geçmediği ise karara bağlanmamıştır. Tahmin 6 puan daha iyidir, ancak aralık 6.4 puan daha kötüden 18.8 daha iyiye uzanır ve motor bunu kabaca kaç tane daha kaydedilmiş kararın karara bağlayacağını söyler.

Bu genişlik, başkasının seçimlerinden öğrenmenin bedelidir. Büyük model hakkında yalnızca eski yönlendiricinin tesadüfen büyük modele gönderdiği %30'luk talepler bir şey söyler ve her biri üç kattan fazla sayılır. Onu iki şey daraltır: daha uzun bir kayıt ve daha çok keşif yapan bir eski yönlendirici.

Kendi sisteminizden kararları kaydetmek

  • Olasılıkları sonradan değil, yönlendirici karar verirken kaydedin ve yalnızca seçilenin değil, her seçeneğin olasılığını kaydedin. Oloproof onları tahmin etmez: tahmin edilmiş bir olasılık aralığı o tahmine dayandırırdı.
  • input içine yalnızca yönlendiricinin karar verirken gördüğünü koyun, asla seçilen seçeneği ya da sonucu değil: test edilen politika onları görmemelidir.
  • Yeni politikanız seçimini örnekliyorsa, çektiği tek seçeneği değil, örneklediği olasılıkları döndürün. Her seçeneği tam olarak kaydın adlandırdığı gibi adlandırın: farklı yazılmış bir seçenek, eski yönlendiricinin hiç seçmediği bir seçenek sayılır.
  • Üretimdeki yönlendirmede biraz rastgelelik bırakın. Bir seçeneği hiç seçmeyen bir politika, onu seçecek bir kuralı değerlendirmek için kayıtta hiçbir şey bırakmaz.
  • Yanıt, kaydın kapsadığı dönemde, kaydedilenlere benzer talepleri anlatır. Trafiğinizdeki bir değişiklik onun dışındadır.
  • Bozuk biçimli bir satır (toplamı 1 olmayan olasılıklar, 0 olasılıkla seçilmiş bir seçenek, reward_range dışında bir ödül) çalıştırmayı durdurur. Yeni kuralın, eski yönlendiricinin tabandan daha az olasılık verdiği bir seçenekle vereceği ya da ödülü eksik olan bir karar eksik sayılır ve aralığı genişletir.

Neler yapılmadı

  • Her adımdaki seçimin sonra geleni değiştirdiği bir karar dizisinin politika dışı değerlendirmesi. Vaka başına yalnızca tek bir karar desteklenir.
  • Yönlendiricisi, kayıt süresi boyunca öğrenirken olasılıklarını değiştiren bir kayıt.
  • Ortamları, benzeticileri ya da robotları barındırmak veya sıfırlamak.

Sonra nereye