You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

首个卷积层反向传播失败:广播维度不匹配(stride=2异常)

自定义CNN反向传播:第一层卷积层维度不匹配错误

为深入理解CNN原理,我未借助任何深度学习框架从零实现了一个卷积神经网络。网络的前向传播与反向传播流程大部分能正常执行,但在反向传播到第一个卷积层时出现维度不匹配问题。

网络结构

network = [
    Conv(input_shape=(128,96,96,3), kernel_shape=(4,4), num_kernels=40, stride=2, optimizer=GD_M, conv_mode="valid", kernel_initializer="he_normal", name="C1"),
    ReLU(name="R1"),
    ValidMaxPooling(3,2, name="MP1"),
    Conv(input_shape=(128,23,23,40), kernel_shape=(2,2), num_kernels=105, stride=1, optimizer=GD_M, conv_mode="valid", kernel_initializer="he_normal", name="C2"),
    ReLU(name="R2"),
    ValidMaxPooling(4,2, name="MP2"),
    Conv(input_shape=(128,10,10,105), kernel_shape=(2,2), num_kernels=158, stride=1, optimizer=GD_M, conv_mode="valid", kernel_initializer="he_normal", name="C3"),
    ReLU(name="R3"),
    Conv(input_shape=(128,9,9,158), kernel_shape=(2,2), num_kernels=158, stride=1, optimizer=GD_M, conv_mode="valid", kernel_initializer="he_normal", name="C4"),
    ReLU(name="R4"),
    Conv(input_shape=(128,8,8,158), kernel_shape=(2,2), num_kernels=105, stride=1, optimizer=GD_M, conv_mode="valid", kernel_initializer="he_normal", name="C5"),
    ReLU(name="R5"),
    ValidMaxPooling(3,2, name="MP3"),
    Flatten(name="F1"),
    Dense(input_neurons=945, output_neurons=945, optimizer=GD_M, name="D1"),
    ReLU(name="R6"),
    Dense(input_neurons=945, output_neurons=475, optimizer=GD_M, name="D2"),
    ReLU(name="R7"),
    Dense(input_neurons=475, output_neurons=8, optimizer=GD_M, name="D3"),
    Softmax(name="S1"),
]

问题细节

网络输入为128批次的96×96 RGB图像,第一层Conv是唯一设置stride=2的层。尽管该层的输入梯度无需传递给前层,但更新其权重与偏置时出现特征图/输入维度不匹配问题,且仅该层出现此问题。

Conv层反向传播代码

def backward(self, de_dy):
    de_db = de_dy
    de_dk_store = np.zeros(shape=(len(self.input),*self.kernels.shape)) 
    de_dx_store = np.zeros(shape=self.input.shape) 
    for b in range(self.batch_size): 
        for k in range(self.num_kernels): 
            for i in range(self.kernels.shape[1]): 
                de_dk_store[b,k,i] = correlate2d(self.input[b, i], de_dy[k], "valid")
                de_dx_store[b,i]+= convolve2d(de_dy[k], self.kernels[k,i], "full")
    de_dk_avg = np.mean(de_dk_store, axis=0)
    de_dx_avg = np.mean(de_dx_store, axis=0)
    self.kernels = self.optimizer.apply_optimizer(self.name+":K", self.kernels, de_dk_avg)
    self.biases = self.optimizer.apply_optimizer(self.name+":B", self.biases, de_db)
    return de_dx_avg

错误信息

de_dk_store[b,k,i] = correlate2d(self.input[b, i], de_dy[k], "valid")
ValueError: could not broadcast input array from shape (50,50) into shape (4,4)

具体来说,correlate2d(self.input[b, i], de_dy[k], "valid")的输出形状为(50,50),无法赋值到形状为(4,4)的de_dk_store[b,k,i]位置。推测问题根源在于该层设置的stride=2,因为其他stride=1的层未出现此问题。

该层前向传播代码

def forward(self, input_array): # batch, channels, height, width
    self.input = input_array
    self.batch_size, self.channels, input_height, input_width = input_array.shape
    self.output_height = (input_height - self.pool_size) // self.stride + 1
    self.output_width = (input_width - self.pool_size) // self.stride + 1
    pooled_array = np.zeros((self.batch_size, self.channels, self.output_height, self.output_width))
    self.gradient_indexes = np.zeros(shape=(self.batch_size*self.channels*self.output_height*self.output_width, 4), dtype=int)
    z = 0
    for b in range(self.batch_size):
        for c in range(self.channels):    
            m = input_array[b][c]
            for i in range(self.output_height): # rows
                for j in range(self.output_width): # columns
                    patch = m[i*self.stride:i*self.stride+self.pool_size, j*self.stride:j*self.stride+self.pool_size]
                    pooled_array[b,c,i, j] = np.max(patch)
                    max_index_in_patch = np.unravel_index(np.argmax(patch, axis=None), patch.shape)
                    max_index_in_input = [b, c, int(i*self.stride) + int(max_index_in_patch[0]), int(j*self.stride) + int(max_index_in_patch[1])]
                    self.gradient_indexes[z] = max_index_in_input
                    z+=1                 
    return pooled_array

内容的提问来源于stack exchange,提问作者Bryan Carty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 17:03:07