-
神经网络 卷积操作
例子:
输入:二维图像
[1,2,0,3,1]
[0,1,2,3,1]
[1,2,1,0,0]
[5,2,3,1,1]
[2,1,0,1,1]
卷积核:
[1,2,1]
[0,1,0]
[2,1,0]
然后需要将输入图像和卷积核转化为4维张量
为什么转为4维张量?因为卷积操作需要输入图像和卷积核的维度相同,所以需要将其转化为相同的维度。
(插入 channel:彩色图像就是rgb为3 灰度图像就是1)
下面进行二维卷积操作:
-
步长为1 就是每次移动一步
stride = 1
-
步长为2 就是每次移动两步
-
填充为1
padding = 1
达到填充后的输出和输入的大小相同 都是5x5
为了充分学习边缘信息 提取边缘特征
-
上述输出
code:
import torch import torch.nn.functional as F#原始输入图像 input = torch.tensor([[1,2,0,3,1],[0,1,2,3,1],[1,2,1,0,0],[5,2,3,1,1],[2,1,0,1,1]]) #卷积核 kernel = torch.tensor([[1,2,1],[0,1,0],[2,1,0]]) #将输入图像和卷积核转化为4维张量 reshape(batch_size, channel, height, width) #为什么转为4维张量?因为卷积操作需要输入图像和卷积核的维度相同,所以需要将其转化为相同的维度 input = torch.reshape(input,(1,1,5,5)) kernel = torch.reshape(kernel,(1,1,3,3))#二维卷积 #stride=1 表示步长为1 output = F.conv2d(input,kernel,stride=1) print(output)#步长为2 output = F.conv2d(input,kernel,stride=2) print(output)#填充为1 #填充后输出的大小和输入相同 #就是卷积的时候在原输入的周围补0 上下左右补0 #padding 也是为了充分利用边缘信息 提取边缘特征 output = F.conv2d(input,kernel,stride=1,padding=1) print(output)
-
-
神经网络 卷积层
作用:提取特征
流程:
-
选取数据集
这里我用的是自定义的数据集 还是放一下目录结构
数据集在images下 注意DataLoader加载数据集需要的目录结构是datasets/classes 需要注意下
-
数据预处理
主要是使用transforms工具箱
这里我先统一大小
转成Tensor格式
标准化
#数据预处理 transform = transforms.Compose([transforms.Resize((224,224)),transforms.ToTensor(),transforms.Normalize(mean = [0.5,0.5,0.5],std = [0.5,0.5,0.5]) ])
-
加载数据集
ImageFloder()的时候应用transform
batch_size是指一次取出多少图片来处理(2的倍数)
folder_path = '../images' dataset = ImageFolder(folder_path,transform=transform) dataloader = DataLoader(dataset,batch_size=1)
-
构建卷积层
这里的in_channels为3(彩色图片)out_channels为6(说明应该是应用了两个卷积核去卷积操作 会产生两个输出 所以最后的output的数量是input的两倍)kernel_size=3 卷积核设置的3x3的
然后前向传播 输出结果
class convNet(nn.Module):def __init__(self):#调用父类nn.Module的构造函数super(convNet,self).__init__()self.conv1 = Conv2d(in_channels=3,out_channels=6,kernel_size=3,stride=1,padding=0)def forward(self,x):x = self.conv1(x)return xconvnet = convNet()
-
使用tensorboard观察结果
日志存在logs文件夹下
writer = SummaryWriter('../logs') ... ... ... writer.close()
writer.add_images('input',img,cnt)writer.add_images('output',output,cnt)
-
开始遍历处理加载的图片(见后面完整代码中)
output = torch.reshape(output,(-1,3,222,222))
这一个操作是因为output的通道数是6 运行会报错 这里就给他强制性转换一下shape
输入通道数变成几不知道 就填写-1
(222,222)这个是怎么得到的?
print(output.shape)得到的
-
tensorboard结果:
tensorboard --logdir=../logs
(我数据集中就放了一张图片哈哈哈哈哈 大家能够认出是谁吗)
(笑死我了 这里是变形的小苏苏)
-
完整代码
code:
import torch import torchvision from torch import nn from torch.nn import Conv2d from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriter from torchvision.datasets import ImageFolder from torchvision import transforms#数据预处理 transform = transforms.Compose([transforms.Resize((224,224)),transforms.ToTensor(),transforms.Normalize(mean = [0.5,0.5,0.5],std = [0.5,0.5,0.5]) ])#加载数据集 folder_path = '../images' dataset = ImageFolder(folder_path,transform=transform) dataloader = DataLoader(dataset,batch_size=1)class convNet(nn.Module):def __init__(self):#调用父类nn.Module的构造函数super(convNet,self).__init__()self.conv1 = Conv2d(in_channels=3,out_channels=6,kernel_size=3,stride=1,padding=0)def forward(self,x):x = self.conv1(x)return xconvnet = convNet()writer = SummaryWriter('../logs')cnt = 0 for data in dataloader:img,label = dataprint(img.shape)output = convnet(img)print(output.shape)writer.add_images('input',img,cnt)output = torch.reshape(output,(-1,3,222,222))writer.add_images('output',output,cnt)cnt = cnt + 1writer.close()
-