深度学习入门篇,简单的实例讲明白图像分类。

简介: 深度学习入门篇,简单的实例讲明白图像分类。

深度学习和 Python 开始

摘要

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


我们今天将涵盖的步骤包括:


安装 Keras 和其他对系统的依赖

从磁盘中加载数据

创建您的训练和测试拆分

定义您的 Keras 模型架构

编译您的 Keras 模型

根据培训数据培训模型

根据测试数据评估您的模型

使用训练有素的 Keras 模型进行预测

我还包括一个额外的部分,培训你的第一个凸起神经网络。


这似乎是很多步骤,但我向你保证,一旦我们开始进入示例,你会看到,示例是线性的,使直观的意义,并会帮助您了解与Keras训练神经网络的基本原理。


数据集

数据集选用了猫狗大战的部分数据集,猫狗个选2000张,Pandas类别是我从网上搜索的,一百多张。如下图:




此数据集的目的是将图像正确分类为包含:


熊猫

项目结构

.

├── data

│   ├── cats

│   ├── dogs

│   └── panda

├── images

│   ├── cat.jpg

│   ├── dog.jpg

│   └── panda.jpg

├── output

│   ├── simple_nn.model

│   ├── simple_nn_lb.pickle

│   ├── simple_nn_plot.png

│   ├── smallvggnet.model

│   ├── smallvggnet_lb.pickle

│   └── smallvggnet_plot.png

├── models

│   ├── __init__.py

│   └── smallvggnet.py

├── predict.py

├── train_simple_nn.py

└── train_vgg.py


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

从磁盘中加载数据



**图4:**将图像从磁盘加载到内存中。


现在,Keras 安装在我们的系统上,我们可以开始使用 Keras 实施我们的第一个简单的神经网络训练脚本。我们稍后将实施一个成熟的共周神经网络,但让我们从轻松开始,并努力向上。


train_simple_nn.py


# set the matplotlib backend so figures can be saved in the background

import matplotlib

matplotlib.use("Agg")

# import the necessary packages

from sklearn.preprocessing import LabelBinarizer

from sklearn.model_selection import train_test_split

from sklearn.metrics import classification_report

from tensorflow.keras.models import Sequential

from tensorflow.keras.layers import Dense

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

2-19行导入我们所需的包裹。


# construct the argument parser and parse the arguments

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())

1

2

3

4

5

6

7

8

9

10

11

当我们执行我们的脚本时,我们的脚本将动态处理通过命令行提供的附加信息。 附加信息采用命令行参数的形式。 该模块内置于 Python 中,将处理解析您在命令字符串中提供的信息。


我们有四个命令线参数要解析:


–dataset:通往磁盘上图像数据集的路径。


-model: 我们的模型将序列化,输出到磁盘。此参数包含输出模型文件的路径。


–label-bin: 数据集标签被序列化为磁盘,以便于在其他脚本中回忆。这是通往输出标签二元化器文件的路径。


–plot:输出训练图图像文件的路径。我们将审查此图,以检查我们的数据是否过度/不足。


# initialize the data and labels

print("[INFO] loading images...")

data = []

labels = []

# grab the image paths and randomly shuffle them

imagePaths = sorted(list(paths.list_images(args["dataset"])))

random.seed(42)

random.shuffle(imagePaths)

# loop over the input images

for imagePath in imagePaths:

# load the image, resize the image to be 32x32 pixels (ignoring

# aspect ratio), flatten the image into 32x32x3=3072 pixel image

# into a list, and store the image in the data list

image = cv2.imread(imagePath)

image = cv2.resize(image, (32, 32)).flatten()

data.append(image)

# extract the class label from the image path and update the

# labels list

label = imagePath.split(os.path.sep)[-2]

labels.append(label)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

将数据排序,然后打乱这些序列。


循环读读取图片,将图片resize为(32×32)的图片,然后展平成一列数据。然后将数据放到data里面,将label放到labels里面。


# scale the raw pixel intensities to the range [0, 1]

data = np.array(data, dtype="float") / 255.0

labels = np.array(labels)

1

2

3

对数据做归一化。


切分训练集和测试集



**Figure 5:**在训练深度学习或机器学习模型之前,您必须将数据拆分为训练集和测试集。 这篇博文中使用了 Scikit-learn 来分割我们的数据。


