Keras-4-深度学习用于计算机视觉-猫狗数据集训练卷积网络

news2024/9/26 5:17:27

0. 说明:

本篇学习记录主要包括:《Python深度学习》的第5章(深度学习用于计算机视觉)的第2节(在小型数据集上从头开始训练一个卷积神经网络)内容。

相关知识点:

  1. 从头训练卷积网络;
  2. 数据增强;
  3. dropout

1. 在猫狗分类数据集上训练一个卷积神经网络:

1.1 数据集下载及划分:

下载链接:https://www.kaggle.com/c/dogs-vs-cats/data

该数据集包含25000张猫狗图片(每个类别都有 12500 张)。

本次暂时只用到其中一小部分数据:每个类别各1000个样本作为训练集,各500个样本作验证集,各500个样本作测试集。

将原始文件解压之后得到: sampleSubmission.csv, test1.zip , train.zip;将 test1.zip解压后得到 test1/,包含12500张为分类猫狗图片;train.zip解压后得到25000张带标签的猫狗分类图片。

数据集划分的结果就是:

train: cat(1000), dog(1000)

val: cat(500), dog(500)

test: cat(500), dog(500)

import os

## 将前1000张猫狗图片复制到目标目录,作为训练集
for i in range(1000):
    os.system("cp ./dogs-vs-cats/train/cat.{}.jpg ./dogs-vs-cats/small_dt/train/train_cats/".format(i))
    os.system("cp ./dogs-vs-cats/train/dog.{}.jpg ./dogs-vs-cats/small_dt/train/train_dogs/".format(i))

## 将1000-1500的猫狗图片复制到验证集目录;
for j in range(1000,1500):
    os.system("cp ./dogs-vs-cats/train/cat.{}.jpg ./dogs-vs-cats/small_dt/validation/validation_cats/".format(j))
    os.system("cp ./dogs-vs-cats/train/dog.{}.jpg ./dogs-vs-cats/small_dt/validation/validation_dogs/".format(j))

## 将1500-2000的猫狗图片复制到测试集目录
for k in range(1500, 2000):
    os.system("cp ./dogs-vs-cats/train/cat.{}.jpg ./dogs-vs-cats/small_dt/test/test_cats/".format(k))
    os.system("cp ./dogs-vs-cats/train/dog.{}.jpg ./dogs-vs-cats/small_dt/test/test_dogs/".format(k))

1.2 数据预处理:

处理步骤:

  1. 读取图像文件;

  2. 将 JPEG 文件解码为 RGB 像素网格;

  3. 将这些像素网格转换为浮点张量;

  4. 将像素值 (0-255) 缩放到 [0,1] 之间 (较少的数值便于神经网络处理);

注意目录结构必须是:

train/

  train_cats/

  train_dogs/

validation/

  validation_cats/

  validation_dogs/

test/

  test_cats/

  test_dogs

from keras.preprocessing.image import ImageDataGenerator ## 可以将硬盘上的图像文件自动转换为预处理好的张量批量

## 将所有图像乘以 1./255 进行像素值的缩放
train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)

## 创建批量张量
train_generator = train_datagen.flow_from_directory(directory="./dogs-vs-cats/small_dt/train/",  ## 训练集图像文件所在目录
                                                 target_size=(150, 150),  ## 将所有图像的大小调整为 150x150
                                                 batch_size=20,  ## 批量大小
                                                 class_mode="binary") ## 因为时二分类问题,所以用二进制标签 (0,1)  

validation_generator = test_datagen.flow_from_directory(directory="./dogs-vs-cats/small_dt/validation/", ## 验证集图像文件所在目录
                                                        target_size=(150, 150),
                                                        batch_size=20,
                                                        class_mode="binary")
Found 2000 images belonging to 2 classes.
Found 1000 images belonging to 2 classes.
for data_batch, labels_batch in train_generator:
    print(data_batch.shape)
    print(labels_batch.shape)
    break
