??🍨 本文為:[🔗365天深度學習訓練營] 中的學習記錄博客
?🍖 原作者:[K同學啊 | 接輔導、項目定制]
要求:
- 閱讀給出代碼,判斷是否存在錯誤,正確與否都請給出你的思考;
- 查找相關資料、逐步推理模型、寫下思考過程
# 定義殘差單元
def block(x, filters, strides=1, groups=32, conv_shortcut=True):if conv_shortcut:
shortcut = Conv2D(filters * 2, kernel_size=(1, 1), strides=strides, padding='same', use_bias=False)(x)
# epsilon為BN公式中防止分母為零的值
shortcut = BatchNormalization(epsilon=1.001e-5)(shortcut)
else:
# identity_shortcut
shortcut = x
# 三層卷積層
x = Conv2D(filters=filters, kernel_size=(1, 1), strides=1, padding='same', use_bias=False)(x)
x = BatchNormalization(epsilon=1.001e-5)(x)
x = ReLU()(x)
# 計算每組的通道數
g_channels = int(filters / groups)
# 進行分組卷積
x = grouped_convolution_block(x, strides, groups, g_channels)x = Conv2D(filters=filters * 2, kernel_size=(1, 1), strides=1, padding='same', use_bias=False)(x)
x = BatchNormalization(epsilon=1.001e-5)(x)
x = Add()([x, shortcut])
x = ReLU()(x)
return x# 堆疊殘差單元
def stack(x, filters, blocks, strides, groups=32):
# 每個stack的第一個block的殘差連接都需要使用1*1卷積升維
x = block(x, filters, strides=strides, groups=groups)
for i in range(blocks):
x = block(x, filters, groups=groups, conv_shortcut=False)
return x
問題:如果conv_shortcut=False,那么執行“x=Add()…”語句時,通道數不一致的,為什么不會報錯?
思考分析
????????在ResNext網絡中,將conv_shortcut參數設置為False,表示使用identity_shortcut而不是Conv2D層作為快捷連接。
????????對于定義殘差單元block模塊,Add()是x和shortcut相加,x通道數是filter*2。對于shortcut,conv_shortcut為True則是filters*2,否則是原始輸入通道數。
????????最后對于堆疊殘差模塊stack,第二次調用block時,conv_shortcut參數是False,使用的是identity_shortcut,這種情況下,快捷連接將直接傳遞輸入x給塊的最后一層。因此,在執行“x=Add()…”語句時,快捷連接的通道數與該層的通道數不一致。
????????但是,由于Add()層在通道數不同時會自動對快捷連接進行零填充,所以不會出現尺寸不匹配的錯誤。此外,這種零填充不會對訓練產生任何影響,因為填充的值不會接收任何梯度更新。
????????總之,Add 層具有自動廣播機制,可以在計算時自動擴展較小張量的形狀以匹配較大張量的形狀,因此即使通道數不一致也不會報錯。