大多数Keras教程都尝试使用图像分类数据集(如MNIST(手写识别)或基本对象CIFAR-10(基本对象识别))来开启Keras库的基础知识学习。

这篇文章将对Keras入门教程进行不同的尝试。使用自定义数据集训练第一个神经网络和卷积神经网络——将深度学习应用您自己的数据集,而不是Keras内置的数据集。

使用Keras训练您的第一个简单神经网络不需要很多代码,但是我们将逐步开始,逐步进行,以确保您了解如何在自己的自定义数据集上训练网络的过程。

今天介绍的步骤包括:

1. 安装Keras和其依赖库
2. 从磁盘加载数据
3. 训练和测试数据分组
4. 定义模型
5. 编译模型
6. 训练模型
7. 评估模型
8. 使用训练的模型进行预测

这看起来似乎需要很多步骤,但是我向您保证,一旦我们开始使用示例,您将看到示例是线性的、直观的,并且将帮助您了解使用Keras训练神经网络的基础知识。

实质上,使用MINST或者CIFARr10训练集相当于只是调用了内置的函数,训练、测试数据分组创建模型等都已预定义好, 当我们尝试使用自己的数据集时,我们可能会抓耳挠腮考虑下边几个问题:

  • 这些辅助函数从何处加载数据?
  • 磁盘上的数据集应采用什么格式?
  • 如何将数据集加载到内存中?
  • 我需要执行哪些预处理步骤?

在此Keras教程中,我们将使用名为“动物数据集”的自定义数据集。

1. 此数据集的目的是将图像正确分类: 猫 小狗 大熊猫

使用此自定义数据集可以使您了解:

1. 如何在磁盘上组织数据集
2. 如何从磁盘加载图像和分类标签
3. 如何将数据划分为训练和测试数据
4. 如何在训练数据上训练您的第一个Keras神经网络
5. 如何根据测试数据评估模型
6. 如何在训练和测试划分之外的全新数据上复用训练过的模型

按照本Keras教程中的步骤进行操作,只要您使用下面详述的项目/目录结构,就可以将“动物”数据集换成您选择的任何数据集。

抓取数据集可参考:

  • Bing Images
  • Google Images

2. 项目结构

cats、dogs、panda文件夹下文件数至少1000个,并且相同。某个文件夹下文件多可能导致训练出的模型有偏差;

3. 开始写我们的代码

(1)配置环境

  • ubuntu上 TensorFlow2.0安装:

  • windows上 TensorFlow2.0安装:

pip install tensorflow==2.0.0 # or tensorflow-gpu==2.0.0

(2)简单神经网络模型及卷积神经网络模型

  • train_simple_nn.py 第一个简单神经网络的模型
  • train_vgg.py 更完整的SimpleVGGNet的卷积网络模型
