当前位置: 首页>资讯 >

使用Numpy从头构建卷积神经网络 当前播报

来源: 磐创AI | 时间: 2023-02-08 11:00:43 |

使用该网络对手写数字进行分类。所获得的结果不是最先进的水平,但仍然令人满意。现在想更进一步,我们的目标是开发一个仅使用Numpy的卷积神经网络(CNN)。

这项任务背后的动机与创建全连接的网络的动机相同:尽管Python深度学习库是强大的工具,但它阻止从业者理解底层正在发生的事情。对于CNNs来说,这一点尤其正确,因为该过程不如经典深度网络执行的过程直观。


(资料图)

解决这一问题的唯一办法是尝试自己实现这些网络。

打算将本文作为一个实践教程,而不是一个全面指导CNNs运作原则的教程。因此,理论部分很窄,主要用于对实践部分的理解。

对于需要更好地理解卷积网络工作原理的读者,留下了一些很好的资源。

什么是卷积神经网络?

卷积神经网络使用特殊的结构和操作,使其非常适合图像相关任务,如图像分类、对象定位、图像分割等。它们大致模拟了人类的视觉皮层,每个生物神经元只对视野的一小部分做出反应。此外,高级神经元对其他低级神经元的输出做出反应[1]。

正如我在上一篇文章中所展示的,即使是经典的神经网络也可以用于图像分类等任务。问题是,它们仅适用于小尺寸图像,并且在应用于中型或大型图像时效率极低。原因是经典神经网络需要大量的参数。

例如,200x200像素的图像具有40'000个像素,如果网络的第一层具有1'000个单位,则仅第一层的权重为4000万。由于CNN实现了部分连接的层和权重共享,这一问题得到了高度缓解。

卷积神经网络的主要组成部分包括:

· 卷积层

· 池化层

卷积层

卷积层由一组滤波器(也称为核)组成,当应用于层的输入时,对原始图像进行某种修改。滤波器是一种矩阵,其元素值定义了对原始图像执行的修改类型。类似以下的3x3内核具有突出显示图像中垂直边的效果:

不同的是,该核突出了水平边:

核中元素的值不是手动选择的,而是网络在训练期间学习的参数。

卷积的作用是隔离图像中存在的不同特征。Dense层稍后使用这些功能。

池化层

池化层非常简单。池化层的任务是收缩输入图像,以减少网络的计算负载和内存消耗。事实上,减少图像尺寸意味着减少参数的数量。

池化层所做的是使用核(通常为2x2维)并将输入图像的一部分聚合为单个值。例如,2x2最大池核获取输入图像的4个像素,并仅返回具有最大值的像素。

Python实现

此GitHub存储库中提供了所有代码。

这个实现背后的想法是创建表示卷积和最大池层的Python类。此外,由于该代码后来被应用于MNIST分类问题,我为softmax层创建了一个类。

每个类都包含实现正向传播和反向传播的方法。

这些层随后被连接在一个列表中,以生成实际的CNN。

卷积层实现

class ConvolutionLayer:

def __init__(self, kernel_num, kernel_size):

self.kernel_num = kernel_num

self.kernel_size = kernel_size

self.kernels = np.random.randn(kernel_num, kernel_size, kernel_size) / (kernel_size**2)

def patches_generator(self, image):

image_h, image_w = image.shape

self.image = image

for h in range(image_h-self.kernel_size+1):

for w in range(image_w-self.kernel_size+1):

patch = image[h:(h+self.kernel_size), w:(w+self.kernel_size)]

yield patch, h, w

def forward_prop(self, image):

image_h, image_w = image.shape

convolution_output = np.zeros((image_h-self.kernel_size+1, image_w-self.kernel_size+1, self.kernel_num))

for patch, h, w in self.patches_generator(image):

convolution_output[h,w] = np.sum(patch*self.kernels, axis=(1,2))

return convolution_output

def back_prop(self, dE_dY, alpha):

dE_dk = np.zeros(self.kernels.shape)

for patch, h, w in self.patches_generator(self.image):

for f in range(self.kernel_num):

dE_dk[f] += patch * dE_dY[h, w, f]

self.kernels -= alpha*dE_dk

return dE_dk

构造器将卷积层的核数及其大小作为输入。我假设只使用大小为kernel_size x kernel_size的平方核。

在第5行中,我生成随机滤波器(kernel_num、kernel_size、kernel_size),并将每个元素除以核大小的平方进行归一化。

patches_generator()方法是一个生成器。它产生切片。

forward_prop()方法对上述方法生成的每个切片进行卷积。