(20, 150, 150, 3)
(20,)

1.3 构建网络:

相比于之前的 MNIST,猫狗数据集相对而言数据量较大,所以相应的卷积网络也会比之前的更大一些。

和之前的 MNIST 类似,本次的卷积神经网络也是有 Conv2D层 (relu 为激活函数)和 MaxPooling2D 层交替组成。

增加网络深度既可以增大网络容量,也可以减小特征图的尺寸,使之在输入 Flatten 层时尺寸不会太大。

网络中特征图的深度在逐渐增大 (从32增加到128),而特征图的尺寸在逐渐减小 (从150x150 减到 7x7),这几乎是所有卷积网络的模式。

from keras import layers
from keras import models

model = models.Sequential()
model.add(layers.Conv2D(32, (3,3), activation="relu", input_shape=(150, 150, 3))) ## cnn1 (32个分类器,卷积核为3x3)
model.add(layers.MaxPool2D((2,2))) ## maxpooling 1

model.add(layers.Conv2D(64, (3,3), activation="relu")) ## cnn3
model.add(layers.MaxPool2D((2,2))) ## maxpooling 2

model.add(layers.Conv2D(128, (3,3), activation="relu")) ## cnn 3
model.add(layers.MaxPool2D((2,2))) ## maxpooling 3

model.add(layers.Conv2D(128, (3,3), activation="relu")) ## cnn4
model.add(layers.MaxPool2D((2,2))) ## maxpooling 4

model.add(layers.Flatten()) ## Flatten

model.add(layers.Dense(512, activation="relu")) ## FC1 (512个隐藏单元)

model.add(layers.Dense(1, activation="sigmoid")) ## 输出层 (1个隐藏单元,对应1个输出结果;二分类问题,激活函数为 sigmoid)
Metal device set to: Apple M1

systemMemory: 8.00 GB
maxCacheSize: 2.67 GB

查看 model 的特征维度随着每层的变化而产生的变化:

model.summary()
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 148, 148, 32)      896       
                                                                 
 max_pooling2d (MaxPooling2D  (None, 74, 74, 32)       0         
 )                                                               
                                                                 
 conv2d_1 (Conv2D)           (None, 72, 72, 64)        18496     
                                                                 
 max_pooling2d_1 (MaxPooling  (None, 36, 36, 64)       0         
 2D)                                                             
                                                                 
 conv2d_2 (Conv2D)           (None, 34, 34, 128)       73856     
                                                                 
 max_pooling2d_2 (MaxPooling  (None, 17, 17, 128)      0         
 2D)                                                             
                                                                 
 conv2d_3 (Conv2D)           (None, 15, 15, 128)       147584    
                                                                 
 max_pooling2d_3 (MaxPooling  (None, 7, 7, 128)        0         
 2D)                                                             
                                                                 
 flatten (Flatten)           (None, 6272)              0         
                                                                 
 dense (Dense)               (None, 512)               3211776   
                                                                 
 dense_1 (Dense)             (None, 1)                 513       
                                                                 
=================================================================
Total params: 3,453,121
Trainable params: 3,453,121
Non-trainable params: 0
_________________________________________________________________

关于上面结果中 Param 列参数的个数的计算 (以第一个 896 为例): 参数个数(896) = 卷积核个数(32) * 卷积核大小(3x3x3) + 卷积核个数(32)

## 配置并编译模型
from keras import optimizers

model.compile(optimizer=optimizers.RMSprop(learning_rate=1e-4),
              loss="binary_crossentropy", ## 二分类问题用 二元交叉熵损失函数
              metrics=["acc"])

1.4 用 fit_generator() 方法对数据进行拟合:

