| 79 | |
| 80 | |
| 81 | class ConvStacks(nn.Module): |
| 82 | def __init__(self, idim=80, n_layers=5, n_chans=256, odim=32, kernel_size=5, norm='gn', |
| 83 | dropout=0, strides=None, res=True): |
| 84 | super().__init__() |
| 85 | self.conv = torch.nn.ModuleList() |
| 86 | self.kernel_size = kernel_size |
| 87 | self.res = res |
| 88 | self.in_proj = Linear(idim, n_chans) |
| 89 | if strides is None: |
| 90 | strides = [1] * n_layers |
| 91 | else: |
| 92 | assert len(strides) == n_layers |
| 93 | for idx in range(n_layers): |
| 94 | self.conv.append(ConvBlock( |
| 95 | n_chans, n_chans, kernel_size, stride=strides[idx], norm=norm, dropout=dropout)) |
| 96 | self.out_proj = Linear(n_chans, odim) |
| 97 | |
| 98 | def forward(self, x, return_hiddens=False): |
| 99 | """ |
| 100 | |
| 101 | :param x: [B, T, H] |
| 102 | :return: [B, T, H] |
| 103 | """ |
| 104 | x = self.in_proj(x) |
| 105 | x = x.transpose(1, -1) # (B, idim, Tmax) |
| 106 | hiddens = [] |
| 107 | for f in self.conv: |
| 108 | x_ = f(x) |
| 109 | x = x + x_ if self.res else x_ # (B, C, Tmax) |
| 110 | hiddens.append(x) |
| 111 | x = x.transpose(1, -1) |
| 112 | x = self.out_proj(x) # (B, Tmax, H) |
| 113 | if return_hiddens: |
| 114 | hiddens = torch.stack(hiddens, 1) # [B, L, C, T] |
| 115 | return x, hiddens |
| 116 | return x |
| 117 | |
| 118 | |
| 119 | class PitchExtractor(nn.Module): |