使用卷积神经网络开发图像分类模型, ~, o* w- A% \, p$ s1 ]7 M
简介
7 S2 x+ S* b- y. }. o7 n3 K2 P, |3 A0 w; i. H( A
这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。% l; B5 v$ k/ w/ e* l8 [% r: V+ c# ^
! ?, S( \& u5 [ H4 @( P; o+ k简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。5 l# J) N3 b3 _8 c L
) A0 C8 Q- h* o: Z' q
今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。
# H3 v, i% h! e6 q0 F4 v- @, E
实施
6 P; g4 O- N* J9 R6 e, N
3 W# U, z. h F) Y3 ~: e5 P6 Q# importing necessary libraries- U) E( \: b9 X+ V: Q
import numpy as np
3 S w# P; a' v/ Simport matplotlib.pyplot as plt
& c4 `+ A2 C4 o ~! z" @%matplotlib inline9 O4 K" @* @# V6 l9 R. i/ ~
# To convert to categorical data
1 n$ g$ }. v% Nfrom tensorflow.keras.utils import to_categorical* T3 y* R( Z8 R) H
#libraries for building model% T$ l0 t7 {2 V
from tensorflow.keras.models import Sequential
- C# E$ @, T+ m( X! h# h1 o2 hfrom tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten- t' c3 T" X# E, [
from tensorflow.keras.datasets import cifar10 _+ o' G0 h! b" P3 h, b' j3 s
, \1 |3 k, b+ }8 c
#loading the data$ h# Z8 x0 U( y5 a! ]0 y# }4 q! K
(X_train, y_train), (X_test, y_test) = cifar10.load_data() |6 D9 I# Y* x/ d! O" q
( k1 J7 b) r2 K6 k& j2 h5 e探索性数据分析
9 x4 c# u4 r v. N& t#shape of the dataset3 S1 a7 |! M1 y4 _% n2 O
print(X_train.shape)
" k' A/ s( T" o* V4 pprint(y_train.shape)$ B6 T' A9 E, v7 C
print(X_test.shape)
1 ^" B k x3 d$ M3 P; bprint(y_test.shape)
6 L* V& p% ~0 ^! P
- m* m6 a$ a- q/ @- R4 A![]()
! k- e: u4 A) H6 C我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝)( P/ R x: ~8 R; a
#checking the labels $ g" |0 O9 a$ u O, ~7 Y
np.unique(y_train)/ t. q( z h, O3 X
! J2 o( F1 n5 Q / D+ F, s5 b# U+ K8 f
#first image of training data" F; X! B% j! x5 v
plt.subplot(121)
: `% K* [3 L! L. T8 Mplt.imshow(X_train[0])! X, Z" @$ J( n# @
plt.title("Label : {}".format(y_train[0]))1 Q' ^; u. N1 ]! {# u
#first image of test data
# Q5 G2 L/ s9 a' N& A9 X) dplt.subplot(122)2 @" B# A8 p) X# Q7 P* P
plt.imshow(X_test[0])
! [7 t6 L4 I9 hplt.title("Label : {}".format(y_test[0]));/ J. Z1 C$ J3 E
% o: T6 V2 s7 W
9 K3 N7 X3 M( v. n- l M
#visualizing the first 20 images in the dataset
; o8 U" a" x0 E2 I9 J2 q ]5 afor i in range(20):
! F- l, r0 p, i1 ]" P #subplot
0 Y) ?* ]) w: M8 _6 Y" | plt.subplot(5, 5, i+1), z$ }, D* d$ P
# plotting pixel data
" J! `" C' V+ T* F/ Y( z plt.imshow(X_train, cmap=plt.get_cmap('gray'))
0 R3 s V4 u0 C1 ?; K9 a# show the figure
! X5 s# Y7 L% _4 U3 |: o# D" o3 tplt.show()
. C! w. ^# B: Y3 j2 I( x
+ H! M0 _! n/ o) m" l , H" H, a* ]: Y, w. T( j
预处理数据对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D
: O8 f b; V; l8 T4 @$ V# Scale the data to lie between 0 to 1
. N( {1 a1 P4 cX_train = X_train/2554 b) Y, g' i: r( Z& f5 U6 @
X_test = X_test/255
0 R5 @" v0 J6 o+ Bprint(X_train)
& q9 N U8 L0 A1 @4 ^1 V3 ^+ ]7 e" v" b8 p- Q, j( i: V
" V: q) g) Y( M8 s
#reshaping the train and test lables to 1D
4 Q& ~' m$ s* b& D- ey_train = y_train.reshape(-1,)
# I( y( w* E. p& b/ Cy_test = y_test.reshape(-1,)& H- @% F2 g5 {$ w
. [& r2 }# G' z1 a我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。
4 a, a( C9 Z* b8 l模型搭建正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。
2 Z5 w: I) j* Y: _model=Sequential()
# b1 p" ~; k7 E- Y; N* b5 c/ s( n#adding the first Convolution layer
( d* M y8 P N5 [( o$ Omodel.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
% z3 U/ q" |' x% E9 ^+ b/ Z% t#adding Max pooling layer
5 \' P3 N3 s9 s ]# E smodel.add(MaxPool2D(2,2)). c) z& _/ I& y, |) i
#adding another Convolution layer
/ q3 w. b$ y2 cmodel.add(Conv2D(64,(3,3),activation='relu'))
, U6 i9 G# f- C) _model.add(MaxPool2D(2,2))
! {( h. j+ t: }model.add(Flatten())7 k; M. Y. I3 U9 N1 ~+ o; W
#adding dense layer4 g. R- \) v/ X! C8 T/ ~% \8 I
model.add(Dense(216,activation='relu'))
4 b) [" c9 Y! r#adding output layer
8 T3 D: a% b( t+ nmodel.add(Dense(10,activation='softmax'))
8 g r8 F0 g8 U& g. o4 x$ B. _ _% v
我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。& Y2 {0 z5 e' z3 {) P
?6 e$ C1 f; c, `( U接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/
+ a b3 i6 n) x' r. H+ f- y
9 P% c# V% t6 w8 Z9 i4 E: s然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层; |8 F* H# w' |- a% h9 S
) a( Q$ A$ g7 B q0 ?( ?
在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。
+ i) v/ X( h1 _; i3 D7 s) b7 @4 A; P5 O% |0 \. l
最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。
: u0 s: I; U2 b2 m+ ~1 n' W4 y7 y+ H: k/ {0 u' H3 Y: P) R. k; |( s
第 2 步:编译模型$ w: l" V( f5 r8 u2 I% D$ C) r
model.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy'])3 C4 Z7 w* e- D5 S+ ]# C
, C# ?1 ^8 q5 d+ T0 o
第 3 步:拟合模型model.fit(X_train,y_train,epochs=10)
$ {, u0 `$ l9 k. G![]()
# P8 L3 j% P/ W, y![]()
1 j" g: ^$ X# Z如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。
* o4 ]/ }0 @' q' B5 `第 4 步:评估模型model.evaluate(X_test,y_test)
! B) O% K. r) A: i+ g3 i & m9 @5 G: J% X3 W2 Z
4 ?' N( h& h2 q% w9 _1 B1 ?! x
测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。
8 A5 [* @8 D9 L% c3 d第 5 步:进行预测1 u# ~4 T9 m6 N3 R% t; ]
pred=model.predict(X_test), j, c' U7 s. R7 ~
#printing the first element from predicted data* E* u) j& \ C3 ]$ ^# i$ b9 [
print(pred[0])3 C7 h! ]" F* b$ s. Q2 J- w( ^
#printing the index of % D! V' X6 A8 N0 Q
print('Index:',np.argmax(pred[0]))
/ R# R# a* g4 H( r; ]
0 c( q! u3 g9 {' h9 n . U" l1 t: u/ g/ {
$ O* S. r1 J3 Q. d+ Z
因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。 将预测值与实际值进行比较以查看模型执行的正确程度。 在下图中,我们可以看到预测值与实际值的差异。 y_classes = [np.argmax(element) for element in pred]
6 }3 ]( ^# {8 s: Y; `print('Predicted_values:',y_classes[:10])
3 z1 J0 \4 G1 i: `5 i$ z& yprint('Actual_values:',y_test[:10])
. H2 w _3 W e5 w+ C' h) a8 ? `& j5 z8 N7 T: x$ L
6 J/ X! g4 m4 Q# C
当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。 在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。 . ~# I3 t; ?8 m( M3 S4 K1 m
model4=Sequential()
. u- H& U& u: E' c& u* Y) a' E#adding the first Convolution layer
5 N1 r2 k% Q `. ^. M) `9 Umodel4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3))), ^& K$ |& }) d0 v3 T$ h5 }
#adding Max pooling layer P U: C. v! V. b2 b, n
model4.add(MaxPool2D(2,2))2 P9 M' k$ v- M ~* O7 g
#adding dropout
4 a( R; z3 q7 V: H, ^- h- h lmodel4.add(Dropout(0.2))8 _4 A% }8 C, t" m
#adding another Convolution layer
5 g4 {) Z9 j+ L# n* Omodel4.add(Conv2D(64,(3,3),activation='relu'))+ b& J6 i. k1 L* T
model4.add(MaxPool2D(2,2))4 e+ I$ n1 i: A
#adding dropout
- J1 X4 c+ Y7 Fmodel4.add(Dropout(0.2))* z) V7 }& N" }* {* P. Z
model4.add(Flatten())# u `$ m. M" J5 Y8 I8 P
#adding dense layer
( D7 Z, x7 [& n7 f+ A1 n! jmodel4.add(Dense(216,activation='relu'))2 r( u5 p0 U, [7 ?. \
#adding dropout
( N9 t) e% P* w7 L9 b( Cmodel4.add(Dropout(0.2))
- B3 i0 \% T/ |6 z% J+ F8 z#adding output layer
9 \+ ^5 E. O' q; k. _4 Q, n9 Rmodel4.add(Dense(10,activation='softmax'))
* q9 C/ T1 w5 P; ^ S2 l: Zmodel4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
) O* q3 h. g( Gmodel4.fit(X_train,y_train,epochs=10)* F0 {' L) U) {* g$ s
2 [, Q) L. Q2 Y8 s8 k' {- f% |![]()
8 W' s0 O1 F% o. {model4.evaluate(X_test,y_test)
7 |( F) n+ C: s- i+ X 1 z: ]0 ]" r% _: _
通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。: N" O' ^- F! o! k2 K7 K# ^
. t$ D- x/ ^8 ~0 C x" g6 {
尾注& ]" e3 Q# V c0 K, f5 l
这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。. Z0 T# Y" W$ u# v: x
% K6 \! L/ E# `! h7 \% u* p' n. e7 e$ m! t$ V F) S3 j! t
3 u. R% ?% r# V( m$ b9 a9 M# o: W* N
|