0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于Python和深度学习的CNN原理详解

新机器视觉 来源:新机器视觉 2024-04-06 05:51 次阅读

介绍

卷积神经网络 (CNN) 彻底改变了计算机视觉领域,成为图像和视频分析应用的基石。在本文中,我们将深入研究使 CNN 强大的关键组件和操作,探索卷积、最大池化、步长、填充、上采样、下采样等概念。此外,我们将使用 Python 和流行的深度学习框架讨论数据集上的简单 CNN 模型。

卷积神经网络 (CNN) 由各种类型的层组成,这些层协同工作以从输入数据中学习分层表示。每个层在整体架构中都发挥着独特的作用。让我们探索典型 CNN 中的主要层类型:

1. 输入层 输入层是网络的初始数据输入点。在基于图像的任务中,输入层表示图像的像素值。在下面的示例中,我们假设我们正在处理大小为 28x28 像素的灰度图像。

tensorflow.keras.layersimport Input 
input_layer=Input(shape=(28, 28, 1))
2.卷积层 卷积层是 CNN 的核心构建块。这些层使用可学习的滤波器对输入数据应用卷积运算。这些滤波器扫描输入,提取边缘、纹理和图案等特征在卷积神经网络 (CNN) 中,“核”和“滤波器”这两个术语经常互换使用,指的是同一个概念。让我们来分析一下这些术语的含义:
from tensorflow.keras.layers import Conv2D


conv_layer=Conv2D(filters=32, kernel_size=(3, 3),
activation='relu')(input_layer)
2.1 核是卷积运算中使用的小矩阵。它是一组可学习的权重,应用于输入数据以生成输出特征图。核是让 CNN 自动学习输入数据中特征的空间层次结构的关键元素。在图像处理中,核可能是 3x3 或 5x5 这样的小矩阵。

2.2滤波器 另一方面,滤波器是一组多个内核。在大多数情况下,卷积层使用多个滤波器来捕获输入数据中的不同特征。每个滤波器与输入进行卷积以产生特征图,并且网络通过在训练期间调整这些滤波器的权重(参数)来学习提取各种模式。

在这个例子中,我们定义了一个有 32 个滤波器的卷积层,每个滤波器的内核大小为 3x3。在训练期间,神经网络会调整这 32 个滤波器的权重(参数),以从输入数据中学习不同的特征。让我们通过一个图像示例来看一下:

f7513b66-f0ac-11ee-a297-92fbcf53809c.jpg

核形状(3X3)

总之,核是在输入数据上滑动或卷积的小矩阵,而滤波器是一组用于从输入中提取各种特征的核,从而允许神经网络学习分层表示。

3.激活层 (ReLU) 在卷积操作之后,逐元素应用激活函数(通常是整流线性单元 (ReLU)),以将非线性引入模型。ReLU 可帮助网络学习复杂的关系并使模型更具表现力。使用哪种激活完全取决于您的用例,在大多数情况下,研究人员使用 ReLU,但也可以使用一些激活,例如:Leaky ReLU、ELU。

f7604552-f0ac-11ee-a297-92fbcf53809c.jpg

ReLU 激活 在 Python 中实现整流线性单元 (ReLU) 函数非常简单。ReLU 是神经网络中常用的引入非线性的激活函数。这是一个简单的 Python 实现:

def  relu(x):
     return max(0,x)
4.池化层 池化层(例如MaxPoolingAveragePooling)可减少卷积层生成的特征图的空间维度。例如,MaxPooling 从一组值中选择最大值,重点关注最显著的特征。

f763b08e-f0ac-11ee-a297-92fbcf53809c.jpg

最大池化——平均池化 池化层减少了空间维度。MaxPooling 通常用于:

从tensorflow.keras.layers import MaxPooling2D 


pooling_layer = MaxPooling2D(pool_size=( 2 , 2 ))(conv_layer)
5.全连接(密集)层 全连接层将一层中的每个神经元连接到下一层中的每个神经元。这些层通常位于网络的末端,将学习到的特征转换为预测或类概率。全连接层通常用于网络的末端。对于分类任务:


从tensorflow.keras.layers import Dense、Flatten

