0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【C++ / LibTorch】エラーなしで即落ちするプログラムをtry-catchで捕まえてみたら、単純なコピペミスだった話

0
Posted at

初めに

最近、C++とLibtorchを用いた機械学習(強化学習)のプログラムを書いています。そこで起きた事件を丸一日使って解決したので、教訓としてここに書きます。

  • OS: Windows 11
  • 言語: C++
  • ライブラリ: Libtorch (最新版)

事件発生

コンパイルは通るのに 「実行するとエラーメッセージもなくプログラムが落ちる」 という現象に遭遇しました。

調査

どこで落ちているのかわからないので、怪しい箇所を try-catch で囲み、無理やりエラーを出力させました。

model.hpp
  torch::Tensor forward(torch::Tensor x) {
    try {
      x = torch::relu(conv1(x));
      x = torch::relu(conv2(x));
      x = torch::relu(conv3(x));
      x = x.view({x.size(0), -1});
      x = torch::relu(fc1(x));
      x = fc2(x);
    } catch(const std::exception& e){
      std::cerr << "Error details: " << e.what() << std::endl;
      throw;
    }
    return x;
  }

その結果、このようなログが出力されました。

Error details: Given groups=1, weight of size [64, 64, 3, 3], expected input[1, 32, 24, 24] to have 64 channels, but got 32 channels instead

原因特定

ログには「入力64を期待していたのに32しかありませんでした」と書いてありますね。
では、原因となったコードを見てみましょう。

model.hpp
// ...省略

struct QNetworkImpl : torch::nn::Module {
  torch::nn::Conv2d conv1{nullptr}, conv2{nullptr}, conv3{nullptr};
  QNetworkImpl() {
    // ...
    conv1 = register_module("conv1", torch::nn::Conv2d(torch::nn::Conv2dOptions(3, 32, 3).padding(1)));
    conv2 = register_module("conv2", torch::nn::Conv2d(torch::nn::Conv2dOptions(32, 64, 3).padding(1)));
    conv2 = register_module("conv3", torch::nn::Conv2d(torch::nn::Conv2dOptions(64, 64, 3).padding(1)));

    // ...
  }
};

// ...

どこがおかしいのか、わかりましたか?
それでは答え合わせです。

何が起きていたか

conv1 を通過したデータはチャンネル数が 32 になっています。
本来の conv2 は「入力32 -> 出力64」の設定ですが、コピペミスにより変数 conv2 には 「入力64 -> 出力64」 の層(本来 conv3 に入るはずだったもの)が上書き代入されてしまいました。
その結果、 forward() 内で conv2(x) が実行された瞬間、 「32チャンネルのデータが渡されたが、この層は64チャンネルの入力を期待している」 という不整合が発生し、プログラムがクラッシュしてしまいました。

教訓

  • register_module を連続して書くときは、代入先の変数名が正しいかを確認する
  • エラー文が出ずに落ちる場合、 nullptr へのアクセスだけでなく、 行列演算の次元不一致 も疑う必要がある
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?