pytorch报错整理(1):搭建卷积层时,误用Conv2d和conv2d而引发的错误

最近为了找创新点,重拾pytorch,在看小土堆的网课时,报了些错误,于是整理了一下。

一、Conv2d和conv2d的不同及其报错

(1)需要引用的库不同
Conv2d需要引用torch.nn,(即import torch.nn)
conv2d是torch.nn.functional中的方法,需要引用torch.nn.functional(即 import torch.nn.functional),引用错会报NameError: name ‘conv2d’ is not defined
(2)传参方式不同
Conv2d()的传参方式如下:
在这里插入图片描述
in_channels代表输入图片的通道数
out_channels代表输出图片的通道数
kernal_size代表卷积核的大小,如果是nn的卷积核,则kernal_size = n,如果是ab的卷积核,则kernal_size = [a,b],在这里Conv2d()的作用是在前向网络中搭建一个卷积层,所以用户没法自定义卷积核中的每个参数,只能由pytorch自己初始化。
stride代表卷积核的步长
padding代表在图片周围补充的像素数量,如果在图片上下分别补充了x1行0,在图片的左右分别补充了x2列0,那么我们可以令padding = [x1, x2]
dilation代表卷积核之间参数的距离,如果dilation = 1,那么卷积核中各参数连续排列,如果dilation = 2,那么卷积核中各参数(在横向和纵向上)相距一个像素。(如下图所示)
pytorch报错整理(1):搭建卷积层时,误用Conv2d和conv2d而引发的错误_第1张图片

其余参数一般保持默认
conv2d()的传参方式如下:
在这里插入图片描述
input是输入图像,必须是tensor形式,且需要通过reshape()转换为特定的格式,具体转换方式见代码。
(tensor形式可使用torchvision.transforms.ToTensor(imag)进行类型转换)
这里的weight其实是卷积核kernal,也必须是tensor形式
conv2d()执行的操作是:用我们定义好的卷积核kernal对输入图像进行卷积操作,而不是作为前向通道的一部分。
如果误将conv2d的参数传给Conv2d,例如误将conv2d(input, kernal, stride=1)写成Conv2d(input,kernal,kernel_size=3,stride=1),那么可能报错:RuntimeError: Boolean value of Tensor with more than one value is ambiguous

代码演示

conv2d代码演示
程序功能:输入一个矩阵或图像(input),接着自定义一个卷积核kernal,用kernal对输入矩阵进行卷积操作

import torch.nn.functional as F
#import torch.nn as F
input = torch.tensor([[1, 2, 0, 1, 1],
                      [2, 2, 0, 3, 6],
                      [1, 2, 5, 3, 1],
                      [5, 3, 0, 4, 1],
                      [1, 2, 3, 4, 5]])

kernal = torch.tensor([[1, 2, 1],
                       [0, 0, 0],
                       [-1, -2, -1]])

input = torch.reshape(input, (1, 1, 5, 5))  #(channel数为1, ??, input的size为4*5)
kernal = torch.reshape(kernal, (1, 1, 3, 3))  #(channel数为1, ??, input的size为3*3)
                                              #RuntimeError: shape '[1, 1, 3, 3]' is invalid for input of size 20
                                              # 这种错误是因为reshape的第一个参数和第二个没对应起来
print(input.shape)
print(kernal.shape)

output = F.conv2d(input, kernal, stride=1)  #之前使用Conv2d,一直不好使。后来发现要用conv2d,又报错找不到conv2d,但是conv2d下还不报错,以为是版本问题,
                                             #最后发现我在一开始引用了torch.nn ,改为import torch.nn.functional 问题解决。
#output2 = F.Conv2d(input, kernal, kernel_size=3,stride=1)  #要import torch.nn 才能使用Conv2d,但是使用方法是不同的
print(output)

Conv2d代码演示
程序功能:搭建一个只有单层卷积层的前向传播网络,卷积核由pytorch随机初始化,卷积核大小为3

#搭建一个卷积层
import torch
import torchvision
from tensorboardX import SummaryWriter
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader
from torchvision.transforms import ToTensor

dataset = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor(),download=True)  #获取测试集

dataloader = DataLoader(dataset, batch_size=64)  #以64张为一组,抽取数据

class single_conv(nn.Module):

    def __init__(self):
        super().__init__()
        self.conv1 = Conv2d(in_channels=3, out_channels=6, kernel_size=3, stride=1, bias=True)

    def forward(self, input):
        output = self.conv1(input)
        return output

writer = SummaryWriter("./Ni_Conv2d")
Ni_Conv2d = single_conv()
step = 1
for data in dataloader:
    image, target = data
    print(image.type)
    # x = ToTensor(image)  image已经是tensor数据类型了,所以不需要转换了
    output = Ni_Conv2d(image)  #这里写Ni_Conv2d()或者Ni_Conv2d.forward()都是可以的,前者是通过内置的__call__来调用的
    print(image.shape)    # torch.Size([64, 3, 32, 32])
    print(output.shape)   # torch.Size([64, 6, 30, 30])  从数据结果来看,因为未加padding,所以从32*32变为了30*30
    output2 = torch.reshape(output, (-1, 3, 30, 30))  #最好一步一步实例化,而不要只写一行 torch.reshape(output, (-1, 3, 30, 30)),
                                                      # 这样是没法改变output的数据形式的
    print(output2.shape)
#output是六通道的,无法显示所以我们需要从【64, 6, 30, 30】 -->【xx, 3, 30, 30】  所以xx=128
    writer.add_images("output", output2, step)
    step = step + 1

writer.close()

你可能感兴趣的:(pytorch,深度学习,python)