现在我们已经从磁盘加载了我们的图像数据,接下来我们需要构建我们的训练和测试分割:


# partition the data into training and testing splits using 75% of

# the data for training and the remaining 25% for testing

(trainX, testX, trainY, testY) = train_test_split(data,

labels, test_size=0.25, random_state=42)

1

2

3

4

按照4:1的比例将数据切分为训练集和测试集。


# convert the labels from integers to vectors (for 2-class, binary

# classification you should use Keras' to_categorical function

# instead as the scikit-learn's LabelBinarizer will not return a

# vector)

lb = LabelBinarizer()

trainY = lb.fit_transform(trainY)

testY = lb.transform(testY)

1

2

3

4

5

6

7

将标签做二值化操作


1, 0, 0# 对应猫


0, 1, 0# 对应狗


0, 0, 1# 对应熊猫


请注意,只有一个阵列元素是"hot"的,这就是为什么我们称之为"one-hot"编码。


定义您的 Keras 模型架构



**图6:**我们简单的神经网络是使用Keras在这个深度学习教程创建的。


下一步是使用 Keras 定义我们的神经网络架构。在这里,我们将使用一个网络,其中一个输入层、两个隐藏层和一个输出层:


# define the 3072-1024-512-3 architecture using Keras

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"))

1

2

3

4

5

由于我们的模型非常简单,我们继续在此脚本中定义它(通常我喜欢在单独的文件中为模型架构创建一个单独的类)。


第一个隐藏层将有节点。input_shape是3072(32x32x3=3072)输出:1024。


第二个隐藏层将有节点输入就是上一个节点的输出所以是1024,输出是512


最后,最终输出层(第 78 行)中的节点数将是可能的类标签的数量——在这种情况下,输出层将有三个节点,一个用于我们的每个类标签(“猫”、“狗” ”和“熊猫”)。


编译你的 Keras 模型



上一步我们定义了我们的神经网络架构,下一步是"compile"它:


# initialize our initial learning rate and # of epochs to train for

INIT_LR = 0.01

EPOCHS = 80

# compile the model using SGD as our optimizer and categorical

# cross-entropy loss (you'll want to use binary_crossentropy

# for 2-class classification)

print("[INFO] training network...")

opt = SGD(lr=INIT_LR)

model.compile(loss="categorical_crossentropy", optimizer=opt,

metrics=["accuracy"])

1

2

3

4

5

6

7

8

9

10

学习率在优化器中设置,优化器使用SGD。


分类交叉熵被用作几乎所有训练进行分类的网络的损失。唯一的例外是2类分类,其中只有两个可能的类标签。在这种情况下,你会想交换"categorical_crossentropy"为"binary_crossentropy"。


训练



**图8:**训练数据和汇编模型培训深度学习模型。


现在,我们的 Keras 模型已编译,我们可以在我们的培训数据上"拟合"(即训练)它:


# train the neural network

H = model.fit(x=trainX, y=trainY, validation_data=(testX, testY),

epochs=EPOCHS, batch_size=32)

1

2

3

batch_size:控制通过网络传递的每组数据的大小。较大的 GPU 将能够容纳更大的批次大小。我建议从32或64(实际大小需要考虑显存的大小)