# train_simple_nn.py# 训练第一个简单的 Keras 模型# Python的必备绘图包  我们指定matplotlib  使用“ Agg” 后使我们能够将绘图保存到磁盘
import matplotlibmatplotlib.use("Agg")# 导入必要的模块包
# scikit-learn库将帮助我们对标签进行二值化处理,拆分数据以进行训练/测试以及在终端生成训练报告
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
# 您正在阅读本教程以了解Keras,它是TensorFlow和其他深度学习后端的高级前端, 2017年Keras并入了TensorFlow
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import SGD
# imutils 便利功能包 我们将使用paths 生成用于训练的图像文件路径列表
from imutils import paths
import matplotlib.pyplot as plt
# numpy Python中进行数值处理的包 必备包之一
import numpy as np
# argparse 模块是内置于Python中的模块,将动态处理命令行提供的信息
import argparse
import random
import pickle
import cv2
import os# 1. 构建命令行参数
# --dataset   磁盘上图像数据集的路径
# --model     训练得到的模型的输出路径
# --label-bin 序列化的二进制标签文件的输出路径
# --plot      输出训练图(精确度、损失)图像文件的路径,我们将通过该图判断模型拟合是否 过度/不足
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True,help="path to input dataset of images")
ap.add_argument("-m", "--model", required=True,help="path to output trained model")
ap.add_argument("-l", "--label-bin", required=True,help="path to output label binarizer")
ap.add_argument("-p", "--plot", required=True,help="path to output accuracy/loss plot")
args = vars(ap.parse_args())# 2. 从磁盘加载数据
print("[INFO] loading images...")
# 初始化 数据和分类标签列表
data = []
labels = []# 抓取imagePaths 并随机洗牌(randomly shuffle)
# paths.list_images() 很方便的返回路径中的所有图片列表   播下种子因此随机重排序是可重现的。
imagePaths = sorted(list(paths.list_images(args["dataset"])))
random.seed(42)
random.shuffle(imagePaths)# 循环遍历所有的图片
for imagePath in imagePaths:# 加载图像,忽略宽高比缩放到 32*32 像素,展平数据为 32*32*3 = 3072 像素图像, 并存储到list中# resize数据是至关重要的,因为neural network需要这样的维度,不同神经网络需要不同的维度# 展平数据使我们可以轻松地将原始像素强度传递到输入层神经元。稍后您会看到,对于VGGNet,我们将卷传递到网络,因为它是卷积的。该示例只是一个简单的非卷积网络-我们将在后文中介绍一个更高级的示例image = cv2.imread(imagePath)image = cv2.resize(image, (32, 32)).flatten()data.append(image)# 从图像路径中提取分类标签并存储到分类标签数组中label = imagePath.split(os.path.sep)[-2]labels.append(label)# 将像素强度的缩放范围从[0,255]缩放到[0,1](常见的预处理步骤)。转换array 为 NumPy数组
data = np.array(data, dtype="float") / 255.0
labels = np.array(labels)# 3. 构建训练和测试数据分组
# 将数据划分为75%的训练数据和25%的测试数据
# 通常分配一定比例的数据用于训练,而分配较小比例的数据用于测试。 scikit-learn提供了方便的train_test_split 函数为我们拆分数据
(trainX, testX, trainY, testY) = train_test_split(data,labels, test_size=0.25, random_state=42)# 我们的分类标签当前以字符串表示; 但是,Keras会假定两者都:标签被编码为整数  而且,对这些标签执行单热编码,使每个标签表示为矢量而不是整数
# 要完成此编码,我们可以使用scikit-learn 中的LabelBinarizer
# 将标签从 integer 转换为 vector
# 初始化LabelBinaries 调用fit_transform zai trainY中找到所有唯一的类标签并将他们转换为单热编码的标签
# testY 上执行单热编码
# 由于数组中只有一个是 1,因此成为单热编码
# [1, 0, 0] # corresponds to cats
# [0, 1, 0] # corresponds to dogs
# [0, 0, 1] # corresponds to panda
lb = LabelBinarizer()
trainY = lb.fit_transform(trainY)
testY = lb.transform(testY)# 4. 定义您的Keras模型架构
# 使用Keras定义我们的神经网络架构。在这里,我们将使用一个具有一个输入层,两个隐藏层和一个输出层的网络:
# define the 3072-1024-512-3 architecture using Keras
#            32*32*3 = 3072 拼合的输入图像中的像素 第一个隐藏层由1024节点 第二个隐藏层有512节点 最终输出层中的节点数将为可能的类标签的数目-
#            在这种情况下,输出层将具有三个节点,每个节点对应一个类标签(“ cats”,“ dogs” ”和“ panda”)。
model = Sequential()
model.add(Dense(1024, input_shape=(3072,), activation="sigmoid"))
model.add(Dense(512, activation="sigmoid"))
model.add(Dense(len(lb.classes_), activation="softmax"))# 5. 编译Keras模型
# 初始化学习速度和要训练的时期总数
INIT_LR = 0.01
EPOCHS = 80
# 使用随机梯度下降(SGD Stochastic Gradient Descent)优化器编译模型,“categorical_crossentropy”作为损失函数
# 分类交叉熵(Categorical cross-entropy)被用作几乎所有训练执行分类的网络的损失函数。
# 唯一的例外是2-class classification (2类分类 其中只有两个可能的类标签),在这种情况下,选择“ binary_crossentropy”
print("[INFO] training network...")
opt = SGD(lr=INIT_LR)
model.compile(loss="categorical_crossentropy", optimizer=opt,metrics=["accuracy"])# 6. “拟合”Keras模型使其适合数据
# 训练神经网络
# batch_size 控制通过网络传递的每组数据的大小。较大的GPU将能够容纳较大的批处理大小。建议从32或者64开始,然后逐步增加
H = model.fit(x=trainX, y=trainY, validation_data=(testX, testY),epochs=EPOCHS, batch_size=32)# 7. 评估Keras模型
# 我们已经训练了实际模型,现在我们需要根据测试数据对其进行评估。
# 重要的是,我们必须对测试数据进行评估,以便我们能够对模型进行从未被训练过的数据进行无偏(或尽可能接近无偏)表示。
# 要评估我们的Keras模型,我们可以结合使用.predict 模型的方法以及scikit-learn 中的category_report :
print("[INFO] evaluating network...")
predictions = model.predict(x=testX, batch_size=32)
print(classification_report(testY.argmax(axis=1),predictions.argmax(axis=1), target_names=lb.classes_))
# plot the training loss and accuracy
N = np.arange(0, EPOCHS)
plt.style.use("ggplot")
plt.figure()
plt.plot(N, H.history["loss"], label="train_loss")
plt.plot(N, H.history["val_loss"], label="val_loss")
plt.plot(N, H.history["accuracy"], label="train_acc")
plt.plot(N, H.history["val_accuracy"], label="val_acc")
plt.title("Training Loss and Accuracy (Simple NN)")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend()
plt.savefig(args["plot"])# 8.保存模型和二进制标签文件
print("[INFO] serializing network and label binarizer...")
model.save(args["model"], save_format="h5")
f = open(args["label_bin"], "wb")
f.write(pickle.dumps(lb))
f.close()

