《Python深度学习》第四讲:计算机视觉中的深度学习

embedded/2025/3/18 2:24:42/

计算机视觉深度学习中最酷的应用之一,它让计算机能够像人类一样“看”和理解图像。想象一下,计算机可以自动识别照片中的物体、人脸,甚至可以读懂交通标志。这一切听起来是不是很神奇?其实,这一切都离不开深度学习中的卷积神经网络(CNN)。今天,我们就来深入了解一下CNN是如何工作的。


5.1 卷积神经网络简介

先来看下卷积神经网络(CNN)是什么。

CNN是一种专门用于处理图像数据的神经网络。它的灵感来源于人类视觉系统的工作方式。想象一下,当你看到一张照片时,你的大脑会先识别出照片中的边缘、纹理等基本特征,然后逐步组合这些特征,最终识别出照片中的物体。CNN的工作原理也是类似的,它通过多层的卷积操作来逐步提取图像的特征。

我们来看一个简单的CNN结构。

from keras import layers
from keras import modelsmodel = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

这里,我们用Conv2D层来提取图像的特征,用MaxPooling2D层来减少特征图的尺寸。最后,我们用Flatten层将特征图展平为一维向量,然后用Dense层进行分类。

这个网络可以用来做什么呢?

我们可以用它来识别照片中的猫和狗。想象一下,你有一堆猫和狗的照片,你想让计算机自动识别出哪些是猫,哪些是狗。这就是一个典型的二分类问题。


5.2 在小型数据集上从头开始训练一个卷积神经网络

好,下面我们来看看如何用CNN解决一个实际问题。

假设你有一个小型的数据集,包含2000张猫和狗的照片,你想用这些照片训练一个CNN模型。虽然数据量不大,但CNN依然可以很好地工作。

我们先来看看数据预处理。

我们需要将照片的尺寸调整为统一的大小(比如150×150),并将像素值归一化到0到1之间。这样可以让神经网络的学习过程更加稳定。

