cse-frog

このページは GitHub の文書 から作っています。

cse API リファレンス 🐸

cse 0.2.0 の全機能の一覧です。説明はすべて、実際のコード(src/cse/__init__.py と src/cse/_engine.py)の動きに合わせています。


Frog

cse.Frog(**overrides)

🐸 を1匹つくります。設定を変えたいときは Frog(temperature=2.0) のように名前で渡します(全項目は設定の一覧)。

引数 型 説明
**overrides 設定名=値 変えたい設定だけを渡す。渡さなかった項目は既定値

戻り値: Frog

属性 | 名前 | 説明 | |---|---| | frog.config | 今の設定(CSEConfig)。frog.config.temperature のように読める |

メモ - 作っても、あなたのプログラムの乱数(random / numpy.random)の状態は変わりません。 - 同じ Frog を複数のスレッドから同時に使っても安全です(学習と予測は1つずつ順番に処理されます)。

from cse import Frog
frog = Frog()                          # 既定の設定
hot = Frog(temperature=2.0)            # 温度だけ変える
print(frog.config.refractory_steps)    # -> 0

学習と予測

learn

frog.learn(data, epochs=3) -> Frog

系列を覚えます。自分自身を返すので Frog().learn(...).predict(...) のようにつなげられます。

引数 型 既定 説明
data 下の3通り — 覚えさせる系列
epochs int 3 同じデータを何周くり返して覚えるか

data の渡し方(predict と同じ考え方): | 渡し方 | 例 | 意味 | |---|---|---| | 文字列1つ | "右右下右右下" | 1本の系列。1文字が1記号 | | リスト1つ | ["正常", "温度上昇", "停止"] | 1本の系列。1要素が1記号(「停止」は分かれない) | | リストのリスト | [["右", "右", "下"], ["正常", "停止"]] | 何本もの系列 |

predict

frog.predict(prefix=()) -> 記号 または END

prefix の次に一番来そうな記号を1つ返します。prefix を空にすると「最初の記号」を予測します。

top

frog.top(prefix=(), k=3) -> [(記号, 確率), ...]

確率の高い順に k 個返します。

probabilities

frog.probabilities(prefix=()) -> {記号: 確率}

次に来る記号の確率をすべて返します(確率が 0 の記号は含まれません)。合計は 1 です(<START>・<UNK> を除いて割り直しています)。

確率の作られ方: 点数(→scores)の上位 top_k_edges 個だけを、probability_mode(softmax なら温度 temperature)で確率に変えます。点数がプラスの候補が1つもないときは END が確率 1 になります。

frog = Frog().learn([["右", "右", "下"] * 5])
frog.predict(["右", "右"])          # -> '下'
frog.top(["右", "右"], k=2)         # -> [('下', 0.777...), ('右', 0.222...)]

generate

frog.generate(prefix=(), n=20, *, greedy=False, seed=None) -> 文字列 または [記号, ...]

prefix の続きを最大 n 個つくります。END が選ばれたらそこで止まります(END 自体は返しません)。

frog = Frog().learn([["右", "右", "下"]] * 3)
frog.generate(["右"], greedy=True)        # -> ['右', '下']
frog.generate(["右"], seed=1)             # くじ。seed が同じなら毎回同じ
Frog().learn("あいうえお").generate("あ", n=3, greedy=True)   # -> 'いうえ'

中身をのぞく

scores

frog.scores(prefix=()) -> {記号: 点数}

確率に変える前の生の点数を、高い順に返します(プラスのものだけ)。Top-p などのサンプラーを自分で作る材料になります。

explain

frog.explain(prefix=(), k=5) -> [dict, ...]

候補ごとに、点数が「どこから来たか」を返します(点数の高い順に k 個)。

キー 意味 0 になる条件
token 候補の記号 —
direct 今の記号からの直接のつながり(学習で強くなった結びつき) —
history 少し前に出た記号の活性の残り × history_boost history_boost=0(既定)
pair 直前2つの並びの記憶 × pair_context_boost 並びを覚えていない、pair_context_boost=0
trace ゆっくり残る文脈の痕跡 × context_projection_boost context_projection_boost=0(既定)
score 合計点(上の4つの和) 不応期で消されたとき
blocked 不応期で 0 にされたか —
prob 最終的な確率 上位 top_k_edges に入らないとき

保証: 内訳の合計がエンジン自身の点数とビット単位で一致することを、呼ぶたびに確認しています。ずれたら RuntimeError で止まります(説明が実際の計算とずれることはありません)。

show

frog.show(prefix=(), k=5) -> None

explain の結果を表で表示します。

Frog(refractory_steps=2).learn([["右", "右", "下"] * 5]).show(["右", "右", "下"])
# 🐸 ['右', '右', '下'] の次の候補
# 候補            直接      履歴      並び      痕跡      合計点      確率
# <END>      0.298   0.000   0.200   0.000    0.498   1.000
# 右          1.186   0.000   0.800   0.000    0.000   0.000  ← 不応期で消された

edges

frog.edges(token, k=10) -> [(記号, 強さ), ...]

その記号から出ている「直接のつながり」を、強い順に k 個返します(何を覚えたか)。


保存と読み込み

save

frog.save(path) -> None

覚えたことをファイルに保存します。中身は JSON と数値の配列だけの zip です(pickle は使いません。人の 🐸 を読み込んでも安全です)。

