mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-24 05:37:13 +00:00
Merged the training data generator and the machine learning logic from YaneuraOu.
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
#ifndef _EVALUATE_COMMON_H_
|
||||
#define _EVALUATE_COMMON_H_
|
||||
|
||||
// いまどきの手番つき評価関数(EVAL_KPPTとEVAL_KPP_KKPT)の共用header的なもの。
|
||||
|
||||
#if defined (EVAL_KPPT) || defined(EVAL_KPP_KKPT) || defined(EVAL_NNUE)
|
||||
#include <functional>
|
||||
|
||||
// KKファイル名
|
||||
#define KK_BIN "KK_synthesized.bin"
|
||||
|
||||
// KKPファイル名
|
||||
#define KKP_BIN "KKP_synthesized.bin"
|
||||
|
||||
// KPPファイル名
|
||||
#define KPP_BIN "KPP_synthesized.bin"
|
||||
|
||||
namespace Eval
|
||||
{
|
||||
|
||||
#if defined(USE_EVAL_HASH)
|
||||
// prefetchする関数
|
||||
void prefetch_evalhash(const Key key);
|
||||
#endif
|
||||
|
||||
// 評価関数のそれぞれのパラメーターに対して関数fを適用してくれるoperator。
|
||||
// パラメーターの分析などに用いる。
|
||||
// typeは調査対象を表す。
|
||||
// type = -1 : KK,KKP,KPPすべて
|
||||
// type = 0 : KK のみ
|
||||
// type = 1 : KKPのみ
|
||||
// type = 2 : KPPのみ
|
||||
void foreach_eval_param(std::function<void(int32_t, int32_t)>f, int type = -1);
|
||||
|
||||
// --------------------------
|
||||
// 学習用
|
||||
// --------------------------
|
||||
|
||||
#if defined(EVAL_LEARN)
|
||||
// 学習のときの勾配配列の初期化
|
||||
// 学習率を引数に渡しておく。0.0なら、defaultの値を採用する。
|
||||
// update_weights()のepochが、eta_epochまでetaから徐々にeta2に変化する。
|
||||
// eta2_epoch以降は、eta2から徐々にeta3に変化する。
|
||||
void init_grad(double eta1, uint64_t eta_epoch, double eta2, uint64_t eta2_epoch, double eta3);
|
||||
|
||||
// 現在の局面で出現している特徴すべてに対して、勾配の差分値を勾配配列に加算する。
|
||||
// freeze[0] : kkは学習させないフラグ
|
||||
// freeze[1] : kkpは学習させないフラグ
|
||||
// freeze[2] : kppは学習させないフラグ
|
||||
// freeze[3] : kpppは学習させないフラグ
|
||||
void add_grad(Position& pos, Color rootColor, double delt_grad, const std::array<bool, 4>& freeze);
|
||||
|
||||
// 現在の勾配をもとにSGDかAdaGradか何かする。
|
||||
// epoch : 世代カウンター(0から始まる)
|
||||
// freeze[0] : kkは学習させないフラグ
|
||||
// freeze[1] : kkpは学習させないフラグ
|
||||
// freeze[2] : kppは学習させないフラグ
|
||||
// freeze[3] : kpppは学習させないフラグ
|
||||
void update_weights(uint64_t epoch, const std::array<bool,4>& freeze);
|
||||
|
||||
// 評価関数パラメーターをファイルに保存する。
|
||||
// ファイルの末尾につける拡張子を指定できる。
|
||||
void save_eval(std::string suffix);
|
||||
|
||||
// 現在のetaを取得する。
|
||||
double get_eta();
|
||||
|
||||
// -- 学習に関連したコマンド
|
||||
|
||||
// KKを正規化する関数。元の評価関数と完全に等価にはならないので注意。
|
||||
// kkp,kppの値をなるべくゼロに近づけることで、学習中に出現しなかった特徴因子の値(ゼロになっている)が
|
||||
// 妥当であることを保証しようという考え。
|
||||
void regularize_kk();
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _EVALUATE_KPPT_COMMON_H_
|
||||
@@ -0,0 +1,186 @@
|
||||
#include "evaluate_mir_inv_tools.h"
|
||||
|
||||
namespace Eval
|
||||
{
|
||||
|
||||
// --- tables
|
||||
|
||||
// あるBonaPieceを相手側から見たときの値
|
||||
// BONA_PIECE_INITが-1なので符号型で持つ必要がある。
|
||||
// KPPTを拡張しても当面、BonaPieceが2^15を超えることはないのでint16_tで良しとする。
|
||||
int16_t inv_piece_[Eval::fe_end];
|
||||
|
||||
// 盤面上のあるBonaPieceをミラーした位置にあるものを返す。
|
||||
int16_t mir_piece_[Eval::fe_end];
|
||||
|
||||
|
||||
// --- methods
|
||||
|
||||
// あるBonaPieceを相手側から見たときの値を返す
|
||||
Eval::BonaPiece inv_piece(Eval::BonaPiece p) { return (Eval::BonaPiece)inv_piece_[p]; }
|
||||
|
||||
// 盤面上のあるBonaPieceをミラーした位置にあるものを返す。
|
||||
Eval::BonaPiece mir_piece(Eval::BonaPiece p) { return (Eval::BonaPiece)mir_piece_[p]; }
|
||||
|
||||
std::function<void()> mir_piece_init_function;
|
||||
|
||||
void init_mir_inv_tables()
|
||||
{
|
||||
// mirrorとinverseのテーブルの初期化。
|
||||
|
||||
// 初期化は1回に限る。
|
||||
static bool first = true;
|
||||
if (!first) return;
|
||||
first = false;
|
||||
|
||||
// fとeとの交換
|
||||
int t[] = {
|
||||
f_pawn , e_pawn ,
|
||||
f_knight , e_knight ,
|
||||
f_bishop , e_bishop ,
|
||||
f_rook , e_rook ,
|
||||
f_queen , e_queen ,
|
||||
};
|
||||
|
||||
// 未初期化の値を突っ込んでおく。
|
||||
for (BonaPiece p = BONA_PIECE_ZERO; p < fe_end; ++p)
|
||||
{
|
||||
inv_piece_[p] = BONA_PIECE_NOT_INIT;
|
||||
|
||||
// mirrorは手駒に対しては機能しない。元の値を返すだけ。
|
||||
mir_piece_[p] = (p < f_pawn) ? p : BONA_PIECE_NOT_INIT;
|
||||
}
|
||||
|
||||
for (BonaPiece p = BONA_PIECE_ZERO; p < fe_end; ++p)
|
||||
{
|
||||
for (int i = 0; i < 32 /* t.size() */; i += 2)
|
||||
{
|
||||
if (t[i] <= p && p < t[i + 1])
|
||||
{
|
||||
Square sq = (Square)(p - t[i]);
|
||||
|
||||
// 見つかった!!
|
||||
BonaPiece q = (p < fe_hand_end) ? BonaPiece(sq + t[i + 1]) : (BonaPiece)(Inv(sq) + t[i + 1]);
|
||||
inv_piece_[p] = q;
|
||||
inv_piece_[q] = p;
|
||||
|
||||
/*
|
||||
ちょっとトリッキーだが、pに関して盤上の駒は
|
||||
p >= fe_hand_end
|
||||
のとき。
|
||||
|
||||
このpに対して、nを整数として(上のコードのiは偶数しかとらない)、
|
||||
a) t[2n + 0] <= p < t[2n + 1] のときは先手の駒
|
||||
b) t[2n + 1] <= p < t[2n + 2] のときは後手の駒
|
||||
である。
|
||||
|
||||
ゆえに、a)の範囲にあるpをq = Inv(p-t[2n+0]) + t[2n+1] とすると180度回転させた升にある後手の駒となる。
|
||||
そこでpとqをswapさせてinv_piece[ ]を初期化してある。
|
||||
*/
|
||||
|
||||
// 手駒に関してはmirrorなど存在しない。
|
||||
if (p < fe_hand_end)
|
||||
continue;
|
||||
|
||||
BonaPiece r1 = (BonaPiece)(Mir(sq) + t[i]);
|
||||
mir_piece_[p] = r1;
|
||||
mir_piece_[r1] = p;
|
||||
|
||||
BonaPiece p2 = (BonaPiece)(sq + t[i + 1]);
|
||||
BonaPiece r2 = (BonaPiece)(Mir(sq) + t[i + 1]);
|
||||
mir_piece_[p2] = r2;
|
||||
mir_piece_[r2] = p2;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mir_piece_init_function)
|
||||
mir_piece_init_function();
|
||||
|
||||
for (BonaPiece p = BONA_PIECE_ZERO; p < fe_end; ++p)
|
||||
{
|
||||
// 未初期化のままになっている。上のテーブルの初期化コードがおかしい。
|
||||
assert(mir_piece_[p] != BONA_PIECE_NOT_INIT && mir_piece_[p] < fe_end);
|
||||
assert(inv_piece_[p] != BONA_PIECE_NOT_INIT && inv_piece_[p] < fe_end);
|
||||
|
||||
// mirとinvは、2回適用したら元の座標に戻る。
|
||||
assert(mir_piece_[mir_piece_[p]] == p);
|
||||
assert(inv_piece_[inv_piece_[p]] == p);
|
||||
|
||||
// mir->inv->mir->invは元の場所でなければならない。
|
||||
assert(p == inv_piece(mir_piece(inv_piece(mir_piece(p)))));
|
||||
|
||||
// inv->mir->inv->mirは元の場所でなければならない。
|
||||
assert(p == mir_piece(inv_piece(mir_piece(inv_piece(p)))));
|
||||
}
|
||||
|
||||
#if 0
|
||||
// 評価関数のミラーをしても大丈夫であるかの事前検証
|
||||
// 値を書き込んだときにassertionがあるので、ミラーしてダメである場合、
|
||||
// そのassertに引っかかるはず。
|
||||
|
||||
// AperyのWCSC26の評価関数、kppのp1==0とかp1==20(後手の0枚目の歩)とかの
|
||||
// ところにゴミが入っていて、これを回避しないとassertに引っかかる。
|
||||
|
||||
std::unordered_set<BonaPiece> s;
|
||||
vector<int> a = {
|
||||
f_hand_pawn - 1,e_hand_pawn - 1,
|
||||
f_hand_lance - 1, e_hand_lance - 1,
|
||||
f_hand_knight - 1, e_hand_knight - 1,
|
||||
f_hand_silver - 1, e_hand_silver - 1,
|
||||
f_hand_gold - 1, e_hand_gold - 1,
|
||||
f_hand_bishop - 1, e_hand_bishop - 1,
|
||||
f_hand_rook - 1, e_hand_rook - 1,
|
||||
};
|
||||
for (auto b : a)
|
||||
s.insert((BonaPiece)b);
|
||||
|
||||
// さらに出現しない升の盤上の歩、香、桂も除外(Aperyはここにもゴミが入っている)
|
||||
for (Rank r = RANK_1; r <= RANK_2; ++r)
|
||||
for (File f = FILE_1; f <= FILE_9; ++f)
|
||||
{
|
||||
if (r == RANK_1)
|
||||
{
|
||||
// 1段目の歩
|
||||
BonaPiece b1 = BonaPiece(f_pawn + (f | r));
|
||||
s.insert(b1);
|
||||
s.insert(inv_piece[b1]);
|
||||
|
||||
// 1段目の香
|
||||
BonaPiece b2 = BonaPiece(f_lance + (f | r));
|
||||
s.insert(b2);
|
||||
s.insert(inv_piece[b2]);
|
||||
}
|
||||
|
||||
// 1,2段目の桂
|
||||
BonaPiece b = BonaPiece(f_knight + (f | r));
|
||||
s.insert(b);
|
||||
s.insert(inv_piece[b]);
|
||||
}
|
||||
|
||||
cout << "\nchecking kpp_write()..";
|
||||
for (auto sq : SQ)
|
||||
{
|
||||
cout << sq << ' ';
|
||||
for (BonaPiece p1 = BONA_PIECE_ZERO; p1 < fe_end; ++p1)
|
||||
for (BonaPiece p2 = BONA_PIECE_ZERO; p2 < fe_end; ++p2)
|
||||
if (!s.count(p1) && !s.count(p2))
|
||||
kpp_write(sq, p1, p2, kpp[sq][p1][p2]);
|
||||
}
|
||||
cout << "\nchecking kkp_write()..";
|
||||
|
||||
for (auto sq1 : SQ)
|
||||
{
|
||||
cout << sq1 << ' ';
|
||||
for (auto sq2 : SQ)
|
||||
for (BonaPiece p1 = BONA_PIECE_ZERO; p1 < fe_end; ++p1)
|
||||
if (!s.count(p1))
|
||||
kkp_write(sq1, sq2, p1, kkp[sq1][sq2][p1]);
|
||||
}
|
||||
cout << "..done!" << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef _EVALUATE_MIR_INV_TOOLS_
|
||||
#define _EVALUATE_MIR_INV_TOOLS_
|
||||
|
||||
// BonaPieceのmirror(左右反転)やinverse(盤上の180度回転)させた駒を得るためのツール類。
|
||||
|
||||
#include "../types.h"
|
||||
#include "../evaluate.h"
|
||||
#include <functional>
|
||||
|
||||
namespace Eval
|
||||
{
|
||||
// -------------------------------------------------
|
||||
// tables
|
||||
// -------------------------------------------------
|
||||
|
||||
// --- BonaPieceに対してMirrorとInverseを提供する。
|
||||
|
||||
// これらの配列は、init()かinit_mir_inv_tables();を呼び出すと初期化される。
|
||||
// このテーブルのみを評価関数のほうから使いたいときは、評価関数の初期化のときに
|
||||
// init_mir_inv_tables()を呼び出すと良い。
|
||||
// これらの配列は、以下のKK/KKP/KPPクラスから参照される。
|
||||
|
||||
// あるBonaPieceを相手側から見たときの値を返す
|
||||
extern Eval::BonaPiece inv_piece(Eval::BonaPiece p);
|
||||
|
||||
// 盤面上のあるBonaPieceをミラーした位置にあるものを返す。
|
||||
extern Eval::BonaPiece mir_piece(Eval::BonaPiece p);
|
||||
|
||||
|
||||
// mir_piece/inv_pieceの初期化のときに呼び出されるcallback
|
||||
// fe_endをユーザー側で拡張するときに用いる。
|
||||
// この初期化のときに必要なのでinv_piece_とinv_piece_を公開している。
|
||||
// mir_piece_init_functionが呼び出されたタイミングで、fe_old_endまでは
|
||||
// これらのテーブルの初期化が完了していることが保証されている。
|
||||
extern std::function<void()> mir_piece_init_function;
|
||||
extern int16_t mir_piece_[Eval::fe_end];
|
||||
extern int16_t inv_piece_[Eval::fe_end];
|
||||
|
||||
// この関数を明示的に呼び出すか、init()を呼び出すかしたときに、上のテーブルが初期化される。
|
||||
extern void init_mir_inv_tables();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -224,8 +224,8 @@ EvaluateHashTable g_evalTable;
|
||||
|
||||
// prefetchする関数も用意しておく。
|
||||
void prefetch_evalhash(const Key key) {
|
||||
constexpr auto mask = ~((u64)0x1f);
|
||||
prefetch((void*)((u64)g_evalTable[key] & mask));
|
||||
constexpr auto mask = ~((uint64_t)0x1f);
|
||||
prefetch((void*)((uint64_t)g_evalTable[key] & mask));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -269,7 +269,7 @@ Value compute_eval(const Position& pos) {
|
||||
}
|
||||
|
||||
// 評価関数
|
||||
Value NNUE::evaluate(const Position& pos) {
|
||||
Value evaluate(const Position& pos) {
|
||||
const auto& accumulator = pos.state()->accumulator;
|
||||
if (accumulator.computed_score) {
|
||||
return accumulator.score;
|
||||
|
||||
@@ -55,8 +55,6 @@ bool ReadParameters(std::istream& stream);
|
||||
// 評価関数パラメータを書き込む
|
||||
bool WriteParameters(std::ostream& stream);
|
||||
|
||||
Value evaluate(const Position& pos);
|
||||
|
||||
} // namespace NNUE
|
||||
|
||||
} // namespace Eval
|
||||
|
||||
@@ -9,8 +9,9 @@
|
||||
#include "../../learn/learning_tools.h"
|
||||
|
||||
#include "../../position.h"
|
||||
#include "../../usi.h"
|
||||
#include "../../uci.h"
|
||||
#include "../../misc.h"
|
||||
#include "../../thread_win32_osx.h"
|
||||
|
||||
#include "../evaluate_common.h"
|
||||
|
||||
@@ -37,7 +38,7 @@ std::vector<Example> examples;
|
||||
Mutex examples_mutex;
|
||||
|
||||
// ミニバッチのサンプル数
|
||||
u64 batch_size;
|
||||
uint64_t batch_size;
|
||||
|
||||
// 乱数生成器
|
||||
std::mt19937 rng;
|
||||
@@ -57,20 +58,20 @@ double GetGlobalLearningRateScale() {
|
||||
void SendMessages(std::vector<Message> messages) {
|
||||
for (auto& message : messages) {
|
||||
trainer->SendMessage(&message);
|
||||
ASSERT_LV3(message.num_receivers > 0);
|
||||
assert(message.num_receivers > 0);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// 学習の初期化を行う
|
||||
void InitializeTraining(double eta1, u64 eta1_epoch,
|
||||
double eta2, u64 eta2_epoch, double eta3) {
|
||||
void InitializeTraining(double eta1, uint64_t eta1_epoch,
|
||||
double eta2, uint64_t eta2_epoch, double eta3) {
|
||||
std::cout << "Initializing NN training for "
|
||||
<< GetArchitectureString() << std::endl;
|
||||
|
||||
ASSERT(feature_transformer);
|
||||
ASSERT(network);
|
||||
assert(feature_transformer);
|
||||
assert(network);
|
||||
trainer = Trainer<Network>::Create(network.get(), feature_transformer.get());
|
||||
|
||||
if (Options["SkipLoadingEval"]) {
|
||||
@@ -82,8 +83,8 @@ void InitializeTraining(double eta1, u64 eta1_epoch,
|
||||
}
|
||||
|
||||
// ミニバッチのサンプル数を設定する
|
||||
void SetBatchSize(u64 size) {
|
||||
ASSERT_LV3(size > 0);
|
||||
void SetBatchSize(uint64_t size) {
|
||||
assert(size > 0);
|
||||
batch_size = size;
|
||||
}
|
||||
|
||||
@@ -97,7 +98,7 @@ void SetOptions(const std::string& options) {
|
||||
std::vector<Message> messages;
|
||||
for (const auto& option : Split(options, ',')) {
|
||||
const auto fields = Split(option, '=');
|
||||
ASSERT_LV3(fields.size() == 1 || fields.size() == 2);
|
||||
assert(fields.size() == 1 || fields.size() == 2);
|
||||
if (fields.size() == 1) {
|
||||
messages.emplace_back(fields[0]);
|
||||
} else {
|
||||
@@ -112,7 +113,7 @@ void RestoreParameters(const std::string& dir_name) {
|
||||
const std::string file_name = Path::Combine(dir_name, NNUE::kFileName);
|
||||
std::ifstream stream(file_name, std::ios::binary);
|
||||
bool result = ReadParameters(stream);
|
||||
ASSERT(result);
|
||||
assert(result);
|
||||
|
||||
SendMessages({{"reset"}});
|
||||
}
|
||||
@@ -136,7 +137,7 @@ void AddExample(Position& pos, Color rootColor,
|
||||
if (pos.side_to_move() != BLACK) {
|
||||
active_indices[0].swap(active_indices[1]);
|
||||
}
|
||||
for (const auto color : COLOR) {
|
||||
for (const auto color : Colors) {
|
||||
std::vector<TrainingFeature> training_features;
|
||||
for (const auto base_index : active_indices[color]) {
|
||||
static_assert(Features::Factorizer<RawFeatures>::GetDimensions() <
|
||||
@@ -162,8 +163,8 @@ void AddExample(Position& pos, Color rootColor,
|
||||
}
|
||||
|
||||
// 評価関数パラメーターを更新する
|
||||
void UpdateParameters(u64 epoch) {
|
||||
ASSERT_LV3(batch_size > 0);
|
||||
void UpdateParameters(uint64_t epoch) {
|
||||
assert(batch_size > 0);
|
||||
|
||||
EvalLearningTools::Weight::calc_eta(epoch);
|
||||
const auto learning_rate = static_cast<LearnFloatType>(
|
||||
@@ -215,7 +216,7 @@ void save_eval(std::string dir_name) {
|
||||
const std::string file_name = Path::Combine(eval_dir, NNUE::kFileName);
|
||||
std::ofstream stream(file_name, std::ios::binary);
|
||||
const bool result = NNUE::WriteParameters(stream);
|
||||
ASSERT(result);
|
||||
assert(result);
|
||||
|
||||
std::cout << "save_eval() finished. folder = " << eval_dir << std::endl;
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#ifndef _EVALUATE_NNUE_LEARNER_H_
|
||||
#define _EVALUATE_NNUE_LEARNER_H_
|
||||
|
||||
#include "../../config.h"
|
||||
|
||||
#if defined(EVAL_LEARN) && defined(EVAL_NNUE)
|
||||
|
||||
#include "../../learn/learn.h"
|
||||
@@ -14,11 +12,11 @@ namespace Eval {
|
||||
namespace NNUE {
|
||||
|
||||
// 学習の初期化を行う
|
||||
void InitializeTraining(double eta1, u64 eta1_epoch,
|
||||
double eta2, u64 eta2_epoch, double eta3);
|
||||
void InitializeTraining(double eta1, uint64_t eta1_epoch,
|
||||
double eta2, uint64_t eta2_epoch, double eta3);
|
||||
|
||||
// ミニバッチのサンプル数を設定する
|
||||
void SetBatchSize(u64 size);
|
||||
void SetBatchSize(uint64_t size);
|
||||
|
||||
// 学習率のスケールを設定する
|
||||
void SetGlobalLearningRateScale(double scale);
|
||||
@@ -34,7 +32,7 @@ void AddExample(Position& pos, Color rootColor,
|
||||
const Learner::PackedSfenValue& psv, double weight);
|
||||
|
||||
// 評価関数パラメータを更新する
|
||||
void UpdateParameters(u64 epoch);
|
||||
void UpdateParameters(uint64_t epoch);
|
||||
|
||||
// 学習に問題が生じていないかチェックする
|
||||
void CheckHealth();
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#ifndef _NNUE_LAYERS_SUM_H_
|
||||
#define _NNUE_LAYERS_SUM_H_
|
||||
|
||||
#include "../../../config.h"
|
||||
|
||||
#if defined(EVAL_NNUE)
|
||||
|
||||
#include "../nnue_common.h"
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#ifndef _NNUE_TRAINER_FEATURES_FACTORIZER_H_
|
||||
#define _NNUE_TRAINER_FEATURES_FACTORIZER_H_
|
||||
|
||||
#include "../../../../config.h"
|
||||
|
||||
#if defined(EVAL_NNUE)
|
||||
|
||||
#include "../../nnue_common.h"
|
||||
@@ -29,7 +27,7 @@ class Factorizer {
|
||||
// 学習用特徴量のインデックスと学習率のスケールを取得する
|
||||
static void AppendTrainingFeatures(
|
||||
IndexType base_index, std::vector<TrainingFeature>* training_features) {
|
||||
ASSERT_LV5(base_index < FeatureType::kDimensions);
|
||||
assert(base_index < FeatureType::kDimensions);
|
||||
training_features->emplace_back(base_index);
|
||||
}
|
||||
};
|
||||
@@ -45,8 +43,8 @@ template <typename FeatureType>
|
||||
IndexType AppendBaseFeature(
|
||||
FeatureProperties properties, IndexType base_index,
|
||||
std::vector<TrainingFeature>* training_features) {
|
||||
ASSERT_LV5(properties.dimensions == FeatureType::kDimensions);
|
||||
ASSERT_LV5(base_index < FeatureType::kDimensions);
|
||||
assert(properties.dimensions == FeatureType::kDimensions);
|
||||
assert(base_index < FeatureType::kDimensions);
|
||||
training_features->emplace_back(base_index);
|
||||
return properties.dimensions;
|
||||
}
|
||||
@@ -59,14 +57,14 @@ IndexType InheritFeaturesIfRequired(
|
||||
if (!properties.active) {
|
||||
return 0;
|
||||
}
|
||||
ASSERT_LV5(properties.dimensions == Factorizer<FeatureType>::GetDimensions());
|
||||
ASSERT_LV5(base_index < FeatureType::kDimensions);
|
||||
assert(properties.dimensions == Factorizer<FeatureType>::GetDimensions());
|
||||
assert(base_index < FeatureType::kDimensions);
|
||||
const auto start = training_features->size();
|
||||
Factorizer<FeatureType>::AppendTrainingFeatures(
|
||||
base_index, training_features);
|
||||
for (auto i = start; i < training_features->size(); ++i) {
|
||||
auto& feature = (*training_features)[i];
|
||||
ASSERT_LV5(feature.GetIndex() < Factorizer<FeatureType>::GetDimensions());
|
||||
assert(feature.GetIndex() < Factorizer<FeatureType>::GetDimensions());
|
||||
feature.ShiftIndex(index_offset);
|
||||
}
|
||||
return properties.dimensions;
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#ifndef _NNUE_TRAINER_FEATURES_FACTORIZER_FEATURE_SET_H_
|
||||
#define _NNUE_TRAINER_FEATURES_FACTORIZER_FEATURE_SET_H_
|
||||
|
||||
#include "../../../../config.h"
|
||||
|
||||
#if defined(EVAL_NNUE)
|
||||
|
||||
#include "../../features/feature_set.h"
|
||||
@@ -38,7 +36,7 @@ class Factorizer<FeatureSet<FirstFeatureType, RemainingFeatureTypes...>> {
|
||||
static void AppendTrainingFeatures(
|
||||
IndexType base_index, std::vector<TrainingFeature>* training_features,
|
||||
IndexType base_dimensions = kBaseDimensions) {
|
||||
ASSERT_LV5(base_index < kBaseDimensions);
|
||||
assert(base_index < kBaseDimensions);
|
||||
constexpr auto boundary = FeatureSet<RemainingFeatureTypes...>::kDimensions;
|
||||
if (base_index < boundary) {
|
||||
Tail::AppendTrainingFeatures(
|
||||
@@ -50,7 +48,7 @@ class Factorizer<FeatureSet<FirstFeatureType, RemainingFeatureTypes...>> {
|
||||
for (auto i = start; i < training_features->size(); ++i) {
|
||||
auto& feature = (*training_features)[i];
|
||||
const auto index = feature.GetIndex();
|
||||
ASSERT_LV5(index < Head::GetDimensions() ||
|
||||
assert(index < Head::GetDimensions() ||
|
||||
(index >= base_dimensions &&
|
||||
index < base_dimensions +
|
||||
Head::GetDimensions() - Head::kBaseDimensions));
|
||||
@@ -81,13 +79,13 @@ public:
|
||||
static void AppendTrainingFeatures(
|
||||
IndexType base_index, std::vector<TrainingFeature>* training_features,
|
||||
IndexType base_dimensions = kBaseDimensions) {
|
||||
ASSERT_LV5(base_index < kBaseDimensions);
|
||||
assert(base_index < kBaseDimensions);
|
||||
const auto start = training_features->size();
|
||||
Factorizer<FeatureType>::AppendTrainingFeatures(
|
||||
base_index, training_features);
|
||||
for (auto i = start; i < training_features->size(); ++i) {
|
||||
auto& feature = (*training_features)[i];
|
||||
ASSERT_LV5(feature.GetIndex() < Factorizer<FeatureType>::GetDimensions());
|
||||
assert(feature.GetIndex() < Factorizer<FeatureType>::GetDimensions());
|
||||
if (feature.GetIndex() >= kBaseDimensions) {
|
||||
feature.ShiftIndex(base_dimensions - kBaseDimensions);
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#ifndef _NNUE_TRAINER_FEATURES_FACTORIZER_HALF_KP_H_
|
||||
#define _NNUE_TRAINER_FEATURES_FACTORIZER_HALF_KP_H_
|
||||
|
||||
#include "../../../../config.h"
|
||||
|
||||
#if defined(EVAL_NNUE)
|
||||
|
||||
#include "../../features/half_kp.h"
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#ifndef _NNUE_TRAINER_H_
|
||||
#define _NNUE_TRAINER_H_
|
||||
|
||||
#include "../../../config.h"
|
||||
|
||||
#if defined(EVAL_LEARN) && defined(EVAL_NNUE)
|
||||
|
||||
#include "../nnue_common.h"
|
||||
@@ -36,11 +34,11 @@ class TrainingFeature {
|
||||
|
||||
explicit TrainingFeature(IndexType index) :
|
||||
index_and_count_((index << kCountBits) | 1) {
|
||||
ASSERT_LV3(index < (1 << kIndexBits));
|
||||
assert(index < (1 << kIndexBits));
|
||||
}
|
||||
TrainingFeature& operator+=(const TrainingFeature& other) {
|
||||
ASSERT_LV3(other.GetIndex() == GetIndex());
|
||||
ASSERT_LV3(other.GetCount() + GetCount() < (1 << kCountBits));
|
||||
assert(other.GetIndex() == GetIndex());
|
||||
assert(other.GetCount() + GetCount() < (1 << kCountBits));
|
||||
index_and_count_ += other.GetCount();
|
||||
return *this;
|
||||
}
|
||||
@@ -48,7 +46,7 @@ class TrainingFeature {
|
||||
return static_cast<IndexType>(index_and_count_ >> kCountBits);
|
||||
}
|
||||
void ShiftIndex(IndexType offset) {
|
||||
ASSERT_LV3(GetIndex() + offset < (1 << kIndexBits));
|
||||
assert(GetIndex() + offset < (1 << kIndexBits));
|
||||
index_and_count_ += offset << kCountBits;
|
||||
}
|
||||
IndexType GetCount() const {
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#ifndef _NNUE_TRAINER_AFFINE_TRANSFORM_H_
|
||||
#define _NNUE_TRAINER_AFFINE_TRANSFORM_H_
|
||||
|
||||
#include "../../../config.h"
|
||||
|
||||
#if defined(EVAL_LEARN) && defined(EVAL_NNUE)
|
||||
|
||||
#include "../../../learn/learn.h"
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#ifndef _NNUE_TRAINER_CLIPPED_RELU_H_
|
||||
#define _NNUE_TRAINER_CLIPPED_RELU_H_
|
||||
|
||||
#include "../../../config.h"
|
||||
|
||||
#if defined(EVAL_LEARN) && defined(EVAL_NNUE)
|
||||
|
||||
#include "../../../learn/learn.h"
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#ifndef _NNUE_TRAINER_FEATURE_TRANSFORMER_H_
|
||||
#define _NNUE_TRAINER_FEATURE_TRANSFORMER_H_
|
||||
|
||||
#include "../../../config.h"
|
||||
|
||||
#if defined(EVAL_LEARN) && defined(EVAL_NNUE)
|
||||
|
||||
#include "../../../learn/learn.h"
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#ifndef _NNUE_TRAINER_INPUT_SLICE_H_
|
||||
#define _NNUE_TRAINER_INPUT_SLICE_H_
|
||||
|
||||
#include "../../../config.h"
|
||||
|
||||
#if defined(EVAL_LEARN) && defined(EVAL_NNUE)
|
||||
|
||||
#include "../../../learn/learn.h"
|
||||
@@ -35,7 +33,7 @@ class SharedInputTrainer {
|
||||
current_operation_ = Operation::kSendMessage;
|
||||
feature_transformer_trainer_->SendMessage(message);
|
||||
}
|
||||
ASSERT_LV3(current_operation_ == Operation::kSendMessage);
|
||||
assert(current_operation_ == Operation::kSendMessage);
|
||||
if (++num_calls_ == num_referrers_) {
|
||||
num_calls_ = 0;
|
||||
current_operation_ = Operation::kNone;
|
||||
@@ -49,7 +47,7 @@ class SharedInputTrainer {
|
||||
current_operation_ = Operation::kInitialize;
|
||||
feature_transformer_trainer_->Initialize(rng);
|
||||
}
|
||||
ASSERT_LV3(current_operation_ == Operation::kInitialize);
|
||||
assert(current_operation_ == Operation::kInitialize);
|
||||
if (++num_calls_ == num_referrers_) {
|
||||
num_calls_ = 0;
|
||||
current_operation_ = Operation::kNone;
|
||||
@@ -66,7 +64,7 @@ class SharedInputTrainer {
|
||||
current_operation_ = Operation::kPropagate;
|
||||
output_ = feature_transformer_trainer_->Propagate(batch);
|
||||
}
|
||||
ASSERT_LV3(current_operation_ == Operation::kPropagate);
|
||||
assert(current_operation_ == Operation::kPropagate);
|
||||
if (++num_calls_ == num_referrers_) {
|
||||
num_calls_ = 0;
|
||||
current_operation_ = Operation::kNone;
|
||||
@@ -90,7 +88,7 @@ class SharedInputTrainer {
|
||||
}
|
||||
}
|
||||
}
|
||||
ASSERT_LV3(current_operation_ == Operation::kBackPropagate);
|
||||
assert(current_operation_ == Operation::kBackPropagate);
|
||||
for (IndexType b = 0; b < batch_size_; ++b) {
|
||||
const IndexType batch_offset = kInputDimensions * b;
|
||||
for (IndexType i = 0; i < kInputDimensions; ++i) {
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#ifndef _NNUE_TRAINER_SUM_H_
|
||||
#define _NNUE_TRAINER_SUM_H_
|
||||
|
||||
#include "../../../config.h"
|
||||
|
||||
#if defined(EVAL_LEARN) && defined(EVAL_NNUE)
|
||||
|
||||
#include "../../../learn/learn.h"
|
||||
|
||||
Reference in New Issue
Block a user