在 pytorch 中使用 AdaptiveAvgPool2d 进行 CNN

问题描述 投票:0回答:1

我尝试用不同尺寸的图像训练 CNN,但它抛出错误

ValueError: expected sequence of length 1200 at dim 2 (got 1069)
当我将它们转换为张量时。

我认为这是因为图像尺寸不同。但我不想调整图像大小。如何使用 AdaptiveAvgPool2d?

这是我的代码:

def makeData():
    data = []
    # cat
    for i in range(1, 11):
        data.append({"path": "images/cat_" + str(i) + ".jpeg", "label": 1})
    # not cat
    for i in range(1, 11):
        data.append({"path": "images/not_cat_" + str(i) + ".jpeg", "label": 0})
    return data

def loadImage(path):
    return Image.open(path).convert('RGB')

class MyDataset(Data.Dataset):
    def __init__(self, data):
        self.data = data
        self.transform = transforms.Compose([
            transforms.ToTensor(),
            transforms.Normalize(mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5))  
        ])
    def __getitem__(self, idx):
        img = loadImage(self.data[idx]["path"])
        img = self.transform(img)
        label = torch.FloatTensor([self.data[idx]["label"]])
        return img, torch.FloatTensor(label)

    def __len__(self):
        return len(self.data)
    
def collate_fn(batch_list):
    data, labels = [], []
    for item in batch_list:
        data.append(item[0].tolist())
        labels.append(item[1].tolist())
    return torch.FloatTensor(data), torch.FloatTensor(labels)


loader = Data.DataLoader(MyDataset(makeData()), 2, True, collate_fn=collate_fn)
   

这是我的模型代码:

class CatModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 32, kernel_size=(3,3), stride=1, padding=1)
        self.act1 = nn.ReLU()
        self.drop1 = nn.Dropout(0.3)
 
        self.conv2 = nn.Conv2d(32, 32, kernel_size=(3,3), stride=1, padding=1)
        self.act2 = nn.ReLU()
        self.pool2 = nn.AdaptiveAvgPool2d((16, 16))
 
        self.flat = nn.Flatten()
 
        self.fc3 = nn.Linear(8192, 512)
        self.act3 = nn.ReLU()
        self.drop3 = nn.Dropout(0.5)
 
        self.fc4 = nn.Linear(512, 1)
 
    def forward(self, x):
        # input 3x32x32, output 32x32x32
        x = self.act1(self.conv1(x))
        x = self.drop1(x)
        # input 32x32x32, output 32x32x32
        x = self.act2(self.conv2(x))
        # input 32x32x32, output 32x16x16
        x = self.pool2(x)
        # input 32x16x16, output 8192
        x = self.flat(x)
        # input 8192, output 512
        x = self.act3(self.fc3(x))
        x = self.drop3(x)
        # input 512, output 1
        x = self.fc4(x)
        return nn.Sigmoid()(x)

我添加了 AdaptiveAvgPool2d 层以及一些 dropout 和线性层。

python pytorch conv-neural-network
1个回答
0
投票

该错误是由于尝试将不同尺寸的图像一起批处理而引起的。您需要在

transforms.Compose
之前向
transforms.ToTensor()
块添加调整大小转换,以使所有输入图像具有相同的大小。如果您查看文档,有几种方法可以做到这一点。

wrt

AdaptiveAvgPool2d
,这有不同的目的。使用固定窗口大小的最大池化的旧版 CNN 只能处理特定的输入大小,例如 224x224 图像。如果您使用不同的输入图像大小,则对于 CNN 编码器之后的线性层来说,您的池化输出将会太大或太小。
AdaptiveAvgPool2d
将张量池化为特定的所需输出大小。这允许编码器处理任何输入图像大小,并且仍然为最终线性层提供正确的池化大小。

© www.soinside.com 2019 - 2024. All rights reserved.