pytorch学习日记之图片的简单卷积、池化

该文演示了如何使用Python的TensorFlow库对灰度图像进行卷积和不同类型的池化操作,包括最大池化、平均池化和自适应平均池化,以提取图像特征并减小数据尺寸。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

导入图片并转化为张量

import torch
import torch.nn as nn
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
mymi = Image.open("pic/123.png")
# 读取图像转化为灰度图片转化为numpy数组
myimgray = np.array(mymi.convert("L"), dtype=np.float32)
# 可视化图片
plt.figure(figsize=(10, 10))
plt.imshow(myimgray, cmap=plt.cm.gray)
plt.show()

# 将数组转化成张量
imh, imw = myimgray.shape
myimgray_t = torch.from_numpy(myimgray.reshape(1, 1, imh, imw))
print(myimgray_t.shape)

可视化图片内容如下图所示:
在这里插入图片描述

对灰度图像进行卷积提取图像轮廓

kersize = 5  # 定义边缘检测卷积核,并将维度处理为1*1*5*5
ker = torch.ones(kersize, kersize, dtype=torch.float32)*-1
ker[2, 2] = 24
ker = ker.reshape((1, 1, kersize, kersize))
# 进行卷积操作
# 设置卷积层,输入数为1,特征映射的数量为2,卷积核大小为之前边缘检测卷积核大小
# 卷积步长为默认1,输入填充数量为0,步幅默认为1,偏置为False
conv2d = nn.Conv2d(1, 2, (kersize, kersize), bias=False)
# 设置卷积时使用的核,第一个核使用边缘检测
conv2d.weight.data[0] = ker
# 对灰度图像进行卷积操作
imconv2dout = conv2d(myimgray_t)
# 对卷积后的输出进行维度压缩
imconv2dout_im = imconv2dout.data.squeeze()
print("卷积后的尺寸:", imconv2dout_im.shape)

# 可视化卷积后的图像
plt.figure(figsize=(20, 10))
plt.subplot(1, 2, 1)
plt.imshow(imconv2dout_im[0], cmap=plt.cm.gray)
plt.subplot(1, 2, 2)
plt.imshow(imconv2dout_im[1], cmap=plt.cm.gray)
plt.show()

边缘检测后得到的图像如下图所示:
在这里插入图片描述

池化操作:

这一步骤主要是为了对特征进行进一步处理,池化层可以起到对数据进一步浓缩,从而缓解计算时对内存的需求。池化会选取一定大小区域,将该区域的额像素值使用一个代表元素表示。如果使用该区域的平均值代替则称为平均池化,如果使用最大值代替则称为最大池化,这两种方式的计算如下图所示:
在这里插入图片描述

最大池化代码以及结果:

# 对卷积后的图像进行最大池化
maxpool2 = nn.MaxPool2d(2, stride=2)
pool2_out = maxpool2(imconv2dout)
pool2_out_im = pool2_out.squeeze()
print("最大池化后的尺寸", pool2_out.shape)
# 可视化最大池化后的结果
plt.figure(figsize=(20, 10))
plt.subplot(1, 2, 1)
plt.imshow(pool2_out_im[0].data, cmap=plt.cm.gray)
plt.subplot(1, 2, 2)
plt.imshow(pool2_out_im[1].data, cmap=plt.cm.gray)
plt.show()

在这里插入图片描述
其中torch.nn.MaxPool2d(kernel_size,stride,padding=0,dilation=1,return_indices=False,ceil_mode=False)中包含了池化的一些参数设置,
kernel_size表示最大值池化的窗口大小,
stride是最大值池化窗口移动的步长,默认值是kernel_size,
padding为输入矩阵的每条边补充0的层数,主要作用是保持数据矩阵的大小减少信息损失(之前看的印象可能有点不对),
dilation是控制窗口中元素步幅的参数,
return_indices如果为True则返回最大值的索引,
ceil_mode如果等于True,计算输出信号大小的时候,会使用向上取整,默认是向下取整。
torch.nn.MaxPool2d()输入为:在这里插入图片描述
输出为:在这里插入图片描述
其中在这里插入图片描述

平均池化代码及结果:

# 卷积后的结果进行平均值池化
avgpool2 = nn.AvgPool2d(2, stride=2)
pool2avg_out = avgpool2(imconv2dout)
pool2avg_out_im = pool2avg_out.squeeze()
print(pool2avg_out.shape)

# 可视化平均池化后的结果
plt.figure(figsize=(20, 10))
plt.subplot(1, 2, 1)
plt.imshow(pool2avg_out_im[0].data, cmap=plt.cm.gray)
plt.subplot(1, 2, 2)
plt.imshow(pool2avg_out_im[1].data, cmap=plt.cm.gray)
plt.show()

在这里插入图片描述
可以观察到,特征图像比最大化池化要淡化一点。

自适应平均池化代码及结果

下面使用nn.AdaptiveAvgPool2d()函数对卷积后的输出进行自适应平均值池化并可视化:


# 卷积后的结果进行自适应平均值池化
AdaAvgpool2 = nn.AdaptiveAvgPool2d(output_size=(100, 100))
# output_size参数指定输出特征映射的尺寸
pool2ada_out = AdaAvgpool2(imconv2dout)
pool2ada_out_im = pool2ada_out.squeeze()
print(pool2ada_out.shape)

# 可视化自适应平均值池化后的结果
plt.figure(figsize=(20, 10))
plt.subplot(1, 2, 1)
plt.imshow(pool2ada_out_im[0].data, cmap=plt.cm.gray)
plt.subplot(1, 2, 2)
plt.imshow(pool2ada_out_im[1].data, cmap=plt.cm.gray)
plt.show()

在这里插入图片描述
池化后特征映射尺寸变小,图像更加模糊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好的!文西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值