最后,back_prop()方法负责计算损失函数相对于层的每个权重的梯度,并相应地更新权重值。注意,这里提到的损失函数不是网络的全局损失。相反,它是由最大池层传递给前一卷积层的损失函数。

为了显示这个类的实际效果,我用32个3x3滤波器实例化了一个卷积层对象,并将正向传播方法应用于图像。输出包含32个稍小的图像。

原始输入图像的大小为28x28像素,如下所示:

在应用卷积层的前向传播方法后,我获得了32幅尺寸为26x26的图像。这里我绘制了其中一幅:

如你所见,图像稍小,手写数字变得不那么清晰。考虑到这个操作是由一个填充了随机值的滤波器执行的,所以它并不代表经过训练的CNN实际执行的操作。

尽管如此,你可以得到这样的想法,即这些卷积提供了较小的图像,其中对象特征被隔离。

最大池层实现

class MaxPoolingLayer:

def __init__(self, kernel_size):

self.kernel_size = kernel_size

def patches_generator(self, image):

output_h = image.shape[0] // self.kernel_size

output_w = image.shape[1] // self.kernel_size

self.image = image

for h in range(output_h):

for w in range(output_w):

patch = image[(h*self.kernel_size):(h*self.kernel_size+self.kernel_size), (w*self.kernel_size):(w*self.kernel_size+self.kernel_size)]

yield patch, h, w

def forward_prop(self, image):

image_h, image_w, num_kernels = image.shape