flatten_layer = Flatten()(pooling_layer) 
density_layer = Dense(units= 128 ,activation= 'relu' )(flatten_layer)
6.Dropout 层 Dropout 层用于正则化以防止过拟合。在训练期间,随机神经元被“丢弃”,这意味着它们被忽略,从而迫使网络学习更稳健和更通用的特征。它通过在训练期间随机忽略一小部分输入单元来帮助防止过拟合:

f77051c2-f0ac-11ee-a297-92fbcf53809c.gif

Dropout 机制

从tensorflow.keras.layers import Dropout

dropout_layer = Dropout(rate= 0.5)(dense_layer)
7.批量标准化层 批量标准化 (BN) 是神经网络中用于稳定和加速训练过程的一种技术。它通过在训练期间调整和缩放层输入来标准化层输入。批量标准化背后的数学细节涉及标准化、缩放和移位操作。让我们深入研究批量标准化的数学原理。假设我们有一个大小为m且包含n 个特征的小批量。批量标准化的输入可以总结如下:

7.1均值计算 计算每个特征的小批量的均值μ :

f7741a0a-f0ac-11ee-a297-92fbcf53809c.jpg

数组 X 的平均值

这里,xi 表示小批量中第 i个特征的值。

7.2方差计算 计算每个特征的小批量方差σ² :

f7838ada-f0ac-11ee-a297-92fbcf53809c.jpg

方差计算

7.3标准化 通过减去平均值并除以标准差(σ)来标准化输入:

f7876f9c-f0ac-11ee-a297-92fbcf53809c.jpg

在范围内标准化

这里,ϵ是为了避免被零除而添加的一个小常数。

7.4缩放和平移 引入可学习参数(γ和β)来缩放和平移标准化值:

f7975538-f0ac-11ee-a297-92fbcf53809c.jpg

这里,γ是尺度参数,β是平移参数。

批量标准化操作通常插入神经网络层中的激活函数之前。它已被证明具有正则化效果,可以缓解内部协变量偏移等问题,使训练更稳定、更快速。这是一个简单的代码,用于 CNN 或任何深度神经网络中的批量标准化。

从tensorflow.keras.layers import BatchNormalization

batch_norm_layer = BatchNormalization()(dropout_layer)
总之,批量标准化对输入进行标准化,缩放和移动标准化值,并引入可学习的参数,使网络在训练期间能够适应。批量标准化的使用已成为深度学习架构中的标准做法。 8.Flatten Layer Flatten Layer 将多维特征图转换为一维向量,为输入到全连接层准备数据。

flatten_layer=Flatten()(batch_norm_layer)
9.上采样层 上采样是深度学习中用来增加特征图空间分辨率的技术。它通常用于图像分割和生成等任务。以下是常见上采样方法类型的简要说明:

9.1最近邻 (NN) 上采样 最近邻 (NN) 上采样,也称为通过复制或复制进行上采样,是一种简单而直观的方法。在这种方法中,输入中的每个像素都被复制或复制以生成更大的输出。虽然简单明了,但 NN 上采样可能会导致块状伪影和精细细节的丢失,因为它不会在相邻像素之间进行插值。

f7a85d9c-f0ac-11ee-a297-92fbcf53809c.jpg

最近邻上采样

9.2转置卷积(反卷积)上采样 转置卷积,通常称为反卷积,是一种可学习的上采样方法。它涉及使用具有可学习参数的卷积运算来增加输入的空间维度。转置卷积层中的权重在优化过程中进行训练,使网络能够学习特定于任务的上采样模式。

f7afcab4-f0ac-11ee-a297-92fbcf53809c.jpg

importtensorflowas tf
from tensorflow.keras.layers import Conv2DTranspose


#转置卷积上采样
transposed_conv_upsampling=Conv2DTranspose(filters=32, kernel_size=(3, 3), strides=(2, 2), padding='same')

每种上采样方法都有其优点和权衡,选择取决于任务的具体要求和数据的特点。

填充和步幅

这些是卷积神经网络 (CNN) 中的关键概念,它们会影响卷积运算后输出特征图的大小。让我们讨论三种类型的填充,并解释一下步幅的概念。