评估您的Keras模型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jOd6McZD-1635420207841)(https://pyimagesearch.com/wp-content/uploads/2018/09/keras_tutorial_step7.png)]


**图9:**在符合我们的模型后,我们可以使用我们的测试数据进行预测并生成分类报告。


我们已经培训了我们的实际模型,但现在我们需要根据我们的测试数据来评估它。


重要的是,我们评估我们的测试数据,以便我们可以获得一个公正的(或尽可能接近公正)的表示,我们的模型如何表现良好的数据,它从来没有受过培训。


# evaluate the network

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"])

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

运行此脚本时,您会注意到我们的 Keras 神经网络将开始训练,一旦培训完成,我们将评估测试集上的网络:


$ python train_simple_nn.py --dataset animals --model output/simple_nn.model \

--label-bin output/simple_nn_lb.pickle --plot output/simple_nn_plot.png

Using TensorFlow backend.

[INFO] loading images...

[INFO] training network...

Train on 2250 samples, validate on 750 samples

Epoch 1/80

2250/2250 [==============================] - 1s 311us/sample - loss: 1.1041 - accuracy: 0.3516 - val_loss: 1.1578 - val_accuracy: 0.3707

Epoch 2/80

2250/2250 [==============================] - 0s 183us/sample - loss: 1.0877 - accuracy: 0.3738 - val_loss: 1.0766 - val_accuracy: 0.3813

Epoch 3/80

2250/2250 [==============================] - 0s 181us/sample - loss: 1.0707 - accuracy: 0.4240 - val_loss: 1.0693 - val_accuracy: 0.3533

...

Epoch 78/80

2250/2250 [==============================] - 0s 184us/sample - loss: 0.7688 - accuracy: 0.6160 - val_loss: 0.8696 - val_accuracy: 0.5880

Epoch 79/80

2250/2250 [==============================] - 0s 181us/sample - loss: 0.7675 - accuracy: 0.6200 - val_loss: 1.0294 - val_accuracy: 0.5107

Epoch 80/80

2250/2250 [==============================] - 0s 181us/sample - loss: 0.7687 - accuracy: 0.6164 - val_loss: 0.8361 - val_accuracy: 0.6120

[INFO] evaluating network...

             precision    recall  f1-score   support

       cats       0.57      0.59      0.58       236

       dogs       0.55      0.31      0.39       236

      panda       0.66      0.89      0.76       278

   accuracy                           0.61       750

  macro avg       0.59      0.60      0.58       750

weighted avg       0.60      0.61      0.59       750


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

此网络很小,当与小数据集结合时,我的 CPU 上每个epoch只需 2 秒。


在这里你可以看到,我们的网络正在获得60%的准确性。


由于我们随机挑选给定图像的正确标签的几率为 1/3,我们知道我们的网络实际上已经学会了可用于区分三个类别的模式。


我们还保存了我们的情节:


训练损失

验证损失

训练精度

验证精度

…确保我们能够轻松地发现我们的结果中过度拟合或不合适。

oo.png




**图10:**我们简单的神经网络训练脚本(与Keras一起创建)生成精确/丢失情节,以帮助我们发现不足/过度拟合。


看看我们的情节,我们看到少量的过度适合开始发生超过epoch+45,我们的训练和验证损失开始分歧,并出现了明显的差距。


最后,我们可以将模型保存到磁盘中,以便以后可以重复使用,而无需重新训练它:


# save the model and label binarizer to disk

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()

1

2

3

4

5

6

使用 Keras 模型对新数据进行预测

在这一点上, 我们的模型是训练有素的, 但如果我们想在我们的网络已经培训后对图像做出预测呢?


那我们该怎么办?


我们如何从磁盘中加载模型?


我们如何加载图像,然后对图像进行预处理以进行分类?


在predict.py 脚本中,我将向您展示如何操作,因此打开它并插入以下代码:


# import the necessary packages

from tensorflow.keras.models import load_model

import argparse

import pickle

import cv2

# construct the argument parser and parse the arguments

ap = argparse.ArgumentParser()

ap.add_argument("-i", "--image", required=True,

help="path to input image we are going to classify")

ap.add_argument("-m", "--model", required=True,

help="path to trained Keras model")

ap.add_argument("-l", "--label-bin", required=True,

help="path to label binarizer")

ap.add_argument("-w", "--width", type=int, default=28,

help="target spatial dimension width")

ap.add_argument("-e", "--height", type=int, default=28,

help="target spatial dimension height")

ap.add_argument("-f", "--flatten", type=int, default=-1,

help="whether or not we should flatten the image")

args = vars(ap.parse_args())

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

首先,我们将导入所需的包和模块。 每当您编写脚本以从磁盘加载 Keras 模型时,您都需要显式导入 from。 OpenCV 将用于注释和显示。该模块将用于加载我们的标签 binarizer.load_modeltensorflow.keras.modelspickle 接下来,让我们解析我们的命令行参数:


–image :我们输入图像的路径。


–model :我们经过训练和序列化的 Keras 模型路径。


–label-bin :序列化标签二值化器的路径。


–width :我们的 CNN 输入形状的宽度。本次设置为32。


–height :输入到 CNN 的图像的高度。本次设置为32。


–flatten :我们是否应该展平图像。默认情况下,我们不会展平图像。如果您需要展平图像,将其设置为1。


接下来,让我们根据命令行参数加载图像并调整其大小:


# load the input image and resize it to the target spatial dimensions

image = cv2.imread(args["image"])

output = image.copy()

image = cv2.resize(image, (args["width"], args["height"]))

# scale the pixel values to [0, 1]

image = image.astype("float") / 255.0

1

2

3

4

5

6

# check to see if we should flatten the image and add a batch

# dimension

if args["flatten"] > 0:

image = image.flatten()

image = image.reshape((1, image.shape[0]))

# otherwise, we must be working with a CNN -- don't flatten the

# image, simply add the batch dimension

else:

image = image.reshape((1, image.shape[0], image.shape[1],

 image.shape[2]))

1

2

3

4

5

6

7

8

9

10

将图像展平。


# load the model and label binarizer

print("[INFO] loading network and label binarizer...")

model = load_model(args["model"])

lb = pickle.loads(open(args["label_bin"], "rb").read())

# make a prediction on the image

preds = model.predict(image)

# find the class label index with the largest corresponding

# probability

i = preds.argmax(axis=1)[0]

label = lb.classes_[i]

1

2

3

4

5

6

7

8

9

10

加载模型然后预测模型


猫: 54.6%

狗: 45.4%

熊猫: +0%

换句话说,我们的网络"认为"它看到*“猫”,它肯定"知道"它没有看到"熊猫"。*


找到最大值的索引(第 0 个"猫"指数)。


标签二进制器中提取‘“猫”字符串标签。


很简单, 对吧?


现在,让我们显示结果:


# draw the class label + probability on the output image

text = "{}: {:.2f}%".format(label, preds[0][i] * 100)

cv2.putText(output, text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7,

(0, 0, 255), 2)

# show the output image

cv2.imshow("Image", output)

cv2.waitKey(0)

1

2

3

4

5

6

7

oo.png



**图11:**在我们的 Keras 教程中,猫被正确地分类为一个简单的神经网络。


在这里你可以看到,我们简单的Keras神经网络已经分类输入图像为"猫"55.87%的概率,尽管猫的脸被一块面包部分遮盖。


搭建CNN网络

无可否认,使用标准的馈入神经网络对图像进行分类并不是一个明智的选择。


相反,我们应该利用卷积神经网络 (CNN),该网络旨在对图像的原始像素强度进行操作,并学习可用于高精度对图像进行分类的歧视性滤镜。


我们今天在这里讨论的模型是Vggnet的较小变体, 我称之为 “小 Vggnet” 。


VGGNet 样型号具有两个共同特征:


只使用 3×3 卷积核

在应用池操作之前,在网络架构中,相互叠加在一起

现在,让我们继续实施小型VGGNet。


打开


smallvggnet.py


文件并插入以下代码:


# import the necessary packages

from tensorflow.keras.models import Sequential

from tensorflow.keras.layers import BatchNormalization

from tensorflow.keras.layers import Conv2D

from tensorflow.keras.layers import MaxPooling2D

from tensorflow.keras.layers import Activation

from tensorflow.keras.layers import Flatten

from tensorflow.keras.layers import Dropout

from tensorflow.keras.layers import Dense

from tensorflow.keras import backend as K

1

2

3

4

5

6

7

8

9

10

导入需要的包。


class SmallVGGNet:

@staticmethod

def build(width, height, depth, classes):

 # initialize the model along with the input shape to be

 # "channels last" and the channels dimension itself

 model = Sequential()

 inputShape = (height, width, depth)

 chanDim = -1

 # if we are using "channels first", update the input shape

 # and channels dimension

 if K.image_data_format() == "channels_first":

  inputShape = (depth, height, width)

  chanDim = 1

1

2

3

4

5

6

7

8

9

10

11

12

13

创建SmallVGGNet类,在类中增加build方法。


build需要四个参数,分别是宽,高,深度和类别。


# CONV => RELU => POOL layer set

 model.add(Conv2D(32, (3, 3), padding="same",

  input_shape=inputShape))

 model.add(Activation("relu"))

 model.add(BatchNormalization(axis=chanDim))

 model.add(MaxPooling2D(pool_size=(2, 2)))

 model.add(Dropout(0.25))

1

2

3

4

5

6

7

第一个卷积层,经过池化后,尺寸减少一半。


# (CONV => RELU) * 2 => POOL layer set

 model.add(Conv2D(64, (3, 3), padding="same"))

 model.add(Activation("relu"))

 model.add(BatchNormalization(axis=chanDim))

 model.add(Conv2D(64, (3, 3), padding="same"))

 model.add(Activation("relu"))

 model.add(BatchNormalization(axis=chanDim))

 model.add(MaxPooling2D(pool_size=(2, 2)))

 model.add(Dropout(0.25))

1

2

3

4

5

6

7

8

9

第二个卷积层,经过池化后,尺寸减少一半。


# (CONV => RELU) * 3 => POOL layer set

 model.add(Conv2D(128, (3, 3), padding="same"))

 model.add(Activation("relu"))

 model.add(BatchNormalization(axis=chanDim))

 model.add(Conv2D(128, (3, 3), padding="same"))

 model.add(Activation("relu"))

 model.add(BatchNormalization(axis=chanDim))

 model.add(Conv2D(128, (3, 3), padding="same"))

 model.add(Activation("relu"))

 model.add(BatchNormalization(axis=chanDim))

 model.add(MaxPooling2D(pool_size=(2, 2)))

 model.add(Dropout(0.25))

1

2

3

4

5

6

7

8

9

10

11

12

第三个卷积层,经过池化后,尺寸减少一半。


# first (and only) set of FC => RELU layers

 model.add(Flatten())

 model.add(Dense(512))

 model.add(Activation("relu"))

 model.add(BatchNormalization())

 model.add(Dropout(0.5))

 # softmax classifier

 model.add(Dense(classes))

 model.add(Activation("softmax"))

 # return the constructed network architecture

 return model

1

2

3

4

5

6

7

8

9

10

11

展平,然后输入全连接层。到这里模型就完成了。下面开始编写train代码:


train_vgg.py


# set the matplotlib backend so figures can be saved in the background

import matplotlib

matplotlib.use("Agg")

# import the necessary packages

from pyimagesearch.smallvggnet import SmallVGGNet

from sklearn.preprocessing import LabelBinarizer

from sklearn.model_selection import train_test_split

from sklearn.metrics import classification_report

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

导入需要的包。


# construct the argument parser and parse the arguments

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())

