资讯动态

深度学习(15)卷积层

发布时间:2026/10/26 11:31:15 来源:尧图企业网站定制
1. 从全连接到卷积① k、l表示图片的第k行、第l列个像素它相当于全连接层的乘以一个权重值得到全连接层中一层神经元中一个神经元的一条线的值。② 有一个四维的W里面有很多个w例如前图的全连接层有100个w。ij表示此w的坐标即遍历所有的i、j合为100。每个w又是一个矩阵每个w连接所有像素对应矩阵宽高为k和l。因此下图中的为全连接层中一个神经元的输出。③ 原来的k,l是基于图片的绝对位置ab是根据ij的相对位置这里就省略绝对位置只需要一个原点加相对原点的相对位置就可以表示位置信息。hij为输出xkl是输入① 当在图片中形成一个识别器后在一定像素大小的范围内它都有自己的权重当这个识别器在图片上换位置之后它的权重应该不变。② 理解成用同一张卷积核遍历整张图片。卷积核不会随着位置变化而变化。③ 权重就是特征提取器不应该随位置而发生变化。④ 简而言之卷积核就是个框在图片上不断扫描无论扫在图上的哪个位置卷积核都是不变的。⑤ 对于一张图片应该有多个卷积核但是每个卷积核要识别的东西不同一个卷积核就是一个分类器。⑥ 卷积确实是weight shared但不是全联接每个神经元是对应卷积核大小个输入。⑦ 卷积就是weight shared全连接。① 指取一个不那么大的框。总结卷积核应该在数值不变的情况下遍历整张图卷积核不应该太大2. 卷积层① 卷积核遇到和自己相似的会极度膨胀遇到和自己不一样的会极度缩小。② 提取图像特征卷积层越深提取的是语义的特征。卷积比交叉相关时索引多了个负号3. 总结① 假如就是要看一个3 * 3的局部信息的话卷积核就是一个 3 * 3 的矩阵不会因为输入变得特别大导致权重变得特别大。1. 卷积层操作使用自定义卷积神经网络最核心的一步二维互相关conv 的本质代码主要做用一个“小矩阵 K卷积核”在“大矩阵 X图片上滑动每次做乘法求和得到一个新的矩阵 Y# 互相关运算 import torch from torch import nn from d2l import torch as d2l def corr2d(X, K): # X 为输入K为核矩阵 计算二维互相关信息 h, w K.shape # 核矩阵的行数和列数 Y torch.zeros((X.shape[0] - h 1, X.shape[1] - w 1)) # X.shape[0]为输入高 #双重循环滑动窗口 for i in range(Y.shape[0]): for j in range(Y.shape[1]): #取一个小区域和 K 做“逐元素乘法”全部加起来 Y[i, j] (X[i:i h, j:j w] * K).sum() # 图片的小方块区域与卷积核做点积 return Y # 验证上述二维互相关运算的输出 X torch.tensor([[0.0,1.0,2.0],[3.0,4.0,5.0],[6.0,7.0,8.0]]) K torch.tensor([[0.0,1.0],[2.0,3.0]]) corr2d(X,K)tensor([[19., 25.], [37., 43.]])手写卷积层 用卷积做边缘检测# 实现二维卷积层 class Conv2D(nn.Module): #kernel_size卷积核大小 def __init__(self, kernel_size): #创建卷积核(filter);nn.Parameter:告诉 PyTorch这是要训练的参数 self.weight nn.Parameter(torch.rand(kernel_size)) #最终输出 卷积结果 偏置 self.bias nn.Parameter(torch.zeros(1)) def forward(Self, x): #用卷积核扫描corr2d)再加 bias,最后输出 return corr2d(x, self.weight) self.bias # 卷积层的一个简单应用检测图片中不同颜色的边缘 X torch.ones((6,8)) X[:,2:6] 0 # 把中间四列设置为0 print(X) # 0 与 1 之间进行过渡表示边缘 K torch.tensor([[1.0,-1.0]]) # 如果左右原值相等那么这两原值乘1和-1相加为0则不是边缘 Y corr2d(X, K) print(Y) #X.t()转置行列交换 print(corr2d(X.t(), K)) # X.t() 为X的转置而K卷积核只能检测垂直边缘tensor([[1., 1., 0., 0., 0., 0., 1., 1.], [1., 1., 0., 0., 0., 0., 1., 1.], [1., 1., 0., 0., 0., 0., 1., 1.], [1., 1., 0., 0., 0., 0., 1., 1.], [1., 1., 0., 0., 0., 0., 1., 1.], [1., 1., 0., 0., 0., 0., 1., 1.]]) tensor([[ 0., 1., 0., 0., 0., -1., 0.], [ 0., 1., 0., 0., 0., -1., 0.], [ 0., 1., 0., 0., 0., -1., 0.], [ 0., 1., 0., 0., 0., -1., 0.], [ 0., 1., 0., 0., 0., -1., 0.], [ 0., 1., 0., 0., 0., -1., 0.]])转置后就无法边缘化检测了tensor([[0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.]])不用手写卷积核而是让模型“自己学出那个边缘检测核”# 学习由X生成Y的卷积核 #创建卷积层 conv2d nn.Conv2d(1, 1, kernel_size(1,2), biasFalse) # 单个矩阵输入通道为1黑白图片通道为1彩色图片通道为3。这里输入通道为1输出通道为1. #调整数据形状 X X.reshape((1,1,6,8)) # 通道维通道数RGB图3通道灰度图1通道批量维就是样本维就是样本数 Y Y.reshape((1,1,6,7)) for i in range(10): #前向传播 Y_hat conv2d(X) #计算损失:均方误差MSE l (Y_hat - Y) ** 2 #清空梯度 conv2d.zero_grad() #反向传播 l.sum().backward() #更新参数 新参数 旧参数 - 学习率 × 梯度 conv2d.weight.data[:] - 3e-2 * conv2d.weight.grad # 3e-2是学习率 if(i1) % 2 0: print(fbatch {i1},loss {l.sum():.3f}) # 所学的卷积核的权重张量 print(conv2d.weight.data.reshape((1,2)))batch 2,loss 9.914 batch 4,loss 3.107 batch 6,loss 1.113 batch 8,loss 0.429 batch 10,loss 0.171 tensor([[ 0.9473, -1.0320]])

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