Архитектура модели Python:
- вход: 768 нейронов (плоское состояние платы 8x8x12)
- скрытые слои: 1024 -> 512 -> 256 -> 128 -> 64
- выход: 1 нейрон (активация tanh)
Код: Выделить всё
Input size: 768
Number of layers: 6
Processing layer 0
Input size: 1024 # should be 768
Output size: 768 # should be 1024
Код: Выделить всё
def convert_model_to_binary(model_path, output_path):
# Load the TensorFlow model
chess_nn = pickle.load(open(model_path, "rb"))
model = chess_nn.model
with open(output_path, "wb") as f:
# write number of dense layers
dense_layers = [
layer
for layer in model.layers
if isinstance(layer, tf.keras.layers.Dense)
]
np.array([len(dense_layers)], dtype=np.int32).tofile(f)
for layer in dense_layers:
weights, biases = layer.get_weights()
# convert to float32 for c++ compatibility
weights = weights.astype(
np.float32
) # no transpose needed (weights are already in the correct shape)
biases = biases.astype(np.float32)
# write input and output dimensions
input_dim = weights.shape[0] # number of rows (input dimension)
output_dim = weights.shape[
1
] # number of columns (output dimension)
np.array([input_dim, output_dim], dtype=np.int32).tofile(f)
np.array([output_dim], dtype=np.int32).tofile(f) # bias shape
weights.tofile(f)
biases.tofile(f)
Код: Выделить всё
bool load_model(const std::string &filename)
{
std::ifstream file(filename, std::ios::binary);
int32_t num_layers;
file.read(reinterpret_cast(&num_layers), sizeof(int32_t));
layers.resize(num_layers);
for (int i = 0; i < num_layers; i++)
{
int32_t weight_shape[2];
file.read(reinterpret_cast(weight_shape), 2 sizeof(int32_t));
int32_t bias_shape[1];
file.read(reinterpret_cast(bias_shape), sizeof(int32_t));
layers[i].input_size = weight_shape[1];
layers[i].output_size = weight_shape[0];
layers[i].weights.resize(weight_shape[0] weight_shape[1]);
layers[i].biases.resize(bias_shape[0]);
file.read(reinterpret_cast(layers[i].weights.data()), layers[i].weights.size() sizeof(float));
file.read(reinterpret_cast(layers[i].biases.data()), layers[i].biases.size() sizeof(float));
}
return true;
}
- перенос весов в Python перед сохранением:
по-прежнему возникают несоответствия размеров, но в обратном порядкеКод: Выделить всё
weights = weights.T.astype(np.float32) - замена входных/выходных размеров в C++:
Код: Выделить всё
layers[i].input_size = weight_shape[0];
layers[i].output_size = weight_shape[1];
- изменение расчета индекса веса в c++:
Код: Выделить всё
size_t weight_idx = i * layer.input_size + j; // original
size_t weight_idx = j * layer.output_size + i; // tried this
size_t weight_idx = i + j layer.output_size; // and this
ожидается:
- веса должны загружаться с правильные размеры (768->1024->512->256->128->64->1)
- модель должна давать аналогичные прогнозы для версии Python
- Состояние входной платы должно обрабатываться на всех уровнях правильно
[*]размеры поменялись местами (1024->768, 512->1024 и т. д.
[*]получаются ошибки «несоответствия входных размеров» на каждом уровне
[*]окончательное предсказание всегда возвращает 0
Подробнее здесь: https://stackoverflow.com/questions/791 ... -correctly
Мобильная версия