1

2

3

4

5

6

7

8

9

10

11

我们有四个命令线参数要解析:


–dataset集


:通往磁盘上图像数据集的路径。


–model: 我们的模型将序列化,输出到磁盘。此参数包含输出模型文件的路径。请务必相应地命名您的模型,以便您不会覆盖任何以前训练过的模型(如简单的神经网络模型)。


–label-bin: 数据集标签被序列化为磁盘,以便于在其他脚本中回忆。这是通往输出标签二元化器文件的路径。


-plot:输出训练图图像文件的路径。我们将审查此图,以检查我们的数据是否过度/不足。


每次训练模型时,应更改参数,应在命令行中指定不同的图段文件名,以便您拥有与笔记本或笔记文件中的训练笔记对应的图集历史记录。这个教程使深度学习看起来很容易,但请记住,我经历了几次迭代的训练之前,我确定了所有参数与您分享这个脚本。


让我们加载并预处理我们的数据:


# initialize the data and labels

print("[INFO] loading images...")

data = []

labels = []

# grab the image paths and randomly shuffle them

imagePaths = sorted(list(paths.list_images(args["dataset"])))

random.seed(42)

random.shuffle(imagePaths)

# loop over the input images

for imagePath in imagePaths:

# load the image, resize it to 64x64 pixels (the required input

