使用卷积神经网络开发图像分类模型1 r2 J/ W- E) L
简介
6 o. b, G2 [% s8 f7 D! H4 o+ r+ v9 _3 n; O. d# b3 i9 S$ ~
这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。
, X6 V! e0 X) n- N
/ M/ ~; I3 G( y; W简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。4 s7 K& q$ _- k0 Q; E
7 ^! N% u W7 N4 W7 d今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。6 u/ h( r% [3 h: D
6 ?0 E0 I0 m6 I& ^ m; V5 x实施$ _5 K- Q# Z p* [
O7 [% h3 s1 t# importing necessary libraries
/ D, _; t0 x! N7 P$ cimport numpy as np- s ?1 a# s3 |' R" r% j, k. E" o
import matplotlib.pyplot as plt. u: }0 |9 d1 J4 `: I+ \
%matplotlib inline; H: J2 f7 ~( W6 \7 t8 m
# To convert to categorical data
1 K1 V, w1 Q+ \( tfrom tensorflow.keras.utils import to_categorical
) \% J% |' x$ ^' ]$ D4 R#libraries for building model
% e$ f) \3 z; w$ r/ a# d3 ^from tensorflow.keras.models import Sequential
' z' N, Z+ d/ t1 o& Tfrom tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten- c, Q4 A. ?9 @* O6 q. H5 g. H
from tensorflow.keras.datasets import cifar10
4 u6 j& Z0 R ^& p L r! g$ J# b0 ~! X' `
#loading the data1 P! z7 [& a, g- ~2 H# A" ~3 p1 ]
(X_train, y_train), (X_test, y_test) = cifar10.load_data()# I! x' X0 k* D# t+ t7 _
, i- g: b/ x! B4 }
探索性数据分析
8 e( C9 j4 p6 a$ q; M#shape of the dataset
- I3 y3 p8 `3 f% nprint(X_train.shape)
- K/ I3 q6 o$ wprint(y_train.shape)
2 E( R9 y$ y2 p, J+ g6 C) ?& [9 g, zprint(X_test.shape)
& y# U* U9 j h( h. u0 rprint(y_test.shape)
9 ] G1 j; o: t; {' u! K- r
3 O& ~& U1 j0 _6 n; U![]()
8 ^- m C1 u" }& v& T我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝)$ E2 ^& ] e+ n6 V4 r& m# K, Q" {- v. a
#checking the labels
& z& a, B* {! H' gnp.unique(y_train)
& j5 V' G4 t3 o, F& o r$ Z/ H, V; i2 J/ }9 u9 T
![]()
* R) Y3 [- i! S# M+ b, L#first image of training data4 H# @3 F' M; B- W
plt.subplot(121)
" s) R0 W! f0 L- R. {3 Pplt.imshow(X_train[0])
7 O1 I# W9 @; x2 w9 y. Z! _plt.title("Label : {}".format(y_train[0]))6 ?: n8 M, u; r( X" ]4 U5 _1 s
#first image of test data0 ~5 `" c. u+ x% ?2 E
plt.subplot(122)- G2 Y7 V6 b9 a- R
plt.imshow(X_test[0])# q/ m! K0 L8 l' E+ `
plt.title("Label : {}".format(y_test[0]));. d' [$ z p7 S& Z0 L
6 ~& l; Q+ q/ r) B/ W h2 j( N
![]()
/ t5 _, y, A' j# f& \% @4 U% g#visualizing the first 20 images in the dataset
0 T% l7 A3 y. @ H9 Bfor i in range(20):
% B' }' G6 D; ]3 X/ d F #subplot
5 }3 P( C( ~6 } plt.subplot(5, 5, i+1)& y S; M! d, f/ g% z( }" s
# plotting pixel data
* Y3 M6 a8 \2 N* N8 H6 V plt.imshow(X_train, cmap=plt.get_cmap('gray'))" F! G8 x: W/ E5 R5 X
# show the figure* `+ G7 @7 P" x2 \ I
plt.show()2 I7 N$ {' _4 r# J# i$ ]5 h
; P; q7 M" e x2 ` ( P" R, q. x1 q" L+ [9 u
预处理数据对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D
% }2 {# S- O" y# Scale the data to lie between 0 to 1& R% x" ^! A! T* A; g3 h
X_train = X_train/2559 f0 K. I" U. w0 Q" u
X_test = X_test/255) T( o; S; } K A
print(X_train)
3 V9 h. E2 g. u9 Z! B$ [3 [( T. m) @/ X0 B5 f+ E6 P
![]()
+ _& |' e: B2 J0 s: C/ b#reshaping the train and test lables to 1D3 e/ s1 n3 z% |- p) f
y_train = y_train.reshape(-1,)4 ~5 O2 G! R$ i# d+ J$ @; G
y_test = y_test.reshape(-1,)5 [' x( n" |+ p
- {/ K; p" H( _% i) Y" t: L我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。
* V# S, u* T8 s! _' H模型搭建正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。 ( v0 ?0 Z2 W2 C0 e+ l. ^+ L$ U3 J2 g% o
model=Sequential()3 P# }5 s& b9 G! s, w( F5 v( H
#adding the first Convolution layer
$ f: z; e/ c' C( X; |# o' Amodel.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
, K4 G% l2 Y- I- z# `1 X* l E#adding Max pooling layer
) L7 t) o9 F" m! O4 O9 j" P6 Hmodel.add(MaxPool2D(2,2))8 S4 u8 [$ o1 v( t) K5 g1 v! t
#adding another Convolution layer% o0 u& a# g$ K' U. n3 y
model.add(Conv2D(64,(3,3),activation='relu'))1 ^+ i( z" V' K+ g& s
model.add(MaxPool2D(2,2))- P2 B2 k p+ d/ s
model.add(Flatten())# `8 V1 \5 `* g7 y9 r+ f
#adding dense layer
5 ]: e" ^* j. p3 fmodel.add(Dense(216,activation='relu'))
- } F7 G2 j! E* p! I#adding output layer
, j* D( U5 \, Smodel.add(Dense(10,activation='softmax')); Z9 h$ B% |1 P5 U+ G* \4 X$ X' C
3 X9 [4 l, x+ Z4 a3 S* T我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。
) s$ a6 a5 d; T. n6 J |, e/ L) Q+ j* q
接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/. E ^/ \' f9 q7 b% a& U$ h
% D+ f+ ^3 A7 m" o2 r l
然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层
4 C2 M, b* n" z1 t" O- \
! X% [3 ?7 w4 r/ F, E在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。" O8 i; R' R. y/ q+ b, O- K, J" [( V
6 L1 p7 X& r% n9 O最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。# T. I+ \8 d0 ]+ l0 G) V7 _" v
* y+ \- K$ F3 L4 w
第 2 步:编译模型
5 `* T7 E% f7 L; z; d7 S7 c) Omodel.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy'])7 W+ c; {. C) T' ^6 F& C3 ^6 q
2 ~" l5 m( K* }! R! O第 3 步:拟合模型model.fit(X_train,y_train,epochs=10)
% @! _! Q" E7 X1 ^ @8 E7 T- R 1 K* K, K! u- s2 d2 I" E
* ]% H H2 @/ V5 |5 k: \6 g
如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。
8 c" |/ z% T2 _# X( J第 4 步:评估模型model.evaluate(X_test,y_test)
. c/ p0 q: Y6 A# Z6 Q6 g 1 b4 q1 H' @8 O, d. G
2 a; N f/ P6 J: f+ n% c! s测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。7 K2 O4 O, w, a/ A! p7 C* C
第 5 步:进行预测
- F8 z. W; [+ p: u0 v+ [pred=model.predict(X_test)2 H5 a' H" J( G: O( o, F* k4 ?
#printing the first element from predicted data9 @9 m( Y" D# M5 d
print(pred[0])2 H2 f E% F! z
#printing the index of / f. A7 g" u) r
print('Index:',np.argmax(pred[0]))
# y5 u& g& t+ _5 V+ c3 x3 c. I* G3 g' _! D& `3 {
# e) L6 `3 Y( F
9 K# J& F- E+ E" B$ d
因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。 将预测值与实际值进行比较以查看模型执行的正确程度。 在下图中,我们可以看到预测值与实际值的差异。 y_classes = [np.argmax(element) for element in pred]
8 c3 H" u5 V# W( V0 B1 }print('Predicted_values:',y_classes[:10])
' K. ]" v, V, ?+ B2 e7 Jprint('Actual_values:',y_test[:10]) d6 d E, \2 K3 k O1 K3 K3 |
; b! D1 I% i5 I" c![]()
8 e/ _0 t; W3 f( O6 S9 ^当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。 在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。
7 `1 |5 @2 j* m3 Tmodel4=Sequential()+ G9 H6 b% v2 `- F/ x3 u- t/ R
#adding the first Convolution layer
/ e1 ^; P/ {6 S4 F; a* Umodel4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
; }# t1 K" c7 l& O# l#adding Max pooling layer
4 u6 W6 ?. E# f4 [4 jmodel4.add(MaxPool2D(2,2))
% U, h, D4 r" n$ {# W$ {+ q; t#adding dropout
$ Q7 H+ C ^' ]6 ]+ i5 amodel4.add(Dropout(0.2))6 m$ k' U3 w' T) ^) S
#adding another Convolution layer9 S/ i9 c2 q/ Q Z# G2 j
model4.add(Conv2D(64,(3,3),activation='relu'))
; U" S7 S( U* y' ?! O6 Ymodel4.add(MaxPool2D(2,2))
8 p8 e/ T" g8 V" a#adding dropout, f% @9 s1 J, Z: ?
model4.add(Dropout(0.2))
$ r& G6 L0 p0 ~% Omodel4.add(Flatten())
" P; B3 T. [8 p$ G7 d#adding dense layer Q- |. j3 Y7 q, |5 p
model4.add(Dense(216,activation='relu'))
/ b% i. ~) m, e8 X#adding dropout( v5 M8 L M+ G! M% }
model4.add(Dropout(0.2))4 _2 i$ l( K9 _+ @$ @2 Y0 U
#adding output layer' x; \& P% o# P* ^
model4.add(Dense(10,activation='softmax'))# `& F( _" Y: C/ N; r" t! d
model4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
5 |, S/ t3 c$ C$ R+ o2 `$ fmodel4.fit(X_train,y_train,epochs=10)
( i, m9 c4 C7 i, Z8 Q( [
0 P7 N. m! o6 w: D& L7 r![]()
* X- Y* [; V3 j) m: B# e! N6 ?model4.evaluate(X_test,y_test)" o' j8 m% M7 n* ]+ W4 c& }
* b0 c6 t; {0 f
通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。
4 ?8 e" i: W, K: U/ I4 M+ z B) q$ M4 `+ P
尾注* r$ W0 q- Y! t; U, \4 q! A# j
这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。
: v9 d( E3 q0 e, J* ?* _5 J5 R
' u4 _5 ]9 d L) ~" @4 ]9 B: d: p$ J/ {
0 H1 ~1 d) v2 G |