how to pass trained weight to neural network module

Suppose i used own data and trained a conv1d, how could we pass the weight to conv1d in c++ like what the PyTorch acts ?

Noticed that the implementation of conv1d in PyTorch, we could update the parameters like in_channels, out_channels, etc in the __init__ function. If we want to update the weights and bias, which are from pretrained model, we could rewrite the Conv1d, which may not so difficult.

class Conv1d(_ConvNd):

    def __init__(self, in_channels, out_channels, kernel_size, stride=1,
                 padding=0, dilation=1, groups=1,
                 bias=True, padding_mode='zeros'):
        kernel_size = _single(kernel_size)
        stride = _single(stride)
        padding = _single(padding)
        dilation = _single(dilation)
        super(Conv1d, self).__init__(
            in_channels, out_channels, kernel_size, stride, padding, dilation,
            False, _single(0), groups, bias, padding_mode)

    def forward(self, input):
        if self.padding_mode == 'circular':
            expanded_padding = ((self.padding[0] + 1) // 2, self.padding[0] // 2)
            return F.conv1d(F.pad(input, expanded_padding, mode='circular'),
                            self.weight, self.bias, self.stride,
                            _single(0), self.dilation, self.groups)
        return F.conv1d(input, self.weight, self.bias, self.stride,
                        self.padding, self.dilation, self.groups)

While notice the conv1d implementation in libtorch, noticed that

namespace nn {
Conv1dImpl::Conv1dImpl(
    Conv1dOptions options_)
    : ConvNdImpl(
        detail::ConvNdOptions<1>(
          /*in_channels=*/options_.in_channels(),
          /*out_channels=*/options_.out_channels(),
          /*kernel_size=*/options_.kernel_size())
          .stride(options_.stride())
          .padding(options_.padding())
          .dilation(options_.dilation())
          .transposed(false)
          .output_padding(0)
          .groups(options_.groups())
          .bias(options_.bias())
          .padding_mode(options_.padding_mode())) {}

Tensor Conv1dImpl::forward(const Tensor& input) {
  if (c10::get_if<enumtype::kCircular>(&options.padding_mode())) {
    std::vector<int64_t> expanded_padding = {((*options.padding())[0] + 1) / 2, (*options.padding())[0] / 2};
    return F::detail::conv1d(
      F::detail::pad(input, expanded_padding, torch::kCircular, 0),
      weight, bias,
      options.stride(),
      /*padding=*/0,
      options.dilation(),
      options.groups());
  }
  return F::detail::conv1d(
    input,
    weight,
    bias,
    options.stride(),
    options.padding(),
    options.dilation(),
    options.groups());
}

So how could we pass the weight in the c++ version ?

You can copy the weight as follows

	conv1->weight.copy_(weight);
	conv1->bias.copy_(bias);

But this method is not good.
If you want to copy the weight of a Python model, use below code
Currently you can use

but I know other ways to develop now

#python
import torch
import torch.jit

cov1 = torch.nn.Conv1d(3,64,7)
torch.jit.script(cov1).save('cov1.pt')

#c++
torch::nn::Conv2d conv1(torch::nn::Conv2dOptions(3, 64, 7);
torch::load(conv1,"cov1.pt");

1 Like

Wow, thanks a lot.:+1::+1::+1: