使用卷积神经网络开发图像分类模型; A6 w( B9 `- i( l5 T8 D
简介
& T% E7 ~: E9 K9 R
* Y7 z5 L, j% B) W/ ]( ~# b. \' }这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。
7 x$ H6 A2 k& [' S( w9 t) R/ K
" Z: F) B8 l% O; D6 J, R/ A! J简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。& v# h! F# t, x, `4 Q
) x$ M% t/ ^8 H8 B& ^# x# t# W z今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。
, @7 V. m2 B4 i. O ~$ i$ ^, z; H2 u! ^* F
实施
- B& H6 ?$ n D8 T9 V* {' v; Z% F6 F1 G8 J# G! w
# importing necessary libraries
3 _$ k" t7 K5 u8 yimport numpy as np
: p% m+ h/ j6 O! X9 ?import matplotlib.pyplot as plt
! ?& ^( L7 c& |9 N1 v9 L' g0 \%matplotlib inline# u9 m( ]# u" }1 o
# To convert to categorical data5 P( T* u# |% C1 C$ d" w g$ f0 s
from tensorflow.keras.utils import to_categorical; I' m& B" Z7 i; C
#libraries for building model
5 v" H5 @7 m) K- d6 M! \5 zfrom tensorflow.keras.models import Sequential
1 N7 n) s+ I1 ]- g2 Ofrom tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten
2 P- _8 J3 t' P/ d& p9 R4 Efrom tensorflow.keras.datasets import cifar10
6 Y9 B) L. D% k2 |; {8 I; W- J+ U& b& d0 {. }! T& V9 f1 c
#loading the data
6 `" q9 }$ ^- S: ~(X_train, y_train), (X_test, y_test) = cifar10.load_data()* N9 y1 \5 v% I; L/ k8 _, i
: U7 ?* l1 m `4 `* }6 r
探索性数据分析
9 \1 r' E1 I7 }/ q' j Y: s! Q#shape of the dataset
$ o4 J* [; N. ?+ e6 m- eprint(X_train.shape)% l9 D3 e& A3 F3 a) n3 v# s7 [
print(y_train.shape)
+ V0 S) [. ]6 N9 X5 Mprint(X_test.shape). z" V X; k% G+ p9 \* U
print(y_test.shape)3 T' c# O4 @3 b2 Y4 z
% {2 r8 c i& K. Y& a) a5 j: c
" B) O5 R' ?8 ~: f
我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝)+ N" ? B, f# [- n. J4 ~+ P
#checking the labels $ Z+ Y V; n8 Q
np.unique(y_train) {0 r, q( }! Z8 d
. I" H# F9 r- K- }3 D& |2 m$ ~% R% S$ U$ ~. M
#first image of training data
. R' H g# [% x/ Oplt.subplot(121)
" ]1 {) ?% U& l7 }" J6 I: X3 eplt.imshow(X_train[0])- J! E3 m- X) c. W
plt.title("Label : {}".format(y_train[0]))
* q p9 C- ^' E- p. v* `0 S#first image of test data6 Q( q8 C/ _" a: P/ }5 P
plt.subplot(122)
4 u, G* e! [# J+ V8 }7 `8 Z% tplt.imshow(X_test[0])
& t& @; }: l8 o& ]plt.title("Label : {}".format(y_test[0]));
/ F$ y3 b$ ]0 d k; _, r# q/ o9 @1 e; w' L5 M
+ |5 z2 }) H! X8 J j0 Q2 g6 U#visualizing the first 20 images in the dataset# ]( C5 @0 \5 E2 n: c) |
for i in range(20):
% R. ~6 Y7 y% g5 G8 j" x2 P #subplot
V0 e$ F0 d* S; ~1 q6 V$ \8 ? plt.subplot(5, 5, i+1)2 J* X7 N( z% r
# plotting pixel data6 x% ^1 R" o3 k4 k7 O
plt.imshow(X_train, cmap=plt.get_cmap('gray'))
q6 d# ?% B; f6 ~, A% ~. j# show the figure
5 F$ N% A% `0 fplt.show()
( Z# t/ o. }( ]/ B" {
) t. V9 [5 L- h' H) t( z* ~" S9 {( S. x
预处理数据对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D
% |4 A5 b- _/ u7 F4 N. |# Scale the data to lie between 0 to 1
3 |* `# m1 ]. zX_train = X_train/255' m* J4 ~% T$ f
X_test = X_test/255$ m# v c5 S6 r" q P& N3 I# X0 L* X
print(X_train). `# x0 [' q8 P: b
; l* m( x' p: }- C
1 d: G2 c' [2 d- ?#reshaping the train and test lables to 1D
6 n. r P( }7 ?$ |: sy_train = y_train.reshape(-1,)5 b8 E5 P! n6 x1 j$ D; P
y_test = y_test.reshape(-1,)
# |% a9 k1 H5 u3 P
& [. ], I9 A+ W! A- r我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。
, C8 }" p6 C/ H模型搭建正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。 * ? v) V2 J6 D8 T; D8 T8 d
model=Sequential(): e* P) {: Z# E" j
#adding the first Convolution layer
, l( K2 Y% q# U: o% ?0 F2 Gmodel.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
- D r1 _8 x% V$ W E#adding Max pooling layer
& E/ l! J) K* H* jmodel.add(MaxPool2D(2,2))
1 A: Y4 x7 K$ a$ m#adding another Convolution layer. @' x( e5 E# p' I5 U
model.add(Conv2D(64,(3,3),activation='relu'))
9 e" o' U* _. K. w, t% m& p! ^model.add(MaxPool2D(2,2)), e) l8 Y" J f) y2 ~( ~7 p% O$ |# L
model.add(Flatten())% i5 J" r3 l% B% G% f) h: Q# w" Q8 i
#adding dense layer( J9 H" h+ Y; |: C5 j
model.add(Dense(216,activation='relu'))7 H: m$ s5 ^+ t" c" _- G) y
#adding output layer
! c1 a1 l" ?% J( w4 g4 @: }model.add(Dense(10,activation='softmax'))
% z2 n2 Q) j9 b% z' B/ k+ w% i/ s9 ^. M* Q. e {2 k* _3 M' R! C) K
我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。& o! j* B+ J" N) y$ t
+ X$ T0 f( x6 ]% Y
接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/
1 A5 N8 K, n2 a7 e
) B5 T- @' C0 @/ P, R然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层, i; {9 D/ X* L! x/ k
9 d' Z. q) l5 y; Y/ T o( B4 t
在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。
6 {" A2 A" d( l
/ R" q0 y, t) ~, X" |8 V( r7 T最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。
, n5 J& b3 E) g. y! f" o/ y6 e3 f) J, E- t6 T
第 2 步:编译模型
/ T7 q* o& t1 K2 O# i4 w% b1 U8 Imodel.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy'])2 g/ n: m# k; Q: s" E+ U8 }
0 Z! \6 @9 B# H& F. p第 3 步:拟合模型model.fit(X_train,y_train,epochs=10). k) d, I6 w) v8 [* Q) y8 N0 V. V
" L9 b& d4 Y! g# h+ G
* c0 _' y9 J: l7 P7 [+ }如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。
8 v6 e+ |+ C' V8 i7 t7 ?第 4 步:评估模型model.evaluate(X_test,y_test)
% C1 F" C2 ]2 D9 ^. e8 e1 Z' U7 \3 \2 t9 Z: S
/ M- f! ~0 O1 i9 f1 g: M/ f测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。* s+ S( R, R$ j4 N; m
第 5 步:进行预测, g1 Y: M1 y7 |( |) _, {& a
pred=model.predict(X_test)1 L1 L! ~* n3 F
#printing the first element from predicted data' ]8 i0 L1 p, N+ z' Q7 `
print(pred[0])
( U5 r% `) q4 o+ \0 R#printing the index of
/ ?: k& B" T% i6 t2 ?/ M+ Wprint('Index:',np.argmax(pred[0]))$ ]+ C" w ~/ e5 G$ e
) ]$ ]/ \# r. n* A
% b. E) p% l3 W& }
3 _2 B9 @- U0 S# h7 k因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。 将预测值与实际值进行比较以查看模型执行的正确程度。 在下图中,我们可以看到预测值与实际值的差异。 y_classes = [np.argmax(element) for element in pred]/ E3 K* }, V3 v
print('Predicted_values:',y_classes[:10])) V5 j3 R. C6 p/ k
print('Actual_values:',y_test[:10])
& C( [6 q6 ~9 s4 A/ S4 ]* D3 U
! h& y3 V- j* ?/ S$ m
! j: D' k3 q) c. ]" Q5 n当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。 在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。
/ E! G+ \' H9 e& \5 dmodel4=Sequential()
' w' ?, p1 {+ B. z* j$ ^# o#adding the first Convolution layer
7 l7 }6 T8 a# k' ]5 Emodel4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))2 } _5 B& e# a6 L, p" g2 R4 p# D3 V8 P+ _2 v
#adding Max pooling layer/ j. z. m3 I1 Q1 N+ M8 A8 S
model4.add(MaxPool2D(2,2))
7 |+ }" f1 M: j) P#adding dropout8 }8 A( f2 o" k8 _2 f
model4.add(Dropout(0.2))
" C$ N; ]1 x! B5 A5 X. L; }) [+ B#adding another Convolution layer8 i) x7 ~" S7 Z; t
model4.add(Conv2D(64,(3,3),activation='relu')): Q! R5 [( c% C `
model4.add(MaxPool2D(2,2))3 D3 O$ j- [3 u0 X$ D
#adding dropout0 n1 a w, e0 z
model4.add(Dropout(0.2))7 E% O6 O1 [! r# c5 {, X
model4.add(Flatten())
1 o( b9 h$ z, Y$ @7 g! g% w#adding dense layer. \9 H$ }& L0 M2 B# F* n5 i
model4.add(Dense(216,activation='relu'))
( z/ X/ o# D/ M+ I! T#adding dropout, p- W9 M7 Q5 R/ [) T5 x
model4.add(Dropout(0.2))
$ g. `) T! k- B9 E, e! K#adding output layer* n2 T# }+ c V
model4.add(Dense(10,activation='softmax'))1 Z0 V; Z- I3 I9 k5 e
model4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])8 S* P' n6 h% L9 e" D3 c
model4.fit(X_train,y_train,epochs=10)+ S4 _0 {# T* W' l0 u* {
: J& W, w/ ~4 W( [
* R1 Z9 j0 m, x1 L) V
model4.evaluate(X_test,y_test)- E# R- _! z* M o4 W" ], y
5 q/ R& ^, w7 ^8 t
通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。4 D Y; i! W6 ] l6 J3 C2 {
( Q! A& D7 U! e2 r+ h7 k- [, B' c- c
尾注
: B j; O- u- z2 Y5 J; r3 @6 q4 L这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。1 {, |% C/ c9 S1 r, M8 u& D4 B+ D2 p
+ S8 W5 x* s2 E3 _
% h J6 ? L( R% C- F& X: I8 R8 Y
* p1 g/ ]8 k; k/ P& T# ` |