专栏首页村雨深度学习之卷积神经网络

深度学习之卷积神经网络

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/github_39655029/article/details/87603342

二维卷积层

卷积神经网络convolutional neural network是含有卷积层convolutional layer的神经网络,二维卷积层具有高和宽两个空间维度,常用于处理图像数据;

二维互相关运算

在二维卷积层中,一个二维输入数组和一个二维核数组通过互相关运算输出一个二维数组; 二维互相关运算中,卷积窗口从输入数组的最左上方开始,然后按照从左往右、从上往下的顺序在输入数组上滑动; 输出的维度确定:假设输入形状是 nh×nw ,卷积核窗口形状是 kh×kw ,那么输出形状:

  • 高 = (nh−kh+1);
  • 宽 = (nw−kw+1);

二维卷积层

在这一层中将输入和卷积核做互相关运算,并加上一个标量偏差来得到输出。卷积层的模型参数包括卷积核和标量偏差,训练模型时,先对卷积核随机初始化,然后不断迭代卷积核和偏差;

互相关运算和卷积运算

卷积运算的输出等于将核数组左右翻转并上下翻转,再与输入数组做互相关运算,深度学习中的的核数组都是通过学习得到的;

特征图与感受野

  • 特征图:二维卷积层输出的二维数组可看做是输入在空间维度(宽和高)上某一级的表征;
  • 感受野:影响元素x的前向计算的所有可能输入区域(可能大于输入的实际尺寸)叫做x的感受野receptive field;

相关代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/2/18 10:43
# @Author  : Cunyu
# @Site    : cunyu1943.github.io
# @File    : chapter5.py
# @Software: PyCharm

from mxnet import autograd, nd
from mxnet.gluon import nn

# 二维互相关运算函数
def corr2d(X, K):
	# 获取核的高,宽
	h, w = K.shape
	# 定义一个全为0的输出
	Y = nd.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 = nd.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
# 核
K = nd.array([[0, 1], [2, 3]])
# 二维互相关运算结果
print(corr2d(X, K))

class Conv2D(nn.Block):
	def __init__(self, kernel_size, **kwargs):
		super(Conv2D, self).__init__(**kwargs)
		self.weight = self.params.get('weight', shape = kernel_size)
		self.bias - self.params.get('bias', shape = (1,))

	def forward(self, x):
		return corr2d(x, self.weight.data()) + self.bias.data()

填充与步幅

填充padding

指在输入高和宽的两侧填充元素( 常为0元素); 若在高的两侧一共填充ph行,在宽的两侧一共填充pw列,则输出形状为: (nh - kh + ph + 1) x (nw - kw + pw + 1);

步幅stride

指卷积窗口从输入数组的最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动,每次滑动的行数和列数; 一般来说,当高上步幅为 sh ,宽上步幅为 sw 时,输出形状为: ⌊(nh−kh+ph+sh)/sh⌋×⌊(nw−kw+pw+sw)/sw⌋;

小结

  • 填充可以增加输出的高和宽,常用于使输入输出具有相同高和宽;
  • 步幅可以减小输出的高和宽;

相关代码

"""
填充
"""
from mxnet import nd
from mxnet.gluon import nn

# 定义一个函数计算卷积层,初始化卷积层权重,并对输入和输出做出相应升降维
def comp_conv2d(conv2d, X):
	conv2d.initialize()
	# (1, 1)代表批量大小和通道数(“多输入通道和多输出通道”一节将介绍)均为1
	X = X.reshape((1, 1) + X.shape)
	Y = conv2d(X)
	return Y.reshape(Y.shape[2:])  # 排除不关心的前两维:批量和通道


# 注意这里是两侧分别填充1行或列,所以在两侧一共填充2行或列
conv2d = nn.Conv2D(1, kernel_size=3, padding=1)
X = nd.random.uniform(shape=(8, 8))
print("卷积核高宽相同时输出形状")
print(comp_conv2d(conv2d, X).shape)

# 使用高5,宽3的卷积核,在高和宽两侧的填充数分别为2和1
conv2d = nn.Conv2D(1, kernel_size=(5, 3), padding=(2, 1))
print("卷积核高宽不同时输出形状")
print(comp_conv2d(conv2d, X).shape)

