使用卷积神经网络开发图像分类模型2 i1 \" Y0 F6 u& H
简介0 e' b, T( B% M+ r
) a' }& c! g. Q# @4 L2 @
这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。( ?% ? o2 z$ q
' V. W* X6 W" G1 F& C1 w
简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。
0 l# r1 ^7 l8 d1 h1 [# L! T1 z" |. X/ v/ k9 ]7 x
今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。
9 R9 ~. l5 ` X" u. h# P( q6 t- ]1 y, R+ ^% R
实施
6 M. r+ l/ R( a- j% u/ m6 I1 g- M
# importing necessary libraries
$ l( R: W8 A8 h! k2 Iimport numpy as np
$ }3 Q2 m2 {" j! t3 fimport matplotlib.pyplot as plt* b# Z, G. |4 T7 w; z. ]( V! a
%matplotlib inline
0 _/ e% m2 K. O1 {6 d5 y# To convert to categorical data
& _, B, ` x G- D) jfrom tensorflow.keras.utils import to_categorical( v- A! @# x5 G# S
#libraries for building model
3 i4 R) @# ]6 R" ufrom tensorflow.keras.models import Sequential$ F6 f# s; M1 y7 I2 o' [% K: d
from tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten6 k8 c' J0 J5 }# K! q
from tensorflow.keras.datasets import cifar10
3 x# I: W4 \; U9 u. I- j7 A9 l. _% [- A
#loading the data T6 Q8 e5 x1 x7 _0 X
(X_train, y_train), (X_test, y_test) = cifar10.load_data()0 A" _4 q4 b* O4 T
1 z R8 _5 x) `& \: i探索性数据分析
/ [4 p" [2 k9 v9 c5 A5 q#shape of the dataset) o8 l& E, T: p* j$ R7 X% f y' q/ T
print(X_train.shape)
$ T4 ]* C: ^7 v. K$ w2 A! @- Xprint(y_train.shape); \. m. T+ U5 t6 T5 W
print(X_test.shape)
; S+ O6 ?# ~9 ]6 X9 m- C' ]2 m2 ?9 x7 @7 Wprint(y_test.shape)
+ |$ W' m; m9 ?" j# e
- g1 i" b" K/ ^/ b# |1 _ a : {0 Z$ @4 X) O! q
我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝)' ~6 F3 b+ w; \: h% z# p' e
#checking the labels ' F; U8 I M$ }8 V! M
np.unique(y_train)
/ ?8 m* w, |4 ^- @6 M% s
7 [2 _! T3 W( T9 U2 l7 O8 g$ Q $ {- \# W( z1 P7 m0 D
#first image of training data. Z- o3 \4 l" Z8 Q% @4 M
plt.subplot(121)
$ b/ O- ]" M; X: D( R8 Zplt.imshow(X_train[0])
7 H5 q# B( c- f, wplt.title("Label : {}".format(y_train[0]))4 Y" s8 W* g7 ^9 U% s2 o5 G V6 p
#first image of test data
, a( Q% `! s1 L2 L- O Jplt.subplot(122)
6 Q9 }* V: ^" F: x, Zplt.imshow(X_test[0])' o# x# G" r) @2 L
plt.title("Label : {}".format(y_test[0])); Y' U" c: B' I. o4 N; I; B) q0 G9 x& v
; Y6 B+ Q$ W+ I& t+ w![]()
' K) W: c' _& h* T2 C# y8 [0 M& U#visualizing the first 20 images in the dataset
$ M8 g, O4 c. N Rfor i in range(20):
, L" Q7 b- P. }& s# C( Y) A: t #subplot
# n9 s6 l, Z4 W* ] plt.subplot(5, 5, i+1)
, m! H0 r1 | J # plotting pixel data
3 w3 X a6 Q9 _, w plt.imshow(X_train, cmap=plt.get_cmap('gray'))7 { t! _6 R. u, }4 N' i/ n5 g; l6 b: `
# show the figure
/ K3 L9 s9 z2 U' Mplt.show()
' [" |$ V. ]; \8 B% T0 o( h0 z8 N3 Z' D4 X" [1 m( `, d5 M# d
![]()
& E6 ^% \" z0 F预处理数据对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D 3 t7 @' R- N0 \* V" |- L x+ d( S
# Scale the data to lie between 0 to 1+ a% c. g' w) E) u) |1 f
X_train = X_train/255; f) A9 w& z7 V2 H1 ~
X_test = X_test/255. V+ Z J e6 t& ?. h/ q3 ^
print(X_train)+ D0 Y3 X4 r# g* v
! P6 O! m* A v, H. [- |1 I- t
![]()
" [7 n. B+ ~' T+ I' N9 m: d#reshaping the train and test lables to 1D; G. _: d4 B+ v% g
y_train = y_train.reshape(-1,)& H7 V. f$ r7 ?
y_test = y_test.reshape(-1,) A7 t& {$ t# C( j2 `
2 x3 V% g8 i1 H+ E我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。
1 X% L5 m8 A8 d* x5 { q模型搭建正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。
1 M. T+ |: _' Q4 h* A$ Vmodel=Sequential()3 B+ W* u8 K1 t" v! _
#adding the first Convolution layer
+ R: z0 k5 Z8 I' A8 P1 emodel.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
$ T. `: u. F; a. ~' f7 \#adding Max pooling layer
$ T3 L, z0 i4 [; ^) Smodel.add(MaxPool2D(2,2))5 ?7 \+ M9 Z7 y7 T0 n% D
#adding another Convolution layer- i' H% N: ]) m6 w( D
model.add(Conv2D(64,(3,3),activation='relu'))8 \2 Q3 {# ^; z* m
model.add(MaxPool2D(2,2))
/ X2 X/ z* S& B3 |: ymodel.add(Flatten()). {3 k- W: M7 m8 u, S' h
#adding dense layer
; f! j" o: F$ U7 Amodel.add(Dense(216,activation='relu'))
4 ]' _0 n/ T6 u& [+ W#adding output layer* @5 `- g: _! V. ~2 d2 g6 y6 }
model.add(Dense(10,activation='softmax'))4 `3 e/ f! E: l. {% T+ c
* [' o4 c5 n% m! ^# a- v
我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。( d1 ?* g& [6 q5 [8 E
f4 f; S7 H# v7 q7 G4 J* w接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/# s8 s$ } ^+ ]8 u% r! f
" ?: c# Z/ |: l/ x, g2 d+ ?然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层
. e0 h- {4 h: l- i# s, X1 G
- \' C" P) I, W: s* w在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。
4 r1 |2 o+ _# c! B2 h
6 |7 _$ O- p: ?. a+ T8 @" _! m最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。
) U3 p' u* R% K' C' a- n. }* z0 S d3 X* D. ], j' L
第 2 步:编译模型1 v/ p* p# y, L1 m- ]. @
model.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy'])1 n! j9 @. y2 R- o5 a
7 y- ~! p" T N1 s) c
第 3 步:拟合模型model.fit(X_train,y_train,epochs=10)
0 S( D O. I8 M" k. C1 y6 e/ Z6 y![]()
0 F# I2 B6 {$ t4 U" S![]()
* v& z+ J, c* {5 U' N3 o如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。. D# {. ]6 ?' r6 k0 b
第 4 步:评估模型model.evaluate(X_test,y_test)
?, ^% S; F2 K4 i![]()
8 V+ q# P. i, @; g! W7 I
5 x! L. p( ?! w4 g2 _测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。
0 m# a' h) \3 M: J第 5 步:进行预测 c6 |8 ]3 e+ m, D/ k1 A( K0 E
pred=model.predict(X_test)
0 Z6 r! J/ D. d* T#printing the first element from predicted data
: z4 o0 {; M4 X7 z$ s8 Qprint(pred[0])
6 k: A2 @8 v' \: x#printing the index of - _- i: |: s, J, C8 n* D: l3 `
print('Index:',np.argmax(pred[0]))2 G& c1 `) \ E, ^, U+ @
" D" c" m2 ^. H6 G
![]()
6 a1 g/ t, J9 g t. p4 ]! U: d, H* F$ e8 \1 z: m! Z+ u
因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。 将预测值与实际值进行比较以查看模型执行的正确程度。 在下图中,我们可以看到预测值与实际值的差异。 y_classes = [np.argmax(element) for element in pred]8 X( e$ o( y& r A1 K9 a5 B0 C
print('Predicted_values:',y_classes[:10])
, L( l R7 e7 W- N2 `0 t# zprint('Actual_values:',y_test[:10])4 [, t# j. ^5 G& Q4 W
! `' E8 r& v/ N6 ]4 ~8 S. w# R
![]()
- h7 s) R" @% Y- k5 Q4 v6 X5 O当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。 在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。 3 h5 ]" r4 R' H9 ^8 s) P
model4=Sequential()
8 {& P$ E6 M: i8 M6 P+ S#adding the first Convolution layer3 v8 l4 q' \7 w/ T
model4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
( E. f0 z) Q9 x7 ~#adding Max pooling layer
/ k9 e9 M m& Qmodel4.add(MaxPool2D(2,2))/ {4 f U# Q' u/ n5 |* h1 p5 F2 r
#adding dropout
' @) y/ r" O- g* n( {3 | Nmodel4.add(Dropout(0.2))) r( k6 o& I; E0 W6 j
#adding another Convolution layer" Y# i5 i: y4 F1 }
model4.add(Conv2D(64,(3,3),activation='relu'))" V1 l' c7 M6 Z2 I& q" ]4 f
model4.add(MaxPool2D(2,2))5 C0 _3 ~' j: v: A+ I
#adding dropout
z) x7 M. |: o/ [model4.add(Dropout(0.2))
- y+ @3 X9 i3 l) Fmodel4.add(Flatten())
9 i2 W' B% d# g4 A# P. ~ {#adding dense layer: p s4 J0 ^* A* m5 _
model4.add(Dense(216,activation='relu'))
" z! r2 f2 g8 c/ l* e; d#adding dropout
- k8 q/ H1 j9 B- p/ K* `0 `3 k8 a; |model4.add(Dropout(0.2))
) }, H- O- i/ g( \#adding output layer
+ c& B" z) r# [( w9 P1 Jmodel4.add(Dense(10,activation='softmax'))
$ Z# G2 f# R7 k* G! N* u! omodel4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])' y3 w$ o) W* D
model4.fit(X_train,y_train,epochs=10); ]) s) e3 l, C4 ^' R
. e' ], K8 V, y; E1 {4 ^0 N % M$ L9 d( z+ x: ?3 @& d f2 B
model4.evaluate(X_test,y_test)
# ]% c( M, |* X+ m+ u![]()
; |6 W) F! F, U5 U) [: D通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。9 z0 S. x$ N6 s( M* y
0 K2 t3 A/ E7 ?/ z' K
尾注
- C5 i7 D9 @. u6 I这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。
; ~8 T. m1 I/ e8 f2 e& h
1 a+ G5 p' }: d; @4 G4 i1 n+ H
5 h: f6 @# o/ {( |0 C* A" Z/ `1 K9 \# i4 _, r3 v) o- _
|