history = model.fit_generator(
    train_generator,
    steps_per_epoch=100, ## 因为训练样本一共有2000个,批量大小为20,所以读取完全部训练样本需要100个批量.
    epochs=30, ## 训练30次
    validation_data=validation_generator,
    validation_steps=50  ## 验证样本一共1000个,批量大小为20,读取完所有验证样本需要50个批量.
)
Epoch 1/30


/var/folders/0w/m6x2g_g94sqfmg3k8dldpwgm0000gn/T/ipykernel_32812/2996549298.py:1: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  history = model.fit_generator(
2023-06-25 13:34:09.683332: W tensorflow/tsl/platform/profile_utils/cpu_utils.cc:128] Failed to get CPU frequency: 0 Hz


100/100 [==============================] - 8s 69ms/step - loss: 0.6898 - acc: 0.5255 - val_loss: 0.6737 - val_acc: 0.5600
Epoch 2/30
100/100 [==============================] - 7s 67ms/step - loss: 0.6615 - acc: 0.6030 - val_loss: 0.6755 - val_acc: 0.5670
Epoch 3/30
100/100 [==============================] - 7s 66ms/step - loss: 0.6243 - acc: 0.6525 - val_loss: 0.6122 - val_acc: 0.6680

Epoch 29/30
100/100 [==============================] - 7s 67ms/step - loss: 0.0574 - acc: 0.9845 - val_loss: 0.9850 - val_acc: 0.7270
Epoch 30/30
100/100 [==============================] - 7s 67ms/step - loss: 0.0482 - acc: 0.9875 - val_loss: 0.9249 - val_acc: 0.7320

1.5 保存模型:

model.save("cats_and_dogs_small_1.h5")

1.6 绘制训练过程中损失曲线和精度曲线:

## 训练损失和验证损失
import matplotlib.pyplot as plt
history_dict = history.history

loss_values = history_dict["loss"]
val_loss_values = history_dict["val_loss"]

epochs = range(1, len(loss_values)+1)

plt.plot(epochs, loss_values, "bo", label="Training loss") ## "bo" 表示蓝色圆点
plt.plot(epochs, val_loss_values, "b", label="Validation loss") ## "bo" 表示蓝色实线
plt.title("Training and validation loss")
plt.xlabel("Epochs")
plt.ylabel("Loss")
plt.legend()

plt.show()

在这里插入图片描述

## 练精度和验证精度
acc_values = history_dict["acc"]
val_acc_values = history_dict["val_acc"]

plt.plot(epochs, acc_values, "bo", label="Training accuracy") ## "bo" 表示蓝色圆点
plt.plot(epochs, val_acc_values, "b", label="Validation accuracy") ## "bo" 表示蓝色实线
plt.title("Training and validation accuracy")
plt.xlabel("Epochs")
plt.ylabel("Accuracy")
plt.legend()

plt.show()

在这里插入图片描述

1.7 使用数据增强来降低模型过拟合:

由于训练样本较少,所以模型很可能出现过拟合。除了之前提到的 dropoutL2正则化 等降低过拟合的方法外,还可以使用一种针对计算机视觉领域的新方法——数据增强(data augmentation)。

数据增强指从现有的训练样本中生成更多的训练数据,利用多种能够生成可信图像的随机变换来增强样本。(将图像作不同的变化(翻转等)使模型在训练时不会两次查看完全相同的图像))

train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=40,  ## 图像随机旋转的角度范围 (0-180)
    width_shift_range=0.2,  ## 图像在水平方向上平移的范围 (相对于总宽度的比例)
    height_shift_range=0.2, ## 图像在垂直方向上平移的范围 (相对于总高度的比例)
    shear_range=0.2, ## 随机错切变换的角度
    zoom_range=0.2, ## 图像随机缩放的范围
    horizontal_flip=True ## 随机将一半图像水平翻转
)

test_datagen = ImageDataGenerator(rescale=1./255) ## 验证数据不能增强


