使用卷积神经网络开发图像分类模型
, b+ r6 Q7 _9 V! t* t; D0 z简介8 K0 Y" p1 \5 w F. p) E! g5 _+ G# C2 C
+ x, Y0 j! b) h8 E- b这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。1 v L1 i5 b3 e* X8 L
3 C4 [* y) Q" g6 i7 e, M简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。- K0 H, g s, C! T; N0 a) Y5 v
1 e% k9 s7 g& K" ~, u
今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。( g" _# q5 P# b; a. ?
$ e; b3 F8 ~" g实施5 b b1 o% L. H
; Y8 l, |- ~- h/ A6 `$ A* o: L$ ]) \# importing necessary libraries# U. i: |& P8 _0 U1 l5 v
import numpy as np
1 S9 g& {1 a$ M$ ~import matplotlib.pyplot as plt
7 |' p2 M, D( Y: @%matplotlib inline* E* h0 e7 c0 Q5 ?6 d
# To convert to categorical data8 \! Z+ w# l6 g, i
from tensorflow.keras.utils import to_categorical0 d4 y' h( Z1 o- z' g8 q
#libraries for building model
, g @( J; L" l( [7 Tfrom tensorflow.keras.models import Sequential
2 s8 y$ i$ m6 u5 Yfrom tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten+ K% e! R; `/ Z1 ~7 B8 X
from tensorflow.keras.datasets import cifar109 c& ~- L3 B& m
! k$ V2 _# c' t0 v& K' M) ^) E
#loading the data2 Y( p+ R5 [. ]6 g$ Z
(X_train, y_train), (X_test, y_test) = cifar10.load_data()( y3 {5 B+ V! V* ^
& ~' ^/ k6 w- V
探索性数据分析$ m' P+ o( `5 \: i9 v
#shape of the dataset
* g; I7 \0 h( F) b0 zprint(X_train.shape)! H' E6 n. S+ M: o: A) Q2 N: p+ E
print(y_train.shape). V9 s! F: g3 T! w3 O2 n
print(X_test.shape)
, c- X# r% J- e' p+ x5 f" z6 s# eprint(y_test.shape)6 ~/ ?4 Y, `: h4 `
) ^6 E/ F3 T; I) g$ u S
![]()
) D8 ^1 a3 b% i. Q* E我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝)* Y9 R0 S& }' G: E
#checking the labels
6 [ r X7 f2 [4 J N) U4 w( Cnp.unique(y_train)" D6 i0 B3 a+ y* e1 I
3 t. J5 s# j/ \. Q![]()
, D7 c$ @; m' S6 x! n& y1 Z#first image of training data: S x7 k* E6 c1 N# Q& ]; s' x
plt.subplot(121)
& A7 U1 d; W5 d3 V k: aplt.imshow(X_train[0])% D( O+ F _ p m' o% o
plt.title("Label : {}".format(y_train[0]))& z% ]! t$ Z: c1 v
#first image of test data
0 m- `' \' C0 l. Z8 Iplt.subplot(122)
3 S" G/ m( s$ Mplt.imshow(X_test[0])
0 H q& A3 |& {0 j1 ]plt.title("Label : {}".format(y_test[0])); j7 l( W; L8 c7 @
9 h: A: c0 |7 `! b) P) X" N, \ * V0 O. d6 u5 [" ]. } E. F7 U
#visualizing the first 20 images in the dataset7 @( @$ n) X1 w- Z
for i in range(20):
# t/ \% D( D- I8 |$ s2 ` #subplot
1 C& N7 m6 _* v& T plt.subplot(5, 5, i+1)
6 A2 S% w, c/ Z4 s/ U0 f- q # plotting pixel data
1 b x5 u# R+ H( d; E0 `0 Z plt.imshow(X_train, cmap=plt.get_cmap('gray')), e7 C8 Q. M4 r. q9 I
# show the figure
% d7 j6 `6 E u: cplt.show(), t# v3 r7 u6 {3 M8 t9 x" u
* @7 w: F. [' K![]()
. ?% [5 k! A, C% z! T预处理数据对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D 9 s& `. l1 Q5 u$ @/ y' m1 O
# Scale the data to lie between 0 to 17 i( f& Z" ~$ @( ]. d. S6 e
X_train = X_train/255. u' H. |, K' k s
X_test = X_test/255
+ Z& v6 s+ ?8 W1 T; Wprint(X_train)% p6 m" {- ~& O1 E- \' f/ C
: V. g* `: i$ u( F! H) b" S2 X
![]()
! q* p7 Y+ d' f/ C2 j#reshaping the train and test lables to 1D3 i( M8 z* k( h) W6 a- L6 f7 G
y_train = y_train.reshape(-1,); x( C7 f% t+ t4 v. m
y_test = y_test.reshape(-1,)! \7 x0 g- s1 V K% Y! s- q, M3 x
% U# i# r! z; \: o0 K D我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。" _" B# g( S2 F& `/ K9 ]& s" y
模型搭建正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。
; J$ x0 u1 o0 A9 o& h% Tmodel=Sequential()
5 C$ X' P- T+ b8 M% h#adding the first Convolution layer7 Z0 `% L; m+ |9 F" r& S9 u
model.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
0 y& U7 M1 C. h4 _#adding Max pooling layer, q, W, N/ m! z7 M0 I
model.add(MaxPool2D(2,2))
5 o. g& H. ?+ Y/ ?/ e/ [9 V4 l) K/ ]2 `#adding another Convolution layer
* Y( {! r. {5 A' o2 Zmodel.add(Conv2D(64,(3,3),activation='relu'))
! U, x& A# N6 \* s6 D7 V; Umodel.add(MaxPool2D(2,2))
/ N/ C4 a( k; K5 H# Hmodel.add(Flatten())/ {& b- b, K; D
#adding dense layer+ i* }1 U! a9 j; X! V+ M4 _8 ? Z
model.add(Dense(216,activation='relu'))
5 d, I) N3 ?3 R& H#adding output layer
/ h1 a$ Z/ Y' `" rmodel.add(Dense(10,activation='softmax'))7 a6 p9 ^/ y, \; r9 M5 W' U6 C5 x
/ X' M: y( C$ M- O9 e2 I
我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。( q8 d8 D5 M6 X7 K9 w& T: s+ K
! _! ] A* L. B; E
接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/; t7 i+ ]2 a! I# c3 N1 D
: v0 M \2 u( E3 l* \8 {: e4 ]然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层8 V( \: `1 E- R' X
& ^9 t5 g' U3 @3 D9 c
在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。+ k+ @+ [( y2 J2 U. K& p
% N7 M' ~9 x% n- z7 `
最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。3 s6 {# ?( D/ t0 q+ \& r9 W
# b% t- K6 H3 W4 @第 2 步:编译模型7 M0 H. A3 A7 I# T. }- C+ y3 P+ x
model.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
$ C+ j; A( ~) ^& p5 ~9 m) f: I4 X' Z; O' _. R2 {) Q' i8 S" Z
第 3 步:拟合模型model.fit(X_train,y_train,epochs=10)5 N$ n0 s- o& d w) Y$ p
![]()
5 F- z$ J" G' K8 ~! g. F9 Q4 ? 3 P \2 R3 v. K- J. d8 ]
如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。
: H& J' {: ^5 q$ m: l6 ]第 4 步:评估模型model.evaluate(X_test,y_test)2 o& ~8 j7 {0 B3 b* C8 @
![]()
- m4 ] W0 p1 G+ B6 H
3 ]% E* Y% q; s) }# M* i/ `测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。
5 J1 ]. B, p9 U1 s第 5 步:进行预测% W" D8 S% W+ ~3 l2 J& f6 Z4 j
pred=model.predict(X_test)4 \: `& E0 b0 H1 k7 J% _
#printing the first element from predicted data
9 K+ R3 R) M2 g; sprint(pred[0]). u( O& U" j+ E b2 h1 |
#printing the index of / a( l8 v( ?) _. u* @: }
print('Index:',np.argmax(pred[0]))) E0 J9 P0 I. |$ ?9 D
* Q3 ~* K. u9 X$ t% V8 H![]()
. @1 ^' r9 R$ I/ ?; r% r0 I$ s0 J5 c% J1 @# n4 [
因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。 将预测值与实际值进行比较以查看模型执行的正确程度。 在下图中,我们可以看到预测值与实际值的差异。 y_classes = [np.argmax(element) for element in pred]
* i% M2 c4 j* a0 ?+ ?print('Predicted_values:',y_classes[:10])
6 j; K1 k7 c9 U2 j5 N kprint('Actual_values:',y_test[:10])
; F; S/ u- H) \: k" q
) g5 j# l9 x' }![]()
+ V$ t7 v9 y% g& ~/ \- @# j当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。 在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。
' r( r0 q$ T: [" L$ kmodel4=Sequential()
; j6 X8 ]6 ?1 s" \0 n5 m5 E#adding the first Convolution layer9 y' w0 l+ x4 q4 c, ]
model4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))8 _ f( q+ g: m# Y
#adding Max pooling layer" M( a3 j$ K% T" T" z
model4.add(MaxPool2D(2,2))5 T7 p! I0 n9 G2 W
#adding dropout
6 D( }, ~% Y4 k6 I5 h3 c7 Rmodel4.add(Dropout(0.2))& D" r, r+ q6 ?' l4 [+ @7 Y' ^2 {
#adding another Convolution layer+ i! f s0 R, e+ O0 {& x
model4.add(Conv2D(64,(3,3),activation='relu'))
2 R. S8 B' u/ Amodel4.add(MaxPool2D(2,2)); q0 r7 a4 B: y9 \' E8 e
#adding dropout/ j! F9 k7 i% @9 A( [) d" R
model4.add(Dropout(0.2))
, U9 J+ [5 b9 i9 D: y- ]( rmodel4.add(Flatten())
, s( \: f. W2 V; h+ N#adding dense layer
- u3 B* t+ Y, ]: U; Omodel4.add(Dense(216,activation='relu'))
7 w1 v% }/ ~9 I#adding dropout. U% T9 X! y0 s; T) l5 b! i
model4.add(Dropout(0.2))
* [) @6 p# I- w$ `/ N5 @ s) ~#adding output layer* G" e2 Y. A' [$ }
model4.add(Dense(10,activation='softmax'))
. B+ ^" S6 }8 l2 zmodel4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])( O8 z' f% j; ]8 u2 y
model4.fit(X_train,y_train,epochs=10)
. j- R. u% t m, J$ f* L, ~
3 ^1 d- t g0 H& _1 R. N # F5 q5 P% U# @! u
model4.evaluate(X_test,y_test)
% E1 Z& T3 e k2 U$ T![]()
+ E! ?0 g) ?8 _$ H( d通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。
/ C! D3 l3 [' b! \
& M- c( f+ @! T' {) p. ~8 d尾注! O- R i) y7 K" @- d; }
这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。
s. k2 w( T" R. N! O
2 K" b( Q8 z& M4 K1 Y0 Q N A# q
* g* {! z% @3 A6 y) e7 B. [" o1 J j- Q1 Y" E
|