max_pooling_output = np.zeros((image_h//self.kernel_size, image_w//self.kernel_size, num_kernels))

for patch, h, w in self.patches_generator(image):

max_pooling_output[h,w] = np.amax(patch, axis=(0,1))

return max_pooling_output

def back_prop(self, dE_dY):

dE_dk = np.zeros(self.image.shape)

for patch,h,w in self.patches_generator(self.image):

image_h, image_w, num_kernels = patch.shape

max_val = np.amax(patch, axis=(0,1))

for idx_h in range(image_h):

for idx_w in range(image_w):

for idx_k in range(num_kernels):

if patch[idx_h,idx_w,idx_k] == max_val[idx_k]:

dE_dk[h*self.kernel_size+idx_h, w*self.kernel_size+idx_w, idx_k] = dE_dY[h,w,idx_k]

return dE_dk

构造函数方法只分配核大小值。以下方法与卷积层的方法类似,主要区别在于反向传播函数不更新任何权重。事实上,池化层不依赖于权重来执行。

Sigmoid层实现

class SoftmaxLayer:

def __init__(self, input_units, output_units):

self.weight = np.random.randn(input_units, output_units)/input_units

self.bias = np.zeros(output_units)

def forward_prop(self, image):

self.original_shape = image.shape

image_flattened = image.flatten()

self.flattened_input = image_flattened

first_output = np.dot(image_flattened, self.weight) + self.bias

self.output = first_output

softmax_output = np.exp(first_output) / np.sum(np.exp(first_output), axis=0)

return softmax_output

def back_prop(self, dE_dY, alpha):

for i, gradient in enumerate(dE_dY):

if gradient == 0:

continue

transformation_eq = np.exp(self.output)

S_total = np.sum(transformation_eq)

dY_dZ = -transformation_eq[i]*transformation_eq / (S_total**2)

dY_dZ[i] = transformation_eq[i]*(S_total - transformation_eq[i]) / (S_total**2)

dZ_dw = self.flattened_input

dZ_db = 1

dZ_dX = self.weight

dE_dZ = gradient * dY_dZ

dE_dw = dZ_dw[np.newaxis].T @ dE_dZ[np.newaxis]

dE_db = dE_dZ * dZ_db

dE_dX = dZ_dX @ dE_dZ

self.weight -= alpha*dE_dw

self.bias -= alpha*dE_db

return dE_dX.reshape(self.original_shape)

softmax层使最大池提供的输出体积变平,并输出10个值。它们可以被解释为与数字0–9相对应的图像的概率。

结论

你可以克隆包含代码的GitHub存储库并使用main.py脚本。该网络一开始没有达到最先进的性能,但在几个epoch后达到96%的准确率。

参考引用

原文标题:使用Numpy从头构建卷积神经网络

关键词: 卷积神经网络 Numpy

 

热文推荐

使用Numpy从头构建卷积神经网络 当前播报

使用该网络对手写数字进行分类。所获得的结果不是最先进的水平,但仍然令人满意。现在想更进一步,我们的目标是开发一个仅使用Numpy的卷积神经

2023-02-08

诗人称号大全居士_诗人称号大全_焦点热讯

1、诗仙——( 李白 )诗想象丰富奇特,风格雄浑奔放,色彩绚丽,语言清新自然,被誉为“诗仙”。2、2、诗圣——( 杜甫 

2023-02-08

驾照科目二考试技巧总结篇

驾照科目二考试技巧总结篇总结是对过去一定时期的工作、学习或思想情况进行回顾、分析,并做出客观评价的书面材料,它可以明确下

2023-02-08

每日热文:竞怎么读的读法

一、关于竞怎么读的读法1、读法:[jìng]二、关于竞怎么读的释义2、基础释义:1 争着做某事:~相传告。2 比赛:

2023-02-08

山东省高速公路最新路况消息 实时

山东省高速公路最新路况消息下面应届毕业生网小编分享山东省高速公路最新路况消息。截至02月14日07时00分:G15沈海高

2023-02-08

"露奶衫"算什么?这4件才是真时髦!早春这么穿美到爆!

草长莺飞二月天立春后,春天的脚步越来越近了猜猜我现在最想做的事是什么?没错,就是——出!去!玩!讲真,春天绝对是最适合出游的季节郁郁

2023-02-08

曼联欧联杯大名单:埃里克森带伤入选,新援萨比策、韦霍斯特在列

曼联欧联杯大名单:埃里克森带伤入选,新援萨比策、韦霍斯特在列,埃里克森,韦霍斯特,萨比策,曼联,欧联杯,安东尼·马夏尔

2023-02-08

环球今日讯!12530中国移动彩铃怎么收费_12530彩铃怎么收费

除了每首歌两元,歌曲将不收费,但你仍然要支付每月6元的CRBT费用。另外,打12530下载彩玲一分钟,2元,发消息下载彩

2023-02-08

最新:生物股份: 金宇生物技术股份有限公司关于非公开发行股票股东权益变动的提示性公告

生物股份:金宇生物技术股份有限公司关于非公开发行股票股东权益变动的提示性公告

2023-02-07

全球视讯!如何修改qq帐号

如何修改qq帐号,如何修改qq账号呢?网友们为此而感到困扰,其实qq账号是不能修改的,但我们可以修改qq的主显示。那我们该如何解决这个问题呢

2023-02-07

全球看点:海上丝绸之路的路线图简笔画_海上丝绸之路的路线

1、海上丝绸之路的路线:分为东海航线和南海航线两条线路。2、南海航线又称南海丝绸之路起点主要是广州和泉州。3、先秦时期,

2023-02-07

速看:篮球规则大全图解 犯规_篮球规则大全

1、基本规则:2、1 比赛方法:3、一队五人,其中一人为队长(当家或老大),候补球员最多七人,但可依主办单位而增加人数。

2023-02-07

开学第一课:垃圾分类,从我做起

开学第一课:垃圾分类,从我做起---“垃圾分类,从我做起。”2月6日开学第一天,武汉经开区沌口街道综合执法中心来到辖区一所小学开展垃圾分类

2023-02-07

老虎最害怕什么?被打鼻子_老虎最害怕什么 环球热点

1、老虎感到害怕的一个是人类,第二个是火,第三个,就是,带有火药味儿的炮仗这些都是老虎最惧怕的东西。2、老虎是百兽之王对

2023-02-07

维语学习方法 聚焦

维语学习方法,方法步骤:1、学会32个字母:8个元音字母及24个辅音字母;2、适当学习维语语法,但不要过度;3、学习单词,每2至3天学一个句子

2023-02-07

牛奶怎么喝比较好_喝牛奶的时间_关注

1 早上喝:如果你还在工作,那么你早上喝一杯牛奶是合适的。牛奶有化腐朽为神奇的力量,可以补充蛋白质、维生素、钙等多种营养

2023-02-07

微信强提醒怎么设置24小时_微信强提醒 今日热门

1、这个强提醒的意思是,自从这个功能开启之后,该联系人下一条发给你的信息会全屏提醒,同时保持一直震动。这个功能应该是防止

2023-02-07

环球精选!迈赫股份2月7日快速回调

以下是迈赫股份在北京时间2月7日11:13分盘口异动快照:2月7日,迈赫股份盘中快速回调,5分钟内跌幅超过2%,截至11点13分,报27 58元,成交1 78

2023-02-07

一代暴君01 世界最资讯

1、《一代暴君01》是2000年东立出版的图书。2、作者是安彦良和。文章到此就分享结束,希望对大家有所帮助。

2023-02-07

被曝婚内出轨孙红雷曹郁等人,获凌潇肃原谅,姚晨维权胜诉-每日热门

近段时间以来,姚晨的小日子也过得十分的惬意,让人特别的羡慕。在过年期间,她也回到了自己的家乡与好友相聚,频繁的在个人的社交平台上分享

2023-02-07

资讯