互相关运算,卷积核生成,填充,步幅,多输入多输出通道(深度学习—复现)

6.2图像卷积

6.2.1互相关运算 

#二维互相关运算输出

import numpy
import torch
def corr2d(X,K):
    h,w=K.shape
    Y=torch.zeros((X.shape[0]-h+1,X.shape[1]-w+1))
    for i in range(Y.shape[0]):
        for j in range(Y.shape[1]):
            Y[i,j]=(X[i:i+h,j:j+w]*K).sum()
    return Y

X=numpy.array([[0.0,1.0,2.0],
              [3.0,4.0,5.0],
              [6.0,7.0,8.0]])
K=numpy.array([[0.0,1.0],
              [2.0,3.0]])
print(corr2d(X,K))

#实现卷积层
import torch.nn as nn
class Conv2D(nn.Module):
    def __init__(self,kernel_size,**kwargs):
        super().__init__(**kwargs)
        self.weight=nn.Parameter(torch.rand(kernel_size))
        self.bias=nn.Parameter(torch.zeros(1))
    def forward(self,x):
        return corr2d(x,self.weight.data())+self.bias.data()
#图像中目标的边缘检测,找到像素变化的位置,来检测图像中不同颜色的边缘(寻找黑白边缘)
#6×8像素的黑白图像,中间四列为黑色,其余像素为白色

X=torch.ones([6,8]).float()
X[:,2:6]=0
print(X)
#卷积核:1×2,互相关运算,水平相邻两元素相同,则输出为0,否则输出为非0
K=numpy.array([[1.0,-1.0]])
#互相关运算,输出Y中的1代表从白色到黑色的边缘,-1代表从黑色到白色的边缘,其他情况的输出为0
Y=corr2d(X,K)
print(Y)
#输入的二维图像转置,再进行互相关运算。垂直边缘消失(这个卷积核K只可以检测垂直边缘,无法检测水平边缘)
#A=corr2d(torch.transpose(torch.tensor(X),dim0=0,dim1=1),K)#转换数据类型tensor,
#print(A)

#6.2.4学习卷积核
'''
更复杂数值的卷积核+连续的卷积层:由’输入-输出‘对来学习由X生成Y的卷积核
构造一个卷积层,并将其卷积核初始化为随机张量,接下来,在每次的迭代中,我们比较Y与卷积层输出的平方误差,然后计算梯度来更新卷积核。

'''
#构造一个二维卷积层,具有1个输出通道和形状为(1,2)的卷积核
conv2d=nn.Conv2d(1,kernel_size=(1,2),bias=False,out_channels=1)#使用内置的二维卷积层,忽略偏置
#二维卷积层使用四维输入和输出格式(批量大小,通道,高度,宽度)
X=X.reshape(1,1,6,8)
Y=Y.reshape(1,1,6,7)
lr=3e-2#学习率
for i in range(10):
    Y_hat=conv2d(X)
    l = (Y_hat - Y) ** 2
    conv2d.zero_grad()
    l.sum().backward()
    #迭代卷积核
    conv2d.weight.data[:] -= lr * conv2d.weight.grad
    if (i + 1) % 2 == 0:
        print(f'epoch{i + 1},loss {float(l.sum()):3f}')

#l.requires_grad=True#RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn
#l.backward(torch.ones_like(l))#RuntimeError: grad can be implicitly created only for scalar outputs

#卷积核的权重张量(卷积核权重接近之前定义的卷积核)
print(conv2d.weight.data.reshape(1,2))#TypeError: 'Tensor' object is not callable,解决办法:去掉()

6.3填充和步幅 

#错误:TypeError: can only concatenate tuple (not "builtin_function_or_method") tuple,解决办法:将形状大小shape()函数改为view()
#填充
import torch
import torch.nn as nn
def comp_conv2d(conv2d,X):
    #view()调整size,相当于reshape,resize
    #(1,1)批量大下和通道数
    X=X.view((1,1)+X.shape)#view()是把原先tensor中的数据进行排列,排成一行,然后根据所给的view()中的参数从一行中按顺序选择组成最终的tensor。
    Y=conv2d(X)
    return Y.view(Y.shape[2:])
#每边都填充了1行1列,相当于总共添加了2行或2列
conv2d=nn.Conv2d(1,kernel_size=3,padding=1,out_channels=1)
X=torch.rand(8,8)
print(comp_conv2d(conv2d,X).shape)#torch.Size([8, 8])
#卷积核的高度和宽度不同,填充不同的高度和宽度,使输出和输入具有相同的高度和宽度
conv2d=nn.Conv2d(1,kernel_size=(5,3),padding=(2,1),out_channels=1)
print(comp_conv2d(conv2d,X).shape)#torch.Size([8, 8])

#步幅2
conv2d=nn.Conv2d(1,kernel_size=3,padding=1,stride=2,out_channels=1)
print(comp_conv2d(conv2d,X).shape)#torch.Size([4, 4])
#步幅,垂直步幅3,水平步幅4
conv2d=nn.Conv2d(1,kernel_size=(3,5),padding=(0,1),stride=(3,4),out_channels=1)
print(comp_conv2d(conv2d,X).shape)#torch.Size([2, 2]) 

 6.4多输入多输出通道

#多输入通道互相关运算

import torch
import torch.nn as nn

def corr2d_multi_in(X,K):
    return sum(corr2d(x,k)for x,k in zip(X,K))
X=numpy.array([[[0.0,1.0,2.0],
                [3.0,4.0,5.0],
                [6.0,7.0,8.0]],
                [[1.0,2.0,3.0],
                [4.0,5.0,6.0],
                [7.0,8.0,9.0]]])
K=numpy.array([[[0.0,1.0],
                [2.0,3.0]],
                [[1.0,2.0],
                [3.0,4.0]]])
print(corr2d_multi_in(X,K))

#多通道输出的互相关函数
def corr2d_multi_in_out(X,K):
    #迭代K的第0个维度,每次都对输入X执行互相关运算,最后将所有结果都叠加在一起
    return numpy.stack([corr2d_multi_in(X,k)for k in K],0)
K=numpy.stack((K,K+1,K+2),0)#开辟一个新的维度,原始的维度在新的维度上拼接起来
print(K.shape)#(3, 2, 2, 2)
print(corr2d_multi_in_out(X,K))#输出包含3个通道

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值