使用卷积神经网络开发图像分类模型
6 }8 p# M2 V! T7 q# R简介- R# T! l$ s' n' T
4 q B+ k0 P1 R2 S
这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。3 t. G5 s. y8 T7 B( T F) ~ V
& B, n. Z" j* @* X3 H6 B4 G3 H
简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。- ^$ M _! u2 H' y" C
+ ^/ e8 t* G; _$ U! l. m$ [今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。
7 g: e& D0 z! v# J4 {4 ~( @, Q+ ]# Q4 y" V2 |
实施' @ s0 y+ h- a0 r7 n
6 F- ~" Y; f& o* I% O0 @
# importing necessary libraries& e1 G! X9 C3 ~/ M1 J5 k0 j
import numpy as np
% k% M8 r" K. simport matplotlib.pyplot as plt
/ h) p7 ~( x) ?1 j3 d; z" m%matplotlib inline. X, `( X+ V/ y% n. t) z
# To convert to categorical data6 z, n6 d+ `! s+ n& J
from tensorflow.keras.utils import to_categorical( }# a( u# E4 L- t
#libraries for building model
0 a4 a2 _4 D i& ?) Y& Q4 s: k% h& ?from tensorflow.keras.models import Sequential
F" ]( p( V# O3 I2 O- q! X7 P. c( lfrom tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten
. G) m- C; {1 l8 O9 M# Nfrom tensorflow.keras.datasets import cifar10
' q Q5 {' C Y$ C! N3 y
+ E% p: }% ^: t( W3 Z, _2 x#loading the data2 N3 T- Q2 E1 d9 ?
(X_train, y_train), (X_test, y_test) = cifar10.load_data()9 v* F7 N2 d& p' i) n9 @8 `9 o, M( [
/ M7 N1 O' `) ?4 ]; b
探索性数据分析
: z" n; e7 x. r1 t* f% ]8 a; C) @#shape of the dataset5 M. r. o; m0 M
print(X_train.shape)1 N" a2 z. L9 v4 q U0 D2 A
print(y_train.shape)
& e3 {0 v* N4 u9 l+ J& ?. s7 Nprint(X_test.shape)" d Q! e `* C5 t. Q6 z
print(y_test.shape)( @$ L5 w3 b5 u5 d* w
) E) X$ D6 ]; L( u# ^
# i* M) Z6 ?+ Q7 q: ?, H" W: R
我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝)
8 C4 x# J0 }; Q6 k; F8 ?3 T: P#checking the labels 9 X/ l6 g6 h2 Y
np.unique(y_train)# L* Y3 Z* ~% u+ S; u$ c5 M/ Q
, f* q4 N, p/ N4 ]![]()
# O7 R2 ?0 [; C: d#first image of training data. I4 N i) w1 y7 b. Q
plt.subplot(121)* o4 s6 I8 Y3 t: I9 C j0 I
plt.imshow(X_train[0])1 p* q) M. h- O- \% | [
plt.title("Label : {}".format(y_train[0]))
0 Z8 U" V$ i, A' {8 L#first image of test data) ]1 } p: _4 t! @* w3 Y, C
plt.subplot(122)2 k: z+ s- M, n" p9 j
plt.imshow(X_test[0])
% N p" @8 Z3 E n% e2 Hplt.title("Label : {}".format(y_test[0]));
. q' e2 f4 Y3 T/ l! ?3 c* F* T6 f2 y. J' ~. f( a
4 b, F& C3 t6 s/ }9 k
#visualizing the first 20 images in the dataset8 s; t$ n4 n! O
for i in range(20):. q: @- j- y1 _8 i8 H' p
#subplot
6 f6 S; r6 O' ?+ Z5 }& U! j plt.subplot(5, 5, i+1)4 t5 \) [3 j2 O9 ^: C8 A/ \/ R4 a
# plotting pixel data/ V' q3 j k! ~; Z" o
plt.imshow(X_train, cmap=plt.get_cmap('gray'))
5 ?' I$ S1 x2 ~2 g# show the figure/ O3 f p. z# ~" o5 }8 y [" H7 j
plt.show()
9 b) W8 B! W7 {" a3 m' a) Q+ Y' {' E. W5 ^0 F$ m ?* u- r
![]()
- M$ b* u& ?* ~9 H预处理数据对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D 1 h2 O3 a2 o& p% ?
# Scale the data to lie between 0 to 19 d/ d! a) U; G6 [! o- B
X_train = X_train/255
; \5 q" ?% o5 Q5 ]$ t. V, i: PX_test = X_test/255* J( o* K6 V3 |# `! s8 O
print(X_train)% w5 _" {1 {" M6 b
5 ? X Q& e& O1 M: p, }![]()
; C* r2 }! Q4 d#reshaping the train and test lables to 1D: D& N4 @4 _2 ]$ _% W) O
y_train = y_train.reshape(-1,)5 ^3 u4 _& o# w2 i
y_test = y_test.reshape(-1,)
0 y$ d H2 o9 G% d
+ ~( e8 A, H: Z我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。" Q6 P5 j' n6 X3 r2 ?# o
模型搭建正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。 * t6 u2 t4 V, s8 g
model=Sequential()* {/ r; E. A% d$ `$ A; L8 ~
#adding the first Convolution layer+ x, j i( h P2 t5 O
model.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
\" P3 e5 v9 {; T# `! c& ]& K9 H. c+ G#adding Max pooling layer
/ h X6 o) h% [" `5 U' amodel.add(MaxPool2D(2,2))
' A) I5 i: H" Z- }1 a* W, @9 n#adding another Convolution layer
0 u$ a2 h, h# J' u$ mmodel.add(Conv2D(64,(3,3),activation='relu'))+ j8 r9 Q- K/ M+ c+ i0 E
model.add(MaxPool2D(2,2))/ S/ D( J/ D7 w( z( C0 C
model.add(Flatten())
2 {' }* P/ g8 E: k#adding dense layer- K& D# d7 |. e- y7 A
model.add(Dense(216,activation='relu'))- ]. X+ g* a, p7 C, J( F$ S5 u
#adding output layer" z m9 ]# ~% o' x* b: I
model.add(Dense(10,activation='softmax'))( [, P7 e4 r8 {( n
6 }( t) c& o" v$ _5 B我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。
- o5 I, ^9 y% B& O( Y3 p$ P- e7 o% i' V6 Z0 r8 J
接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/8 B, E7 L6 A0 Z
1 W) ~4 J0 ?5 D/ G. A- a然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层
$ `; G* Z) p+ l4 z7 ^# z* D! ]8 t+ N; y7 B I
在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。
; F) ~+ [/ r% @# o* c! K; [$ L+ z7 t+ R/ v3 w( {
最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。- i3 ^8 K. [1 ^1 z/ P! W
- g0 C2 U @8 T/ F9 X第 2 步:编译模型
: W: ], P$ P! _. Z! v) smodel.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy'])' g3 Z; u% V0 Q" `' t+ ?
- r% _3 p8 F H0 H/ L第 3 步:拟合模型model.fit(X_train,y_train,epochs=10)
( C# z4 n( K' ?1 i4 Z1 r ; N4 k: v; M6 \4 ?7 e- T
![]()
1 v8 c( ` N4 u- T如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。) s# S) r( i# u
第 4 步:评估模型model.evaluate(X_test,y_test)
2 m7 \( O6 q i3 B4 C/ c% Z6 i # n( ]# u" w) m- M% C8 J6 K
# I* G2 e8 W- J, f0 o! f测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。( s8 {' j% ?- ^- ~$ ]! j" h
第 5 步:进行预测/ }" O4 J" j; `, h& J+ b# ^4 T
pred=model.predict(X_test)
1 L @* \* p5 x5 V5 H( q#printing the first element from predicted data
5 j- E% u+ g$ u7 W+ K3 Nprint(pred[0])
# V2 f- `# @) a C V1 M#printing the index of
1 s: h: Z9 x: p) o5 o" ]' Vprint('Index:',np.argmax(pred[0]))
4 k+ d. [( O2 S1 {3 ?( A5 d' g: ~
2 P6 l& f0 H0 L K( j![]()
* S( r# D% ~- }/ g, C6 y& r2 z
5 [) D d) l* n" M5 q0 x8 K- M因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。 将预测值与实际值进行比较以查看模型执行的正确程度。 在下图中,我们可以看到预测值与实际值的差异。 y_classes = [np.argmax(element) for element in pred]
3 y" Z8 t t6 i( x1 h: y2 vprint('Predicted_values:',y_classes[:10])7 z! r! H" a, V F( F( g/ S1 t0 O" N
print('Actual_values:',y_test[:10])" ]4 q4 i% N$ C
1 M' M+ I3 n( [! F! `4 P# M* M![]()
# n1 _5 [/ M- V# F当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。 在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。 . O: `0 [7 H& E7 L
model4=Sequential()
+ e3 f# S+ B7 _9 K4 H# O#adding the first Convolution layer
: o' [2 Z8 W& rmodel4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))' X& Q. a3 G1 i: N9 ~5 j
#adding Max pooling layer
. d5 A& e' Q; ]7 umodel4.add(MaxPool2D(2,2)), R! r: I, x6 J# K' F# k5 s
#adding dropout, Z9 c q. _9 Y" p x) B0 Q
model4.add(Dropout(0.2))
4 P6 J" [( e1 N. A#adding another Convolution layer7 J k# h n, k! B- J }: ^& T v
model4.add(Conv2D(64,(3,3),activation='relu'))" M( q6 r9 d2 {: E
model4.add(MaxPool2D(2,2))
+ Q* }: M4 ~$ }#adding dropout7 I: n! T* V: [3 d9 K+ h
model4.add(Dropout(0.2))2 g7 H9 U; K, v
model4.add(Flatten())) m" h+ J( a, }0 ]6 {6 u
#adding dense layer' [! w' z, O" F& y' \2 `# q* x
model4.add(Dense(216,activation='relu'))2 u Y9 p/ ]" a% E* E
#adding dropout$ q/ `' _" O# F% |- [- u8 R
model4.add(Dropout(0.2))
2 w' Q! e- I- @) c#adding output layer- D; K1 j$ M5 f4 j# ^5 i5 h d
model4.add(Dense(10,activation='softmax'))9 K# n5 H, T y& u* r
model4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
8 p/ s5 r; L3 q& lmodel4.fit(X_train,y_train,epochs=10)$ q [) e) y4 z" E
9 z8 T0 P: g& u9 G3 d$ D) {![]()
h& r0 G3 k0 t* ]model4.evaluate(X_test,y_test), O. j) s/ H8 R% w( d0 }/ [
' z, T! g) [' Y, a4 V5 F, j
通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。7 }, c ?, o" |, p( I. Z2 R( T. ]
. v2 R/ Y. J" N
尾注
; Y/ B% |. W7 {" @这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。
4 `$ i$ e7 b( d z, N
& G7 ` w( v C* w6 k3 o' t
% Y+ M! a. v! s3 ~0 b+ S. j
+ e! @% [& F( ~" {/ @/ J0 Y- r |