# spatial dimensions of SmallVGGNet), and store the image in the

# data list

image = cv2.imread(imagePath)

image = cv2.resize(image, (64, 64))

data.append(image)

# extract the class label from the image path and update the

# labels list

label = imagePath.split(os.path.sep)[-2]

labels.append(label)

# scale the raw pixel intensities to the range [0, 1]

data = np.array(data, dtype="float") / 255.0

labels = np.array(labels)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

和前面的类似,这里resize大小是64×64。下一步是切分数据集。


# partition the data into training and testing splits using 75% of

# the data for training and the remaining 25% for testing

(trainX, testX, trainY, testY) = train_test_split(data,

labels, test_size=0.25, random_state=42)

# convert the labels from integers to vectors (for 2-class, binary

# classification you should use Keras' to_categorical function

# instead as the scikit-learn's LabelBinarizer will not return a

# vector)

lb = LabelBinarizer()

trainY = lb.fit_transform(trainY)

testY = lb.transform(testY)

1

2

3

4

5

6

7

8

9

10

11

按照4:1拆分训练集和测试集,然后二值化。


# construct the image generator for data augmentation

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")

# initialize our VGG-like Convolutional Neural Network

model = SmallVGGNet.build(width=64, height=64, depth=3,

classes=len(lb.classes_))

