szymonmaszke / torchlayers

Shape and dimension inference (Keras-like) for PyTorch layers and neural networks
MIT License
568 stars 46 forks source link

Adding tl.Linear() in autoencoder model #9

Closed soulhi-vz closed 4 years ago

soulhi-vz commented 4 years ago

Hi ,

The following model works without the tl layer:

class Autoencoder(nn.Module):
    def __init__(self):
        super(
            Autoencoder, self
        ).__init__()  # This should apply Uniform random values to weights and biases.

        self.encoder = nn.Sequential(
            nn.Conv1d(in_channels, out_channels, kernel_size),
            nn.ReLU(True),
            nn.Conv1d(out_channels, in_channels, kernel_size),
            nn.ReLU(True),
            tl.Linear(2),
        )

        self.decoder = nn.Sequential(
            nn.ConvTranspose1d(in_channels, out_channels, kernel_size),
            nn.ReLU(True),
            nn.ConvTranspose1d(out_channels, in_channels, kernel_size),
        )

    def forward(self, x):
        encoded = self.encoder(x)
        decoded = self.decoder(encoded)
        return decoded, encoded

I have added tl.Linear(2) as the compressed layer between the encoder and decoder.

Autoencoder_tl = tl.build(Autoencoder(), Train_x_t_e) will throw this error:

Train_x_t_e.shape ---> torch.Size([210, 719, 11])

RuntimeErrorTraceback (most recent call last)

in ----> 1 Autoencoder_tl = tl.build(Autoencoder(), Train_x_t_e) ~/.local/lib/python3.7/site-packages/torchlayers/__init__.py in build(module, *args, **kwargs) 65 with torch.no_grad(): 66 module.eval() ---> 67 module(*args, **kwargs) 68 module.train() 69 module = torch_compile(module) /opt/conda/lib/python3.7/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs) 548 result = self._slow_forward(*input, **kwargs) 549 else: --> 550 result = self.forward(*input, **kwargs) 551 for hook in self._forward_hooks.values(): 552 hook_result = hook(self, input, result) in forward(self, x) 18 19 def forward(self,x): ---> 20 encoded = self.encoder(x) 21 decoded = self.decoder(encoded) 22 return decoded, encoded /opt/conda/lib/python3.7/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs) 548 result = self._slow_forward(*input, **kwargs) 549 else: --> 550 result = self.forward(*input, **kwargs) 551 for hook in self._forward_hooks.values(): 552 hook_result = hook(self, input, result) /opt/conda/lib/python3.7/site-packages/torch/nn/modules/container.py in forward(self, input) 98 def forward(self, input): 99 for module in self: --> 100 input = module(input) 101 return input 102 /opt/conda/lib/python3.7/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs) 548 result = self._slow_forward(*input, **kwargs) 549 else: --> 550 result = self.forward(*input, **kwargs) 551 for hook in self._forward_hooks.values(): 552 hook_result = hook(self, input, result) ~/.local/lib/python3.7/site-packages/torchlayers/_dev_utils/infer.py in forward(self, inputs, *args, **kwargs) 212 infered_module = getattr(self, module) 213 --> 214 return infered_module(inputs, *args, **kwargs) 215 216 return forward /opt/conda/lib/python3.7/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs) 548 result = self._slow_forward(*input, **kwargs) 549 else: --> 550 result = self.forward(*input, **kwargs) 551 for hook in self._forward_hooks.values(): 552 hook_result = hook(self, input, result) /opt/conda/lib/python3.7/site-packages/torch/nn/modules/linear.py in forward(self, input) 85 86 def forward(self, input): ---> 87 return F.linear(input, self.weight, self.bias) 88 89 def extra_repr(self): /opt/conda/lib/python3.7/site-packages/torch/nn/functional.py in linear(input, weight, bias) 1610 ret = torch.addmm(bias, input, weight.t()) 1611 else: -> 1612 output = input.matmul(weight.t()) 1613 if bias is not None: 1614 output += bias RuntimeError: size mismatch, m1: [150990 x 7], m2: [719 x 2] at /pytorch/aten/src/TH/generic/THTensorMath.cpp:41
szymonmaszke commented 4 years ago

Hi @soulhi-vz. Next time please post an issue regarding code not working as expected to StackOverflow, I would like to keep issues clean for implementation bugs/feature requests, thanks.

Everything works as expected, torch.nn.Linear cannot be applied to Conv1d without torch.nn.MaxPool1d (or tl.MaxPool), at least not in the way you think it should be (encoder's last Conv1d last dimension [which can vary] will be used to infer input shape to tl.Linear, at least for torchlayers-nightly package [0.1.1 has bug of not working as PyTorch original nn.Linear for multiple dimensions]).

Please use tl.GlobalMaxPool before tl.Linear or tl.Flatten() (and use tl.Reshape before nn.ConvTranspose1d as well) or just try to rewrite it in pure PyTorch and post to StackOverflow in case you have any questions.