使用卷积神经网络开发图像分类模型
& Q, a. W, @3 C1 H1 o" F简介
7 ]4 l1 y$ R. [; Q7 Q" p2 s6 |) U% l3 `
这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。: Z- J) O2 u# q
; C4 n+ X/ }3 _- L6 C
简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。
+ y1 m% ?% _- Q( _5 G0 U' ~) k0 P, B, X7 ~6 C
今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。
6 Q/ Y0 F( y$ Y4 K+ ?+ Z0 o4 D) v8 p5 u" j
实施0 G2 e: R, w( J+ Q" d! h
2 ~5 Q$ j5 k4 y# importing necessary libraries
" k; N" a2 y: h7 O2 Vimport numpy as np
& M- A5 W L/ g3 `6 V. k; G3 v) Cimport matplotlib.pyplot as plt* ?+ p5 E+ h5 J- }
%matplotlib inline' g) d. P2 k: p7 C# P; E
# To convert to categorical data1 Y2 z0 }8 G/ k. |9 G; O! X: ?
from tensorflow.keras.utils import to_categorical
# \7 u% ^% N: a$ C% u' V: H#libraries for building model
; [) f! S, b. e6 }from tensorflow.keras.models import Sequential
) W0 y. W% N2 w" ?from tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten! y2 D h# a& @: \7 ?
from tensorflow.keras.datasets import cifar103 [: t' z! Y' q. p& d& ?$ T; y( D
3 J! \8 V, n9 y, g
#loading the data
' a: n* p& ?7 G9 _! _$ Q) Y9 P(X_train, y_train), (X_test, y_test) = cifar10.load_data()
) U A: k' @0 V' O" C1 S
- z9 |3 ~' s/ L" `探索性数据分析" Q/ J8 y% [$ H" J7 S7 k
#shape of the dataset
. ~( S7 P |3 g+ e9 w4 p% Z Aprint(X_train.shape)
1 `1 l% y t3 ^7 Y) s# f0 \print(y_train.shape), ?2 q( H+ Q9 v5 D
print(X_test.shape)) e7 e+ N* \" {
print(y_test.shape)) ]4 a+ }/ V9 r7 H- t4 |# {5 K- `. T3 |
! E' E0 R3 k F8 |& ]/ l, K 8 e" J/ W* X& T( r' I4 B
我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝)5 F0 E6 n/ r( v8 h6 d
#checking the labels p" D5 d. j! V4 `' U( \
np.unique(y_train)
1 R$ m: F$ l( l' h4 x: x- b, `4 Z6 S: F) Q8 x* V5 P4 H- Y7 w
/ F! i$ _" z$ u6 ~7 Y7 k- l
#first image of training data
; L% ? Q/ g; Z2 xplt.subplot(121)/ t$ q- a+ I, a/ i+ O
plt.imshow(X_train[0]) w! A, o: ~8 f& M, ^ @
plt.title("Label : {}".format(y_train[0]))
9 A, ]0 n, `! P; j# e" t( Q: g#first image of test data8 U# M1 w# f4 j! F z M
plt.subplot(122)
7 L" ~+ n; w( s" G: i8 ~- m( yplt.imshow(X_test[0])" P2 `4 C3 l0 F7 ^: ~% i7 y
plt.title("Label : {}".format(y_test[0]));
$ |* P# p" Y" J- \- w" z$ P1 A9 @7 b4 e/ g
+ U6 d* _8 w7 v) @0 _" O/ W
#visualizing the first 20 images in the dataset5 e+ ?0 J% [% S# Q: e; S
for i in range(20):' ]! m8 v& j' ~ X
#subplot z0 q" k9 z" I
plt.subplot(5, 5, i+1)
6 S E0 x. u8 |/ D# n! r # plotting pixel data; ^# c" `4 N# E: b5 l" k
plt.imshow(X_train, cmap=plt.get_cmap('gray')) o$ U' _5 G. C# W, z9 `4 j5 Y
# show the figure
; K- {: z/ T/ R2 ~plt.show()
7 F, w3 _& ?# C% Y7 C* v( Q; B
4 |9 l: M* T3 Z z5 D# T 4 I5 e! z* v( J! S. Y+ a
预处理数据对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D - A3 K J5 w( x! w3 P8 S6 l. h1 C8 {2 k
# Scale the data to lie between 0 to 1* c9 N9 i, W& ^3 R' j$ s8 a
X_train = X_train/255
2 l) ?: l0 b9 h7 iX_test = X_test/2559 S% O" C0 t# ?
print(X_train)
% W+ L2 R( A3 u2 V, x' X7 ^( V9 x4 A, [" S2 t- z/ j+ P
![]()
0 U8 W8 _* b: a4 I, q+ l#reshaping the train and test lables to 1D9 x4 G# e% s- y4 Z9 l
y_train = y_train.reshape(-1,) q5 {: N2 W: E c9 t. a" Q' c: V _
y_test = y_test.reshape(-1,)
+ X! @! W: {" g } P1 G7 g% k! K6 ^! ^4 K6 t7 f
我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。% n& D% I* b. K8 {+ x N# j
模型搭建正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。
; E2 E9 v- ^9 ^# l0 Fmodel=Sequential()2 l9 Z: ~9 R9 [8 ?2 H" m
#adding the first Convolution layer
* d) ^1 y+ u0 R+ bmodel.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
. i, P X! Q, Z6 a% C1 N#adding Max pooling layer/ I! `+ Q; c4 O; O
model.add(MaxPool2D(2,2))
6 {2 x- g: ? y6 z6 i8 W7 R#adding another Convolution layer0 }3 @6 M. w4 x& Y' Q. W. n
model.add(Conv2D(64,(3,3),activation='relu'))
2 N: k" O/ C& A: p" T }& D) @model.add(MaxPool2D(2,2)) s0 i. g8 f1 ~# {* |
model.add(Flatten())) F0 d0 s. L* l% j. c7 c5 s8 [% C
#adding dense layer" V Y) v6 `7 V) Z+ q
model.add(Dense(216,activation='relu'))6 [6 Z. f: w0 f
#adding output layer7 k0 q0 H+ S# w- P$ v% z) n
model.add(Dense(10,activation='softmax'))
3 G; `7 v3 @6 e4 y X- C( Z5 o6 J- P& t
我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。. j, [! [: L; b1 ]
0 J: p" X1 @2 |1 g* ?1 y接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/2 C7 V8 W3 T8 D. i- l+ J9 ^, k
, }6 A2 h& T3 _0 g然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层# \! ?! D3 A. b: Z. z; f
0 G9 g; H3 k# @2 T. ~在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。5 _+ h* r* e' t; e
1 e$ ^- m7 J1 {- p/ L$ M; |6 A5 v
最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。: b5 W; e6 X0 S F
) T3 C. }7 K% _* x- E- O8 V6 ?0 ?第 2 步:编译模型% P: ^$ `% V7 k7 P; V
model.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy'])( f ^4 x$ \9 @. L( d
. B# s6 I2 ?- X3 K) e
第 3 步:拟合模型model.fit(X_train,y_train,epochs=10), F0 A0 t9 ?' i! p; J
![]()
4 o3 A3 ~7 x9 d . J) q) Y& [/ H) L' v* c/ W1 k* l
如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。- z* ^3 C9 q* @0 G
第 4 步:评估模型model.evaluate(X_test,y_test)5 j' A& H) i7 H" D
7 ~$ @9 p& D, m$ m8 p0 `
4 l- }2 t+ e9 C' T2 a2 }( B
测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。& V& |' N3 d8 o. U
第 5 步:进行预测* E0 d$ D; v U- w0 s4 l5 z( u0 s
pred=model.predict(X_test)
) m0 p( b2 B5 w1 H2 n#printing the first element from predicted data
9 E4 G8 O& V5 Xprint(pred[0])
. I( i8 w, ^) J" L#printing the index of - q$ Q1 H' M- ]
print('Index:',np.argmax(pred[0])); t% k' |$ u* a, J
, ^$ h) A) R0 v" z9 ?
![]()
- k/ ^" E# Y3 @# t. x) ^5 i$ c7 e8 s, R
因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。 将预测值与实际值进行比较以查看模型执行的正确程度。 在下图中,我们可以看到预测值与实际值的差异。 y_classes = [np.argmax(element) for element in pred]
) P* k4 Z5 v& V; }3 W0 [, sprint('Predicted_values:',y_classes[:10])4 L$ c/ e4 J! o' }
print('Actual_values:',y_test[:10])3 o5 r$ `0 S9 {
1 l% @* X# Q) ~& K
![]()
( }& G+ Y, j7 N' v当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。 在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。 9 ]% w/ ~! X2 C
model4=Sequential()
& K% w/ s/ Z3 Z& a. U#adding the first Convolution layer
. H- g) p3 s& J4 l3 D/ i% [model4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))" {, }) l3 m9 [. |% |
#adding Max pooling layer
; m, O/ j0 o' s5 i7 |( Xmodel4.add(MaxPool2D(2,2))
! X6 \4 r, g( V* k#adding dropout- Y* ]! Y+ |% B- W) W0 |, N! L
model4.add(Dropout(0.2))
6 { Z s( r7 {( g" }; y! M#adding another Convolution layer
5 ?6 X- i z+ k$ k& r5 Cmodel4.add(Conv2D(64,(3,3),activation='relu'))
1 G7 ~) ^: q Y, F" Amodel4.add(MaxPool2D(2,2))
3 G7 I7 a+ g- {' [: d#adding dropout
' R d$ G4 [8 |1 Q, q7 B. x# amodel4.add(Dropout(0.2))" b$ Y$ B: ]( Y C p
model4.add(Flatten())
- ^1 `" M8 R& {! P% m" l#adding dense layer8 g% |( ^1 ], X# A" [
model4.add(Dense(216,activation='relu')): f+ d" s. U% A. T
#adding dropout# M% V2 U! v( _# v
model4.add(Dropout(0.2))+ ~9 e9 l( e0 ]
#adding output layer$ p9 a0 [+ R5 y. U. n+ U3 r1 }
model4.add(Dense(10,activation='softmax'))0 f2 D6 @4 A0 `+ H/ l D. G6 T- Y7 A
model4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
* n8 D N: V7 z6 M) omodel4.fit(X_train,y_train,epochs=10)
4 A; [* D# V) b' ?' N$ N# a" ^. y4 O" Z8 ~+ y$ I
' R6 U* |1 X$ h6 ]- ~: \+ D
model4.evaluate(X_test,y_test)
) C4 [" l% l2 n2 {! ~9 W+ M![]()
, K6 t* o& e- {通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。 J3 L. X% Y3 z8 o, r8 o
- Y' H8 [0 h6 g, u6 h+ [尾注1 e/ r8 c/ A; H7 |
这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。; P. @/ }; T" n6 Y3 Y' k
2 b8 @" U9 A' c! V7 z! R- G& Z8 S
' g; i$ X, c# ?3 B2 i0 h4 L" R0 q; Z; Y @9 F& q! |
|