ResNetをべた書きしてクラス化するまで

Yutaka_kun
LSC PSD
Published in
6 min readMar 12, 2020

[python][keras][ResNet][def][class][resblocks]

勉強のためにResNetの構造を分解していって、手書きしました。
ついでにclassも勉強したのでclass化もやります。
見ていけばわかりますが、初心者なのでものっそいネチネチ解説してあります。

完成版はここにあります。

そもそもResNetってなんやねん

ニューラルネットワーク(CNNなど)の精度を上げようとした場合、層を深くしていけば精度はある程度までは上がっていきます。しかしこれには1つ欠点があり、層が深くなればなるほど微分の回数も増え、伝播させたい情報が失われてしいます。
例えば、層を進むたびに微分が2倍になるとすると、、、、
10層目では 2¹⁰=1024 倍
20層目では 2²⁰= 1048576 倍
30層以上のものは言わずもがなです。

情報が伝播しやすいように畳み込み層を通るルートを飛び越えて次の層に情報を伝えるresidual(前の層の残り)を加えたものがResNetです。
ではそのルートを1つ1つ見ていきましょう。
ルートはResNet18で考えます。

あ、言い忘れてましたが、keras、使います。

入力からmaxpoolingまで

入力は224×224の3チャンネルを想定します。
Conv2D(filters=64, kernel_size=(7, 7), strides=(2, 2), padding=”same”,)
で畳み込みます。
padding=sameというのは畳み込み後の出力が同じになるようにkerasお兄さんが画像の周りを”0”で埋めてくれます。
「いや、224→112の半分になっとるやんけ」
と思われた方、今回はstride2で2マスずつフィルタを動かしているので、出力は半分になります。
もちろんstride1の場合は出力は224のままです。
0埋めしないと(224+2×padding–7)/2=109.5の出力になりややこしくなるのと、画像の端っこの情報が失われやすくなります。
畳み込みの詳しい説明はここのサイトがわかりやすい気がします。

batchnormalization関数で正規化した後、活性化関数reluを通します。

max poolingでは、同じようにゼロ埋めした後3×3のフィルターを2マスずつストライドさせているので出力サイズはさらに半分の56×56になります

conv2_x層

strideは1なのでこの層では特に出力の変化はなし。

※緑矢印のshortcutの位置

shortcutを接続する場所はbatchnormalizationの後がいいらしい。
shortcutの後にbatchnormalization(正則化)するとresblockの値とshortcutの値の両方とも正則化されていいように感じますが、実際にはshortcutの情報をbatchnormalizationが大きく変更してせっかく生の状態で持ってきた情報が失われてしまうかららしい。

ほかのブログによると、、、、、、

上の図のようにshortcutを入れると精度がよくなるらしい、、、
が理由はよくわからん。
正則化の役割が強くなるとか、なんとか、、、

conv3_x層

shortcut層のみ2マスずつフィルターをスライドさせています。
よって出力が28×28にかわります。

※conv3_1、conv3_2をまたいでいるshortcutの接続に注意!!!!!

図を見ればわかりますが、conv3_1の入力(56,56,64)と正則化後の出力(28,28,128)が違います。
shortcut関数の作成時に形状を合わせるコードを組み込んでおきます。

conv4_x層

conv3_x層に同じです

conv5_x層

conv3_x層に同じです

最終層

globalaveragepoolingで1次元に落とし、全結合層に入れて10クラスに分類します。活性化関数はsoftmaxに設定しますが、2クラス分類の場合はsigmoidが推奨されています。

おいまて、globalaveragepoolingってなんやねん

例えば、7×7×512(25008)のデータを1×1×4096の全結合層に接続する場合、 25088×4096=102760448の重みパラメータが存在することになります。

7×7×512のデータをglobalaveragepoolingに通すと、各チャンネルの画素平均を求め、まとめてくれます。重みのパラメータは減り512×4096で済みます。

ここまではResNetのルートを追ってきました。
次の章では実際にコードを書いていきます。

まずは何も考えずに上からべた書き。

shortcut関数は後述します。

shortcut関数

conv2_x層の場合、元のルートとshortcutの出力は同じなので、わざわざ出力を合わせる必要はありません。
conv3_1層、conv4_1層、conv5_1層は、元のルートとshortcutの出力を合わせる必要があります。

クラス化

クラス化はこうします、
もう疲れました。
クラス化の詳しい書き方は次回で。

--

--

Yutaka_kun
LSC PSD
Editor for

Microbiology technician,Machine learning engineer(beginner)