使用卷积神经网络开发图像分类模型5 {; u1 q' [! d d) u2 R* ?
简介
8 X# C4 ~1 I+ T9 m( F0 e
( o8 W5 t7 w+ \7 C这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。, J/ N( I2 W9 o) B
9 Q) K* V5 y' r" y c# S简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。. j6 o V9 _( c# u
7 }. l$ [1 I: d" ]' n% a- Q K今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。; h- z7 Z6 U+ e$ o2 }
$ t7 R8 u, R( U2 B& G
实施9 a6 u: Q0 M+ O7 d
# ]: S! Q' a) @9 [8 d% y# importing necessary libraries7 Y) H0 Y- Q: L ? t7 S% f7 b
import numpy as np$ W- l8 f, z4 M" V
import matplotlib.pyplot as plt" X! T3 w4 P1 x# E' G
%matplotlib inline4 |) S1 w M( v6 P; O
# To convert to categorical data; ~; \- x" ~9 k" d$ G# [& _
from tensorflow.keras.utils import to_categorical
- T# X; e& ], q3 {& K9 r#libraries for building model1 D: B6 |7 L3 r2 v( ]' k
from tensorflow.keras.models import Sequential
$ s0 ?4 S5 B" D; o E; d! Z6 zfrom tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten0 s: D2 _' m' ^6 g. K# [2 S
from tensorflow.keras.datasets import cifar10 T+ t# p( ~, }7 K
4 D, d" q* ^) G( I3 A#loading the data
/ i6 H6 r4 H8 n* N; j1 v(X_train, y_train), (X_test, y_test) = cifar10.load_data()( I& X1 l2 k0 W) Q# ^3 K/ l0 M% G! n
3 m7 J) c# E4 s9 J$ E7 B" E+ r `% z/ L探索性数据分析/ k. @ ]+ ?+ o/ W4 r3 R
#shape of the dataset: l6 M8 k7 [# T g8 X
print(X_train.shape)
8 R, z3 y. }" d, h* e- rprint(y_train.shape)
; w- c% S6 O" b& {2 X2 v( Cprint(X_test.shape)
7 ]# `' g2 x2 Oprint(y_test.shape)5 \5 q% x7 c# H& [( s
8 X) ~$ t6 p2 e% b9 a T
( E1 P- d/ V# k+ A P+ o2 ]& u7 b
我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝)! W6 O% u! b& ]
#checking the labels & B( D& T \7 O5 ~6 @ d5 T7 M
np.unique(y_train)
1 G: y& Z% _& G! v) N. I5 f
4 B9 ^* j; u0 s; ^5 ~0 h2 n - B7 Z; a7 ?/ e
#first image of training data+ b; }1 n: j' f" h3 G) l
plt.subplot(121)
" m: W( f/ s1 c: c& c0 `# l2 bplt.imshow(X_train[0])6 j5 v0 C2 k1 f
plt.title("Label : {}".format(y_train[0])). _1 m: F) s; Y R
#first image of test data# [* X4 m. R; k% e
plt.subplot(122)
: N5 W! ]: J" X( q; `! Rplt.imshow(X_test[0])* M/ B6 R; b% c4 Z/ Y
plt.title("Label : {}".format(y_test[0]));6 G$ j2 O k# v7 E$ `2 e. w H. k: G7 \% v
" U, p: O% `* u* H; q: a5 M0 D![]()
N0 t- M$ }1 @! I- Z p R7 [#visualizing the first 20 images in the dataset
& {4 K. B* L% V& ^& c3 e* |1 mfor i in range(20):
: Z0 |* A! F7 G8 s0 _9 Y9 J #subplot+ `' J9 @& @, h' E. H" {
plt.subplot(5, 5, i+1)
$ D: _4 h" ]6 n6 `, A* ] # plotting pixel data
0 N2 X! r2 O+ N/ |+ c. {, e8 X' p' ^- L plt.imshow(X_train, cmap=plt.get_cmap('gray'))
' x# T7 o% W6 g# s4 z A" w/ ?0 T- u# show the figure$ o+ i) }7 B( F$ G7 o
plt.show()' V Z; U. @9 x2 B* q4 z; A# O; {/ l
8 D/ v) n2 i% f
' A& h2 _1 ~5 q( N
预处理数据对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D " @1 d: q9 o% G& a; P
# Scale the data to lie between 0 to 1! ~6 \' n& |, [/ y* G
X_train = X_train/2550 r0 q+ L- }0 {& a& Z9 m# m0 E% j
X_test = X_test/255
) V. T3 l' }" A& P! U1 Xprint(X_train)
) g2 x1 n& O: r8 C$ _# f3 i% h3 Y0 x, X7 A) g! ?$ r
![]()
( M7 n3 `6 d) Q; x3 W3 {# w5 ?#reshaping the train and test lables to 1D2 R6 ?6 F5 Q, Q3 W/ p" G
y_train = y_train.reshape(-1,)
1 Y2 i; {9 s) O5 Y) C5 w7 |y_test = y_test.reshape(-1,)
/ {! R7 I* O' W% q# J6 e+ Y+ K+ t8 Q4 v0 s( }) n" o" z$ S" R( O% A$ \3 o
我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。
$ z8 K# G4 I2 `, Y模型搭建正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。
: E: J9 c9 [( W! y$ Bmodel=Sequential(). w* e7 Q, j- t. x: w+ B) L
#adding the first Convolution layer
+ ?8 j6 h" ~% s# q- H0 bmodel.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))$ n5 F- l5 X0 \" b% W
#adding Max pooling layer
3 d* f4 O6 F! a8 xmodel.add(MaxPool2D(2,2))
% t& d: x$ v6 L: K$ [$ v/ I5 ?#adding another Convolution layer" f+ t7 R7 o' j& z
model.add(Conv2D(64,(3,3),activation='relu'))
9 A5 A" ^% f* ?7 d6 mmodel.add(MaxPool2D(2,2))
. _; f( ?& f# dmodel.add(Flatten())
" I4 M/ u% _/ V; k+ m( u#adding dense layer
~9 o0 O n1 g/ Kmodel.add(Dense(216,activation='relu'))& w# v/ N. A9 d9 ]7 z
#adding output layer( n: G: H. [: V3 e+ R) _3 Q: L
model.add(Dense(10,activation='softmax'))
& X. M. K6 T! G' ]
, o9 b! l- \6 V$ \我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。# k! A, m4 f+ `+ B
# E5 g7 G* L' u, M# |2 m$ w+ {0 M8 o
接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/1 B/ A- i5 ^! l; o/ V
. e+ P% K$ C( s0 |8 e
然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层
+ i% y* w) g: U, c4 k7 z0 d' ~8 L- h* M W, k' A: a$ o1 A
在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。
6 p+ u3 t$ A$ z3 z7 P6 H3 o4 u( B/ x, Z* _
最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。4 p4 @; l5 d6 |: h
3 D4 S0 F& _5 X, }$ c* ^: g1 W- c" }第 2 步:编译模型
1 A" Q0 O* ~1 }( r% U7 w* @$ [( [model.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
0 ]) y+ q- p; j
) i3 r$ P( y% p9 H0 N) n5 O第 3 步:拟合模型model.fit(X_train,y_train,epochs=10)
( S. D# a5 T; N& h% v: S![]()
# Z( a0 u2 X6 E; m8 ?![]()
" l+ I: s& w1 Q+ y7 y5 T如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。
0 n3 R9 \: u) S: U' S2 O1 z, H+ [. x- a第 4 步:评估模型model.evaluate(X_test,y_test)( \/ k- _1 X+ Q- l) {8 z0 I
![]()
/ Z; [8 N5 U& l' y9 A6 @9 ?" }; l8 g3 m% B7 s/ r
测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。
* B$ g! s/ u: O ~第 5 步:进行预测
. w; C' T) I! Q: C/ H# dpred=model.predict(X_test)7 S0 ~9 h0 l/ s4 g2 r, |: b* O
#printing the first element from predicted data4 ~- e5 W* ]% W
print(pred[0])* b, K% ]1 n/ v& v/ |: N
#printing the index of
) Z" k; @; h9 _4 }4 aprint('Index:',np.argmax(pred[0]))2 t1 E- Q! b. ^! W; y8 M7 q) \1 l
$ H+ V' k3 \1 ~" W$ A X
6 n. U* l* c. Y0 q7 M
2 K5 e/ ~; ~% H- S, o0 ` D
因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。 将预测值与实际值进行比较以查看模型执行的正确程度。 在下图中,我们可以看到预测值与实际值的差异。 y_classes = [np.argmax(element) for element in pred]
& A) m7 R* ^4 f6 Z6 K* rprint('Predicted_values:',y_classes[:10]) F' o. i9 {; m9 h/ }8 y
print('Actual_values:',y_test[:10])
& f' ` C3 g. `5 z# Q% I3 N) S6 w* N0 P! c
3 W3 `) m; r6 A$ r" b0 s, ]
当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。 在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。
0 ]0 g3 l; A) l9 r4 T9 dmodel4=Sequential()
! M! p2 W# g+ q2 o$ `. E4 C0 T#adding the first Convolution layer
' b7 [2 A1 N" b8 ]) V: u% n* N3 Umodel4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))8 v: J N. F8 {2 e
#adding Max pooling layer D2 S, `* {6 @3 H1 Q
model4.add(MaxPool2D(2,2))8 \6 ?, }* c% ^
#adding dropout8 V) }9 ^3 B$ _1 @* d
model4.add(Dropout(0.2))! i4 p1 M" L; j4 H. n
#adding another Convolution layer
! w1 \2 T' H; B; s4 J' rmodel4.add(Conv2D(64,(3,3),activation='relu'))
( F' m+ G5 m% T$ I( Y9 [model4.add(MaxPool2D(2,2))
9 N; J- |! _- M8 y#adding dropout5 ^+ c9 O! V; X6 t
model4.add(Dropout(0.2))
5 ]) \6 @8 z6 {1 V+ ~9 h- Y' ~model4.add(Flatten()): L! E& `7 J0 Z0 c8 k8 i6 n. s- r9 U
#adding dense layer3 E% A f' ~6 P6 Z" b1 ^" z6 w1 |
model4.add(Dense(216,activation='relu'))$ o4 h; @7 R3 Y, p- [5 G
#adding dropout+ O7 | |* q. J" M J
model4.add(Dropout(0.2))& B) y7 | U, a# L) X
#adding output layer. K5 g& L3 C5 i4 \+ R; K A. J# S
model4.add(Dense(10,activation='softmax'))
: P/ B! t. ~, N; P9 J5 B4 x- x6 ~model4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
+ d/ z, E7 ?1 e! y" ?model4.fit(X_train,y_train,epochs=10)4 r* b7 ^" c4 A( h: i/ Z% A
( X8 k! }: t: c) W " ~3 c( S; N& k% Q; B6 [8 A/ G2 s& \
model4.evaluate(X_test,y_test), x7 ? e+ m& x8 p, h- M" M
( ~# ?; _+ R& q
通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。9 u8 X; O6 G8 Z/ n- F% W) [- G
3 u' T! r% \1 M1 W1 j6 w
尾注4 F. Z& c; V0 n: C* w7 c* y: C9 w
这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。: }" d1 a/ L, z( `7 @ _5 ], I
" L; t2 P0 Z. u4 d/ L. k
: x+ P$ @: `) T( n/ j! ]# w7 Y
) {+ N4 D: f( F5 v: Z! t* d7 } |