使用卷积神经网络开发图像分类模型+ v' {) ^: V& j6 P- w5 v+ s
简介
& r2 a: ~3 e4 ?0 W+ O) t7 R5 c7 K5 h1 ?2 H$ w9 S+ c
这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。; t! r& A& |2 \$ W5 h3 P
( S4 ]3 z1 s2 }/ C; X1 S简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。
4 l- }' a( x, a1 W4 H; n2 G) U- { k! [1 Q& D, t: n% x. [
今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。4 J1 ?% U* U* S9 E/ k5 A
2 g9 ]+ l+ q* K+ u" Z7 O
实施
6 Y. A' x4 c( }! w
3 O1 F% R9 q$ B$ u6 ?# importing necessary libraries
7 |; P* }* @/ h. n2 Z1 ^* pimport numpy as np2 P5 ]/ y( h6 O
import matplotlib.pyplot as plt
$ W$ e/ r5 v1 \8 q+ ~%matplotlib inline
' C% l) m+ ?" b7 R# To convert to categorical data* P9 O# @& Y1 ~" a9 o+ n, L) B
from tensorflow.keras.utils import to_categorical D- \' k) b" D0 U+ t: |
#libraries for building model
( }1 H$ J' n! U0 vfrom tensorflow.keras.models import Sequential
' U! l# _4 P# M" [; Y0 K9 efrom tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten
: e, ^# e- M) Y4 [/ Nfrom tensorflow.keras.datasets import cifar100 z: S- R& @' A( ]8 [, ^, }& h
; h& v% E+ `) K2 B#loading the data
# N: `7 V, K: k, R, ?; J- d$ w(X_train, y_train), (X_test, y_test) = cifar10.load_data()4 n3 I9 X; \% g6 I& g% Z2 U- V
2 V* T1 [' \3 t& z% C# M9 l2 i
探索性数据分析9 m3 i" V6 p3 U0 N; ]: O$ p
#shape of the dataset
/ Q$ |6 y6 r% L8 c$ mprint(X_train.shape)
3 E) Q/ l4 x, N) Wprint(y_train.shape)
& i% w% W) J0 Z4 Z( s! sprint(X_test.shape)
$ S) R5 l( O, ~+ y% S6 ?print(y_test.shape)
9 d+ y5 h2 e( V" L/ |
" O5 n# t2 v) s- A* G![]()
, k; v# k% B9 v [# K w& u* S4 ^我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝)
8 c4 v$ E& F! z4 J#checking the labels / W, v& X1 O7 @2 Y* F" U. h
np.unique(y_train)+ F7 O1 |7 w. H: U
; B( F% {" K1 \# F5 t![]()
4 ?7 ~" R# g3 W o4 g6 m. V#first image of training data
7 p( ]$ F& W1 Jplt.subplot(121)
. l. l! ~: ^+ f- m; fplt.imshow(X_train[0])
; H4 R& M) ~8 I4 i4 F$ Jplt.title("Label : {}".format(y_train[0]))! S9 I" Q6 K6 D+ J/ |' ^7 V0 T6 Y
#first image of test data6 C3 j+ n) c: e" Z9 m! l: _
plt.subplot(122)
4 G$ s9 E) l. hplt.imshow(X_test[0])
6 |3 ]4 K$ a! ~4 [, {) ^2 vplt.title("Label : {}".format(y_test[0]));
" E3 [% F D% b, T& l M( X5 Y1 r1 J8 ~: e. R+ x5 v
![]()
* m8 i+ z: |6 M8 ^: L#visualizing the first 20 images in the dataset
" E+ ]( ^ G) J g, r7 J6 X4 i+ M- nfor i in range(20):2 F* H) _' I9 M
#subplot
+ u6 k* Y) w* D( ?: I3 i7 ~/ ] plt.subplot(5, 5, i+1)1 ~, F. R& p0 E8 @1 p
# plotting pixel data
: A8 V! E+ w: a \" @: _% _ plt.imshow(X_train, cmap=plt.get_cmap('gray'))
! O" P/ `4 u0 M' M! |; p# show the figure1 M! M( Y( c0 N& U
plt.show()
$ O# \; R, |( P
& I' b6 Q) [7 A2 l! G![]()
/ r& q0 k I6 ^1 g( v+ ^预处理数据对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D & A U( z3 C) Z8 A5 r( N& {) w1 a* `
# Scale the data to lie between 0 to 1
/ b1 C. K9 t; I+ o" q+ zX_train = X_train/255) }9 x$ \4 [8 c1 o0 Q) r
X_test = X_test/255 l2 V& K# s, O/ F) Q' k
print(X_train)+ n. y& j" D$ M" I) f, t- J* p( u
9 L+ J5 H, x3 I. I, R" e+ Q+ u![]()
$ k4 ~: H H/ N3 l#reshaping the train and test lables to 1D
8 f% f& ?3 W; H# O" _' qy_train = y_train.reshape(-1,), C4 D2 L4 y; b& r# e
y_test = y_test.reshape(-1,)6 u; D* u+ E; d
2 s5 ?; y% u" n) l H1 l; E我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。
) L! r( u& |! [1 J2 K3 q% r% I模型搭建正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。
7 C; m* m' _( c$ S. A6 p# tmodel=Sequential()4 W- f9 [& G/ e; }( _9 e! e
#adding the first Convolution layer
1 R7 Z3 }- A+ D. H0 p! _) w6 ~9 T2 smodel.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3))) h' V+ A, w. z, p1 Z6 ~
#adding Max pooling layer; T I! W9 @& o: T6 [; Z# H
model.add(MaxPool2D(2,2))5 w: |3 T1 p; [$ J/ b: W& U0 B
#adding another Convolution layer4 L% T2 c9 q" _3 h( x& A
model.add(Conv2D(64,(3,3),activation='relu'))
9 N, ?- z" k4 imodel.add(MaxPool2D(2,2)) _) v" [$ X6 @" S- o
model.add(Flatten())
, U" \1 ]' e$ q#adding dense layer
5 W8 P8 h. R, J/ qmodel.add(Dense(216,activation='relu'))
! ?( ?# A. S0 E1 n#adding output layer
, H) f1 F' k' Y {# G' l) J7 b Smodel.add(Dense(10,activation='softmax'))8 D7 i- m1 h0 t, \
5 L/ _# @+ p0 t# H! I# F
我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。
. E9 H. g+ ~. j$ g3 H7 V& P# t3 b" K% R! A2 n: w' @8 ?
接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/
' e, }) j3 a6 s* V8 Z2 O
' b- C8 R/ l+ u: O3 ]7 g. R8 a然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层
: m! y c, L+ k1 |: Y4 W
/ a; s8 t' |( O1 @在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。
6 n+ ^& P+ ]0 I2 Y9 S, q3 ~8 h* d' o3 ~% P9 N1 H6 z* u# G1 F+ H
最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。
# d0 _/ a- J5 e2 m/ `) z; a
- t3 {) E/ |4 G+ D+ j/ X第 2 步:编译模型
/ w1 O7 P2 g% w3 L8 L) zmodel.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy']), [: }& `- Y* F% w& Y+ F3 I) b
- ~& _5 X8 f, E/ @3 v
第 3 步:拟合模型model.fit(X_train,y_train,epochs=10)" l: d2 Z2 Q7 R+ D0 d0 E
![]()
9 T. E l4 |! I4 Y8 b * e" F8 j8 J. k' `3 x
如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。
1 a9 m* z4 o( O# ?3 h第 4 步:评估模型model.evaluate(X_test,y_test); V" Y4 K7 W/ X- b
4 `! P. h+ s. W8 p# N. [" n1 m3 j
4 B x$ p. O$ X; h! Q, ^/ P测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。
3 ~8 a9 y, Q, |" q第 5 步:进行预测
9 C8 J$ p7 x1 ^1 k d1 Jpred=model.predict(X_test)
1 @& a, L4 X# `7 Q) B8 @ I7 S: L#printing the first element from predicted data6 a" s' k; W5 y9 K! T
print(pred[0])# E' A* h7 [! H1 a4 w0 }: G5 ^
#printing the index of ; F$ c+ b" Q: F# b# o( ^" u/ w
print('Index:',np.argmax(pred[0]))
1 g9 j, E$ }" \7 y# i0 H
: O; B- Z2 D, G: q8 k ; A4 T6 J3 t' Y" K3 q* x- p
1 O3 C- q( q" ?6 B. R
因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。 将预测值与实际值进行比较以查看模型执行的正确程度。 在下图中,我们可以看到预测值与实际值的差异。 y_classes = [np.argmax(element) for element in pred]
/ f( i8 m8 B' j; R. B* lprint('Predicted_values:',y_classes[:10])
3 j6 g0 _) }6 @5 U" zprint('Actual_values:',y_test[:10])6 @( ?& A2 z9 Y. F
* x" a( W$ R/ E, Q3 I![]()
8 R B# k, s& H9 u当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。 在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。
7 Z5 E5 ]! N$ ?6 n# T O8 I6 umodel4=Sequential()2 w. r: q# |. H( x; q6 N! {
#adding the first Convolution layer2 B; f- ^4 b- M
model4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))3 n& |4 Q1 _8 f( ?
#adding Max pooling layer* M, {! g1 E. [- e' `; M1 g* J
model4.add(MaxPool2D(2,2))
4 A, ^+ C& J0 V3 Z8 d, v#adding dropout1 B* K6 m# J `3 H8 S
model4.add(Dropout(0.2))
( N0 i; E8 ~ R#adding another Convolution layer
" Y( x4 c A3 }$ ~( q, U, i: vmodel4.add(Conv2D(64,(3,3),activation='relu')). I3 H3 S( |4 ^# H8 I" ]
model4.add(MaxPool2D(2,2))1 a6 V `5 ~( Y: a4 {# H. d
#adding dropout) L1 j; E* Y F- `+ J; v
model4.add(Dropout(0.2))
. r P. p2 _1 n5 M! @- V1 L4 Imodel4.add(Flatten())
. r. h) W' s6 c#adding dense layer
- N) R/ T3 X5 |. r2 k o) pmodel4.add(Dense(216,activation='relu'))
$ W9 I: D9 W2 L#adding dropout) E/ S" Y) c/ G! _: [8 k
model4.add(Dropout(0.2))0 [8 d# @$ ^* s; H* m
#adding output layer
- |" `0 _: r+ F: Z; v8 r; Qmodel4.add(Dense(10,activation='softmax'))" M1 q/ l. H; u' a* A8 _; K* U
model4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])4 T5 `7 B6 A; G4 @3 u/ j; b$ w
model4.fit(X_train,y_train,epochs=10)4 q* j8 S8 V( v! n7 o# y* r n
6 F. q) g! C# H: x
. \7 A* w+ y$ Q2 S) a0 j) T
model4.evaluate(X_test,y_test), P+ v# w, o, ^2 Q
n" s( o$ R/ c
通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。
. q% I* ~5 u2 {: I1 L4 Z! R5 L+ \$ V E! W$ E+ O
尾注2 J% B) n! a* z
这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。# {& C: D& w* M) W" F, D, e/ y" m0 U
$ k0 ~$ N0 M5 I, m3 w0 H; K T* N0 `( W9 v G8 K
% M/ q7 Z& e* @! v0 m |