Dense block with 2D convolutions
Background
A dense block is the core of DenseNet. Unlike a plain stack where each layer feeds only the next, every layer in a dense block receives the concatenation of all preceding feature maps and appends its own output. Each layer adds a fixed number of channels — the growth rate — so feature reuse is maximal and gradients reach early layers directly. After layers starting from channels, the block outputs channels.
Problem statement
A working conv2d(x, kernel, padding) (NHWC layout, valid convolution after zero-padding) is provided. Implement dense_net_block(input_data, num_layers, growth_rate, kernels, kernel_size=(3,3)):
For each layer :
Use same padding so spatial dims are preserved.
Input
input_data—np.ndarrayof shape(N, H, W, C0)(batch, height, width, channels).num_layers—int, number of layers .growth_rate—int, channels added per layer (equals each kernel's output channels).kernels— list ofLkernels;kernels[l]has shape(kh, kw, C_l, growth_rate), whereC_lis the current channel count.kernel_size—(kh, kw)tuple.
Output
An np.ndarray of shape (N, H, W, C0 + L*growth_rate): the original features followed by every layer's output, concatenated along the channel axis.
Examples
Example 1
Input: input_data shape (1, 4, 4, 2), num_layers = 2, growth_rate = 1
Output: shape (1, 4, 4, 4) # 2 original + 1 + 1
Explanation: each layer applies ReLU, convolves with same padding (spatial stays 4×4), and concatenates one new channel. Two layers turn 2 channels into 4.
Constraints
- ReLU is applied to the current concatenated features before each convolution.
- Padding is
(kernel_size[0] - 1)//2(same convolution), preservingHandW. - The original input must remain the leading channels of the output (concatenation appends new maps).
Notes
- Channel count grows additively, not multiplicatively, which keeps DenseNets parameter-efficient compared to their depth.
- The skip-by-concatenation differs from ResNet's skip-by-addition: DenseNet preserves all earlier features rather than summing them.
This problem ships 5 hidden tests. They run in your browser via Pyodide — no backend, no submission queue. Press ▶ Run tests to execute.
- •Provided conv2d sums the window for an all-ones kernel
- •Channel count grows by L * growth_rate
- •Same padding preserves spatial dimensions
- •Original features are preserved as the leading channels
- •ReLU clamps negative features before convolution