使用卷积神经网络开发图像分类模型5 @( {( E7 E. o( z9 s y! o4 E
简介' b- u) K8 q1 a7 N- z5 g
. e2 v1 v7 \! j( K这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。
. S( ^: o$ E) f3 I/ g( n
. h. l0 ^6 q, y+ P' r' f& C简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。! v' {4 X1 q- S# J$ x) d) X
& u( k8 S) n3 }$ q$ N& I b" ^今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。) b. {4 Y$ |. J9 [0 i7 t k
1 G/ a( o- ^& d' p& J
实施
( |& j8 o5 c7 h/ Z" Y0 D! G3 _& u: w A6 F2 B( r* {
# importing necessary libraries
; _# {7 ]- N6 o# ^import numpy as np K0 p$ D5 y! X% n
import matplotlib.pyplot as plt
9 v4 s3 e& G1 }" c- \( a%matplotlib inline
4 H( j' _2 I) E4 `# To convert to categorical data
4 f% P* A* T3 Y) v' l/ A2 Gfrom tensorflow.keras.utils import to_categorical
" X8 r8 K, D) M: K( G/ X: u3 K4 l8 B#libraries for building model
i: T5 [, T2 r Ofrom tensorflow.keras.models import Sequential9 @ y, b8 Y0 i8 U& R# N. e0 D# q! z
from tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten
* E* C3 ]. I2 I0 l, [# zfrom tensorflow.keras.datasets import cifar10% O0 K r3 L& T; U0 A2 x9 T- V
3 i9 S) ~% p( ^; E
#loading the data
8 f+ A( Q9 X6 b& E6 f ~(X_train, y_train), (X_test, y_test) = cifar10.load_data()! ~; [6 f3 j( ^* j7 [4 O& l
2 ?0 A( w! }6 R) g( L8 B探索性数据分析4 B* W* M5 H& Q0 p& l" b+ I
#shape of the dataset; G, Q3 ~1 P3 {+ ]4 m$ l. }
print(X_train.shape)5 j$ Y( B5 x5 c
print(y_train.shape)
% h. u2 T w% e# e4 hprint(X_test.shape)! t. P3 S% _$ f( |
print(y_test.shape)
7 A% g# b& a8 Y/ W# B8 a u8 m0 L1 w
) ], S/ z' v/ h1 W. p5 ^
5 t N- P1 X/ Z8 K我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝)
! ^6 G5 Z' u4 o. @#checking the labels 1 H+ m1 H4 L' R4 V% x/ U: h& h2 r: Z
np.unique(y_train)
6 g# H) z$ p# J8 J: M' u; p
, X I/ t$ ]. k) }, F) N% b+ N
+ [/ N$ _7 L* R' s, A7 J( K/ {#first image of training data
! q0 P! `$ H+ B0 p0 G4 Rplt.subplot(121)$ X7 R& C) x& ^/ Q& ~
plt.imshow(X_train[0])( N2 J* ?" M/ o+ M& i7 k' u
plt.title("Label : {}".format(y_train[0]))
# F0 p j/ p. A# ~. F" b7 W2 B+ _, m#first image of test data
' W: S# b' [0 M. R5 Splt.subplot(122)
: U! X1 X- Y/ z, mplt.imshow(X_test[0]) z& N6 n3 L( c
plt.title("Label : {}".format(y_test[0]));( @3 m; ^/ l" _
9 ?* Z: W/ h4 y2 y0 B" v
! h& c' s' O& ~! U+ M#visualizing the first 20 images in the dataset
$ b! c W" y0 e) h, ?: }& N* ~for i in range(20):' Z1 J j1 j4 b, j" w( [
#subplot6 ^; e- f9 o x8 D9 p: b4 Q
plt.subplot(5, 5, i+1)
' Z% }- d% O9 N" q! J. z# z # plotting pixel data
8 ]% b4 [* T: |$ e# h plt.imshow(X_train, cmap=plt.get_cmap('gray'))0 ]& Y& B4 K) N1 C+ z
# show the figure' j( t% { n# y# e0 ^8 ]/ h
plt.show()
1 P& K# }6 U% w" m4 @4 s5 m1 _. [) A) }' ~6 V8 M O7 I, [3 n4 T" W
( Q( [6 w9 x- H
预处理数据对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D
6 k9 P. K) Y# C1 F# Scale the data to lie between 0 to 1- X, `/ J9 R' S! L
X_train = X_train/255
, q+ H N* E1 S4 z) ?' N j9 K1 AX_test = X_test/255
1 `8 {( {$ k% K# j0 sprint(X_train)' o6 t- g1 c3 F, A) s
) x& M$ ?/ k+ n" Z" p1 I! j/ m6 F$ R" B0 Y5 k
#reshaping the train and test lables to 1D K/ s5 T$ ^9 J8 f
y_train = y_train.reshape(-1,)* B4 [; I, j0 g' W7 G
y_test = y_test.reshape(-1,)
" D! ^# t9 c* G" q; |0 J7 @0 V' \( _ u" q/ l3 N5 P9 R
我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。
% U" U4 o' A9 h8 k2 @/ K模型搭建正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。
+ l' c' V9 E4 F/ p0 Hmodel=Sequential()
: r/ {2 S# O/ j, H- h: L4 J#adding the first Convolution layer5 g! G+ n( V+ w% S2 B0 [$ ]9 C' `7 u
model.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
. g% o! ^' y( |" M0 _#adding Max pooling layer
. S! ~4 s$ u9 x) f( t9 K( E& \model.add(MaxPool2D(2,2))3 a) y5 G" }$ [# K6 s* r
#adding another Convolution layer
+ k& L! \. ^) y; j; O. Cmodel.add(Conv2D(64,(3,3),activation='relu'))
F7 ^4 a8 F; N1 R: E' H. t' D/ F! E; ]model.add(MaxPool2D(2,2))- i; O* b' L) z4 X6 U
model.add(Flatten())
8 _' \) Q1 C$ u* N' \6 @( z! T* \#adding dense layer
* E" C3 l3 ?2 |1 Z, H2 R' Xmodel.add(Dense(216,activation='relu')): Z) e6 Y/ {7 v% u$ N" y: _8 m- g
#adding output layer
& E8 V7 `* @: F4 Tmodel.add(Dense(10,activation='softmax'))
$ P# w# U5 q+ Y, ?1 S. r( x4 g3 J$ \. @% P5 |
我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。! w0 q$ P7 z* ]/ f0 |# n. t" w+ Y0 O
# T8 w% ^3 a; y2 f
接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/
7 ?- C2 k$ x' P% e, `1 Z. W2 {/ \4 {/ w9 m# N6 L
然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层- C$ }9 g* x5 s3 L3 n
& k5 ?/ Z6 l6 E. B1 `, t6 R' z在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。8 i: x- U" I+ L" F i7 T, M
4 j6 D( t* |1 ?; V最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。
, \6 x5 K* h) x; J5 R% g, F
2 q' Q9 V u4 E, J7 G6 ^( n( o4 A6 t/ ~第 2 步:编译模型
) R' r2 K" F3 r& p! o/ }model.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
* o( Q2 Q5 [. _- x2 Y
; }! W$ M, W5 U. X第 3 步:拟合模型model.fit(X_train,y_train,epochs=10)
A3 c! J% ?$ k+ U% u q8 [
% k) I& w2 I+ ?- I( a" C( a t6 e) }7 m4 r: v
如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。* s8 t5 s, b; o* V4 q' t4 b
第 4 步:评估模型model.evaluate(X_test,y_test)9 V3 d0 h- c4 P7 d3 p" j
; [/ ?0 F, E! C
4 S p$ v/ H# b& a3 B" H. _
测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。
# x- T7 q/ m* w6 M9 w第 5 步:进行预测! f: Z( g( _( U" H7 Y: {; k
pred=model.predict(X_test). y- c; F [3 d
#printing the first element from predicted data
: }5 a c Q( h+ d5 w, i0 a& Eprint(pred[0])
4 y* J4 Y& b+ I( `2 k9 W4 I/ Q#printing the index of
0 N+ ~) F O. Iprint('Index:',np.argmax(pred[0]))" W& l0 e ^+ Y& a
+ Z. n( t/ J" z# Q! T5 t5 m
2 ]0 ~! p8 a0 \+ _1 c/ z
# m/ f w" @- ~7 c- X! E
因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。 将预测值与实际值进行比较以查看模型执行的正确程度。 在下图中,我们可以看到预测值与实际值的差异。 y_classes = [np.argmax(element) for element in pred]! K- U: C% S0 l1 A& { ?
print('Predicted_values:',y_classes[:10])$ L; f- E& N% U
print('Actual_values:',y_test[:10])
( L/ T6 j1 A$ i: Y" d0 @( p% f; i+ I$ q8 e) V5 B
3 }: S' X% z. F( D9 V
当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。 在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。 % [1 h* i% b; [) x$ m) E3 z# }/ f
model4=Sequential()
* R* j' E( Z, y#adding the first Convolution layer
4 P5 y) x" a% u/ Lmodel4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
0 g# C1 t/ t, e* y4 S1 n#adding Max pooling layer
3 d3 E. b2 J! }- u) T4 c5 q2 Smodel4.add(MaxPool2D(2,2))! V( L5 y; T7 M8 @ w# q
#adding dropout
; N: a3 F6 t9 N1 O. \# \& q# }model4.add(Dropout(0.2))
/ F$ X; \" U2 _#adding another Convolution layer
. [# d; M1 X. c& |1 M' `, {model4.add(Conv2D(64,(3,3),activation='relu'))# |6 J( s1 F6 P( c; j
model4.add(MaxPool2D(2,2))
6 `* |, U1 e& K: d: U9 {4 X#adding dropout8 D# I+ T. p# ~5 e
model4.add(Dropout(0.2))
. Y3 a! f8 ^% M+ w, l8 G( c0 x* ]model4.add(Flatten())# Q. Q4 O( y3 y
#adding dense layer% Z# t0 l" g1 {' y k) S
model4.add(Dense(216,activation='relu'))5 w7 x0 _% m1 u: X2 _* d- h
#adding dropout
* g. e" A1 T2 w& X+ Gmodel4.add(Dropout(0.2))
4 Z6 C* g+ d2 M#adding output layer" f& ]% F" M$ \% _! o; W; S
model4.add(Dense(10,activation='softmax'))
+ J' B: Y+ @3 ^+ X& s6 N5 Rmodel4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy']); d8 C2 f3 x) B1 h# e: l6 A6 ?
model4.fit(X_train,y_train,epochs=10)& w9 j3 {9 j3 W$ A
( W6 l: N# V( T/ ?
! ?) y& ^2 A. o- V& T$ Fmodel4.evaluate(X_test,y_test)8 P) K+ e0 |. V& P% k
/ s3 h. B$ J0 G h) U通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。/ R0 C3 j6 k/ F `
# z) D1 m K, G3 B尾注
; F7 w- E; I7 X" ^$ |0 l; a( j- {这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。
0 x; u* m( l( @' ~' x [. V8 I/ E5 ~4 N( `/ V$ f
! Y4 j' d% p7 J7 Q# i1 Q3 R
% @" s6 O7 Q8 x2 B$ ~ J1 F |