RuntimeError: shape '[10, 3, 150, 150]' is invalid for input of size 472500
RuntimeError: shape '[10, 3, 150, 150]' is invalid for input of size 472500
我正在尝试对 covid CT 数据集执行卷积运算,但不断出现此错误。我在 train loader 中的图像大小是 (10, 150, 150, 3),我使用 torch.reshape() 将其重塑为 [10, 3, 150, 150]。谁能帮我解决问题
我的 CNN 代码
class BConv(nn.Module):
def __init__(self, out=3):
super(BConv, self).__init__()
#(10, 150, 150, 3)
self.conv1=nn.Conv2d(in_channels=3,out_channels=12,kernel_size=3,stride=1,padding=1)
self.bn1=nn.BatchNorm2d(num_features=12)
self.relu1=nn.ReLU()
self.pool=nn.MaxPool2d(kernel_size=2)
self.conv2=nn.Conv2d(in_channels=12,out_channels=20,kernel_size=3,stride=1,padding=1)
self.relu2=nn.ReLU()
# self.conv3=nn.Conv2d(in_channels=20,out_channels=32,kernel_size=3,stride=1,padding=1)
# self.bn3=nn.BatchNorm2d(num_features=32)
# self.relu3=nn.ReLU()
self.fc=nn.Linear(in_features= 20*75*75, out_features=3)
def forward(self,input):
output=self.conv1(input)
#print("output 1", output.shape)
output=self.bn1(output)
#print("output 1", output.shape)
output=self.relu1(output)
#print("output 1", output.shape)
output=self.pool(output)
#print("output 1", output.shape)
output=self.conv2(output)
#print("output 1", output.shape)
output=self.relu2(output)
#print("output 1", output.shape)
# output=self.conv3(output)
# output=self.bn3(output)
# output=self.relu3(output)
print(output.shape)
#Above output will be in matrix form, with shape (256,32,75,75)
output=output.view(output.size(0), -1)
output=self.fc(output)
return output
数据预处理
class Ctdataset(Dataset):
def __init__(self, path):
self.data= pd.read_csv(path, delimiter=" ")
data= self.data.values.tolist()
self.image= []
self.labels=[]
for i in data:
self.image.append(i[0])
self.labels.append(i[1])
#print(len(self.image), len(self.labels))
#self.class_map = {"0": 0, "1":1 , "2": 2}
def __len__(self):
return len(self.image)
def __getitem__(self, idx):
img_path = os.path.join("2A_images", self.image[idx])
img= Image.open(img_path).convert("RGB")
img= img.resize((150, 150))
img= np.array(img)
img= img.astype(float)
return img, label
这里我考虑的是您的整个模型,包括由 conv3
、bn3
和 relu3
组成的第三个块。有几点需要注意:
整形与排列轴有很大不同。当您说您的输入形状为 (batch_size, 150, 150, 3)
时,这意味着通道轴在最后。由于 PyTorch 2D 内置层以 NHW
格式工作,因此您需要排列轴:您可以使用 torch.Tensor.permute
:
>>> x = torch.rand(10, 150, 150, 3)
>>> x.permute(0, 3, 1, 2).shape
(10, 3, 150, 150)
假设您的输入形状为 (batch_size, 3, 150, 150)
,那么 relu3
的输出形状将为 (32, 75, 75)
。因此,下面的全连接层必须恰好具有 32*75*75
个输入特征。
但是,您需要像在代码中使用 view
: output = output.view(output.size(0), -1)
一样展平此张量。另一种方法是定义一个 self.flatten = nn.Flatten()
层并用 output = self.flatten(output)
.
调用它
从 PyTorch v1.8.0 开始,在全连接层中设置 in_features
的替代方法是使用 nn.LazyLinear
它将根据第一个推理为您初始化它:
>>> self.fc = nn.LazyLinear(out_features=3)
旁注:您不需要使用 relu1
、relu2
和 relu3
定义单独的 ReLU 层,因为它们是非参数函数:
>>> self.relu = nn.ReLU()
完整代码供参考:
class BConv(nn.Module):
def __init__(self, out=3):
super().__init__()
# input shape (10, 150, 150, 3)
self.conv1 = nn.Conv2d(3, 12,kernel_size=3, stride=1, padding=1)
self.bn1 = nn.BatchNorm2d(num_features=12)
self.pool = nn.MaxPool2d(kernel_size=2)
self.conv2 = nn.Conv2d(12, 20,kernel_size=3, stride=1, padding=1)
self.conv3 = nn.Conv2d(20, 32, kernel_size=3, stride=1, padding=1)
self.bn3 = nn.BatchNorm2d(num_features=32)
self.relu = nn.ReLU()
self.flatten = nn.Flatten()
self.fc = nn.Linear(in_features=32*75*75, out_features=out)
def forward(self,input):
output = input.permute(0, 3, 1, 2)
output = self.conv1(output)
output = self.bn1(output)
output = self.relu(output)
output = self.pool(output)
output = self.conv2(output)
output = self.relu(output)
output = self.conv3(output)
output = self.bn3(output)
output = self.relu(output)
output = self.flatten(output)
output = self.fc(output)
return output
我正在尝试对 covid CT 数据集执行卷积运算,但不断出现此错误。我在 train loader 中的图像大小是 (10, 150, 150, 3),我使用 torch.reshape() 将其重塑为 [10, 3, 150, 150]。谁能帮我解决问题
我的 CNN 代码
class BConv(nn.Module):
def __init__(self, out=3):
super(BConv, self).__init__()
#(10, 150, 150, 3)
self.conv1=nn.Conv2d(in_channels=3,out_channels=12,kernel_size=3,stride=1,padding=1)
self.bn1=nn.BatchNorm2d(num_features=12)
self.relu1=nn.ReLU()
self.pool=nn.MaxPool2d(kernel_size=2)
self.conv2=nn.Conv2d(in_channels=12,out_channels=20,kernel_size=3,stride=1,padding=1)
self.relu2=nn.ReLU()
# self.conv3=nn.Conv2d(in_channels=20,out_channels=32,kernel_size=3,stride=1,padding=1)
# self.bn3=nn.BatchNorm2d(num_features=32)
# self.relu3=nn.ReLU()
self.fc=nn.Linear(in_features= 20*75*75, out_features=3)
def forward(self,input):
output=self.conv1(input)
#print("output 1", output.shape)
output=self.bn1(output)
#print("output 1", output.shape)
output=self.relu1(output)
#print("output 1", output.shape)
output=self.pool(output)
#print("output 1", output.shape)
output=self.conv2(output)
#print("output 1", output.shape)
output=self.relu2(output)
#print("output 1", output.shape)
# output=self.conv3(output)
# output=self.bn3(output)
# output=self.relu3(output)
print(output.shape)
#Above output will be in matrix form, with shape (256,32,75,75)
output=output.view(output.size(0), -1)
output=self.fc(output)
return output
数据预处理
class Ctdataset(Dataset):
def __init__(self, path):
self.data= pd.read_csv(path, delimiter=" ")
data= self.data.values.tolist()
self.image= []
self.labels=[]
for i in data:
self.image.append(i[0])
self.labels.append(i[1])
#print(len(self.image), len(self.labels))
#self.class_map = {"0": 0, "1":1 , "2": 2}
def __len__(self):
return len(self.image)
def __getitem__(self, idx):
img_path = os.path.join("2A_images", self.image[idx])
img= Image.open(img_path).convert("RGB")
img= img.resize((150, 150))
img= np.array(img)
img= img.astype(float)
return img, label
这里我考虑的是您的整个模型,包括由 conv3
、bn3
和 relu3
组成的第三个块。有几点需要注意:
整形与排列轴有很大不同。当您说您的输入形状为
(batch_size, 150, 150, 3)
时,这意味着通道轴在最后。由于 PyTorch 2D 内置层以NHW
格式工作,因此您需要排列轴:您可以使用torch.Tensor.permute
:>>> x = torch.rand(10, 150, 150, 3) >>> x.permute(0, 3, 1, 2).shape (10, 3, 150, 150)
假设您的输入形状为
(batch_size, 3, 150, 150)
,那么relu3
的输出形状将为(32, 75, 75)
。因此,下面的全连接层必须恰好具有32*75*75
个输入特征。但是,您需要像在代码中使用
调用它view
:output = output.view(output.size(0), -1)
一样展平此张量。另一种方法是定义一个self.flatten = nn.Flatten()
层并用output = self.flatten(output)
.从 PyTorch v1.8.0 开始,在全连接层中设置
in_features
的替代方法是使用nn.LazyLinear
它将根据第一个推理为您初始化它:>>> self.fc = nn.LazyLinear(out_features=3)
旁注:您不需要使用
relu1
、relu2
和relu3
定义单独的 ReLU 层,因为它们是非参数函数:>>> self.relu = nn.ReLU()
完整代码供参考:
class BConv(nn.Module):
def __init__(self, out=3):
super().__init__()
# input shape (10, 150, 150, 3)
self.conv1 = nn.Conv2d(3, 12,kernel_size=3, stride=1, padding=1)
self.bn1 = nn.BatchNorm2d(num_features=12)
self.pool = nn.MaxPool2d(kernel_size=2)
self.conv2 = nn.Conv2d(12, 20,kernel_size=3, stride=1, padding=1)
self.conv3 = nn.Conv2d(20, 32, kernel_size=3, stride=1, padding=1)
self.bn3 = nn.BatchNorm2d(num_features=32)
self.relu = nn.ReLU()
self.flatten = nn.Flatten()
self.fc = nn.Linear(in_features=32*75*75, out_features=out)
def forward(self,input):
output = input.permute(0, 3, 1, 2)
output = self.conv1(output)
output = self.bn1(output)
output = self.relu(output)
output = self.pool(output)
output = self.conv2(output)
output = self.relu(output)
output = self.conv3(output)
output = self.bn3(output)
output = self.relu(output)
output = self.flatten(output)
output = self.fc(output)
return output