使用卷积神经网络开发图像分类模型
3 V9 f! E- o8 o0 {简介
0 A- B6 S4 s$ L
' o9 g, \4 x: h: H/ Q* z- z" e这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。0 @0 W5 d' L" H- l9 |! ]
" F. |* i# o. Q/ t& _3 D# R简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。
8 A7 z8 } G% N0 \3 ~, ~, U, `8 h- v6 Z7 f6 P6 b2 N
今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。: {2 Q, d3 w K, D& [2 v) r
! c. ~( s' V H2 H
实施: `9 X( F% @) Q2 W7 T
( W8 g+ k6 A7 w+ c! u# importing necessary libraries: J3 `* u6 d6 M5 r
import numpy as np! U2 H% |* W; w* H3 R0 l
import matplotlib.pyplot as plt; F( H C, Y$ @" }% ?
%matplotlib inline" ~ g& v) u3 f" r, \
# To convert to categorical data
: { M& T; _5 h. ^3 G Qfrom tensorflow.keras.utils import to_categorical
6 N8 S4 }7 ]; G8 M) V6 \1 I#libraries for building model
" o, T" @& A: s) Bfrom tensorflow.keras.models import Sequential8 M! \* ~* |1 A. y* C5 x. S
from tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten
8 L: q* c& v# m1 U9 \3 Xfrom tensorflow.keras.datasets import cifar102 A$ N' O0 T5 Z9 p, s Q6 ^# ~3 m
7 Q/ g \8 w' O+ B
#loading the data
: Q# X1 w+ u) w' u) y d(X_train, y_train), (X_test, y_test) = cifar10.load_data()! B7 D. y- }, x6 r0 t7 M
* q& J S$ w" B! j/ {6 m* m# Z
探索性数据分析* z# `/ U* E2 |7 {
#shape of the dataset
* ?) A0 l+ y' i: Dprint(X_train.shape)# m9 m, _6 J7 E; o* t [+ d
print(y_train.shape)
% ]6 O6 H( i" M8 r) |9 O/ _, lprint(X_test.shape)
* ^5 f+ n$ l. C6 Gprint(y_test.shape)) z) B& ?; z1 r! \) m
7 W n' m, i) b
![]()
2 r1 ~5 v2 @8 R: l0 `我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝)
( }$ J' X `' H u% O' m. T#checking the labels 6 G: ]2 Y, |, h7 o1 k* o
np.unique(y_train)/ K1 e7 r. Y9 z6 a% `% ]7 J, y( T
$ Q7 P; o! T8 O
![]()
% Z- ?+ m4 K9 K3 H& l" H& M# [#first image of training data& ^! h( n3 y0 c
plt.subplot(121)
! [' Z: F1 r5 a8 Y0 q. d7 w. ^4 m) Mplt.imshow(X_train[0])
( e! r6 w7 i( @+ I) ~5 gplt.title("Label : {}".format(y_train[0]))
. T! n) x+ ` C% {7 V#first image of test data
, G; w; r" e" M- O, g0 n Pplt.subplot(122): V2 H w; o2 |8 A3 s: d6 F& p2 D: W
plt.imshow(X_test[0])
+ r0 r( p, \0 A# z* \. A, xplt.title("Label : {}".format(y_test[0]));% h2 D$ Z4 a: O7 |# l/ ^
) h! J H1 Z( [
![]()
7 d [5 N3 d8 F, [#visualizing the first 20 images in the dataset
' b1 M% j& @8 u* i ]for i in range(20):
( s- R! o b% ] #subplot( K! t% x7 o6 o. c8 V, @
plt.subplot(5, 5, i+1)
/ E: |4 H# w. p+ [$ ]: l1 ] # plotting pixel data
1 ^3 D( Q. A' `! h2 N4 T plt.imshow(X_train, cmap=plt.get_cmap('gray'))
% e3 _5 C# U9 b3 t8 O+ @; r# show the figure
+ h8 q1 m1 Q# o1 |& Aplt.show()
[% \8 v- G4 C4 h; Y$ g: b$ p5 P$ s8 k8 J- o8 D
![]()
+ ?0 ~: V" r8 v9 y预处理数据对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D " }2 t6 W7 t0 o$ z
# Scale the data to lie between 0 to 13 `' p/ j$ H& j; `$ G
X_train = X_train/255: o$ q, V' f. y1 f, `
X_test = X_test/255
1 q6 n0 l# s' R1 tprint(X_train)
+ A% u; B( g/ B+ g/ \" F o! A: }& r5 D3 d0 W. y/ ]
d e! D5 P3 k# x0 y
#reshaping the train and test lables to 1D
% r* E, I2 L2 V% my_train = y_train.reshape(-1,)" |) |; }+ V- Q3 q: T$ s: a
y_test = y_test.reshape(-1,)
5 O" w5 \" T0 r) _* h/ K6 C: `6 ~' ?& Q/ V) A
我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。
( m' n% F" F+ Z9 [/ V8 n% N+ Y模型搭建正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。
8 ~2 u2 m$ M+ u* c6 Q/ F' Xmodel=Sequential()
! z6 e5 R9 L( [. ~2 G4 g+ @#adding the first Convolution layer) |7 F( L% N$ @
model.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
2 H$ Q' ?& z# y' n( O* S8 P#adding Max pooling layer; L) T: U5 g5 g' C1 C6 R0 f2 ] I4 \
model.add(MaxPool2D(2,2)): _% s- p2 d7 E( w7 k X* e
#adding another Convolution layer
& V: R O& @- A8 M& [9 f, ~" p, tmodel.add(Conv2D(64,(3,3),activation='relu'))! R) Z( c4 c/ T% C' }& V
model.add(MaxPool2D(2,2))
. P7 c% F) d- @/ x# s1 Pmodel.add(Flatten())) Q: r5 }: E" h/ j3 h: ^" |
#adding dense layer
: p) I% K1 p7 y' ?4 X8 b9 P( d8 Y- fmodel.add(Dense(216,activation='relu'))
6 { |, }5 O! H#adding output layer) t* U* i* u2 D% e2 q$ M6 w5 o
model.add(Dense(10,activation='softmax'))
: e+ |$ j6 ^2 g4 c# P) x2 h. n4 a7 a9 I- \. x+ _! v
我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。
G$ O6 O- ?! O7 f* t U* c1 L+ _9 z. l0 g" P, x; m
接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/
, _) _7 J; O, D/ r/ ?) b% U. t% B+ M9 \
然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层
# U: Z: B- S' C) p5 Z) K7 S1 x7 K0 [/ x
在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。
) r8 F; }% x8 k% |( {7 ~
- v/ {3 u8 p n& ~最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。
% [0 c! B! z3 y& T0 w9 @5 c6 o9 O
第 2 步:编译模型2 R) @9 W! e: o" A0 q4 t' G+ T% [
model.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
3 Z8 Z( ~$ P+ ~* J' U8 i
2 N* Y w3 s; I( z1 @1 Y第 3 步:拟合模型model.fit(X_train,y_train,epochs=10)
' M( V6 j* c. [% y![]()
" y( \( l. r% {4 h![]()
. x8 z! \3 I, Q如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。
) `; |# m* ~0 {: ~. q) S第 4 步:评估模型model.evaluate(X_test,y_test)# ?/ ^. d+ G& U6 ? g7 |
* E7 \1 H5 Z6 o
$ T0 ^ ^% O9 {# g$ h测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。
" S b- J* H* N' m7 t# E. j8 v第 5 步:进行预测
% N) m* i8 o: ^pred=model.predict(X_test)& _* Q# |3 @; q& S$ c
#printing the first element from predicted data
3 {! O0 Y' Y5 l1 e/ fprint(pred[0])
- k9 Z/ n! I$ D! }2 u9 B) A! o#printing the index of
& G) t% z6 { a8 v0 a' nprint('Index:',np.argmax(pred[0]))
% s' h& Z) S5 ?* Z4 G8 K* w! c/ A. e+ i
![]()
9 {0 e* W5 g# [( X' s3 Q7 D |5 S U- ]4 I
因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。 将预测值与实际值进行比较以查看模型执行的正确程度。 在下图中,我们可以看到预测值与实际值的差异。 y_classes = [np.argmax(element) for element in pred]
* I3 _2 {# r4 e7 M/ g" E9 eprint('Predicted_values:',y_classes[:10])* Z& E0 W( m# Z
print('Actual_values:',y_test[:10])
: ]8 f* |) M2 Z, c9 r* X6 o
) G* N( O6 M* e* o1 W. v 2 I% D8 Q0 `+ y \5 Z
当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。 在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。 ; @/ L, T7 }1 x3 w5 }- B
model4=Sequential()7 x9 r& [+ `% |7 L; g _( x+ L; r
#adding the first Convolution layer
2 x( |8 J: j; j$ c) Bmodel4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))4 _! O; K' {, I, H& B4 K; g8 n
#adding Max pooling layer
8 u. ^5 [. Y( ~7 qmodel4.add(MaxPool2D(2,2)), ~2 q! L! ~+ u4 @! [
#adding dropout. U T. G/ W9 V. H$ h$ w& U
model4.add(Dropout(0.2))9 d( o7 F3 h) t2 B' l, \. B
#adding another Convolution layer. U; u7 ^9 ]9 E7 \) D
model4.add(Conv2D(64,(3,3),activation='relu'))7 J, R) n( ?/ C$ c4 Y* C
model4.add(MaxPool2D(2,2))
; K7 Q6 l( s% l#adding dropout6 m$ G" _7 O2 O/ k: C( ]
model4.add(Dropout(0.2))
# v2 ?& m) L: n5 W6 @, I/ o) lmodel4.add(Flatten())
% [* L# o7 T5 j# P$ u# F#adding dense layer
, U. P x( `7 s$ _$ H% D8 e* F6 bmodel4.add(Dense(216,activation='relu'))7 t a5 i1 f5 I5 C
#adding dropout
% F, t# \3 \0 R) U3 Wmodel4.add(Dropout(0.2))% Y2 {% ~" W( x1 A( U5 d
#adding output layer# `4 N7 }5 r4 e% \& K
model4.add(Dense(10,activation='softmax'))/ l* d. G G J% ]0 i1 q
model4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
; @' z! F7 x, h: Z7 \ K% \9 ?5 imodel4.fit(X_train,y_train,epochs=10)3 h0 F5 T8 [% \+ e! [9 ~ {6 t
3 ]" I7 b2 I+ W6 V6 \( i5 t![]()
- E1 M* [4 W& p& h; w! umodel4.evaluate(X_test,y_test)8 F4 J2 n6 o" n' z6 x* M; Y5 |* y
![]()
# _. `( B. |9 U, s N: x: j1 |通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。0 |; T2 u/ r3 W
$ i+ H8 \7 @6 ~# i6 `1 M; K尾注
( ?; q# o, n) v G/ R" N1 u这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。8 l' d; K9 R# ]# @3 U) u; o9 @5 F
# j- X& N7 t$ J9 n
2 B8 h5 K- c- l0 z; t! J/ L9 M
! {9 D( y& c& p0 t9 O) g8 b6 ^ |