pytorch之卷积模块、池化、激活函数(可视化)

pytorch之卷积模块

卷积

卷积在 pytorch 中有两种方式,一种是 torch.nn.Conv2d(),一种是torch.nn.functional.conv2d(),这两种形式本质都是使用一个卷积操作这两种形式的卷积对于输入的要求都是一样的,首先需要输入是一个 torch.autograd.Variable() 的类型,大小是 (batch, channel, H, W),其中 batch 表示输入的一批数据的数目,第二个是输入的通道数,一般一张彩色的图片是 3,灰度图是 1,而卷积网络过程中的通道数比较大,会出现几十到几百的通道数,H 和 W 表示输入图片的高度和宽度,比如一个 batch 是 32 张图片,每张图片是 3 通道,高和宽分别是 50 和 100,那么输入的大小就是 (32, 3, 50, 100)

导入一些能够用到的模块

import numpy as np
import torch
from torch import nn
from torch.autograd import Variable
import torch.nn.functional as F
from PIL import Image
import matplotlib.pyplot as plt

im = Image.open('./1.jpg').convert('L') # 读入一张灰度图的图片
im = np.array(im, dtype='float32') # 将其转换为一个矩阵

#print(im.shape[0],im.shape[1])     448*448
# 可视化图片
plt.imshow(im.astype('uint8'), cmap='gray')

在这里插入图片描述

将图片矩阵转化为 pytorch tensor,并适配卷积输入的要求

im = torch.from_numpy(im.reshape((1, 1, im.shape[0], im.shape[1])))

定义一个算子对其进行轮廓检测

使用 nn.Conv2d

conv1 = nn.Conv2d(1, 1, 3, bias=False) # 定义卷积

sobel_kernel = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], dtype='float32') # 定义轮廓检测算子
sobel_kernel = sobel_kernel.reshape((1, 1, 3, 3)) # 适配卷积的输入输出
conv1.weight.data = torch.from_numpy(sobel_kernel) # 给卷积的 kernel 赋值

edge1 = conv1(Variable(im)) # 作用在图片上
edge1 = edge1.data.squeeze().numpy() # 将输出转换为图片的格式

可视化边缘检测之后的结果

plt.imshow(edge1, cmap='gray')

在这里插入图片描述

使用 F.conv2d

sobel_kernel = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], dtype='float32') # 定义轮廓检测算子
sobel_kernel = sobel_kernel.reshape((1, 1, 3, 3)) # 适配卷积的输入输出
weight = Variable(torch.from_numpy(sobel_kernel))

edge2 = F.conv2d(Variable(im), weight) # 作用在图片上
edge2 = edge2.data.squeeze().numpy() # 将输出转换为图片的格式
plt.imshow(edge2, cmap='gray')

在这里插入图片描述
可以看到两种形式能够得到相同的效果,使用 nn.Conv2d() 相当于直接定义了一层卷积网络结构,而使用 torch.nn.functional.conv2d() 相当于定义了一个卷积的操作,所以使用后者需要再额外去定义一个 weight,而且这个 weight 也必须是一个 Variable,而使用 nn.Conv2d() 则会帮我们默认定义一个随机初始化的 weight,如果需要修改,那么取出其中的值对其修改,如果不想修改,那么可以直接使用这个默认初始化的值,非常方便
实际使用中基本都使用 nn.Conv2d() 这种形式

池化层

卷积网络中另外一个非常重要的结构就是池化,这是利用了图片的下采样不变性,即一张图片变小了还是能够看出了这张图片的内容,而使用池化层能够将图片大小降低,非常好地提高了计算效率,同时池化层也没有参数。池化的方式有很多种,比如最大值池化,均值池化等等,在卷积网络中一般使用最大值池化。

在 pytorch 中最大值池化的方式也有两种,一种是 nn.MaxPool2d(),一种是 torch.nn.functional.max_pool2d(),他们对于图片的输入要求跟卷积对于图片的输入要求是一样了 举例说明

使用 nn.MaxPool2d

pool1 = nn.MaxPool2d(2, 2)
print('before max pool, image shape: {} x {}'.format(im.shape[2], im.shape[3]))
small_im1 = pool1(Variable(im))
small_im1 = small_im1.data.squeeze().numpy()
print('after max pool, image shape: {} x {} '.format(small_im1.shape[0], small_im1.shape[1]))
plt.imshow(small_im1, cmap='gray')

before max pool, image shape: 448 x 448
after max pool, image shape: 224 x 224

在这里插入图片描述
F.max_pool2d

print('before max pool, image shape: {} x {}'.format(im.shape[2], im.shape[3]))
small_im2 = F.max_pool2d(Variable(im), 2, 2)
small_im2 = small_im2.data.squeeze().numpy()
print('after max pool, image shape: {} x {} '.format(small_im1.shape[0], small_im1.shape[1]))
plt.imshow(small_im2, cmap='gray')

在这里插入图片描述
跟卷积层一样,实际使用中,一般使用 nn.MaxPool2d()

在实际应用中加入基层激活函数以及卷积层池化层的应用

im = torch.from_numpy(im.reshape((1, 1, im.shape[0], im.shape[1])))
conv1 = nn.Conv2d(1, 1, 3, bias=False) # 定义卷积

sobel_kernel = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], dtype='float32') # 定义轮廓检测算子
sobel_kernel = sobel_kernel.reshape((1, 1, 3, 3)) # 适配卷积的输入输出
conv1.weight.data = torch.from_numpy(sobel_kernel) # 给卷积的 kernel 赋值

edge1 = conv1(Variable(im)) # 作用在图片上
x=F.relu(edge1)
x=F.relu(x)
x=F.relu(x)#加入三层激活函数
pool1 = nn.MaxPool2d(2, 2)
x = pool1(Variable(x))
x = pool1(Variable(x))#加入两层池化
#edge2 = x.data.squeeze().numpy()
x = x.data.squeeze().numpy()
print(x.shape)#输出大小

plt.imshow(x, cmap='gray')

在这里插入图片描述

  • 14
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
PyTorch提供了一种可视化神经网络结构的方法,可以使用`torchsummary`库来实现。首先,你需要安装`torchsummary`库,可以使用以下命令进行安装: ``` pip install torchsummary ``` 安装完成后,你可以按照以下步骤进行卷积神经网络结构的可视化: 1. 导入需要的库: ```python import torch import torch.nn as nn from torchsummary import summary ``` 2. 定义你的卷积神经网络模型: ```python class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1) self.relu1 = nn.ReLU() self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2) self.conv2 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1) self.relu2 = nn.ReLU() self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2) self.fc1 = nn.Linear(128 * 8 * 8, 1024) self.relu3 = nn.ReLU() self.fc2 = nn.Linear(1024, 10) def forward(self, x): x = self.conv1(x) x = self.relu1(x) x = self.pool1(x) x = self.conv2(x) x = self.relu2(x) x = self.pool2(x) x = x.view(-1, 128 * 8 * 8) x = self.fc1(x) x = self.relu3(x) x = self.fc2(x) return x model = Net() ``` 3. 使用`summary`函数可视化模型结构: ```python summary(model, input_size=(3, 32, 32)) ``` 这将输出模型的详细结构信息,包括每一层的输入形状、参数数量等。 需要注意的是,`input_size`参数需要根据你的输入数据的形状进行调整。在上面的示例中,假设输入数据是3通道的32x32图像。 希望这能回答你的问题!如果有其他问题,请随时提问。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值