(3)第一个卷积神经网络

train_vgg.py# 训练第一个卷积神经网络
# python train_vgg.py --dataset animals --model output/smallvggnet.model \
#   --label-bin output/smallvggnet_lb.pickle \
#   --plot output/smallvggnet_plot.png# 在Google相册中,如果您在搜索框中输入“ dog”,则将返回照片库中的狗的图片-我很确定该图片搜索引擎功能已使用CNN。
# 图像搜索引擎并不是CNN的唯一用例-我敢打赌,您的想法已经开始提出各种可应用于深度学习的想法。
#
# SmallVggnet 精确度76% 高于 之前的普通模型 60%# 设置matplotlib为Agg,因此图像可以保存在磁盘上
import matplotlib
matplotlib.use("Agg")
# 导入必要的包
from pyimagesearch.smallvggnet import SmallVGGNet
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
# 我们将使用ImageDataGenerator扩充数据。我几乎总是建议使用数据扩充,这样会导致模型更好地推广。
# 数据扩充涉及对现有训练数据添加随机旋转,平移,剪切和缩放比例。
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.optimizers import SGD
from imutils import paths
import matplotlib.pyplot as plt
import numpy as np
import argparse
import random
import pickle
import cv2
import os# 构建命令行参数
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True,help="path to input dataset of images")
ap.add_argument("-m", "--model", required=True,help="path to output trained model")
ap.add_argument("-l", "--label-bin", required=True,help="path to output label binarizer")
ap.add_argument("-p", "--plot", required=True,help="path to output accuracy/loss plot")
args = vars(ap.parse_args())# --dataset: 磁盘上图像数据集的路径
# --model: 我们的模型将序列化并输出到磁盘。此参数包含输出模型文件的路径。确保对模型进行相应命名,以免覆盖以前训练过的模型(例如简单的神经网络模型)。
# --label-bin: 数据集标签被序列化到磁盘的路径
# --plot:输出训练图图像文件的路径。我们将检查该图,以检查数据是否过度/不足。每次通过更改参数来训练模型时,都应在命令行中指定不同的绘图文件名,以便在笔记本或注释文件中拥有与训练笔记相对应的绘图历史记录。# 初始化数据和标签类
print("[INFO] loading images...")
data = []
labels = []# 获取图像路径并随机洗牌(给定42的随机种子,以重新结果)
imagePaths = sorted(list(paths.list_images(args["dataset"])))
random.seed(42)
random.shuffle(imagePaths)# 循环遍历输入图像
for imagePath in imagePaths:# 加载图像,resize到64*64(SmallVGGNet所需的输入空间尺寸) 并存储道list中image = cv2.imread(imagePath)image = cv2.resize(image, (64, 64))# 一个关键的区别是我们不会为神经网络拼合数据,因为它是卷积的data.append(image)# 从图像路径中提取分类标签并添加到list中label = imagePath.split(os.path.sep)[-2]labels.append(label)# scale 像素强度到 [0,1]
data = np.array(data, dtype="float") / 255.0
labels = np.array(labels)# 分组训练数据(75%)和测试数据(25%)一个建议是80/20比例去看一下是否有明显提高
(trainX, testX, trainY, testY) = train_test_split(data,labels, test_size=0.25, random_state=42)# 初始化类标签器 将类标签器从整数转换为向量
# 标签二值化这样后续可以进行一键热编码,并在脚本的后面将标签二值化器序列化为pickle文件
lb = LabelBinarizer()
trainY = lb.fit_transform(trainY)
testY = lb.transform(testY)# 构建图像加强生成器
# 图像增强使我们可以通过随机旋转,移动,剪切,缩放和翻转从现有的训练数据中构建“其他”训练数据。
# 数据扩充通常是以下关键步骤:
# -避免过度拟合
# -确保模型能很好地泛化  我建议您始终执行数据增强,除非您有明确的理由不这样做。
aug = ImageDataGenerator(rotation_range=30, width_shift_range=0.1,height_shift_range=0.1, shear_range=0.2, zoom_range=0.2,horizontal_flip=True, fill_mode="nearest")# 初始化 构建 VGG-like Convolutional Neural Network
model = SmallVGGNet.build(width=64, height=64, depth=3,classes=len(lb.classes_))# 初始化初始学习率,训练次数,训练批次
INIT_LR = 0.01
EPOCHS = 75
BS = 32# initialize the model and optimizer (you'll want to use
# binary_crossentropy for 2-class classification)
# 编译模型
# 初始化模型及在二值分类中的二值交叉熵优化器
print("[INFO] training network...")
opt = SGD(lr=INIT_LR, decay=INIT_LR / EPOCHS)
model.compile(loss="categorical_crossentropy", optimizer=opt,metrics=["accuracy"])# 训练网络
# model.fit 可同时处理训练和即时扩充的增强数据。
# 我们必须将训练数据作为第一个参数传递给生成器。生成器将根据我们先前进行的设置生成批量的增强训练数据。
H = model.fit(x=aug.flow(trainX, trainY, batch_size=BS),validation_data=(testX, testY), steps_per_epoch=len(trainX) // BS,epochs=EPOCHS)# 评估网络模型
print("[INFO] evaluating network...")
predictions = model.predict(x=testX, batch_size=32)
print(classification_report(testY.argmax(axis=1),predictions.argmax(axis=1), target_names=lb.classes_))# 画出训练精确度和损失图
N = np.arange(0, EPOCHS)
plt.style.use("ggplot")
plt.figure()
plt.plot(N, H.history["loss"], label="train_loss")
plt.plot(N, H.history["val_loss"], label="val_loss")
plt.plot(N, H.history["accuracy"], label="train_acc")
plt.plot(N, H.history["val_accuracy"], label="val_acc")
plt.title("Training Loss and Accuracy (SmallVGGNet)")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend()
plt.savefig(args["plot"])# 保存模型和类标签器到磁盘
print("[INFO] serializing network and label binarizer...")
model.save(args["model"], save_format="h5")
f = open(args["label_bin"], "wb")
f.write(pickle.dumps(lb))
f.close()

(4)ImageDataGenerator

使用ImageDataGenerator扩充数据,是为了使模型更好地推广,泛化


数据扩充涉及对现有训练数据添加随机旋转,平移,剪切和缩放比例。

(5)SGD 随机梯度下降损失函数

使用随机梯度下降(SGD Stochastic Gradient Descent)优化器编译模型,“categorical_crossentropy”作为损失函数


分类交叉熵(Categorical cross-entropy)被用作几乎所有训练执行分类的网络的损失函数。
唯一的例外是2-class classification (2类分类 其中只有两个可能的类标签),在这种情况下,选择“ binary_crossentropy”.

(6) 简单的神经网络 与 卷积神经网络训练结果对比

简单神经网络 卷积神经网络
训练速度 快 3s/Epoch 慢 50s/Step
准确度 近60% 75%
泛化能力

简单的神经网络训练速度快,精确度稍低;
卷积神经网络训练速度慢,精确度高,由于数据集经过了数据增强具有比较好的泛化能力;

同样的数据下的预测精确度:
简单神经网络预测结果:

卷积神经网络预测结果:

简单神经网络训练损失/精确度图:
卷积神经网络损失/精确度图:

ps: 啃英文对我来说有点难,又有点简单。这是我大学无比喜欢上的课,后来也会记单词,英汉互译的看诗集。这一篇文章确实有点难啃,有些学术名词我不是很懂,不过我在努力,学习的感觉真的太好了。
晚安~~~

参考: https://www.pyimagesearch.com/2018/09/10/keras-tutorial-how-to-get-started-with-keras-deep-learning-and-python/

Keras TensorFlow教程:使用自己的数据集进行训练相关推荐

  1. Keras TensorFlow教程:如何从零开发一个复杂深度学习模型

    Keras 是提供一些高可用的 Python API ,能帮助你快速的构建和训练自己的深度学习模型,它的后端是 TensorFlow 或者 Theano .本文假设你已经熟悉了 TensorFlow ...

  2. python怎么导入数据集keras_keras使用Sequence类调用大规模数据集进行训练的实现

    使用Keras如果要使用大规模数据集对网络进行训练,就没办法先加载进内存再从内存直接传到显存了,除了使用Sequence类以外,还可以使用迭代器去生成数据,但迭代器无法在fit_generation里 ...

  3. 带你测试对比深度学习框架!TensorFlow,Keras,PyTorch...哪家强?(附数据集)

    授权自AI科技大本营(ID: rgznai100) 本文长度为3556字,建议阅读7分钟 亚马逊MXNet在CNN.RNN与NLP情感分析任务上性能强劲,而TensorFlow仅擅长于特征提取. 深度 ...

  4. TensorFlow Keras 官方教程

    TensorFlow版本:1.10.0 > Guide >教程地址:https://tensorflow.google.cn/guide/keras Keras 简介 Keras是一个用于 ...

  5. 【Tensorflow教程笔记】TensorFlow Datasets 数据集载入

    Tensorflow教程笔记 基础 TensorFlow 基础 TensorFlow 模型建立与训练 基础示例:多层感知机(MLP) 卷积神经网络(CNN) 循环神经网络(RNN) 深度强化学习(DR ...

  6. Tensorflow keras入门教程

    目录 1.Tensorflow与Keras 2.安装内置Keras的Tensorflow 3.Tensorflow内置的Keras教程 3.1.导入tf.keras 3.2.创建一个简单的模型 3.2 ...

  7. TensorFlow发布语音识别入门教程,附1GB数据集代码

    原标题:TensorFlow发布语音识别入门教程,附1GB数据集&代码 机械鸡的鸡友经常问:如何开始入门深度学习语音和其他音频识别,例如关键字检测或语音命令. 虽然有一些伟大的开源语音识别系统 ...

  8. TensorFlow Keras 官方教程 * * * * *

    TensorFlow版本:1.10.0 > Guide > Keras Keras 简介 Keras 是建立和训练深度学习模型的高级 API.它被用于快速原型.高级研究和生产.Keras ...

  9. 在iOS平台上使用TensorFlow教程(上)

    在利用深度学习网络进行预测性分析之前,我们首先需要对其加以训练.目前市面上存在着大量能够用于神经网络训练的工具,但TensorFlow无疑是其中极为重要的首选方案之一. 大家可以利用TensorFlo ...

最新文章

  1. ORIG1和ORIG2的运用
  2. 2020年信息系统项目管理师真题讲解
  3. boost::histogram::axis::option::growth_t用法的测试程序
  4. python中‘/’和‘//’区别
  5. Docker:易于构建,运行,完成!
  6. 读书笔记——Accelerated C++ Chapter 12 使类对象获得数值功能
  7. [BZOJ 3028]食物(生成函数)
  8. Pandas index详解
  9. java开发项目经验_Java项目经验——程序员成长的钥匙
  10. 开发运维日常坑 总结 51-100
  11. 导 Kinect2库,opencv库,pcl库
  12. 测试连接数据库是否成功
  13. IsPostBack是什么意思,如何运用?
  14. 2022数学建模美赛回顾
  15. 多站点同服务器同IP网站架设(IIS)心得
  16. PHP 异步并行编程_韩天峰
  17. 目标导向的交互设计:About face 3 -- The essentials of interaction design 读书分享
  18. tomcat 严重: Could not contact localhost:80. Tomcat may not be running.
  19. 关于Symantec(赛门铁克)认证服务
  20. 将网站上的信托计划净值数据写入excel,涉及dataframe排序,转换数据类型,列表填入dataframe,取小数点后四位的正则,dataframe生成excel

热门文章

  1. 车道线检测算法经典编程
  2. 2021年大数据ELK(十八):Beats 简单介绍和FileBeat工作原理
  3. 零起点学算法24——求正弦和余弦
  4. git add . 之后 想执行回滚操作(git add 到本地仓库的代码回滚到没有add 之前的操作)
  5. com.android.ide.common process ProcessException:Failed to execcue aapt
  6. swoole安装异步reids
  7. A. 位运算符的应用---管理一组事务的开关状态
  8. 2022-2028年中国服务器行业投资分析及前景预测报告
  9. 3种常见的linux版本,查看linux版本的三种常用方法
  10. 使用jdk生成ssl证书文件