G検定(ジェネラリスト検定)
でぷすわいずせぱらぶるこんぼりゅーしょん
深さ方向分離畳み込み
Depthwise Separable Convolution
深さ方向分離畳み込みとは、入力のチャンネルごとに独立して空間方向の畳み込みを行う深さ方向の畳み込みに続けて、1×1のカーネルでチャンネル方向だけを混ぜ合わせる点ごとの畳み込みを行う演算です。フランソワ・ショレ(François Chollet)はこの演算でInceptionモジュールを置き換えたXceptionを提案しました。
詳しい説明
深さ方向分離畳み込みとは何か
深さ方向分離畳み込み(depthwise separable convolution)とは、畳み込みを2段階に分けて行う演算です。フランソワ・ショレ(François Chollet)は2017年の論文「Xception: Deep Learning with Depthwise Separable Convolutions」で、この演算を「深さ方向の畳み込みに続けて点ごとの畳み込みを行う演算」(a depthwise convolution followed by a pointwise convolution)と定義しています。
ここでいう「深さ」は、入力のチャンネルの方向を指します。カラー画像が赤・緑・青の3つの面を重ねた形をしているように、畳み込み層への入力は縦横に広がる面をチャンネルの数だけ重ねた形をしています。この重なりの方向を奥行きに見立てて、深さと呼んでいます。
2つの段階はそれぞれ次の処理を担います。
1. 深さ方向の畳み込み(depthwise convolution)は、チャンネルごとに独立して空間方向の畳み込みを行います。チャンネル1枚につき縦横だけに広がるカーネルを1枚ずつ用意し、そのチャンネルだけに当てはめます。チャンネルどうしの値は混ざりません。
2. 点ごとの畳み込み(pointwise convolution)は、1×1のカーネルを使って、チャンネル方向だけを混ぜ合わせます。カーネルの縦横が1マスなので、隣の位置の値は使わず、同じ位置にある各チャンネルの値に重みを掛けて足し合わせます。
通常の畳み込みとの違い
通常の畳み込み層では、1枚のカーネルが入力の全チャンネルにまたがる重みを持ちます。そのため1回の計算の中で、縦横の近くの値を集める処理と、チャンネルどうしを混ぜる処理が同時に行われます(詳しい計算は畳み込み層の項目を参照してください)。
深さ方向分離畳み込みは、この2つの処理を切り離します。縦横の近くの値を集める処理は深さ方向の畳み込みが受け持ち、チャンネルどうしを混ぜる処理は点ごとの畳み込みが受け持ちます。出力の形は通常の畳み込みと同じく「縦×横×出力チャンネル数」の特徴マップになりますが、そこに至る計算の組み立て方が違います。
小さな数値例で2段階の処理を追う
以下の数値は説明のために作った架空の例です。縦3×横3の面を2チャンネル重ねた入力を考え、ストライドは1、パディングは0とします。カーネルは入力に重ねて、対応する位置どうしの積を足し合わせるものとします(カーネルを反転しない相互相関の形で計算します。畳み込み層の項目にある反転する定義とは形が異なりますが、多くの機械学習ライブラリが実装しているのはこの反転しない形です)。
チャンネルAとチャンネルBの値は次のとおりです。
第1段階の深さ方向の畳み込み
チャンネルAには左上と右下が1のカーネルを当てはめ、チャンネルBには右上と左下が1のカーネルを別に当てはめます。どちらも縦2×横2のカーネルです。
チャンネルAの左上の2×2の範囲は なので、 を重ねた結果は です。同じ計算を4つの位置で行うと、各チャンネルの出力は次のようになります。
はチャンネルAの値だけから、 はチャンネルBの値だけから計算されています。この段階では出力のチャンネル数は入力と同じ2のままです。
第2段階の点ごとの畳み込み
次に、1×1のカーネルで2つのチャンネルを混ぜ合わせます。1×1のカーネルは、チャンネルごとの重みを1つずつ持つだけのカーネルです。ここでは出力チャンネルを2つ作ることにし、1つ目のカーネルの重みを 、2つ目の重みを とします。
1つ目の出力は、各位置で を計算します。左上の位置では です。2つ目の出力は各位置で を計算し、左上の位置では です。4つの位置すべてで計算すると次のようになります。
点ごとの畳み込みでは、左上の出力は左上の と の値だけから決まり、隣の位置の値は使われていません。縦横の近くの値を集める仕事は第1段階で済んでおり、第2段階はチャンネルを混ぜる仕事だけをしていることが、この計算から分かります。
重みの数を通常の畳み込みと比べる
2段階に分けたときに学習する重みの数がどう変わるか、定義から計算してみます。以下は論文に書かれた数値ではなく、定義に沿って数えた架空の例です。バイアスは数えていません。
入力のチャンネル数を32、出力のチャンネル数を64、空間方向のカーネルを3×3とします。
通常の畳み込みでは、全チャンネルにまたがる3×3×32の重みを持つカーネルを64枚使うので、重みの数は 個です。
深さ方向分離畳み込みでは、第1段階で3×3のカーネルをチャンネルごとに1枚ずつ32枚使うので 個、第2段階で1×1×32の重みを持つカーネルを64枚使うので 個です。合わせて 個となり、同じ形の出力を作るのに必要な重みは通常の畳み込みのおよそ8分の1になります。
ただし、この比は入力と出力のチャンネル数やカーネルの大きさによって変わります。また、重みが減ることは計算の組み立て方から導かれる性質であり、それだけで精度が保たれることまでは言えません。
Xceptionでの位置づけと報告された結果
ショレの論文は、通常の畳み込みとInceptionモジュールの中間にある操作として、深さ方向分離畳み込みを位置づけています。Inceptionモジュールは、GoogLeNetなどの畳み込みニューラルネットワークで使われてきた構成部品です。
この見方にもとづいて、論文はInceptionモジュールを深さ方向分離畳み込みに置き換えたアーキテクチャを提案し、Xceptionと名付けました。論文は、XceptionがInception V3と同じ数のパラメータを持ちながら、パラメータをより効率よく使うことで、Inception V3を上回る性能を示したと報告しています。
この結果は、パラメータの数をそろえたうえでInception V3と比べたものです。通常の畳み込みを深さ方向分離畳み込みに置き換えれば、どのモデルでも必ず性能が上がるという主張ではない点に注意してください。
試験で問われること
G検定
- 深さ方向分離畳み込みは、深さ方向の畳み込みに続けて点ごとの畳み込みを行う演算です。
- 深さ方向の畳み込みは、空間方向の畳み込みをチャンネルごとに独立して行い、チャンネルどうしの値を混ぜません。
- 点ごとの畳み込みは、1×1のカーネルで同じ位置にある各チャンネルの値を混ぜ合わせ、隣の位置の値は使いません。
- 入力32チャンネル・出力64チャンネル・カーネル3×3なら、重みの数は通常の畳み込みの18,432個に対し、288個と2,048個を合わせた2,336個です(バイアスは除く)。
- フランソワ・ショレ(François Chollet)のXceptionは、Inceptionモジュールを深さ方向分離畳み込みに置き換えたアーキテクチャで、Inception V3と同じパラメータ数で性能が上回ったと報告されました。
最終更新日: 2026/09/23