t27.aiEnglish

Выбрать наибольшее

Вы узнаете

Как argmax называет класс, сравнивая одни только биты, и какое правило решает ничью.

Запись ещё не готова: она ждёт команд tri test и tri mutate plant из gHashTag/t27#7400, которые запись запускает, а до тех пор виджет ниже -- заглушка без запуска. Классификатор в конце называет класс с наибольшей оценкой. gft_argmax4.t27 делает это без арифметики: gt ставит отрицательные ниже нуля, ноль ниже положительных, а затем сравнивает младшие 16 бит, растущие с величиной. По заголовку ничью выигрывает меньший индекс, сравнение строгое >. Браузер пропускает все 4 теста, потому что его исполнитель пока не знает assert_eq; нативный t27c запускает все 4, все проходят, ни один не пустой. Запись меняет > на >= для двух положительных оценок, и падает ровно один тест, tie_low: четыре оценки 1.0 теперь выбирают индекс 3, а не 0. Ни один тест не даёт решить ответ двум отрицательным оценкам: переворот их сравнения ничего не роняет. Каждый байт в записи напечатала команда; инсценирован только набор текста.

Попробуйте

Найдите в записи изменённую строку и упавший тест; затем найдите в спеке строку, которая сравнивает две отрицательные оценки, и тот один тест, который до неё доходит.

Открыть интерактивный урок →

gft_argmax4.t27: recording pending
gft_argmax4.t27: recording pending ↗

Recording pending: waits on tri test and tri mutate plant from gHashTag/t27#7400. Until then this page is a placeholder and shows no run.

specs/ternary/gft_argmax4.t27

module GftArgmax4;
// #1764 + GF-T: a classification head over four signed GF-T16 logits. Returns the
// INDEX {0,1,2,3} of the maximum real value (lowest index wins ties, strict >).
// This is the final stage of a GF-T classifier: a GF-T MLP (gft_mlp3) emits a
// vector of logits, argmax picks the predicted class. Comparison is exact on the
// real values -- no arithmetic, just a total order on the GF-T encoding.
//
// A signed GF-T16 value in u32 is [sign(bit16)][offset(7)][mant(9)]; the low 16
// bits (offset<<9 | mant) are MONOTONIC in the real magnitude, and raw 0 is the
// only zero. So the real order is: negatives < zero < positives; within positives
// larger magnitude bits = larger; within negatives larger magnitude bits = smaller.
//
// Inputs: x0..x3 signed GF-T16 (u32). Output: index u8 in {0,1,2,3}.

// sign category: zero->1, positive->2, negative->0 (higher category = greater).
fn category(a: u32) -> u8 {
    if (a == 0) { return 1; }
    if ((a >> 16) == 0) { return 2; }
    return 0;
}
// gt(a,b) = 1 iff real value(a) > value(b), else 0.
fn gt(a: u32, b: u32) -> u8 {
    var ca : u8 = category(a);
    var cb : u8 = category(b);
    if (ca != cb) { if (ca > cb) { return 1; } return 0; }
    var ma : u32 = a & 65535;
    var mb : u32 = b & 65535;
    if (ca == 2) { if (ma > mb) { return 1; } return 0; }   // both positive
    if (ca == 0) { if (ma < mb) { return 1; } return 0; }   // both negative
    return 0;                                               // both zero -> equal
}

// argmax over four logits, lowest index on ties.
fn on_comb(x0: u32, x1: u32, x2: u32, x3: u32) -> u8 {
    var idx : u8 = 0;
    var best : u32 = x0;
    if (gt(x1, best) == 1) { idx = 1; best = x1; }
    if (gt(x2, best) == 1) { idx = 2; best = x2; }
    if (gt(x3, best) == 1) { idx = 3; best = x3; }
    return idx;
}

// +1.0, -1.0, +2.0, 0 -> max is +2.0 at index 2.
test pick_pos { assert_eq(on_comb(20480, 86016, 20992, 0), 2); }
// -1.0, -2.0, 0, +1.0 -> max is +1.0 at index 3.
test pick_last { assert_eq(on_comb(86016, 86528, 0, 20480), 3); }
// -1.0, 0, -4.0, -2.0 -> max is 0 at index 1 (zero beats all negatives).
test zero_wins { assert_eq(on_comb(86016, 0, 87040, 86528), 1); }
// all equal (+1.0) -> lowest index 0.
test tie_low { assert_eq(on_comb(20480, 20480, 20480, 20480), 0); }
endmodule

Открыть спеку урока в плеере ↗

Все уроки