1

2

3

4

5

6

7

初始化图像数据生成器以执行图像增强。


图像增强允许我们通过随机旋转、移动、剪切、缩放和翻转,从现有培训数据中构建"附加"培训数据。


数据增强通常是关键步骤,作用:


避免过度拟合

确保您的模型概括良好

我建议您始终执行数据增强,除非您有明确的理由不执行。


# initialize our initial learning rate, # of epochs to train for,

# and batch size

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"])

# train the network

H = model.fit(x=aug.flow(trainX, trainY, batch_size=BS),

validation_data=(testX, testY), steps_per_epoch=len(trainX) // BS,

epochs=EPOCHS)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

首先,我们确定我们的学习率、EPOCHS和批次大小。


然后,我们初始化我们的随机梯度下降 (SGD) 优化器 。


最后,我们将评估我们的模型,绘制损失/精度曲线,并保存模型:


# evaluate the network

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 (SmallVGGNet)")

plt.xlabel("Epoch #")

plt.ylabel("Loss/Accuracy")

plt.legend()

plt.savefig(args["plot"])

# save the model and label binarizer to disk

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()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

我们对测试集进行预测,然后使用科学学习来计算和打印我们的


$ python train_vgg.py --dataset animals --model output/smallvggnet.model \

--label-bin output/smallvggnet_lb.pickle \

--plot output/smallvggnet_plot.png

Using TensorFlow backend.

[INFO] loading images...

[INFO] training network...

Train for 70 steps, validate on 750 samples

Epoch 1/75

70/70 [==============================] - 13s 179ms/step - loss: 1.4178 - accuracy: 0.5081 - val_loss: 1.7470 - val_accuracy: 0.3147

Epoch 2/75

70/70 [==============================] - 12s 166ms/step - loss: 0.9799 - accuracy: 0.6001 - val_loss: 1.6043 - val_accuracy: 0.3253

Epoch 3/75

70/70 [==============================] - 12s 166ms/step - loss: 0.9156 - accuracy: 0.5920 - val_loss: 1.7941 - val_accuracy: 0.3320

...

Epoch 73/75

70/70 [==============================] - 12s 166ms/step - loss: 0.3791 - accuracy: 0.8318 - val_loss: 0.6827 - val_accuracy: 0.7453

Epoch 74/75

70/70 [==============================] - 12s 167ms/step - loss: 0.3823 - accuracy: 0.8255 - val_loss: 0.8157 - val_accuracy: 0.7320

Epoch 75/75

70/70 [==============================] - 12s 166ms/step - loss: 0.3693 - accuracy: 0.8408 - val_loss: 0.5902 - val_accuracy: 0.7547

[INFO] evaluating network...

             precision    recall  f1-score   support

       cats       0.66      0.73      0.69       236

       dogs       0.66      0.62      0.64       236

      panda       0.93      0.89      0.91       278

   accuracy                           0.75       750

  macro avg       0.75      0.75      0.75       750

weighted avg       0.76      0.75      0.76       750

[INFO] serializing network and label binarizer...

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

CPU 的训练需要一些时间 - 75 个时代都需要超过一分钟的时间。训练需要一个多小时。


GPU 将在几分钟内完成整个过程,因为每个时代只需要 2 秒,如所示!

oo.png




**图12:**我们对 Keras 准确/损失图的深入学习表明,我们通过 SmallVGGNet 模型获得了 76% 的动物数据准确性。


正如我们的结果表明的,你可以看到,我们使用 卷积 神经网络在动物数据集上实现了76% 的准确性,明显高于之前使用标准全连接网络的 60% 的准确性。


$ python predict.py --image images/panda.jpg --model output/smallvggnet.model \

--label-bin output/smallvggnet_lb.pickle --width 64 --height 64

Using TensorFlow backend.

[INFO] loading network and label binarizer...

1

2

3

4

oo.png



