使用卷积神经网络开发图像分类模型" z y4 |* L% S1 s; u" J$ e9 |
简介' ^2 T1 {, v+ u S8 |4 a/ M% z5 m
( r, K9 g- ?+ N% r9 u! o E$ V' ~这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。6 U; z, x0 e1 C4 h
4 c8 j2 e. Q- ?9 R6 ^. a/ E简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。
; l! ]6 Y% d8 c; F% K' @
0 |( A8 `+ G. q7 S/ e/ H7 P今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。
9 G3 @) [/ g$ Q( H n
/ ^0 f& Z) M( H. f" K实施
+ _5 w) g2 A" a: [2 v3 a1 t/ |) r8 A' S4 ]# y) |* F
# importing necessary libraries' y% g2 R0 u v. Z1 j) ?" x [
import numpy as np( X6 m4 \$ O+ }1 f& X* M! W$ b T
import matplotlib.pyplot as plt
* R' Y/ U+ D* W' S; N# ?%matplotlib inline" |" n5 g9 ?: s+ q% p- T# S0 |
# To convert to categorical data
( ~0 ^6 l( s/ l! d! mfrom tensorflow.keras.utils import to_categorical
d' I) ] [& q# k# a5 ?/ Y#libraries for building model9 e9 O1 q7 l0 B0 m
from tensorflow.keras.models import Sequential$ v8 Z- D8 _& T! l
from tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten
5 T, }0 |$ K( v# f8 E" m' [8 ifrom tensorflow.keras.datasets import cifar10
# I6 n' t2 L. f) d; L: g1 V$ c
2 [3 u; V: G) }% v#loading the data
' G; p0 O4 B' o(X_train, y_train), (X_test, y_test) = cifar10.load_data()$ q4 X9 M- V1 U! y- o
& o0 _7 D4 o, N! k$ d6 w. u探索性数据分析 f/ V5 U2 y; s6 j/ p( l
#shape of the dataset
- e! P5 o$ t. Sprint(X_train.shape)# a. }+ Q$ d4 k
print(y_train.shape)' b D4 \: ~& m9 q& D$ a) M
print(X_test.shape)
$ R) g3 }: F2 Y. W3 |% Fprint(y_test.shape)6 k6 n }+ n" a0 z& ?
6 a2 ?3 n* z* l4 W7 \' j
![]()
. H8 \- m5 n+ c我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝); c; c# E) Z l# `$ A; V
#checking the labels
) q! [7 B" s2 W6 l8 S2 e1 C; m) pnp.unique(y_train); j4 F. E2 ]6 j2 D3 S+ H2 J
+ T R) R5 m9 ] ]% O ; N) t6 w9 G2 r* U3 r7 L
#first image of training data: Y2 t& j, b. Z g- H# N& l
plt.subplot(121)
& N$ K& R* z1 zplt.imshow(X_train[0])
3 k- R% ?" \6 ]8 S" Splt.title("Label : {}".format(y_train[0]))1 c( g9 B# i3 J) N
#first image of test data8 Z0 p2 o7 z1 X) X
plt.subplot(122)
. D! t q/ ]" x9 A' S9 F# W# Hplt.imshow(X_test[0])
7 _, r+ b/ Y0 |5 @7 n- |plt.title("Label : {}".format(y_test[0]));* P! M6 d. E4 u$ N- U9 a! G
& g9 N+ Y; B4 M* }3 Z3 ^; b9 h$ }2 b![]()
' [# w! j, Y5 Y#visualizing the first 20 images in the dataset' o _' P, e3 G( j( o$ L
for i in range(20):
: ?' |) F' A8 U4 ?8 b" U #subplot
2 g; l& b ]9 ~+ e2 }5 f plt.subplot(5, 5, i+1)6 f& v+ P0 g+ w& T( @7 ?( Q5 q* F
# plotting pixel data
! J; p% g9 R9 ?7 u2 F plt.imshow(X_train, cmap=plt.get_cmap('gray'))' j2 A& V9 t2 C3 h5 p- l
# show the figure" J$ c& H0 b8 {( H. V: M9 c
plt.show()% z$ N1 n) ~6 h
6 V( A; \7 f! {( l, w: U, U* i
% ~' L! f- s8 a% `# ~
预处理数据对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D
; N! }( w u* F8 l# Scale the data to lie between 0 to 1/ U: h0 \1 }- ]0 j7 Z* E# U
X_train = X_train/255
' k3 o* |: B3 z& I' O( Q' ]( B" pX_test = X_test/255
/ i3 W1 z: j3 O& ~% {4 ^print(X_train)" G9 L$ w3 v% p6 G8 Z
$ ], C4 }9 l' C* K* J) n
! q! i* T! W6 `. |: N( [
#reshaping the train and test lables to 1D; B# P7 t* w' T7 D& p$ u: _
y_train = y_train.reshape(-1,)+ M& w; y( y! }4 [ I" V ]
y_test = y_test.reshape(-1,)' |: J1 `7 S% p* K2 T$ s
' F3 ^1 h/ q2 N3 A2 V
我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。
4 X; Y/ ]$ v( N2 n模型搭建正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。 % y& j) l2 h6 J6 J5 ?
model=Sequential()
& m' X* U: o9 a2 Z: f e5 t( g" g9 B#adding the first Convolution layer
) R( Y" g6 q/ Wmodel.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
7 n# h; E* G! a7 Y! F#adding Max pooling layer: Z' A9 L% H% F' \4 V3 d
model.add(MaxPool2D(2,2))
. a1 K+ X6 n3 A2 y% J: I a#adding another Convolution layer, r4 E; } M3 M; |, N
model.add(Conv2D(64,(3,3),activation='relu'))% J( j: c7 U3 y+ x' |
model.add(MaxPool2D(2,2)), H6 Y' a5 z1 `8 T+ @* Z8 V1 |
model.add(Flatten())/ ^% y" v7 O/ g1 o) ~, `$ k
#adding dense layer
( a& q* h( Q0 Qmodel.add(Dense(216,activation='relu'))% m& Q9 X; J( \- t
#adding output layer
# R4 R; e G9 Y. h0 G, r. ]& Vmodel.add(Dense(10,activation='softmax'))
1 ~+ k: x4 [% r$ C( j- d9 q$ M) b! [8 h; e% A1 t. S2 o7 y/ f9 O
我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。9 B' s1 f5 q$ b: W3 H) B+ @' \
: N( P1 n' l2 F3 h K M$ j接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/5 q8 z+ o6 \7 P, t; x6 A! S
7 {) r w4 c$ T' ~* N4 {. p然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层
' j1 I: B. z! U2 G: g- \1 R# k. i, |3 x c1 R
在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。- T+ q y# K, u; o4 e. g
0 X- D) Q4 d& L5 [" ]3 \
最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。6 f& ?9 b/ `% l# r* M8 `2 s2 J
: w+ g. v" h$ `9 b2 Y5 q
第 2 步:编译模型: t" c9 Q. x2 R/ \" y
model.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy'])4 e) Z/ [: X" l/ J" |4 d1 I
- X3 L4 K7 R# o! Z$ Q
第 3 步:拟合模型model.fit(X_train,y_train,epochs=10)
( a3 k- T; U- l2 S![]()
( M, o! \2 s" V3 U![]()
( E, Z# t0 v4 c; k8 L5 `$ N$ U如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。
4 G4 h* G5 p/ `+ F$ [0 }第 4 步:评估模型model.evaluate(X_test,y_test)
: v+ y) b m! p + a, ~- }/ }$ \! g0 ?% Z5 C
5 C% Q8 J! Z0 y% _- X测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。
3 F$ }" \" j( A0 \! X3 P1 M7 J1 w第 5 步:进行预测, a2 ?# `) j, Y5 m4 `* t
pred=model.predict(X_test): V) X+ s$ o3 g0 C6 y( C
#printing the first element from predicted data
9 j; |1 f z2 eprint(pred[0])( t8 H E2 B; H5 {. r
#printing the index of % Q# c U: Y8 t/ m$ e# [
print('Index:',np.argmax(pred[0]))9 b7 I) `' w0 m3 D" t5 M, P
* ~- B8 t" y* P& U4 ?8 V $ c0 O6 X- |$ `/ _, G# M) ~
" `4 S% b. Q: R2 O+ H
因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。 将预测值与实际值进行比较以查看模型执行的正确程度。 在下图中,我们可以看到预测值与实际值的差异。 y_classes = [np.argmax(element) for element in pred]) `, _4 o3 B* y3 E9 E* k
print('Predicted_values:',y_classes[:10])* `5 a) y3 L% J# u" `: T
print('Actual_values:',y_test[:10])8 P1 g# C" @; @) Y M
4 }! b2 j! a* f1 Y0 h & _( n2 I- V( m" y% Z; E. E5 r! O0 D
当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。 在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。
8 K- K- l. u* ]0 ?/ i; ?4 fmodel4=Sequential()( B, |5 R- u# k' U" }2 E
#adding the first Convolution layer
$ ]( C9 n, w0 D$ E2 R9 zmodel4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))8 e; n. j0 g# i( b
#adding Max pooling layer
) [! k- |" k' M* G* ?1 ]3 nmodel4.add(MaxPool2D(2,2))% I0 G" r- n6 }' A5 r
#adding dropout$ r" {9 F2 D6 o4 L" C4 H( O5 s
model4.add(Dropout(0.2))$ X5 w) f3 F( q/ X% ^0 _
#adding another Convolution layer. H2 X% U, w4 x" l) e# |
model4.add(Conv2D(64,(3,3),activation='relu')): G& ~6 R+ ~4 e7 Z* i( g
model4.add(MaxPool2D(2,2))
$ F. v0 q1 t3 X& ]/ e" R" ?* Y#adding dropout) u& z5 r/ ~) z# B
model4.add(Dropout(0.2))
4 e# s) O/ B" cmodel4.add(Flatten())
+ s8 V* v( z* U/ ]- p6 E#adding dense layer P3 M# s1 b0 T% }7 T. S
model4.add(Dense(216,activation='relu')); A$ z* m; s. Y) U
#adding dropout
" D$ o+ z* k) t$ B9 y3 Q5 Hmodel4.add(Dropout(0.2))+ N1 m8 t/ P+ N7 Q# j! k
#adding output layer& M0 s# Q4 x: N( g: m: f
model4.add(Dense(10,activation='softmax'))
* N7 z5 J2 R/ y zmodel4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])3 l0 E/ s) O' H' `; b
model4.fit(X_train,y_train,epochs=10)! i6 Y* u( C9 K7 t7 R( Z3 D
; |2 A. E& i/ T, w0 t" y7 b" N9 R8 Y
![]()
$ K$ T0 _+ W) k, \- xmodel4.evaluate(X_test,y_test)& ^; n% ]+ L6 l# k2 \+ F: H
5 W! L! F# `: F4 V
通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。
- b! f3 T- Z8 e8 C) Q0 V5 y+ ~# w. T, h& L$ K' W5 p
尾注6 H& ^ i+ ?0 ]2 q/ d
这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。
+ w4 s7 X- R, P$ ~# W% l" Z# E8 s6 O' E0 ~
, R% Z- t& R% v' I7 ^: {" L
$ r4 ?. J# D# |( f( j
|