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

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
网络型负载均衡 NLB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
简介: 深度学习入门篇,简单的实例讲明白图像分类。

深度学习和 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 模型进行预测

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


相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
29天前
|
机器学习/深度学习 人工智能 TensorFlow
人工智能浪潮下的自我修养:从Python编程入门到深度学习实践
【10月更文挑战第39天】本文旨在为初学者提供一条清晰的道路,从Python基础语法的掌握到深度学习领域的探索。我们将通过简明扼要的语言和实际代码示例,引导读者逐步构建起对人工智能技术的理解和应用能力。文章不仅涵盖Python编程的基础,还将深入探讨深度学习的核心概念、工具和实战技巧,帮助读者在AI的浪潮中找到自己的位置。
|
12天前
|
机器学习/深度学习 人工智能 算法
深度学习入门:用Python构建你的第一个神经网络
在人工智能的海洋中,深度学习是那艘能够带你远航的船。本文将作为你的航标,引导你搭建第一个神经网络模型,让你领略深度学习的魅力。通过简单直观的语言和实例,我们将一起探索隐藏在数据背后的模式,体验从零开始创造智能系统的快感。准备好了吗?让我们启航吧!
36 3
|
1月前
|
机器学习/深度学习 人工智能 算法
基于深度学习的地面垃圾识别分类技术
AI垃圾分类系统结合深度学习和计算机视觉技术,实现高效、精准的垃圾识别与自动分类。系统集成高精度图像识别、多模态数据分析和实时处理技术,适用于市政环卫、垃圾处理厂和智能回收设备,显著提升管理效率,降低人工成本。
基于深度学习的地面垃圾识别分类技术
|
27天前
|
机器学习/深度学习 人工智能 算法框架/工具
深度学习中的卷积神经网络(CNN)入门
【10月更文挑战第41天】在人工智能的璀璨星空下,卷积神经网络(CNN)如一颗耀眼的新星,照亮了图像处理和视觉识别的路径。本文将深入浅出地介绍CNN的基本概念、核心结构和工作原理,同时提供代码示例,带领初学者轻松步入这一神秘而又充满无限可能的领域。
|
1月前
|
机器学习/深度学习 编解码 算法
什么是超分辨率?浅谈一下基于深度学习的图像超分辨率技术
超分辨率技术旨在提升图像或视频的清晰度,通过增加单位长度内的采样点数量来提高空间分辨率。基于深度学习的方法,如SRCNN、VDSR、SRResNet等,通过卷积神经网络和残差学习等技术,显著提升了图像重建的质量。此外,基于参考图像的超分辨率技术通过利用高分辨率参考图像,进一步提高了重建图像的真实感和细节。
|
2月前
|
机器学习/深度学习 数据处理 数据库
基于Django的深度学习视频分类Web系统
基于Django的深度学习视频分类Web系统
58 4
基于Django的深度学习视频分类Web系统
|
1月前
|
机器学习/深度学习 人工智能 自动驾驶
深度学习的奇迹:如何用神经网络识别图像
【10月更文挑战第33天】在这篇文章中,我们将探索深度学习的奇妙世界,特别是卷积神经网络(CNN)在图像识别中的应用。我们将通过一个简单的代码示例,展示如何使用Python和Keras库构建一个能够识别手写数字的神经网络。这不仅是对深度学习概念的直观介绍,也是对技术实践的一次尝试。让我们一起踏上这段探索之旅,看看数据、模型和代码是如何交织在一起,创造出令人惊叹的结果。
31 0
|
2月前
|
机器学习/深度学习 数据挖掘 数据处理
深度学习之卫星图像中的环境监测
基于深度学习的卫星图像环境监测是指通过使用深度学习模型处理和分析来自卫星的遥感数据,以实现对地球环境的自动化监测和分析。这项技术极大提升了环境监测的效率、精度和规模,应用于气候变化研究、生态保护、自然灾害监测、城市扩张评估等多个领域。
124 0
|
2月前
|
机器学习/深度学习 自然语言处理 TensorFlow
课外阅读之深度学习如何入门?
课外阅读之深度学习如何入门?
32 0
|
8天前
|
机器学习/深度学习 传感器 数据采集
深度学习在故障检测中的应用:从理论到实践
深度学习在故障检测中的应用:从理论到实践
43 5