有效填充(无填充):在有效填充(也称为无填充)中,在应用卷积运算之前不会向输入添加任何额外填充。因此,卷积运算仅在滤波器和输入完全重叠的地方执行。这通常会导致输出特征图的空间维度减少。

f7bbf096-f0ac-11ee-a297-92fbcf53809c.jpg

from tensorflow.keras.layersimportConv2D


# 有效填充
valid_padding_conv=Conv2D(filters=32,kernel_size=(3,3),
strides=(1,1),padding='valid')

相同填充:相同填充确保输出特征图具有与输入相同的空间维度。它通过向输入添加零填充来实现这一点,这样滤波器就可以在输入上滑动而不会超出其边界。填充量经过计算以保持维度相同。

f7c6e348-f0ac-11ee-a297-92fbcf53809c.jpg

from tensorflow.keras.layers import Conv2D

#Keras中的填充
same_padding_conv=Conv2D(filters=32,kernel_size=(3,3),
strides=(1,1),padding='same')

步幅:步幅定义卷积过程中滤波器在输入上移动的步长。步幅越大,输出特征图的空间维度就越小。可以调整步幅来控制网络中的下采样级别。

从tensorflow.keras.layers导入Conv2D

# Keras 中带步幅的卷积示例
conv_with_stride = Conv2D(filters= 32 , kernel_size=( 3 , 3 ), 
                                  strides=( 2 , 2 ), padding= 'same' )
在此示例中,步幅设置为 (2, 2),表示滤波器在水平和垂直方向上每次移动两个像素。步幅是控制特征图的空间分辨率和影响网络感受野的关键参数。

在本文中,我想探索如何从头开始构建一个简单的卷积神经网络。让我们做早期计算机视觉学习任务中最流行的分类任务:猫与狗分类。此任务包括以下几个步骤:

导入库:

import tensorflow_datasets as tfds
import tensorflow as tf
from tensorflow.keras import layers


import keras
from keras.models import Sequential,Model
from keras.layers import Dense,Conv2D,Flatten,MaxPooling2D,GlobalAveragePooling2D
from keras.utils import plot_model


import numpy as np
import matplotlib.pyplot as plt
import scipy as sp
import cv2

加载数据:Cats vs Dogs 数据集

!curl -O https://download.microsoft.com/download/ 3 /E/ 1 /3E1C3F21-ECDB- 4869 - 8368 -6DEBA77B919F/kagglecatsanddogs_5340.zip 
!unzip -qkagglecatsanddogs_5340.zip
! ls

下面的单元将对图像进行预处理并创建批次,然后将其输入到我们的模型中。

def  augment_images ( image, label ): 
  
  # 转换为浮点数
  image = tf.cast(image, tf.float32) 
  # 标准化像素值
  image = (image/ 255 ) 
  # 调整大小为 300 x 300
   image = tf.image.resize(image,( 300 , 300 )) 

  return image, label 


# 使用上面的实用函数预处理图像
augmented_training_data = train_data.map ( augment_images) 


# 在训练前打乱并创建批次
train_batches = augmented_training_data.shuffle( 1024 ).batch( 32 )

过滤掉损坏的图像

在处理大量现实世界的图像数据时,损坏的图像是常有的事。让我们过滤掉标题中不包含字符串“JFIF”的编码不良的图像。

import os


num_skipped = 0
for folder_name in ("Cat", "Dog"):
folder_path = os.path.join("PetImages", folder_name)
for fname in os.listdir(folder_path):
fpath = os.path.join(folder_path, fname)
try:
fobj = open(fpath, "rb")
is_jfif = tf.compat.as_bytes("JFIF") in fobj.peek(10)
finally:
fobj.close()


if not is_jfif:
num_skipped += 1
# Delete corrupted image
os.remove(fpath)


print("Deleted %d images" % num_skipped)
生成Dataset
image_size = (300, 300)
batch_size = 128


train_ds, val_ds = tf.keras.utils.image_dataset_from_directory(
"PetImages",
validation_split=0.2,
subset="both",
seed=1337,
image_size=image_size,
batch_size=batch_size,
)

可视化数据

这是训练数据集中的前 9 张图片。如你所见,标签 1 是“狗”,标签 0 是“猫”。

import matplotlib.pyplot as plt


