我正在嘗試使用 PyTorch 查找道路車道。我創建了資料集和我的模型。但是當我嘗試訓練我的模型時,我得到了mat1 and mat2 shapes cannot be multiplied (4x460800 and 80000x16)
錯誤。我嘗試過其他主題的解決方案,但這些解決方案對我沒有多大幫助。
我的資料集是一堆帶有驗證影像的道路影像。我有包含影像名稱的 .csv 檔案(例如“image1.jpg,image2.jpg”)。影像和驗證影像的原始尺寸為 1280x720。我在我的資料集代碼中將它們轉換為 200x200。
道路圖:
驗證圖片:
這是我的資料集:
import os
import pandas as pd
import random
import torch
import torchvision.transforms.functional as TF
from torch.utils.data import Dataset
from torchvision import transforms
from PIL import Image
class RNetDataset(Dataset):
def __init__(self, csv_file, root_dir, val_dir, transform=None):
self.annotations = pd.read_csv(csv_file)
self.root_dir = root_dir
self.val_dir = val_dir
self.transform = transform
def __len__(self):
return len(self.annotations)
def __getitem__(self, index):
img_path = os.path.join(self.root_dir, self.annotations.iloc[index, 0])
image = Image.open(img_path).convert('RGB')
mask_path = os.path.join(self.val_dir, self.annotations.iloc[index, 0])
mask = Image.open(mask_path).convert('RGB')
transform = transforms.Compose([
transforms.Resize((200, 200)),
transforms.ToTensor()
])
if self.transform:
image = self.transform(image)
mask = self.transform(mask)
return image, mask
我的模型:
import torch
import torch.nn as nn
class RNet(nn.Module):
def __init__(self):
super().__init__()
self.cnn_layers = nn.Sequential(
# Conv2d, 3 inputs, 128 outputs
# 200x200 image size
nn.Conv2d(3, 128, kernel_size=3, stride=1, padding=1),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2),
# Conv2d, 128 inputs, 64 outputs
# 100x100 image size
nn.Conv2d(128, 64, kernel_size=3, stride=1, padding=1),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2),
# Conv2d, 64 inputs, 32 outputs
# 50x50 image size
nn.Conv2d(64, 32, kernel_size=3, stride=1, padding=1),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2)
)
self.linear_layers = nn.Sequential(
# Linear, 32*50*50 inputs, 16 outputs
nn.Linear(32 * 50 * 50, 16),
# Linear, 16 inputs, 3 outputs
nn.Linear(16, 3)
)
def forward(self, x):
x = self.cnn_layers(x)
x = x.view(x.size(0), -1)
x = self.linear_layers(x)
return x
如何避免此錯誤并在這些驗證影像上訓練我的影像?
uj5u.com熱心網友回復:
答案:在您的情況下,NN 輸入具有 shape (3, 1280, 720)
,而不是(3, 200, 200)
您想要的。transform
可能您忘記修改RNetDataset
. 它保持不變None
,因此不應用變換并且不調整影像大小。另一種可能性是由于以下幾行而發生這種情況:
transform = transforms.Compose([
transforms.Resize((200, 200)),
transforms.ToTensor()
])
if self.transform:
image = self.transform(image)
mask = self.transform(mask)
您有兩個名為 的變數transform
,但其中一個帶有self.
- 也許您把它們搞砸了。驗證它,問題應該消失。
我是如何想到的: 460800
顯然是在線性層之前重塑后的張量大小。根據架構,處理的張量self.cnn_layers
應該有 32 層,所以它的高度乘以寬度應該是460800 / 32 = 14400
. 假設它的高度 = H
,寬度 = W
,所以H x W = 14400
。讓我們了解一下,在這種情況下,原始輸入大小是多少?nn.MaxPool2d(kernel_size=2, stride=2)
layer 將高度和寬度除以 2,它發生了 3 次。因此,原始輸入大小為8H x 8W = 64 x 14400 = 936000
. 最后,請注意936000 = 1280 * 720
. 這不可能是一個神奇的巧合。結案!
另一個建議:即使您正確應用轉換,您的代碼也可能無法正常作業。假設您有一個 size 的輸入(4, 3, 200, 200)
,其中 4 是批量大小。架構中的層將按如下方式處理此輸入:
nn.Conv2d(3, 128, kernel_size=3, stride=1, padding=1) # -> (4, 128, 200, 200)
nn.MaxPool2d(kernel_size=2, stride=2) # -> (4, 128, 100, 100)
nn.Conv2d(128, 64, kernel_size=3, stride=1, padding=1) # -> (4, 64, 100, 100)
nn.MaxPool2d(kernel_size=2, stride=2) # -> (4, 64, 50, 50)
nn.Conv2d(64, 32, kernel_size=3, stride=1, padding=1) # -> (4, 32, 50, 50)
nn.MaxPool2d(kernel_size=2, stride=2) # -> (4, 32, 25, 25)
所以,你的第一層self.linear_layers
應該不是nn.Linear(32 * 50 * 50, 16)
,而是nn.Linear(32 * 25 * 25, 16)
。有了這個改變,一切都應該沒問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/471454.html