AttributeError: 'list' object has no attribute 'size'

I am using an LSTM network multiclass problem setting but i get the above error. Any hints on where to look would be helpful. Thanks

class SequenceModel(nn.Module):
    def __init__(self, n_features, n_classes, n_hidden=256, n_layers=3):
        super().__init__()

        self.lstm = torch.nn.LSTM(input_size=n_features,
                                 hidden_size=n_hidden,
                                 num_layers=n_layers, 
                                 batch_first=True,
                                 dropout=0.25)
        self.classifier = torch.nn.Linear(n_hidden, n_classes)

    def forward(self, x):
      self.lstm.flatten_parameters()
      _, (hidden, _) = self.lstm(x)
      out = hidden[-1] # get the last state of the last layer
      return self.classifier(out)


#Print smaple output
sample = next(iter(train_set))
out = SequenceModel(39, 5)(sample["sequence"])
c = torch.nn.CrossEntropyLoss()
c(out, sample["label"])
#data module for lightning
class PostDataModule(pl.LightningDataModule):
    def __init__(self, train_seq, test_seq, batch_size):
        super().__init__()
        self.train_seq = train_seq
        self.test_seq  = test_seq
        self.batch_size= batch_size

    def setup(self, stage=None):
        self.train_dataset = Post_data(self.train_seq)
        self.test_dataset  = Post_data(self.test_seq) 

    def train_dataloader(self):
        return DataLoader(
            self.train_dataset,
            batch_size=self.batch_size,
            shuffle=True,
            num_workers=cpu_count()
        )

    def val_dataloader(self):
        return DataLoader(
            self.test_dataset,
            batch_size=self.batch_size,
            shuffle=False,
            num_workers=cpu_count()
        )

    def test_dataloader(self):
        return DataLoader(
            self.test_dataset,
            batch_size=self.batch_size,
            shuffle=False,
            num_workers=cpu_count()
        )
from multiprocessing import cpu_count
# from pytorch_lightning.metrics.functional import accuracy

class LamePrediction(pl.LightningModule):
    def __init__(self, n_features:int, n_classes:int):
        super().__init__()
        self.model     = SequenceModel(n_features, n_classes)
        self.criterion = torch.nn.CrossEntropyLoss()

    def forward(self, x, labels):
        output = self.model(x)
        loss = 0
        if labels is not None:
            loss = self.criterion(output, labels)
        return loss, output

    def training_step(self, batch, batch_idx):
        sequence = batch["sequence"]
        labels = batch["label"]
        loss, outputs = self(sequences, labels)
        predictions = torch.argmax(outputs, dim=1)
        accuracy = torchmetrics.Accuracy()
        step_accuracy = accuracy(predictions, labels)

        self.log("train_loss", loss, prog_bar=True, logger=True)
        self.log("train_accuracy", step_accuracy, prog_bar=True, logger=True)

        return {"loss":loss, "accuracy":step_accuracy}

    def validation_step(self, batch, batch_idx):
        sequence = batch["sequence"]
        labels = batch["label"]
        loss, outputs = self(sequences, labels)
        predictions = torch.argmax(outputs, dim=1)
        accuracy = torchmetrics.Accuracy()
        step_accuracy = accuracy(predictions, labels)

        self.log("validation_loss", loss, prog_bar=True, logger=True)
        self.log("validation_accuracy", step_accuracy, prog_bar=True, logger=True)

        return {"loss":loss, "accuracy":step_accuracy}

    def test_step(self, batch, batch_idx):
        sequence = batch["sequence"]
        labels = batch["label"]
        loss, outputs = self(sequences, labels)
        predictions = torch.argmax(outputs, dim=1)
        accuracy = torchmetrics.Accuracy()
        step_accuracy = accuracy(predictions, labels)

        self.log("test_loss", loss, prog_bar=True, logger=True)
        self.log("test_accuracy", step_accuracy, prog_bar=True, logger=True)

        return {"loss":loss, "accuracy":step_accuracy}

    def configure_optimizers(self):
        return torch.optim.Adam(self.parameters(), lr=1e-3)

FEATURE_COLUMNS = 39
model = LamePrediction(n_features=39, 
                       n_classes=5)

in ()
----> 1 trainer.fit(model, data_module)

22 frames
/usr/local/lib/python3.7/dist-packages/torch/nn/modules/rnn.py in forward(self, input, hx)
668 else:
669 batch_sizes = None
→ 670 max_batch_size = input.size(0) if self.batch_first else input.size(1)
671 sorted_indices = None
672 unsorted_indices = None

AttributeError: ‘list’ object has no attribute ‘size’

Based on the error message you are passing a list to the model while tensors are expected.
Maybe unwrap the list and it would work.

1 Like

I figured that my data loader returns a sequence as i wanted and when I pass it through the model it works but when I put it in this class below i get a class list back somehow

#data module for lightning
class PostDataModule(pl.LightningDataModule):
    def __init__(self, train_seq, test_seq, batch_size):
        super().__init__()
        self.train_seq = train_seq
        self.test_seq  = test_seq
        self.batch_size= batch_size

    def setup(self, stage=None):
        self.train_dataset = Post_data(self.train_seq)
        self.test_dataset  = Post_data(self.test_seq) 

    def train_dataloader(self):
        return DataLoader(
            self.train_dataset,
            batch_size=self.batch_size,
            shuffle=True,
            num_workers=cpu_count()
        )

    def val_dataloader(self):
        return DataLoader(
            self.test_dataset,
            batch_size=self.batch_size,
            shuffle=False,
            num_workers=cpu_count()
        )

    def test_dataloader(self):
        return DataLoader(
            self.test_dataset,
            batch_size=self.batch_size,
            shuffle=False,
            num_workers=cpu_count()
        )

I’m not familiar enough with Lightning and don’t know where the type is changed.