【问题标题】:Pytorch Data Loader: getattr(): attribute name must be stringPytorch 数据加载器:getattr():属性名称必须是字符串
【发布时间】:2022-06-10 22:32:19
【问题描述】:

有人可以向我解释为什么这个代码:

import torch
from torch_geometric.datasets import TUDataset
from torch.nn import Linear
import torch.nn.functional as F
from torch_geometric.nn import GCNConv
from torch_geometric.nn import global_mean_pool
from torch_geometric.data import Data, Dataset,DataLoader,DenseDataLoader,InMemoryDataset
from torch_geometric.data import Data, Dataset
from sklearn import preprocessing
device = torch.device('cpu')
torch.backends.cudnn.benchmark = True
import joblib

edge_origins = [0,1,2,3,4,5,6,7,8,10,11,12,13]
edge_destinations = [1,2,3,4,5,6,7,8,9,11,12,13,14]
target = [0,1]
x = [[0.1,0.5,0.2],[0.5,0.6,0.23]]

edge_index = torch.tensor([edge_origins, edge_destinations], dtype=torch.long)
x = torch.tensor(x, dtype=torch.float)
y = torch.tensor(target, dtype=torch.long)

dataset = Data(x=x, edge_index=edge_index, y=y, num_classes = len(set(target)))  #making the graph of nodes and edges

train_loader = DataLoader(dataset, batch_size=64, shuffle=True)
for x,y in train_loader:
    print(x)

产生这个错误:

    for x,y in train_loader:
  File "/root/miniconda3/lib/python3.7/site-packages/torch/utils/data/dataloader.py", line 346, in __next__
    data = self._dataset_fetcher.fetch(index)  # may raise StopIteration
  File "/root/miniconda3/lib/python3.7/site-packages/torch/utils/data/_utils/fetch.py", line 44, in fetch
    data = [self.dataset[idx] for idx in possibly_batched_index]
  File "/root/miniconda3/lib/python3.7/site-packages/torch/utils/data/_utils/fetch.py", line 44, in <listcomp>
    data = [self.dataset[idx] for idx in possibly_batched_index]
  File "/root/miniconda3/lib/python3.7/site-packages/torch_geometric/data/data.py", line 92, in __getitem__
    return getattr(self, key, None)
TypeError: getattr(): attribute name must be string

编辑 1,作为更新:如果我输入:

train_loader = DataLoader(dataset, batch_size=64, shuffle=True)
it = iter(train_loader)
print(it)

返回:

<torch.utils.data.dataloader._SingleProcessDataLoaderIter object at 0x7f4aeb009590>

但是如果我尝试像这样遍历这个对象:

for x,i in enumerate(it):
    print(i)

它返回与以前相同的错误。

编辑 2:顺便提一下,我对打印出数据加载器属性并不是特别感兴趣,但接下来我要做的是将数据加载器输入到下面的代码中,并且当我使用当前的代码运行下面的代码时数据加载器,当我运行 train() 函数的for data in train_loader 行时,我收到上述关于属性名称必须为字符串的错误:

class GCN(torch.nn.Module):
    def __init__(self, hidden_channels):
        super(GCN, self).__init__()
        torch.manual_seed(12345)
        self.conv1 = GCNConv(dataset.num_node_features, hidden_channels)
        self.conv2 = GCNConv(hidden_channels, hidden_channels)
        self.conv3 = GCNConv(hidden_channels, hidden_channels)
        self.lin = Linear(hidden_channels, dataset.num_classes)

    def forward(self, x, edge_index, batch):
        # 1. Obtain node embeddings 
        x = self.conv1(x, edge_index)
        x = x.relu()
        x = self.conv2(x, edge_index)
        x = x.relu()
        x = self.conv3(x, edge_index)

        # 2. Readout layer
        x = global_mean_pool(x, batch)  # [batch_size, hidden_channels]

        # 3. Apply a final classifier
        x = F.dropout(x, p=0.5, training=self.training)
        x = self.lin(x)
        
        return x

model = GCN(hidden_channels=64)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
criterion = torch.nn.CrossEntropyLoss()


def train():
    model.train()

    for data in train_loader:  # Iterate in batches over the training dataset.
         out = model(data.x, data.edge_index, data.batch)  # Perform a single forward pass.
         loss = criterion(out, data.y)  # Compute the loss.
         loss.backward()  # Derive gradients.
         optimizer.step()  # Update parameters based on gradients.
         optimizer.zero_grad()  # Clear gradients.


def test(loader):
     model.eval()

     correct = 0
     for data in loader:  # Iterate in batches over the training/test dataset.
         out = model(data.x, data.edge_index, data.batch)  
         pred = out.argmax(dim=1)  # Use the class with highest probability.
         correct += int((pred == data.y).sum())  # Check against ground-truth labels.
     return correct / len(loader.dataset)  # Derive ratio of correct predictions.


for epoch in range(1, 171):
    train()
    train_acc = test(train_loader)
    test_acc = test(test_loader)
    print(f'Epoch: {epoch:03d}, Train Acc: {train_acc:.4f}, Test Acc: {test_acc:.4f}')

【问题讨论】:

    标签: python pytorch


    【解决方案1】:

    只要做:

    for x,i in enumerate(trainloader):
    

    DataLoader 对象已经是可迭代对象,enumerate 为可迭代对象添加了一个计数器。 iter 在 DataLoader 对象上生成一个迭代器,我怀疑在迭代器而不是可迭代对象上调用 enumerate 会导致上述错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-26
      • 1970-01-01
      • 1970-01-01
      • 2021-08-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多