<p>You can find out the number of (non-)trainable parameters of a model in Keras using the <code>summary</code> function:</p>

<pre class="lang-py prettyprint-override"><code>from keras import models, layers

model = models.Sequential()
model.add(layers.Conv2D(10, (4,4), input_shape=(32, 32, 3)))

model.summary()
</code></pre>

<p>Here is the output:</p>

<pre><code>Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 29, 29, 10)        490       
=================================================================
Total params: 490
Trainable params: 490
Non-trainable params: 0
</code></pre>

<p>In general, for a 2D-convolution layer with <code>k</code> filters with size of <code>w*w</code> applied on an input with <code>c</code> channels the number of trainable parameters (considering one bias parameter for each filter, in the default case) is equal to <code>k*w*w*c+k</code> or <code>k*(w*w*c+1)</code>. In the example above we have: <code>k=10, w=4, c=3</code> therefore we have <code>10*(4*4*3+1) = 490</code> trainable parameters. As you can infer, for each channel there are separate weights and they are not shared. Furthermore, the number of parameters of a 2D-convolution layer does not depend on the width or height of the previous layer.</p>

<p><strong>Update:</strong></p>

<p>A convolution layer with depth-wise shared weights: I am not aware of such   a layer and could not find a built-in implementation of that in Keras or Tensorflow either. But after thinking about it, you realize that it is essentially equivalent to summing all the channels together and then applying a 2D-convolution on the result. For example in case of a <code>32*32*3</code> image, first all the three channels are summed together resulting in a <code>32*32*1</code> tensor and then a 2D-convolution can be applied on that tensor. Therefore at least one way of achieving a 2D-convolution with shared weights across channels could be like this in Keras (which may or may not be efficient):</p>

<pre class="lang-py prettyprint-override"><code>from keras import models, layers
from keras import backend as K

model = models.Sequential()
model.add(layers.Lambda(lambda x: K.expand_dims(K.sum(x, axis=-1)), input_shape=(32, 32, 3)))
model.add(layers.Conv2D(10, (4,4)))

model.summary()
</code></pre>

<p>Output:</p>

<pre><code>Layer (type)                 Output Shape              Param #   
=================================================================
lambda_1 (Lambda)            (None, 32, 32, 1)         0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 29, 29, 10)        170       
=================================================================
Total params: 170
Trainable params: 170
Non-trainable params: 0
</code></pre>

<p>One good thing about that Lambda layer is that it could be added in any place (e.g. after the convolution layer). But I think the most important question to ask here is: "Why using a 2D-conv layer with depth-wise shared weighs would be beneficial?" One obvious answer is that the network size (i.e. the total number of trainable parameters) is reduced and therefore there might be a decrease in training time, which I suspect would be negligible. Further, using shared weights across channels implies that the patterns present in different channels are more or less similar. But this is not always the case, for example in RGB images, and therefore by using shared weights across channels I guess you might observe a (noticeable) decrease in network accuracy. So, at least, you should have in mind this trade-off and experiment with it.</p>

<p>However, there is another kind of convolution layer, which you might be interested in, called "Depth-wise Separable Convolution" which has been implemented in Tensorflow, and Keras <a href="https://keras.io/layers/convolutional/#separableconv2d" rel="nofollow noreferrer">supports it</a> as well. The idea is that on each channel a separate 2D-conv filter is applied and afterwards the resulting feature maps are aggregated using <code>k</code> <code>1*1</code> convolutions(<code>k</code> here is the number of output channels). It basically separates the learning of spatial features and depth-wise features. In his paper, <a href="https://arxiv.org/pdf/1610.02357.pdf" rel="nofollow noreferrer">"Xception: Deep Learning with Depthwise Separable Convolutions"</a>, Francois Chollet (the creator of Keras) shows that using depth-wise separable convolutions improves both the performance and accuracy of network. And <a href="https://towardsdatascience.com/types-of-convolutions-in-deep-learning-717013397f4d" rel="nofollow noreferrer">here</a> you can read more about different kinds of convolution layers used in deep learning.</p>
CNN Keras: How many weights will be trained?
<p>I have a little comprehension problem with CNN. And I'm not quite sure how many filters and thus weights are trained.</p>

<p>Example: I have an input layer with the 32x32 pixels and 3 channels (i.e. shape of <code>(32,32,3)</code>). Now I use a 2D-convolution layer with 10 filters of shape <code>(4,4)</code>. So I end up with 10 channels each with shape of <code>(28,28)</code>, but do I now train a separate filter for each input channel or are they shared? Do I train 3x10x4x4 weights or do I train 10x4x4 weights?</p>