load

Frog.load(path) -> Frog

save したファイルから 🐸 を読み込みます。読み込んだ 🐸 は、予測も続きの学習も、保存する前とビット単位で同じになります。読み込みで、あなたの乱数の状態は変わりません。

frog.save("my_frog.cse")
frog = Frog.load("my_frog.cse")

END

cse.END

「ここで系列が終わる」を表す特別な目印です。表示は <END>。あなたの記号(文字列 "<END>" を含む)とはぶつかりません。

if frog.predict(prefix) is END:
    print("ここで終わりそう")

設定(Config)の一覧

Frog(設定名=値) で変えられます。「Frog の既定」は Frog() で作ったときの値、「エンジンの既定」はエンジン本体の値です(Frog は5項目だけ変えています)。

予測のしかた(点数 → 確率)

設定 Frog の既定 エンジンの既定 説明 LLM で似ているもの
probability_mode "softmax" "softmax" 点数を確率に変える方法。"softmax"(温度を使う)か "linear"(点数に比例) —
temperature 0.8 0.8 softmax の温度。低いほど自信満々(確率が 0 か 1 に張り付きやすい)、高いほど迷う temperature
top_k_edges 3 3 2つの役割: ① 確率にする候補を点数の上位 k 個に絞る ② 活性を広げるときに、各記号から強い順に k 本のつながりだけを使う Top-k(①の役割)
history_boost 0.0 0.35 少し前に出た記号の活性の残りを点数に足す強さ。上げると同じ記号が出やすくなる(研究では生成を崩す方向に効いた) (標準ではない)マイナスの presence_penalty、昔のキャッシュ言語モデル
refractory_steps 0 2 不応期。直前 n 個に出た記号の点数を 0 にする(完全に禁止) 繰り返しペナルティ(より極端)
max_consecutive_repeats 2 2 不応期の例外: 今の記号から自分自身へのつながりを覚えていれば、同じ記号をこの回数まで連続で許す —

文脈の記憶

設定 Frog の既定 エンジンの既定 説明 LLM で似ているもの
pair_context_capacity 2048 0 直前2つの並び(例: 「右右」)を何通り覚えるか。一杯になると、合計が一番弱い並びから忘れる。0 で無効 コンテキストの長さ(🐸 は2つだけ)
pair_context_boost 1.0 0.0 並びの記憶を点数に足す強さ(並びごとに合計 1 に揃えてから掛ける) —
context_trace_decay 0.0 0.0 文脈の痕跡が1記号ごとにどれだけ残るか(0 なら直前の1記号だけ) —
context_projection_boost 0.0 0.0 文脈の痕跡から、つながりをたどって点数に足す強さ。0 で無効 —

学習のしかた

設定 Frog の既定 エンジンの既定 説明
learning_rate 0.1 0.1 1回並んで出るごとに、つながりを強くする量
max_edge_weight 10.0 10.0 つながりの強さの上限(並びの記憶にも同じ上限)
weight_decay 0.9995 0.9995 学習の1ステップごとに、つながりに掛ける数(1.0 で忘れない)
weight_decay_scope "global" "global" 忘れる範囲。"global"(全部)か "active_rows"(今学習している記号の行だけ)
temporal_learning_window 1 1 何個前の記号まで「つながり」を学習するか(1 なら直前だけ)
direct_learning_window 2 2 何個前までを「直接のつながり」に入れるか。これより遠いものは文脈のつながり(context_projection_boost で使う)に入る
temporal_learning_decay 0.5 0.5 遠い記号ほど学習を弱める割合(1個遠くなるごとに掛ける)
normalize_direct_scores False False 直接のつながりの点数を、合計 1 に揃えてから使うか

活性の動き

設定 Frog の既定 エンジンの既定 説明
activation_decay 0.6 0.6 1ステップごとに、活性に掛ける数(残り方)
threshold 0.05 0.05 活性がこれ以上の記号だけが、つながりの先へ活性を広げる
activation_cap 0.0 0.0 活性の上限。0 なら数値があふれない安全な上限を自動で使う

その他

設定 Frog の既定 エンジンの既定 説明
max_nodes 256 50 覚えられる記号の数の上限 + 3(<START>・<END>・<UNK> の分)。メモリは max_nodes の2乗で増える
seed 42 42 エンジンが作られるときに乱数に使う値。Frog の予測・学習は乱数を使わないので、結果には影響しない

エラーの一覧

場面 例外 メッセージ(例)
知らない設定名を渡した ValueError 知らない設定の名前です: [...]。使える名前: [...]
覚えていない記号で予測した ValueError 「ワープ」はまだ覚えていない記号です。learn() で覚えさせてから使ってください。
記号の数が上限をこえた ValueError 覚えられる記号の数(253)をこえました。Frog(max_nodes=…) で大きくしてください。
learn にリストとそれ以外をまぜた ValueError リストの中に、リストとそれ以外がまざっています。…
保存できない種類の記号がある ValueError 保存できない種類の記号があります: [...]
cse の 🐸 ファイルではない ValueError cse の 🐸 ファイルではないか、形式が違います
explain の内訳がエンジンとずれた RuntimeError 内訳の再計算がエンジンの点数と一致しませんでした(cse のバグです。報告してください)