第38周:猫狗识别 (Tensorflow实战第八周)

目录

前言

一、前期工作

1.1 设置GPU

1.2 导入数据

输出

二、数据预处理

2.1 加载数据

2.2 再次检查数据

2.3 配置数据集

2.4 可视化数据

三、构建VGG-16网络

3.1 VGG-16网络介绍

3.2 搭建VGG-16模型

四、编译

五、训练模型

六、模型评估

七、预测

总结


前言

  • 🍨 本文为中的学习记录博客
  • 🍖 原作者:

说在前面

1)本周任务:了解model.train_on_batch()并运用;了解tqdm,并使用tqdm实现可视化进度条;

2)运行环境:Python3.6、Pycharm2020、tensorflow2.4.0


一、前期工作

1.1 设置GPU

代码如下:

import os
os.environ["CUDA_VISIBLE_DEVICES"]="0"
os.environ["TF_CPP_MIN_LOG_LEVEL"]='3' # 忽略 Error
#隐藏警告
import warnings
warnings.filterwarnings('ignore')
# 1.1 设置GPU
import tensorflow as tf
gpus = tf.config.list_physical_devices("GPU")
if gpus:tf.config.experimental.set_memory_growth(gpus[0], True)  #设置GPU显存用量按需使用tf.config.set_visible_devices([gpus[0]],"GPU")
# 打印显卡信息,确认GPU可用
print(gpus)

输出:[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]

⚠️⚠️⚠️前期我没有使用GPU就采用的CPU训练速度很慢,虽然安装了tensorflow-gpu但还是用的CPU因为我的cudnn和cudatoolkit之前没配置成功,然后我补充安装。这里出线会打印很多关于gpu调用的日志信息,会很影响我们对训练过程和打印信息的关注度,这里我在import tensorflow之前先通过下面的设置来控制打印的内容

import os
os.environ["CUDA_VISIBLE_DEVICES"]="0"
os.environ["TF_CPP_MIN_LOG_LEVEL"]='3' 

TF_CPP_MIN_LOG_LEVEL 取值 0 : 0也是默认值,输出所有信息
TF_CPP_MIN_LOG_LEVEL 取值 1 : 屏蔽通知信息
TF_CPP_MIN_LOG_LEVEL 取值 2 : 屏蔽通知信息和警告信息
TF_CPP_MIN_LOG_LEVEL 取值 3 : 屏蔽通知信息、警告信息和报错信息                 
参考自:https://blog.csdn.net/xiaoqiaoliushuiCC/article/details/124435241

1.2 导入数据

代码如下:

# 1.2 导入数据
import matplotlib.pyplot as plt
# 支持中文
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
import os,PIL,pathlib
data_dir = "./data"
data_dir = pathlib.Path(data_dir)
image_count = len(list(data_dir.glob('*/*')))
print("图片总数为:",image_count)

输出

图片总数为:  3400

二、数据预处理

2.1 加载数据

使用image_dataset_from_directory方法将磁盘中的数据加载到tf.data.Dataset,tf.keras.preprocessing.image_dataset_from_directory():是 TensorFlow 的 Keras 模块中的一个函数,用于从目录中创建一个图像数据集(dataset)。这个函数可以以更方便的方式加载图像数据,用于训练和评估神经网络模型

测试集与验证集的关系:

  • 验证集并没有参与训练过程梯度下降过程的,狭义上来讲是没有参与模型的参数训练更新的。
  • 但是广义上来讲,验证集存在的意义确实参与了一个“人工调参”的过程,我们根据每一个epoch训练之后模型在valid data上的表现来决定是否需要训练进行early stop,或者根据这个过程模型的性能变化来调整模型的超参数,如学习率,batch_size等等。因此,我们也可以认为,验证集也参与了训练,但是并没有使得模型去overfit验证集
  • 因此,我们也可以认为,验证集也参与了训练,但是并没有使得模型去overfit验证集

代码如下:

# 二、数据预处理
# 2.1 加载数据
batch_size = 8
img_height = 224
img_width = 224
train_ds = tf.keras.preprocessing.image_dataset_from_directory(data_dir,validation_split=0.2,subset="training",seed=12,image_size=(img_height, img_width),batch_size=batch_size)
val_ds = tf.keras.preprocessing.image_dataset_from_directory(data_dir,validation_split=0.2,subset="validation",seed=12,image_size=(img_height, img_width),batch_size=batch_size)
class_names = train_ds.class_names
print(class_names)

输出如下:

['cat', 'dog']

2.2 再次检查数据

代码如下:

# 2.2 再次检查数据
for image_batch, labels_batch in train_ds:print(image_batch.shape)print(labels_batch.shape)break

输出:

(8, 224, 224, 3)
(8,)

2.3 配置数据集

代码如下:

# 2.3 配置数据集
AUTOTUNE = tf.data.AUTOTUNEdef preprocess_image(image,label):return (image/255.0,label)
# 归一化处理
train_ds = train_ds.map(preprocess_image, num_parallel_calls=AUTOTUNE)
val_ds = val_ds.map(preprocess_image, num_parallel_calls=AUTOTUNE)
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)

2.4 可视化数据

代码如下:

plt.figure(figsize=(15, 10))  # 图形的宽为15高为10
for images, labels in train_ds.take(1):for i in range(8):ax = plt.subplot(5, 8, i + 1)plt.imshow(images[i])plt.title(class_names[labels[i]])plt.axis("off")

输出:

三、构建VGG-16网络

3.1 VGG-16网络介绍

结构说明:

  • 13个卷积层(Convolutional Layer),分别用blockX_convX表示
  • 3个全连接层(Fully connected Layer),分别用fcXpredictions表示
  • 5个池化层(Pool layer),分别用blockX_pool表示

网络结构图如下(包含了16个隐藏层--13个卷积层和3个全连接层,故称为VGG-16)

​​

3.2 搭建VGG-16模型

代码如下:

# 三、构建VGG-16网络
from tensorflow.keras import layers, models, Input
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten, Dropoutdef VGG16(nb_classes, input_shape):input_tensor = Input(shape=input_shape)# 1st blockx = Conv2D(64, (3,3), activation='relu', padding='same',name='block1_conv1')(input_tensor)x = Conv2D(64, (3,3), activation='relu', padding='same',name='block1_conv2')(x)x = MaxPooling2D((2,2), strides=(2,2), name = 'block1_pool')(x)# 2nd blockx = Conv2D(128, (3,3), activation='relu', padding='same',name='block2_conv1')(x)x = Conv2D(128, (3,3), activation='relu', padding='same',name='block2_conv2')(x)x = MaxPooling2D((2,2), strides=(2,2), name = 'block2_pool')(x)# 3rd blockx = Conv2D(256, (3,3), activation='relu', padding='same',name='block3_conv1')(x)x = Conv2D(256, (3,3), activation='relu', padding='same',name='block3_conv2')(x)x = Conv2D(256, (3,3), activation='relu', padding='same',name='block3_conv3')(x)x = MaxPooling2D((2,2), strides=(2,2), name = 'block3_pool')(x)# 4th blockx = Conv2D(512, (3,3), activation='relu', padding='same',name='block4_conv1')(x)x = Conv2D(512, (3,3), activation='relu', padding='same',name='block4_conv2')(x)x = Conv2D(512, (3,3), activation='relu', padding='same',name='block4_conv3')(x)x = MaxPooling2D((2,2), strides=(2,2), name = 'block4_pool')(x)# 5th blockx = Conv2D(512, (3,3), activation='relu', padding='same',name='block5_conv1')(x)x = Conv2D(512, (3,3), activation='relu', padding='same',name='block5_conv2')(x)x = Conv2D(512, (3,3), activation='relu', padding='same',name='block5_conv3')(x)x = MaxPooling2D((2,2), strides=(2,2), name = 'block5_pool')(x)# full connectionx = Flatten()(x)x = Dense(4096, activation='relu',  name='fc1')(x)x = Dense(4096, activation='relu', name='fc2')(x)output_tensor = Dense(nb_classes, activation='softmax', name='predictions')(x)model = Model(input_tensor, output_tensor)return modelmodel=VGG16(1000, (img_width, img_height, 3))
model.summary()