"""
步幅
"""
# 高和宽的步幅均为2,使得输入的高和宽减半
conv2d = nn.Conv2D(1, kernel_size=3, padding=1, strides=2)
print('步幅为2,输出形状')
print(comp_conv2d(conv2d, X).shape)
# 高和宽的步幅不同时,使得输入的高和宽减半
conv2d = nn.Conv2D(1, kernel_size=(3, 5), padding=(0,1), strides=(3,4))
print('不同步幅输出形状')
print(comp_conv2d(conv2d, X).shape)

多输入通道和多输出通道

相关代码

"""
多通道输入
"""
import d2lzh as d2l
from mxnet import nd
def corr2d_multi_in(X, K):
	# 先沿X和K的第0维遍历,然后使用*将结果列表变成add_n函数的位置参数
	# (positional argument)来进行相加
	return nd.add_n(*[d2l.corr2d(x, k) for x, k in zip(X, K)])
# 输入
X = nd.array([[[0, 1, 2], [3, 4, 5], [6, 7, 8]],
              [[1, 2, 3], [4, 5, 6], [7, 8, 9]]])
# 核
K = nd.array([[[0, 1], [2, 3]], [[1, 2], [3, 4]]])
print('输出')
print(corr2d_multi_in(X, K))

"""
多通道输出
"""
# 互相关运算函数来计算多通道的输出
def corr2d_multi_in_out(X, K):
	# 对K的第0维遍历,每次同输入X做互相关计算,所有结果使用stack函数合并
	return nd.stack(*[corr2d_multi_in(X, k) for k in K])

K = nd.stack(K, K + 1, K + 2)
print('核数组')
print(K.shape)
print('输出')
print(corr2d_multi_in_out(X, K))

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Javascript中你必须理解的执行上下文和调用栈

    人的一生就是进行尝试,尝试的越多,生活就越美好。 ——爱默生

    五月君
  • mysql 8本地源码安装注意事项

    yum -y install wget cmake gcc gcc-c++ ncurses ncurses-devel libaio-deve...

    算法之名
  • Spring3 MVC请求参数获取的几种方法

    例如,访问user/123/lei路径时,执行以上方法,其中,参数id=123,name=lei

    一觉睡到小时候
  • 人生靠反省,Java靠泛型

    昨天有同事问 UserService、XxxService 都会调用 Dao 的 insert、update ... ...,这些重复的代码,有没有办法变得灵活...

    一猿小讲
  • 内功修炼-算法04

    简单暴力求解,列举所有的子串,判断是否为回文串,保存最长的回文串。简单粗暴,先将两个数组合并,两个有序数组的合并也是归并排序中的一部分。然后根据奇数,还是偶数,...

    Share猿
  • LSM树(Log-Structured Merge Tree)存储引擎浅析

    随着rocksDB(facebook的),levelDB(google的),以及我们熟知的hbase,他们都是使用的LSM树结构的数据库。

    算法之名
  • Springboot之启动原理

    SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂SpringBoot内部启动原理,以后难免会吃亏。所以这次博主就跟你们一起一步...

    用户3467126
  • go 学习笔记之值得特别关注的基础语法有哪些

    在上篇文章中,我们动手亲自编写了第一个 Go 语言版本的 Hello World,并且认识了 Go 语言中有意思的变量和不安分的常量.

    雪之梦技术驿站
  • 字典树收集(初步读写锁实现线程安全,待续)

    将500W个单词放进一个数据结构进行存储,然后进行快速比对,判断一个单词是不是这个500W单词之中的;来了一个单词前缀,给出500w个单词中有多少个单词是该前缀...

    算法之名
  • 黑人女性报错率比白人高20%,面部识别系统为何不能一视同仁?

    面部识别系统流行于九十年代早期,当时美国国防部希望发明一种可以发现偷渡边境的不法分子的识别技术,为此投入了大量研究。为此,美国国防部为著名的大学科学家和面部识别...

    大数据文摘

扫码关注云+社区

领取腾讯云代金券