## 创建批量张量
train_generator = train_datagen.flow_from_directory(directory="./dogs-vs-cats/small_dt/train/",  ## 训练集图像文件所在目录
                                                 target_size=(150, 150),  ## 将所有图像的大小调整为 150x150
                                                 batch_size=20,  ## 批量大小
                                                 class_mode="binary") ## 因为时二分类问题,所以用二进制标签 (0,1)  

validation_generator = test_datagen.flow_from_directory(directory="./dogs-vs-cats/small_dt/validation/", ## 验证集图像文件所在目录
                                                        target_size=(150, 150),
                                                        batch_size=20,
                                                        class_mode="binary")
Found 2000 images belonging to 2 classes.
Found 1000 images belonging to 2 classes.

1.8 定义一个包含dropout的卷积网络:

## 定义模型框架
model = models.Sequential()
model.add(layers.Conv2D(32, (3,3), activation="relu", input_shape=(150, 150,3)))
model.add(layers.MaxPool2D((2,2)))

model.add(layers.Conv2D(64, (3,3), activation="relu"))
model.add(layers.MaxPool2D((2,2)))

model.add(layers.Conv2D(128, (3,3), activation="relu"))
model.add(layers.MaxPool2D((2,2)))

model.add(layers.Conv2D(128, (3,3), activation="relu"))
model.add(layers.MaxPool2D((2,2)))

model.add(layers.Flatten())

model.add(layers.Dropout(0.5))

model.add(layers.Dense(512, activation="relu"))

model.add(layers.Dense(1, activation="sigmoid"))


## 配置并编译模型
model.compile(optimizer=optimizers.RMSprop(learning_rate=1e-4),
              loss="binary_crossentropy",
              metrics=["acc"])

1.9 训练并保存模型:

history = model.fit_generator(
    train_generator,
    steps_per_epoch=100,
    epochs=50,
    validation_data=validation_generator,
    validation_steps=50
)

model.save("cats_and_dogs_small_2.h5")
Epoch 1/50