**图13:**我们通过Keras教程的深入学习,展示了我们如何自信地识别图像中的熊猫。


我们的CNN很有信心,这是一只"熊猫"。我也是, 但我只是希望他不要盯着我看!


让我们试试一只可爱的小猎犬:


$ python predict.py --image images/dog.jpg --model output/smallvggnet.model \

--label-bin output/smallvggnet_lb.pickle --width 64 --height 64

Using TensorFlow backend.

[INFO] loading network and label binarizer...

1

2

3

4

oo.png



**图14:**一只小猎犬被确认为使用Keras、TensorFlow和Python的狗。我们的 Keras 教程介绍了深度学习的基础知识,但刚刚触及了该领域的表面。


总结

在今天的教程中,您学习了如何从 Keras、深度学习和 Python 开始。


具体来说,您学习了与 Keras 和您自己的自定义数据集合作的七个关键步骤:


如何从磁盘中加载数据

如何创建您的培训和测试拆分

如何定义您的 Keras 模型架构

如何编译和准备您的Keras模型

如何根据您的培训数据对模型进行培训

如何在测试数据上评估模型

如何使用您训练有素的 Keras 模型进行预测

从那里,您还学会了如何实现卷积神经网络,使您能够获得比标准全连接网络更高的精度。


相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
27天前
|
机器学习/深度学习 数据采集 算法
构建高效图像分类模型:深度学习在处理大规模视觉数据中的应用
随着数字化时代的到来,海量的图像数据被不断产生。深度学习技术因其在处理高维度、非线性和大规模数据集上的卓越性能,已成为图像分类任务的核心方法。本文将详细探讨如何构建一个高效的深度学习模型用于图像分类,包括数据预处理、选择合适的网络架构、训练技巧以及模型优化策略。我们将重点分析卷积神经网络(CNN)在图像识别中的运用,并提出一种改进的训练流程,旨在提升模型的泛化能力和计算效率。通过实验验证,我们的模型能够在保持较低计算成本的同时,达到较高的准确率,为大规模图像数据的自动分类和识别提供了一种有效的解决方案。
|
1月前
|
机器学习/深度学习 自然语言处理 自动驾驶
深度学习的应用实例:重塑各个领域的未来
深度学习的应用实例:重塑各个领域的未来
57 0
|
2月前
|
机器学习/深度学习 数据采集 PyTorch
图像分类保姆级教程-深度学习入门教程(附全部代码)
图像分类保姆级教程-深度学习入门教程(附全部代码)
44 1
|
6月前
|
机器学习/深度学习 PyTorch TensorFlow
[深度学习入门]Numpy基础(上)
[深度学习入门]Numpy基础(上)
|
7月前
|
机器学习/深度学习 自然语言处理 算法框架/工具
如何入门深度学习
如何入门深度学习
62 0
|
3月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
基于深度学习的图像分类:使用卷积神经网络实现猫狗分类器
基于深度学习的图像分类:使用卷积神经网络实现猫狗分类器
56 0
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
从零开始学习深度学习:入门指南与实践建议
本文将引导读者进入深度学习领域的大门,从基础概念到实际应用,为初学者提供全面的学习指南和实践建议。通过系统化的学习路径规划和案例实践,帮助读者快速掌握深度学习的核心知识和技能,迈出在人工智能领域的第一步。
|
2月前
|
机器学习/深度学习 算法 TensorFlow
使用Python实现基于深度学习的图像分类器
本文介绍了如何使用Python编写一个基于深度学习的图像分类器。我们将使用TensorFlow框架和Keras库来建立模型,并使用MNIST手写数字数据集进行训练和测试。通过本文,您将了解到如何设计和训练一个卷积神经网络(CNN),并将其应用于图像分类任务中。
|
2月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
深度学习入门:Python 与神经网络
深度学习是机器学习的一个分支,它涉及使用多层神经网络来处理和学习数据。在 Python 中,有许多流行的深度学习库和框架可以帮助我们轻松地构建和训练神经网络模型。在本文中,我们将介绍深度学习的基本概念,并使用 Python 中的 TensorFlow 和 Keras 库来构建一个简单的神经网络模型。
|
3月前
|
机器学习/深度学习 分布式计算 搜索推荐
深度学习入门:一篇概述深度学习的文章
深度学习入门:一篇概述深度学习的文章