plt.figure(figsize=(6, 6))
for images, labels in train_ds.take(1):
for i in range(9):
ax = plt.subplot(3, 3, i + 1)
plt.imshow(images[i].numpy().astype("uint8"))
plt.title(int(labels[i]))
plt.axis("off")

使用图像数据增强

如果您没有大型图像数据集,最好通过对训练图像应用随机但现实的变换(例如随机水平翻转或小幅随机旋转)来人为地引入样本多样性。这有助于让模型接触训练数据的不同方面,同时减缓过拟合。

data_augmentation = keras.Sequential(
[
layers.RandomFlip("horizontal"),
layers.RandomRotation(0.1),
]
)
data_augmentation让我们通过反复应用数据集中的第一个图像来直观地看到增强样本的样子:
plt.figure(figsize=(6, 6))
for images, _ in train_ds.take(1):
for i in range(9):
augmented_images = data_augmentation(images)
ax = plt.subplot(3, 3, i + 1)
plt.imshow(augmented_images[0].numpy().astype("uint8"))
plt.axis("off")

配置数据集以提高性能

我们将数据增强应用到我们的训练数据集,并确保使用缓冲预取,这样我们就可以从磁盘中获取数据而不会导致 I/O 阻塞:

# 将 `data_augmentation` 应用于训练图像。
train_ds = train_ds.map(
lambda img, label: (data_augmentation(img), label),
num_parallel_calls=tf.data.AUTOTUNE,
)
# 在 GPU 内存中预取样本有助于最大限度地提高 GPU 利用率。
train_ds = train_ds.prefetch(tf.data.AUTOTUNE)
val_ds = val_ds.prefetch(tf.data.AUTOTUNE)
构建分类器

这看起来会很熟悉,因为它与我们之前构建的模型几乎相同。关键区别在于输出只是一个 S 激活单元。这是因为我们只处理两个类。

classCustomModel(Sequential):
def __init__(self):
super(CustomModel, self).__init__()


self.add(Conv2D(16, input_shape=(300, 300, 3), kernel_size=(3, 3), activation='relu', padding='same'))
self.add(MaxPooling2D(pool_size=(2, 2)))


self.add(Conv2D(32, kernel_size=(3, 3), activation='relu', padding='same'))
self.add(MaxPooling2D(pool_size=(2, 2)))


self.add(Conv2D(64, kernel_size=(3, 3), activation='relu', padding='same'))
self.add(MaxPooling2D(pool_size=(2, 2)))


self.add(Conv2D(128, kernel_size=(3, 3), activation='relu', padding='same'))
self.add(GlobalAveragePooling2D())
self.add(Dense(1, activation='sigmoid'))


# Instantiate the custom model
model = CustomModel()


# Display the model summarymodel.summary()
损失可以根据上次进行调整,以仅处理两个类别。为此,我们选择binary_crossentropy。
# 使用 GPU 进行训练大约需要 30 分钟。
#如果您的本地机器上没有GPU,请随意使用
model.compile(loss='binary_crossentropy',
metrics=['accuracy'],
optimizer=tf.keras.optimizers.RMSprop(lr=0.001))
model.fit(train_ds,
epochs=25,
validation_data=val_ds,)

测试模型

让我们下载一些图像并看看类别激活图是什么样子的。

!wget -O cat1.jpg https://storage.googleapis.com/laurencemoroney-blog.appspot.com/MLColabImages/cat1.jpg
!wget -O cat2.jpg https://storage.googleapis.com/laurencemoroney-blog.appspot.com/MLColabImages/cat2.jpg
!wget -O catanddog.jpg https://storage.googleapis.com/laurencemoroney-blog.appspot.com/MLColabImages/catanddog.jpg
!wget -O dog1.jpg https://storage.googleapis.com/laurencemoroney-blog.appspot.com/MLColabImages/dog1.jpg
!wget -O dog2.jpg https://storage.googleapis.com/laurencemoroney-blog.appspot.com/MLColabImages/dog2.jpg
# utility function to preprocess an image and show the CAM
def convert_and_classify(image):


# load the image
img = cv2.imread(image)


# preprocess the image before feeding it to the model
img = cv2.resize(img, (300,300)) / 255.0


# add a batch dimension because the model expects it
tensor_image = np.expand_dims(img, axis=0)