from keras.preprocessing.image import ImageDataGeneratortrain_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)train_generator = train_datagen.flow_from_directory(train_dir,  # 训练数据目录target_size=(150, 150),  # 调整照片大小batch_size=20,class_mode='binary')  # 因为是二分类问题validation_generator = test_datagen.flow_from_directory(validation_dir,  # 验证数据目录target_size=(150, 150),batch_size=20,class_mode='binary')

接下来,我们开始训练模型。

我们用fit_generator方法来训练模型,训练100个epoch。

history = model.fit_generator(train_generator,steps_per_epoch=100,  # 每个epoch的步数epochs=100,validation_data=validation_generator,validation_steps=50)

训练完成后,我们在测试集上评估模型的性能。

test_generator = test_datagen.flow_from_directory(test_dir,  # 测试数据目录target_size=(150, 150),batch_size=20,class_mode='binary')test_loss, test_acc = model.evaluate_generator(test_generator, steps=50)
print('Test accuracy:', test_acc)

结果怎么样呢?

你会发现,这个简单的CNN在测试集上的准确率可以达到82%左右。这说明CNN能够很好地学习照片中的特征,识别出猫和狗。


5.3 使用预训练的卷积神经网络

下面我们来看看如何利用预训练的模型来提升性能。

预训练的模型是在大规模数据集(比如ImageNet)上训练好的模型。这些模型已经学习到了很多通用的图像特征,我们可以直接利用这些特征来解决自己的问题。

我们来加载一个预训练的模型:VGG16。

from keras.applications import VGG16conv_base = VGG16(weights='imagenet', include_top=False, input_shape=(150, 150, 3))

这里,weights='imagenet'表示我们加载的是在ImageNet数据集上预训练好的权重。include_top=False表示我们不加载模型的顶部分类层,因为我们有自己的分类任务。

接下来,我们在预训练模型的基础上添加自己的分类器。

model = models.Sequential()
model.add(conv_base)
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

然后,我们冻结预训练模型的权重,只训练我们添加的分类器。

conv_base.trainable = False

最后,我们开始训练模型。

model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])
history = model.fit_generator(train_generator,steps_per_epoch=100,epochs=30,validation_data=validation_generator,validation_steps=50)

训练完成后,我们在测试集上评估模型的性能。

test_loss, test_acc = model.evaluate_generator(test_generator, steps=50)
print('Test accuracy:', test_acc)

你会发现,利用预训练模型后,模型的准确率可以达到96%左右。


5.4 卷积神经网络的可视化

最后,我们来看看如何可视化CNN学到的特征。

可视化可以帮助我们理解CNN是如何工作的。我们可以可视化中间层的激活,看看CNN是如何逐步提取图像特征的。

我们先来看看如何可视化中间层的激活。

from keras.models import Modellayer_outputs = [layer.output for layer in model.layers[:8]]
activation_model = Model(inputs=model.input, outputs=layer_outputs)img_tensor = ...  # 加载一张测试图片
activations = activation_model.predict(img_tensor)

这里,activations是一个列表,包含了每个中间层的激活。我们可以将这些激活可视化,看看CNN是如何逐步提取图像特征的。

我们还可以可视化CNN的过滤器。

过滤器是CNN用来检测图像中特定模式的工具。我们可以生成一个输入图像,让某个过滤器的激活最大化,从而可视化这个过滤器。

from keras import backend as Klayer_name = 'block3_conv1'
filter_index = 0
layer_output = model.get_layer(layer_name).output
loss = K.mean(layer_output[:, :, :, filter_index])grads = K.gradients(loss, model.input)[0]
grads /= (K.sqrt(K.mean(K.square(grads))) + 1e-5)
iterate = K.function([model.input], [loss, grads])input_img_data = np.random.random((1, 150, 150, 3)) * 20 + 128.
step = 1.
for i in range(40):loss_value, grads_value = iterate([input_img_data])input_img_data += grads_value * stepimg = input_img_data[0]

这里,img就是让某个过滤器激活最大化的输入图像。我们可以将它可视化,看看这个过滤器检测的是什么模式。


总结

我们从卷积神经网络(CNN)的基本结构讲起,了解了它如何通过卷积操作逐步提取图像特征。我们还学习了如何用CNN解决实际问题,比如识别照片中的猫和狗。我们还探讨了如何利用预训练的模型来提升性能,以及如何可视化CNN学到的特征。


http://www.ppmy.cn/embedded/173466.html

相关文章

kafka 中的 rebalance

Kafka 的 Rebalance(重平衡)机制本质上是一个协调过程,用于在消费者组内动态分配分区,以保证消费任务均匀分布。Rebalance 主要由 Kafka Consumer Group 协议(Group Membership Protocol)驱动,涉…

Linux 文件与目录操作指令

以下是 Linux 文件与目录操作指令的详细整理&#xff0c;涵盖 基本操作、权限管理、查找统计、压缩解压 等场景&#xff0c;包含常用选项与示例&#xff1a; 一、目录导航与查看 1. pwd&#xff1a;显示当前目录的绝对路径 <BASH> pwd # 输出&#xff1a;/hom…

OpenWebUI项目调研对比

开源地址&#xff1a;https://github.com/open-webui/open-webui 官方文档&#xff1a;https://docs.openwebui.com/ OpenWebUI(以前称为Ollama WebUl)是一款面向大型语言模型(LLMs)的用户友好型Web界面&#xff0c;支持Ollama和兼容OpenAl的API运行。 通过一个直观的界面&a…

【STM32】USART串口协议串口外设-学习笔记

串口协议 通信接口 通信的目的&#xff1a;将一个设备的数据传送到另一个设备&#xff0c;扩展硬件系统。比如STM32芯片内部集成了很多功能模块&#xff0c;像定时器计数、PWM输出、AD采集等等。这些都是芯片内部的电路&#xff0c;这些电路的配置寄存器&#xff0c;数据寄存…

SSL/TLS 1.2过程:Client端如何验证服务端证书?

快速回顾非对称加密和对称加密 首先快速说一下非对称加密和对称加密。非对称加密&#xff0c;就是有一个公钥和私钥(成对存在)。 公钥对一段文本A加密得到文本B&#xff0c;只有对应的私钥能对B解密得到A。 私钥对一段文本C加密得到文本D&#xff0c;只有对应的公钥能对D解密得…

unity生命周期

unity的生命周期 都是有序的1. 实例化与初始化阶段Awake()OnEnable() 2. 开始与更新阶段Start()FixedUpdate()Update()LateUpdate() 3. 渲染阶段OnPreCull()OnBecameVisible() 和 OnBecameInvisible()OnWillRenderObject()OnRenderObject()OnPostRender() 4. 销毁阶段OnDisable…

数学 :矩阵

文章目录 前言1. 基本矩阵运算1.1 矩阵加法1.2 矩阵减法1.3 矩阵乘法 2. 转置矩阵3. 旋转矩阵小结 【全文大纲】 : https://blog.csdn.net/Engineer_LU/article/details/135149485 前言 在许多应用场合下&#xff0c;我们都需要用矩阵来表示公式&#xff0c;接下来简洁描述矩阵…

SpringBoot入门-(1) Maven【概念+流程】

SpringBoot入门-(1) Maven 动机 对于企业级大项目而言&#xff0c;需要手动导入很大Jar包&#xff0c;费时费力&#xff0c;且Jar包之间也可能存在依赖和冲突&#xff0c;这些关系导致Jar包之间想毛线团一样缠在一起&#xff0c;因此我们需要一个包管理系统帮我们自动下载导入…