模型结构打印如下:

​Model: "model"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 224, 224, 3)]     0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 224, 224, 64)      1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 224, 224, 64)      36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 112, 112, 64)      0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 112, 112, 128)     73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 112, 112, 128)     147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 56, 56, 128)       0         
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 56, 56, 256)       295168    
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 56, 56, 256)       590080    
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 56, 56, 256)       590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 28, 28, 256)       0         
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 28, 28, 512)       1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 28, 28, 512)       2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 28, 28, 512)       2359808   
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, 14, 14, 512)       0         
_________________________________________________________________
block5_conv1 (Conv2D)        (None, 14, 14, 512)       2359808   
_________________________________________________________________
block5_conv2 (Conv2D)        (None, 14, 14, 512)       2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 14, 14, 512)       2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 7, 7, 512)         0         
_________________________________________________________________
flatten (Flatten)            (None, 25088)             0         
_________________________________________________________________
fc1 (Dense)                  (None, 4096)              102764544 
_________________________________________________________________
fc2 (Dense)                  (None, 4096)              16781312  
_________________________________________________________________
predictions (Dense)          (None, 1000)              4097000   
=================================================================
Total params: 138,357,544
Trainable params: 138,357,544
Non-trainable params: 0

四、编译

代码如下:

model.compile(optimizer="adam",loss='sparse_categorical_crossentropy',metrics=['accuracy'])

五、训练模型

代码如下:

# 五、训练模型
from tqdm import tqdm
import tensorflow.keras.backend as Kepochs = 10
lr = 1e-4# 记录训练数据,方便后面的分析
history_train_loss = []
history_train_accuracy = []
history_val_loss = []
history_val_accuracy = []
for epoch in range(epochs):train_total = len(train_ds)val_total = len(val_ds)with tqdm(total=train_total, desc=f'Epoch {epoch + 1}/{epochs}', mininterval=1, ncols=100) as pbar:lr = lr * 0.92K.set_value(model.optimizer.lr, lr)for image, label in train_ds:history = model.train_on_batch(image, label)train_loss = history[0]train_accuracy = history[1]pbar.set_postfix({"loss": "%.4f" % train_loss,"accuracy": "%.4f" % train_accuracy,"lr": K.get_value(model.optimizer.lr)})pbar.update(1)history_train_loss.append(train_loss)history_train_accuracy.append(train_accuracy)print('开始验证!')with tqdm(total=val_total, desc=f'Epoch {epoch + 1}/{epochs}', mininterval=0.3, ncols=100) as pbar:for image, label in val_ds:history = model.test_on_batch(image, label)val_loss = history[0]val_accuracy = history[1]pbar.set_postfix({"loss": "%.4f" % val_loss,"accuracy": "%.4f" % val_accuracy})pbar.update(1)history_val_loss.append(val_loss)history_val_accuracy.append(val_accuracy)print('结束验证!')print("验证loss为:%.4f" % val_loss)print("验证准确率为:%.4f" % val_accuracy)

打印训练过程:

六、模型评估

代码如下:

epochs_range = range(epochs)
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)plt.plot(epochs_range, history_train_accuracy, label='Training Accuracy')
plt.plot(epochs_range, history_val_accuracy, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')plt.subplot(1, 2, 2)
plt.plot(epochs_range, history_train_loss, label='Training Loss')
plt.plot(epochs_range, history_val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

训练结果可视化如下:

​​

七、预测

代码如下:

# 七、预测
import numpy as np
# 采用加载的模型(new_model)来看预测结果
plt.figure(figsize=(18, 3))  # 图形的宽为18高为5
plt.suptitle("预测结果展示")
for images, labels in val_ds.take(1):for i in range(8):ax = plt.subplot(1, 8, i + 1)# 显示图片plt.imshow(images[i].numpy())# 需要给图片增加一个维度img_array = tf.expand_dims(images[i], 0)# 使用模型预测图片中的人物predictions = model.predict(img_array)plt.title(class_names[np.argmax(predictions)])plt.axis("off")

输出:

1/1 [==============================] - 0s 129ms/step
1/1 [==============================] - 0s 19ms/step
1/1 [==============================] - 0s 18ms/step
1/1 [==============================] - 0s 18ms/step
1/1 [==============================] - 0s 17ms/step
1/1 [==============================] - 0s 18ms/step
1/1 [==============================] - 0s 17ms/step
1/1 [==============================] - 0s 17ms/step


总结

  • Tensorflow训练过程中打印多余信息的处理,并且引入了进度条的显示方式,更加方便及时查看模型训练过程中的情况,可以及时打印各项指标
  • 修改了以往的model.fit()训练方法,改用model.train_on_batch方法。两种方法的比较:model.fit():用起来十分简单,对新手非常友好;model.train_on_batch():封装程度更低,可以玩更多花样
  • 完成了VGG-16基于Tensorflow下的搭建、训练等工作,对比分析了pytorch和tensorflow两个框架下实现同种任务的异同;
  • 完成VGG-16对猫狗图片的高精度识别

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

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

相关文章

我的2024年年度总结

序言 在前不久(应该是上周)的博客之星入围赛中铩羽而归了。虽然心中颇为不甘,觉得这一年兢兢业业,每天都在发文章,不应该是这样的结果(连前300名都进不了)。但人不能总抱怨,总要向前…

Trimble三维激光扫描-地下公共设施维护的新途径【沪敖3D】

三维激光扫描技术生成了复杂隧道网络的高度详细的三维模型 项目背景 纽约州北部的地下通道网络已有100年历史,其中包含供暖系统、电线和其他公用设施,现在已经开始显露出老化迹象。由于安全原因,第三方的进入受到限制,在没有现成纸…

QT 中 UDP 的使用

目录 一、UDP 简介 二、QT 中 UDP 编程的基本步骤 (一)包含头文件 (二)创建 UDP 套接字对象 (三)绑定端口 (四)发送数据 (五)接收数据 三、完整示例代…

开源鸿蒙开发者社区记录

lava鸿蒙社区可提问 Laval社区 开源鸿蒙项目 OpenHarmony 开源鸿蒙开发者论坛 OpenHarmony 开源鸿蒙开发者论坛

多层 RNN原理以及实现

数学原理 多层 RNN 的核心思想是堆叠多个 RNN 层,每一层的输出作为下一层的输入,从而逐层提取更高层次的抽象特征。 1. 单层 RNN 的数学表示 首先,单层 RNN 的计算过程如下。对于一个时间步 t t t,单层 RNN 的隐藏状态 h t h_t…

RNA 测序技术概览(RNA-seq)

前言 转录组测序(RNA-seq)是当下最流行的二代测序(NGS)方法之一,使科研工作者实现在转录水平上定量、定性的研究,它的出现已经革命性地改变了人们研究基因表达调控的方式。然而,转录组测序&…

C语言练习(16)

猴子吃桃问题。猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半加一个。到第10天早上想再吃时,见只剩一个桃子了…

【机器学习】自定义数据集使用框架的线性回归方法对其进行拟合

一、使用框架的线性回归方法 1. 基础原理 在自求导线性回归中,我们需要先自定义参数,并且需要通过数学公式来对w和b进行求导,然后在反向传播过程中通过梯度下降的方式来更新参数,从而降低损失值。 2. 实现步骤 ① 散点输入 有一…

pytest执行报错:found no collectors

今天在尝试使用pytest运行用例的时候出现报错:found no collectors;从两个方向进行排查,一是看文件名和函数名是不是符合规范,命名要是"test_*"格式;二是是否存在修改文件名的情况,如果修改过文件…

mysql-06.JDBC

目录 什么是JDBC: 为啥存在JDBC: JDBC工作原理: JDBC的优势: 下载mysql驱动包: 用java程序操作数据库 1.创建dataSource: 2.与服务端建立连接 3.构造sql语句 4.执行sql 5.关闭连接,释放资源 参考代码: 插…

机器学习-线性回归(对于f(x;w)=w^Tx+b理解)

一、𝑓(𝒙;𝒘) 𝒘T𝒙的推导 学习线性回归,我们那先要对于线性回归的表达公示,有所认识。 我们先假设空间是一组参数化的线性函数: 其中权重向量𝒘 ∈ R𝐷 …

R语言学习笔记之语言入门基础

一、R语言基础 快速熟悉R语言中的基本概念&#xff0c;先入个门。 1、运算符 运算符含义例子加1 1-减3 - 2*乘3 * 2/除9 / 3^(**)乘方2 ^ 3 2 ** 3%%取余5 %% 2%/%取整5 %/% 2 2、赋值符号 等号a 1三者等价&#xff1a;把1赋值给变量a左箭头<−a <- 1右箭头−&g…

计算机网络三张表(ARP表、MAC表、路由表)总结

参考&#xff1a; 网络三张表&#xff1a;ARP表, MAC表, 路由表&#xff0c;实现你的网络自由&#xff01;&#xff01;_mac表、arp表、路由表-CSDN博客 网络中的三张表&#xff1a;ARP表、MAC表、路由表 首先要明确一件事&#xff0c;如果一个主机要发送数据&#xff0c;那么必…

【Nomoto 船舶模型】

【Nomoto 船舶模型】 1. Nomoto 船舶模型简介2. 来源及发展历程3. 构建 一阶模型Nomoto 船舶模型3.1 C 实现3.2 Python 实现3.3 说明 5. 参数辨识方法5.1 基于最小二乘法的参数辨识5.2 数学推导5.3 Python 实现5.4 说明 4. 结论参考文献 1. Nomoto 船舶模型简介 Nomoto 模型是…

深入理解GPT底层原理--从n-gram到RNN到LSTM/GRU到Transformer/GPT的进化

从简单的RNN到复杂的LSTM/GRU,再到引入注意力机制,研究者们一直在努力解决序列建模的核心问题。每一步的进展都为下一步的突破奠定了基础,最终孕育出了革命性的Transformer架构和GPT大模型。 1. 从n-gram到循环神经网络(RNN)的诞生 1.1 N-gram 模型 在深度学习兴起之前,处理…

【JWT】jwt实现HS、RS、ES、ED签名与验签

JWT 实现 HS、RS、ES 和 ED 签名与验签 签名方式算法密钥类型签名要点验签要点HSHMAC-SHA256对称密钥- 使用 crypto/hmac 和对称密钥生成 HMAC 签名- 将 header.payload 作为数据输入- 使用同一密钥重新计算 HMAC 签名- 比较计算结果与接收到的签名是否一致RSRSA-SHA256公钥 …

地址栏信息location

获取信息 页面跳转 location.href当前地址栏信息 location.assign()设置跳转新的页面 location.replace() location.reload()刷新页面

程序员转型测试:解锁漏洞挖掘新旅程

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 程序…

08-ArcGIS For JavaScript-通过Mesh绘制几何体(Cylinder,Circle,Box,Pyramid)

目录 概述代码实现1、Mesh.createBox2、createPyramid3、Mesh.createSphere4、Mesh.createCylinder 完整代码 概述 对于三维场景而言&#xff0c;二位的点、线、面&#xff0c;三维的圆、立方体、圆柱等都是比较常见的三维对象&#xff0c;在ArcGIS For JavaScript中我们知道点…

直线拟合例子 ,岭回归拟合直线

目录 直线拟合,算出离群点 岭回归拟合直线&#xff1a; 直线拟合,算出离群点 import cv2 import numpy as np# 输入的点 points np.array([[51, 149],[122, 374],[225, 376],[340, 382],[463, 391],[535, 298],[596, 400],[689, 406],[821, 407] ], dtypenp.float32)# 使用…