# get the features and prediction
features,results = cam_model.predict(tensor_image)


# generate the CAM
show_cam(tensor_image, features, results)


convert_and_classify('cat1.jpg')
convert_and_classify('cat2.jpg')
convert_and_classify('catanddog.jpg')
convert_and_classify('dog1.jpg')
convert_and_classify('dog2.jpg')
审核编辑:黄飞

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 滤波器
    +关注

    关注

    161

    文章

    7795

    浏览量

    177993
  • 计算机视觉
    +关注

    关注

    8

    文章

    1698

    浏览量

    45974
  • python
    +关注

    关注

    56

    文章

    4792

    浏览量

    84627
  • cnn
    cnn
    +关注

    关注

    3

    文章

    352

    浏览量

    22203
  • 卷积神经网络

    关注

    4

    文章

    367

    浏览量

    11863

原文标题:CNN的原理详解及代码实战(人手都会)

文章出处:【微信号:vision263com,微信公众号:新机器视觉】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Python深度学习的数学基础

    算法工程师修仙之路:Python深度学习(八)
    发表于 04-02 13:03

    深度学习脱掉图片人物的裤子之python教程

    深度学习脱掉图片人物的裤子【python教程】
    发表于 05-22 13:19

    深度学习入门之基于python的理论与实现

    深度学习入门-基于python的理论与实现(2)
    发表于 06-19 11:22

    labview实现深度学习,还在用python

    传统的视觉算法受打光以及图像的边缘对比度影响,无法做到人眼的分辨效果,而且人具有学习能力,经过大量样本的学习,人就可以找到不同物体之间的细微差别,从而分辨出物体的类别。CNN就是模拟人的大脑
    发表于 07-23 20:33

    一文详解CNN

    1 CNN简介 CNN即卷积神经网络(Convolutional Neural Networks),是一类包含卷积计算的神经网络,是深度学习(deep learning)的代表算法之
    发表于 08-18 06:56

    python机器学习深度学习学习书籍资料免费下载

    本文档的主要主要内容详细介绍的是python机器学习深度学习学习书籍资料免费下载。
    发表于 11-05 16:28 95次下载

    Python深度学习2018的源代码合集免费下载

    本文档的主要内容详细介绍的是Python深度学习2018的源代码合集免费下载。
    发表于 01-16 10:25 70次下载

    深度学习入门:基于Python的理论与实现电子书

    深度学习入门:基于Python的理论与实现电子书
    发表于 03-10 09:42 32次下载
    <b class='flag-5'>深度</b><b class='flag-5'>学习</b>入门:基于<b class='flag-5'>Python</b>的理论与实现电子书

    Python深度学习

    Python深度学习教材资料下载。
    发表于 06-01 14:40 41次下载

    深度学习中的图像分割

    深度学习可以学习视觉输入的模式,以预测组成图像的对象类。用于图像处理的主要深度学习架构是卷积神经网络(C
    的头像 发表于 05-05 11:35 1250次阅读

    [源代码]Python算法详解

    [源代码]Python算法详解[源代码]Python算法详解
    发表于 06-06 17:50 0次下载

    python卷积神经网络cnn的训练算法

    python卷积神经网络cnn的训练算法  卷积神经网络(Convolutional Neural Network,CNN)一直是深度学习
    的头像 发表于 08-21 16:41 1665次阅读

    深度神经网络模型cnn的基本概念、结构及原理

    深度神经网络模型CNN(Convolutional Neural Network)是一种广泛应用于图像识别、视频分析和自然语言处理等领域的深度学习模型。 引言
    的头像 发表于 07-02 10:11 9707次阅读

    深度学习常用的Python

    深度学习作为人工智能的一个重要分支,通过模拟人类大脑中的神经网络来解决复杂问题。Python作为一种流行的编程语言,凭借其简洁的语法和丰富的库支持,成为了深度
    的头像 发表于 07-03 16:04 624次阅读

    基于Python深度学习人脸识别方法

    基于Python深度学习人脸识别方法是一个涉及多个技术领域的复杂话题,包括计算机视觉、深度学习、以及图像处理等。在这里,我将概述一个基本的
    的头像 发表于 07-14 11:52 1249次阅读