<p>In the typical jargon, when someone refers to a conv layer with N kernels of size (x, y), it is implied that the kernels actually have size (x, y, z), where z is the depth of the input volume to that layer.</p>

<p>Imagine what happens when the input image to the network has R, G, and B channels: each of the initial kernels itself has 3 channels. Subsequent layers are the same, treating the input volume as a multi-channel image, where the channels are now maps of some other feature.</p>

<p>The motion of that 3D kernel as it "sweeps" across the input is only 2D, so it is still referred to as a 2D convolution, and the output of that convolution is a 2D feature map.</p>

<p>Edit:</p>

<p>I found a good quote about this in a recent paper, <a href="https://arxiv.org/pdf/1809.02601v1.pdf" rel="nofollow noreferrer">https://arxiv.org/pdf/1809.02601v1.pdf</a></p>

<p>"In a convolutional layer, the input feature map X is a W<sub>1</sub> × H<sub>1</sub> × D<sub>1</sub> cube, with W<sub>1</sub>, H<sub>1</sub> and D<sub>1</sub> indicating its width, height and depth (also referred to as the number of channels), respectively. The output feature map, similarly, is a cube Z with W<sub>2</sub> × H<sub>2</sub> × D<sub>2</sub> entries. The convolution Z = f(X) is parameterized by D<sub>2</sub> convolutional kernels, each of which is a S × S × D<sub>1</sub> cube."</p>
Why are my Keras Conv2D kernels 3-dimensional?
<p>In a typical CNN, a conv layer will have Y filters of size NxM, and thus it has N x M x Y trainable parameters (not including bias).</p>

<p>Accordingly, in the following simple keras model, I expect the second conv layer to have 16 kernels of size (7x7), and thus kernel weights of size (7x7x16). <strong>Why then are its weights actually size (7x7x8x16)?</strong></p>

<p>I understand the mechanics of what is happening: the Conv2D layers are actually doing a 3D convolution, treating the output maps of the previous layer as channels. It has 16 3D kernels of size(7x7x8). What I don't understand is:</p>

<ul>
<li>why this is Keras's default behavior?</li>
<li><strong>how do I get a "traditional" convolutional layer</strong> without dropping down into the low-level API (avoiding that is my reason for using Keras in the first place)?</li>
</ul>

<p>_</p>

<pre><code>from keras.models import Sequential
from keras.layers import InputLayer, Conv2D

model = Sequential([
    InputLayer((101, 101, 1)),
    Conv2D(8, (11, 11)),
    Conv2D(16, (7, 7))
])
model.weights
</code></pre>