Channel wise convolution

username: ShanakaRG
cooked: <p>I have an input tensor of shape (2,3,5). The 3 is the channel dimension. If I need to perform convolution (1D and 2D both) channel-wise ( each channel should have different weights and biases) using Pytorch.</p>
<p>Let’s say the output channel dim of the conv is 10 and kernal size is 3 for 1D conv,  then i should have an output tensor with shape (2,3x10,5). Each input channel should have an output channel dim as 10 separately.<br>
Can i implement it in such a way using Pytorch?<br>
Please give me an example code.</p>

username: ptrblck
cooked: <p>You can use the <code>groups</code> argument to create separate set of filters:</p>
<pre><code class="lang-python">x = torch.randn(2, 3, 5)
conv = nn.Conv1d(3, 30, 3, 1, 1, groups=3)
out = conv(x)
print(out.shape)
# torch.Size([2, 30, 5])
</code></pre>

username: ShanakaRG
cooked: <p>Thank you very much, <a class="mention" href="/u/ptrblck">@ptrblck</a> . So in this case, kernels are groped for each channel. Then is these kernels selected randomly or it is unique for every epoch in training?</p>

username: ptrblck
cooked: <aside class="quote no-group" data-username="ShanakaRG" data-post="3" data-topic="178218">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/shanakarg/48/58080_2.png" class="avatar"> ShanakaRG:</div>
<blockquote>
<p>Then is these kernels selected randomly or it is unique for every epoch in training?</p>
</blockquote>
</aside>
<p>I’m not sure I understand the question correctly, but the parameters are randomly initialized once during the layer creation and trained afterwards. Re-initializing parameters in each epoch would reset the training.</p>

username: J_Johnson
cooked: <p>Each time your data goes through, it gets processed by all of the kernels. In this case, the order will make a difference since you are grouping them. I.e. the kernels applied the “Red” channel (index 0) will always be the same.</p>

username: ShanakaRG
cooked: <p>sorry for the confusion <a class="mention" href="/u/ptrblck">@ptrblck</a> . I mean the selection of kernels for each group is same for all the time?<br>
here is a graphical drawing that i need to do. lets take i have 3 channels and each channel needs to process separately. So by groping k1, k2 allocates to channel 1 and so on. I doubt that k1,k2 are always allocated to channel 1 or can it be changed in each epoch?<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/7/6/768ad8b8df7c7f3ea825d4c9fb17672b981f854d.jpeg" data-download-href="https://discuss.pytorch.org/uploads/default/768ad8b8df7c7f3ea825d4c9fb17672b981f854d" title="tstt"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/7/6/768ad8b8df7c7f3ea825d4c9fb17672b981f854d_2_690x477.jpeg" alt="tstt" data-base62-sha1="gUFOLVojHkSHaP3NqUgi0qAa1HL" width="690" height="477" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/7/6/768ad8b8df7c7f3ea825d4c9fb17672b981f854d_2_690x477.jpeg, https://discuss.pytorch.org/uploads/default/optimized/3X/7/6/768ad8b8df7c7f3ea825d4c9fb17672b981f854d_2_1035x715.jpeg 1.5x, https://discuss.pytorch.org/uploads/default/optimized/3X/7/6/768ad8b8df7c7f3ea825d4c9fb17672b981f854d_2_1380x954.jpeg 2x" data-dominant-color="C2C5BE"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">tstt</span><span class="informations">2048×1417 309 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>

username: ShanakaRG
cooked: <p>Thank you very much for your explanation <a class="mention" href="/u/j_johnson">@J_Johnson</a>. i think this is the answer i expected but can you confirm it by looking at the figure i attached to this thread ?</p>

username: ptrblck
cooked: <p>Thanks for clarifying. <a class="mention" href="/u/j_johnson">@J_Johnson</a> is right and the order will be the same. Shuffling the kernels would also break the training.<br>
<a href="https://discuss.pytorch.org/t/visualizing-the-outputs-of-kernels-instead-of-the-outputs-of-filters/137266/4">This post</a> visualizes the processing and also links to another code snippet verifying the results.</p>

username: ShanakaRG
cooked: <p>Thank you, <a class="mention" href="/u/ptrblck">@ptrblck</a>; the link helps me to understand the case.</p>
<p>I have another problem. let’s take my input as X in shape ( N, C, T, V). N is batch size, C is channels, T frames, V points. So if I need to encode a single for a given channel c1 for a given point v1  using a 1D conv network,  i have to select X[:,c1,T,v1].  Lets assume that the 1D network is shared and to encoder the signals for every point and every channel i have to use for loops as</p>
<pre><code class="lang-auto">class EnCo1D(nn.Conv1d):
    def __init__(self, *args, **kwargs):
        super(EnCo1D, self).__init__(*args, **kwargs)

    def forward(self, x, squeeze=False):
        # x: N x C x L
        if x.dim() not in [2, 3]:
            raise RuntimeError("{} accept 2/3D tensor as input".format(
                self.__name__))
        x = super().forward(x if x.dim() == 3 else torch.unsqueeze(x, 1))
        if squeeze:
            x = torch.squeeze(x)
        return x

for channel in range (0,x.shape[1]):
    for points  in range (0,x.shape[3]):
        s = EnCo1D(x[:,channel ,:,points ])
     
</code></pre>
<p>Here the network is a encoding network which has a 1D conv blocks. Although my target is accomplished I felt that the code i used is not optimised. So can you help me to implement this one in much professional manner ?</p>