/var/folders/0w/m6x2g_g94sqfmg3k8dldpwgm0000gn/T/ipykernel_32812/2595555689.py:1: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  history = model.fit_generator(


100/100 [==============================] - 8s 73ms/step - loss: 0.6944 - acc: 0.5055 - val_loss: 0.6940 - val_acc: 0.5000
Epoch 2/50
100/100 [==============================] - 8s 77ms/step - loss: 0.6901 - acc: 0.5235 - val_loss: 0.6918 - val_acc: 0.5000
Epoch 3/50
100/100 [==============================] - 8s 79ms/step - loss: 0.6780 - acc: 0.5765 - val_loss: 0.6721 - val_acc: 0.5440
 
Epoch 48/50
100/100 [==============================] - 11s 112ms/step - loss: 0.4791 - acc: 0.7715 - val_loss: 0.5140 - val_acc: 0.7340
Epoch 49/50
100/100 [==============================] - 10s 102ms/step - loss: 0.4683 - acc: 0.7725 - val_loss: 0.4514 - val_acc: 0.7720
Epoch 50/50
100/100 [==============================] - 11s 106ms/step - loss: 0.4825 - acc: 0.7790 - val_loss: 0.4511 - val_acc: 0.7810

1.10 可视化损失和精度:

## 训练损失和验证损失
import matplotlib.pyplot as plt
history_dict = history.history

loss_values = history_dict["loss"]
val_loss_values = history_dict["val_loss"]
epochs = range(1, len(loss_values)+1)

plt.plot(epochs, loss_values, "bo", label="Training loss") ## "bo" 表示蓝色圆点
plt.plot(epochs, val_loss_values, "b", label="Validation loss") ## "bo" 表示蓝色实线
plt.title("Training and validation loss")
plt.xlabel("Epochs")
plt.ylabel("Loss")
plt.legend()

plt.show()

在这里插入图片描述

## 训练精度和验证精度
import matplotlib.pyplot as plt
history_dict = history.history

acc_values = history_dict["acc"]
val_acc_values = history_dict["val_acc"]
epochs = range(1, len(acc_values)+1)

plt.plot(epochs, acc_values, "bo", label="Training accuracy") ## "bo" 表示蓝色圆点
plt.plot(epochs, val_acc_values, "b", label="Validation accuracy") ## "bo" 表示蓝色实线
plt.title("Training and validation accuracy")
plt.xlabel("Epochs")
plt.ylabel("Accuracy")
plt.legend()

plt.show()

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/688761.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI 绘画用 Stable Diffusion 图生图局部重绘功能给美女换装(这是我能看的嘛)

昨天带大家一起装好了 Stable Diffusion 的环境,今天就来带大家一起体验一下 Stable Diffusion 的局部重绘功能。 没装好环境的可以看上一篇:AI 绘画基于 Kaggle 10 分钟搭建 Stable Diffusion(保姆级教程) Stable Diffusion 的…

可重入,可打断,公平锁,条件变量原理解读

目录 可重入原理 可打断原理 不可打断模式 可打断模式 公平锁实现原理 条件变量实现原理 await 流程 signal 流程 可重入原理 什么是可重入:当线程请求一个由其它线程持有的对象锁时,该线程会阻塞,而当线程请求由自己持有的对象锁…

阿里刚换帅,京东忙换将:新时代号角吹响

6月26日早间,京东物流在港交所发布公告称,京东物流CEO余睿因个人身体原因辞任执行董事、首席执行官及授权代表,原京东产发CEO胡伟将担任京东物流CEO。 同时,据《科创板日报》报道,京东集团将新成立创新零售部&#xf…

【论文笔记】Fast Segment Anything

我说个数:一个月5篇基于Fast Segment Anything的改进的论文就会出现哈哈哈哈。 1.介绍 1.1 挑战 SAM架构的主要部分Transformer(ViT)模型相关的大量计算资源需求,这给其实际部署带来了障碍 1.2 任务解耦 将分段任意任务解耦为…

正确认识:1189194-65-7,DOTA-CH2-Alkynyl (TFA salt),试剂的结构式和CAS

文章关键词:双功能螯合剂,大环配体,标记螯合剂修饰 【产品描述】 DOTA-CH2-Alkynyl (TFA salt)中TFA是一种强酸。它可以质子化任何氨基。盐酸也是这样。在纯化多肽过程中的反相HPLC,有一种技术是阴离子交换。将多肽加载在柱子上&a…

MySql基础教程(三):创建数据表、数据增删改查、删除数据表

MySql基础教程(三):创建数据表、数据增删改查、删除数据表 1、创建数据表 创建MySQL数据表需要以下信息: 表名表字段名定义每个表字段 1.1 语法 下面是创建MySQL数据表的SQL通用语法: CREATE TABLE table_name (column_name column_typ…

无线蓝牙通信有关(NRF2401模块)的功耗,通道频率等

参考: ISM频段 Industrial Scientific Medical,ISM(工业、科学、医疗)频段为国际电信联盟(ITU)《无线电规则》定义的指定无线电频段。 Frequency-Shift Keying 数字调制技术(FSK调制) 将需要…

又是一年毕业季,准备好踏入职场了吗?

文章目录 一、大学时光二、给毕业生的一些建议三、职场中的经验分享四、程序员未来职业规划 一、大学时光 作为一名程序员,大学时光是我职业生涯中最重要的时期之一。这四年的大学,我不仅学到了计算机科学的理论知识,还积累了丰富的编程经验…

tqdm:python的简单可视化进度

tqdm:python的简单可视化进度 说明 ​ 本篇文章的主要目的是快速上手使用,而不是解析源码。 目录结构 文章目录 tqdm:python的简单可视化进度1. 应用场景2. 库安装3. 方法速览4. 案例5. 总结 1. 应用场景 ​ 进度条应用的场景很多&#xff0…

YOLOv8独家原创改进:独家首发最新原创XIoU_NMS改进点,改进有效可以直接当做自己的原创改进点来写,提升网络模型性能、收敛速度和鲁棒性

💡该教程为属于《芒果书》📚系列,包含大量的原创首发改进方式, 所有文章都是全网首发原创改进内容🚀 💡本篇文章为YOLOv8独家原创改进:独家首发最新原创XIoU_NMS改进点,改进有效可以直接当做自己的原创改进点来写,提升网络模型性能、收敛速度和鲁棒性。 💡对自己…

[RocketMQ] Producer发送消息的总体流程 (七)

单向发送: 把消息发向Broker服务器, 不管Broker是否接收, 只管发, 不管结果。同步发送: 把消息发向Broker服务器, 如果Broker成功接收, 可以得到Broker的响应。异步发送: 把消息发向Broker服务器, 如果Broker成功接收, 可以得到Broker的响应。异步所以发送消息后, 不用等待, 等…

css基础知识十:介绍一下CSS中的Grid网格布局?

一、是什么 Grid 布局即网格布局,是一个二维的布局方式,由纵横相交的两组网格线形成的框架性布局结构,能够同时处理行与列 擅长将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系 这与之前讲到的flex一维…

操作系统—内存管理

单片机是没有操作系统的,每次写完代码都是通过一些工具将程序直接烧录进去,这样程序才能跑起来。单片机的CPU是直接操作内存的物理地址。在这种情况下,要想在内存中同时运行两个程序是不可能的,程序会崩溃。那么操作系统为了解决这…

LLM相关的一些调研

Prompt Engine 可以参考该项目,该项目提供关于提示词书写的规则。由openai以及吴恩达完成。 https://github.com/datawhalechina/prompt-engineering-for-developers由于目前chatgpt 无法直接在国内访问,推荐在claude on slack上尝试。关于claude api h…

Leetcode:1035. 不相交的线、53. 最大子数组和(C++)

目录 1035. 不相交的线 题目描述: 实现代码与解析: 动态规划 原理解析: 53. 最大子数组和 题目描述: 实现代码与解析: 动态规划 原理思路: 1035. 不相交的线 题目描述: 在两条独立的水…

移动端永不过时的高薪技术岗位,原来是它……

随着 Android 设备的普及和应用领域的不断扩大,Android Framework 开发需求量将会持续增长,并且会越来越多地向行业、企业级应用和系统优化等方向发展。以下是一些 Android Framework 开发相关的应用场景: 1. 特定垂直领域的智能设备&#x…

Jmeter性能测试

一、jmeter多并发 1.线程设置: 线程数——多少个虚拟用户 ramp_up时间(秒)——时间,设置时间内将线程都跑完 循环次数——勾选永远,就一直跑,直到手动停止;输入数字,就是循环多少次 2.jmeter逻辑分支控制…

关于MySQL性能优化方案,掌握这一篇就够了!

目录 前言 一、设置索引 1、索引的优缺点: 2、给表列创建索引 3、查看索引 4、删除索引: 5、索引原理: 二、分类讨论 三、针对偶尔很慢的情况 1、 数据库在刷新脏页(flush) 2. 拿不到锁我能怎么办 四、针对一直都这…

力扣题库刷题笔记16--最接近的三数之和

1、题目如下: 2、个人Python代码实现 本题的思路应该与很早之前刷的第15题三数之和是一个思路: 1、先将数组排序,然后进行遍历数组 2、确定左指针、右指针 3、判断三个数之和是否接近目标值 4、重点是,为确保左右指针不是同一个元…

Transformer回归预测

一、Attention is all you need——李沐论文精读Transformer 论文地址: https://arxiv.org/pdf/1706.03762.pdf Transformer论文逐段精读【论文精读】 卷积神经网络对较长的序列难以建模,因为他每次看一个比较小的窗口,如果两个像素隔得比较…