Trainable Hamming Window

username: lfolle
cooked: <p>Hi,</p>
<p>I would like to train a network with the hamming window <a href="https://pytorch.org/docs/stable/generated/torch.hamming_window.html#torch-hamming-window" rel="noopener nofollow ugc">link</a> parametrized with the coefficients alpha and beta.<br>
However, I can’t do</p>
<pre><code class="lang-auto">def __init__(self):
    super().__init__()
    self.alpha = torch.nn.Parameter(1.0)
    self.beta = torch.nn.Parameter(1.0)

def forward(self, data):
    hw = torch.hamming_window(10, True, self.alpha, self.beta)
    return hw * data
</code></pre>
<p>with alpha, beta beign torch.nn.Parameter since <code>torch.hamming_window</code> expects float and not Parameters.<br>
How would I do this?</p>

username: KFrank
cooked: <p>Hi Lukas!</p>
<aside class="quote no-group" data-username="lfolle" data-post="1" data-topic="150132" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/l/e9bcb4/48.png" class="avatar"> lfolle:</div>
<blockquote>
<p><code>torch.hamming_window</code> expects float and not Parameters.</p>
</blockquote>
</aside>
<p>Yes, you’re right – you can’t use <code>Parameter</code>s for <code>alpha</code> and <code>beta</code>.<br>
Well, that’s annoying (and seemingly unnecessary).</p>
<p>As a work-around, you can scale your <code>hw</code> with <code>Parameter</code>s after<br>
creating it:</p>
<pre><code class="lang-plaintext">&gt;&gt;&gt; import torch
&gt;&gt;&gt; torch.__version__
'1.11.0'
&gt;&gt;&gt; alpha = torch.nn.Parameter (torch.tensor ([1.0]))
&gt;&gt;&gt; beta = torch.nn.Parameter (torch.tensor ([1.0]))
&gt;&gt;&gt; hw_tmp = torch.hamming_window (10, True, 0.0, -1.0)
&gt;&gt;&gt; hw = alpha - beta * hw_tmp
&gt;&gt;&gt; hw
tensor([0.0000, 0.1910, 0.6910, 1.3090, 1.8090, 2.0000, 1.8090, 1.3090, 0.6910,
        0.1910], grad_fn=&lt;SubBackward0&gt;)
</code></pre>
<p>Best.</p>
<p>K. Frank</p>

username: lfolle
cooked: <p>Hi Frank,</p>
<p>Thank you for your reply! That indeed did the trick.<br>
In case someone has a similar problem, here´s how I implemented the hamming window as a trainable layer for 3D data:</p>
<pre><code class="lang-auto">class HammingWindowParametrized(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.alpha = torch.nn.Parameter(torch.tensor(0.54))
        self.beta = torch.nn.Parameter(torch.tensor(0.46))
    
    def hamming_function(self, data):
        window_0 = self.alpha - self.beta * torch.cos(torch.pi * 2 * torch.linspace(0, data.shape[0], data.shape[0]) / data.shape[0])
        data = data * window_0.reshape((-1, 1, 1))
        window_1 = self.alpha - self.beta * torch.cos(torch.pi * 2 * torch.linspace(0, data.shape[1], data.shape[1]) / data.shape[1])
        data = data * window_1.reshape((1, -1, 1))
        window_2 = self.alpha - self.beta * torch.cos(torch.pi * 2 * torch.linspace(0, data.shape[2], data.shape[2]) / data.shape[2])
        data = data * window_2.reshape((1, 1, -1))
        return data
    
    def forward(self, data):
        shape = data.shape
        data = data.squeeze()
        data = self.hamming_function(data)
        data = data.reshape(shape)
        return data 
</code></pre>