Установить начальные значения веса нейронной сети в C++ torch

Я искал API для установки начальных значений веса в libtorch. В версии Python (т.е. pytorch) можно легко использовать torch.nn.functional.weight.data.fill_(xx) и torch.nn.functional.bias.data.fill_(xx). Но, похоже, такого API в C++ пока нет. Буду признателен за любую помощь или комментарий для достижения такой функциональности.

Спасибо, Афшин


person Afshin Oroojlooy    schedule 22.01.2019    source источник


Ответы (2)


Я разработал эту функцию, чтобы сделать это:

void set_weights(fc_model &src_net) {

//    torch::NoGradGuard no_grad;
    torch::autograd::GradMode::set_enabled(false);
    for (int k=0; k < src_net.no_layers-1; k++ ) {
        src_net.layers[k]->weight.uniform_(0.001, 0.001);
        src_net.layers[k]->bias.uniform_(0.0, 0.0);
    }
    torch::autograd::GradMode::set_enabled(true);
}

в котором src_net — это объект nn, все слои которого собраны в список с именем `layers'.

person Afshin Oroojlooy    schedule 26.02.2019

Я получил это решение лучше, чем предыдущее, в котором model является объектом типа torch::nn::Sequential:

torch::NoGradGuard no_grad;

for (auto &p : model->named_parameters()) {
    std::string y = p.key();
    auto z = p.value(); // note that z is a Tensor, same as &p : layers->parameters

    if (y.compare(2, 6, "weight") == 0)
        z.uniform_(l, u);
    else if (y.compare(2, 4, "bias") == 0)
        z.uniform_(l, u);
}

Вместо uniform_ вы можете использовать normal_, ... которые доступны на факеле. Это решение не ограничивается torch::nn::Linear слоем и может использоваться для любого типа слоя.

person Afshin Oroojlooy    schedule 18.11.2020