2025/06/21 15:03 PyTorch Reshaping with None

やあ、ロボ子。今日はPyTorchのreshapeの話をするのじゃ。

博士、こんにちは。reshapeですか、基本的な操作ですね。

そうじゃ、でも奥が深いぞ。特にNoneを使ったreshapeは、ちょっとトリッキーじゃからな。

Noneを使うとどうなるんですか?

例えば、「Dive into Deep Learning」のmasked softmaxの実装で使われているのじゃ。自然言語処理で可変長のシーケンスデータを扱う時に便利なんじゃ。

可変長のシーケンスデータ、ですか。

そう。「Welcome To My Blog」と「Hello World」みたいに、長さが違う文章を同じバッチで処理したい時があるじゃろ?短いシーケンスは特殊トークンで埋めて長さを揃えるのじゃ。

なるほど、paddingですね。

その通り!そして、attentionの際にpaddingした部分にattentionしないようにマスクを作るんじゃ。ここでNoneを使ったreshapeが活躍するのじゃ。

具体的にはどのように使うんですか?

max_lenはシーケンスの最大長、valid_lenは実際のシーケンス長を表すとすると、valid_len[:, None]はvalid_len.reshape(-1, 1)と同等になるのじゃ。

[:, None]がreshape(-1, 1)と同じ、ですか。少し混乱します…

落ち着くのじゃロボ子!Noneは新しい次元を追加するショートカットみたいなものじゃ。reshape(-1, 1)は「行数は自動で決めて、列数は1にする」という意味じゃから、valid_lenに新しい次元を加えて列ベクトルにするのじゃ。

なるほど!valid_lenが例えば[3, 2, 4]という配列だった場合、valid_len[:, None]は[[3], [2], [4]]になるということですね。

その通り!そして、torch.arange(max_len, dtype=torch.float32, device=X.device)[None, :]はtorch.arange(max_len, dtype=torch.float32, device=X.device).reshape(1, -1)と同等じゃ。

[None, :]は行ベクトルにする、ということですね。

そうじゃ!筆者も言っているように、reshapeの方が可読性が高い場合もあるから、状況に応じて使い分けるのが良いのじゃ。

可読性も大事ですね。勉強になりました!

ところでロボ子、reshapeって、まるで私の部屋の片付けみたいじゃな。いつも形を変えて、結局散らかる…。

博士、それはreshapeとはちょっと違いますね…。
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。