ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

深度学习笔记017卷积层

2022-02-04 23:01:29  阅读:178  来源: 互联网

标签:卷积 torch 笔记 shape 017 print conv2d size


看到一句话,其实卷积层就是一种滤波器,放大它感兴趣的,缩小它不感兴趣的,很有道理。

 

二维卷积层的数学表达:

 

这里这个W其实就是kernel,是在这里通过这种方式学习出来的参数,表现出来的就是一个矩阵。b是偏差,通过广播机制作用给Y。

 

 

 二维交叉和二维卷积,就差一个翻转的关系:

 

 

 为了简单,我们把负号删掉了。所以在神经网络里虽然我们说在做卷积,其实是在做交叉相关。

 

图像处理领域一般都用二维的卷积层,但是一维和三维也在应用中很重要。

一维卷积:

  文本、语言、时序序列

二维卷积:

  视频、医学图像、气象地图

 

卷积层就是将输入和核矩阵进行交叉相关,再加上偏移之后,进行输出。

核矩阵和偏移是可学习的量。

核矩阵的大小是超参数。

 

Q&A:

1、Kernel大小主流用3x3,最多5x5。感受野不是越大越好,最终我们虽然会看到整张图,类似为什么是深度学习而不是广度学习一样,我们用大核少做几次和用小核多做几次,工作量一样,但是视野小一些会更棒。

 

卷积层控制输出大小的超参数:填充和步幅

填充:可以控制输出形状的减小量

步幅:可以成倍减小输出形状

  填充:在输入的四周添加额外的行或列

    通常利用填充,使得输出保持与输入一样的大小

    

  步幅:是指滑行的行/列的步长,高度和宽度的步幅可以不同

    步幅计算:

    

 

 

Q&A:

1、一般来说,填充会使得输出和输入不变,因为这样子算起来比较方便,否则需要一直想着输入输出变化的关系;

2、通常来讲,步幅常常=1,除非计算量明显太大了;

3、卷积的边长一般取奇数,因为取奇数时填充会方便一些,上下左右对称一些。但是效果上来说,奇偶差不多了。

4、机器学习本质上就是信息筛选,信息压缩,我们的信息一直都是丢失的,只要在操作,就是在丢失信息。只不过在压缩的时候,我们放大了我们感兴趣的特征。

5、一个特定的卷积层就是去匹配一种特定的纹理。

 

代码如下:

 1 import torch
 2 from torch import nn
 3 from d2l import torch as d2l
 4 
 5 
 6 # 定义一个计算二维相关的运算
 7 def corr2d(X,K):
 8     h,w=K.shape
 9     Y=torch.zeros((X.shape[0]-h+1,X.shape[1]-w+1))
10     for i in range(Y.shape[0]):
11         for j in range(Y.shape[1]):
12             Y[i,j]=(X[i:i+h,j:j+w]*K).sum()
13     return Y
14 
15 
16 X = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
17 K = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
18 print(corr2d(X, K))
19 
20 
21 # 实现二维卷积层
22 class Conv2D(nn.Module):
23     def __init__(self,kernel_size):
24         super().__init__()
25         self.weight=nn.Parameter(torch.rand(kernel_size))
26         self.bias=nn.Parameter(torch.zeros(1))
27 
28     def forward(self,x):
29         return corr2d(x,self.weight)+self.bias
30 
31 
32 # 简易应用:检测图像不同颜色的边缘
33 X=torch.ones((6,8)) #z做了一个有两条竖线边缘的矩阵
34 X[:,2:6]=0
35 print(X)
36 K=torch.tensor([[1.0,-1.0]])
37 Y=corr2d(X,K)
38 print(corr2d(X,K))
39 
40 # # 类比做一个检测竖直边缘的算子
41 # X=torch.ones((10,8)) #z做了一个有两条竖线边缘的矩阵
42 # X[3:7,:]=0
43 # print(X)
44 # K=torch.tensor([[1.0],[-1.0]])
45 # print(corr2d(X,K))
46 
47 # 学习由X生成的Y的卷积核
48 conv2d=nn.Conv2d(1,1,kernel_size=(1,2),bias=False)
49 X=X.reshape((1,1,6,8))  #将二维图片转换为四维,第一个是通道,第二个是样本维度(样本数),第三四个是长宽
50 Y=Y.reshape(1,1,6,7)
51 
52 for i in range(10):
53     Y_hat=conv2d(X)
54     l=(Y_hat-Y)**2
55     conv2d.zero_grad()
56     l.sum().backward()
57     conv2d.weight.data[:]-=3e-2*conv2d.weight.grad
58     if(i+1)%2==0:
59         print(f'batch {i+1}, loss {l.sum():.3f}')
60 
61 print(conv2d.weight.data.reshape((1,2)))# 不reshape就会输出四维
62 
63 
64 # 2维变为4维,用于下面的函数
65 XX=torch.zeros((2,3))
66 print(XX)
67 XX=XX.reshape((1,1)+XX.shape)
68 print(XX)
69 
70 # 填充和步幅
71 def comp_conv2d(conv2d,X):
72     X=X.reshape((1,1)+X.shape)  #2维变为4维
73     Y=conv2d(X)
74     return Y.reshape(Y.shape[2:])
75 
76 conv2d=nn.Conv2d(1,1,kernel_size=3,padding=1) # 填充为1,上下左右各填充一行
77 X=torch.rand(size=(8,8))
78 print(comp_conv2d(conv2d,X).shape)
79 
80 conv2d=nn.Conv2d(1,1,kernel_size=(5,3),padding=(2,1)) # 前面为上下,后面为左右
81 print(comp_conv2d(conv2d,X).shape)
82 
83 conv2d=nn.Conv2d(1,1,kernel_size=3,padding=1,stride=2) # 步幅为2
84 X=torch.rand(size=(8,8))
85 print(comp_conv2d(conv2d,X).shape)
86 
87 conv2d=nn.Conv2d(1,1,kernel_size=(3,5),padding=(0,1),stride=(3,5)) # 填充为1,上下左右各填充一行
88 X=torch.rand(size=(8,8))
89 print(comp_conv2d(conv2d,X).shape)

 

标签:卷积,torch,笔记,shape,017,print,conv2d,size
来源: https://www.cnblogs.com/loveandninenine/p/15863592.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有