使用卷积神经网络开发图像分类模型, C7 z! U# ]* h0 G. F' h- P
简介
S0 ?* s- m0 ? o/ |" P. g) G, x6 b0 o$ d2 [* l
这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。# {" h8 v; O" A7 v6 I
$ i+ D h( _" D( I简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。6 u7 @+ W3 M1 r7 }
6 m9 q& ?& ?0 V
今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。
, z! f9 O5 ?5 @9 j/ l0 s
3 P' I) M6 D5 W+ t& U6 Q5 ]2 S b实施/ x5 s; P5 t7 v9 G2 `
0 Z+ S4 T9 `( c5 `- P
# importing necessary libraries6 O! T% \9 x' N( a8 X8 {
import numpy as np
$ N F. B; `7 F6 A2 r7 A) X( D( uimport matplotlib.pyplot as plt1 F' G* _5 M/ I- c! P Q
%matplotlib inline
5 O) p. } \5 {: O& D: Q# To convert to categorical data
: j- A# C' A% J+ X5 |$ Gfrom tensorflow.keras.utils import to_categorical
/ l3 b% j( o' Q$ h2 V, G8 d#libraries for building model
4 Z3 P7 H% X9 a: h Q" l; B+ R Nfrom tensorflow.keras.models import Sequential
& W$ s9 A/ b% C8 t& sfrom tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten& S" @( u% m- C, \
from tensorflow.keras.datasets import cifar10
+ z8 K+ l8 R; d' g- V M3 J- S; F2 k/ |1 L5 {- t/ e5 p
#loading the data
1 J9 {2 e; v( L% t! v' K) X(X_train, y_train), (X_test, y_test) = cifar10.load_data()6 t, Z9 a0 s9 w* E% d2 i3 F
* l' E# R9 r& Q: P+ {探索性数据分析3 j* \2 _9 y) s8 n& G) [
#shape of the dataset
$ S+ y" D2 f+ r0 Gprint(X_train.shape)
9 I4 {' A0 P2 @print(y_train.shape)6 F+ e* K0 Z' ^. ]
print(X_test.shape)' K& {# K4 T# Y [, _6 [* n
print(y_test.shape)
! S; {% c3 V. `5 H' n/ b1 i1 O
* L8 [% v% m4 {0 s![]()
1 V$ s7 u# @7 @7 G V2 E9 U9 w0 C我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝): g% g. ~( x% U0 e% r
#checking the labels
1 E: `2 ^' N$ ]# p- B0 Cnp.unique(y_train)
: h" O4 V1 H6 f5 f& G" S
; G7 O! }' B. b3 \! D![]()
& h( d' s0 R! O#first image of training data( V8 {3 Z! e$ T9 Z+ O" e. J
plt.subplot(121) H x. |2 [! C* B% \2 v
plt.imshow(X_train[0])
: n# W" @- ?9 J: L. O9 E/ [& gplt.title("Label : {}".format(y_train[0])); e9 _, b) y0 r9 J7 l' q
#first image of test data% S4 i! u& k [3 T" J V7 D& I/ K- Q
plt.subplot(122). q7 V9 K* |# s) P5 c' I% @! n7 Y
plt.imshow(X_test[0])' o6 g0 p! |# T. `3 F, y9 L
plt.title("Label : {}".format(y_test[0]));
7 m$ I; r' q3 e/ ?) Y8 s8 ]0 b
, w9 z- R1 |8 A' e1 T- ? 6 D, W7 ?% f8 o- k- ^5 f/ y5 F) e; w
#visualizing the first 20 images in the dataset
: }- a8 a; S" t v& ]for i in range(20):
) x' s) g# Y! a5 e& ^3 L #subplot
0 v" x4 f- e% h' @ plt.subplot(5, 5, i+1)
" I+ G8 e- K4 ~9 E4 c6 a8 F # plotting pixel data0 c6 W% A$ s% @+ _+ `' y* X$ ~5 w
plt.imshow(X_train, cmap=plt.get_cmap('gray'))# {# E% H0 z0 j) O- L: C
# show the figure/ W' J& P% E$ V( Q1 G0 q: h1 }9 S
plt.show()
1 j" G) M. F2 H
: A/ }( o9 t6 O3 E0 s# S( L ! o/ v9 Q- \7 g
预处理数据对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D 4 z. U0 B$ E. N' T" I
# Scale the data to lie between 0 to 1
- x/ e; S) n9 LX_train = X_train/2558 m$ y9 V6 q" \
X_test = X_test/255: O3 O" J& \$ G0 A6 a, W$ t2 I* M V
print(X_train)# L% S' s( T. x/ g6 Y1 G' N
# H: d, u A# @2 X# ?
* _- j( D; ?+ @( D+ |$ Q
#reshaping the train and test lables to 1D
2 C' f% q% R# F7 ]y_train = y_train.reshape(-1,)" H$ B: v/ q) ]0 y
y_test = y_test.reshape(-1,)
' m5 \8 U# R; R0 h+ {7 ]
8 A! Z* x e' m, W# Z: t! B+ I+ D我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。0 c, o" @* k* i9 g- l, v% J
模型搭建正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。 * g% E: g7 [9 m$ C" I5 t
model=Sequential()
1 w6 q! g! R$ A: ~! q#adding the first Convolution layer8 C* d% `4 A e9 k
model.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
8 @; o; g1 n$ w" a8 L6 U6 `' G#adding Max pooling layer
4 ?0 ^/ ?4 ] I, }3 rmodel.add(MaxPool2D(2,2))+ e6 B# m. i) V: J" j
#adding another Convolution layer! x) @# a% V% D2 V; Y: T% b
model.add(Conv2D(64,(3,3),activation='relu')); ^5 @% ~! V$ N( B5 l
model.add(MaxPool2D(2,2))
. {, g; }. J+ E' P" A6 l6 W) Gmodel.add(Flatten()): {9 s5 ~' ^ \& p; ~+ A( I; N
#adding dense layer
( l# I/ Z: k1 jmodel.add(Dense(216,activation='relu'))" }) [" [9 n% B+ g! c8 s/ p; M3 z
#adding output layer
1 K/ \7 ^' I" ?! ^model.add(Dense(10,activation='softmax'))! D$ k, D3 d# M
! D. r1 @0 M2 ?, v8 l3 V! o- D8 e我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。3 W% ]( f$ O: r
+ _4 }% \$ b- @* k
接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/) Y! M d! m# v- q! l
/ Q1 ?, j/ n* B- |然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层4 [! i7 [! S; \: g
0 g( q6 f( |) b4 I! ?7 {
在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。$ X/ e+ @% ~3 Q! d- x, H( @. |
( b+ L: _/ L/ V
最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。 _( E4 V' S G9 G- n: D
) f6 G! G/ x! e+ d$ D
第 2 步:编译模型
6 a7 N: R, i4 Q& t4 J& tmodel.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
; n% R- z; U" a' K) F9 l4 c0 ^5 ]1 O4 x
第 3 步:拟合模型model.fit(X_train,y_train,epochs=10)8 `1 O2 h8 S' E) X; |
: Z" T$ j' X2 C/ G+ X
![]()
1 t4 ?! U5 b3 E& }如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。
) w( Y: e5 I2 r第 4 步:评估模型model.evaluate(X_test,y_test)5 o g. V" P/ ^/ D) {
% h( H% S* s) S
6 M Z0 @ S/ ^3 X; F5 }# k
测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。( V7 P L) H7 @
第 5 步:进行预测: D& U2 O$ T+ r# @/ k; f2 Y
pred=model.predict(X_test)
. P0 d K, s7 F4 B#printing the first element from predicted data- m9 _5 e) g7 {
print(pred[0])/ I a6 I/ g; X. U" j% ]$ t% B% U! P
#printing the index of
1 G4 D' i1 |* p) b. E5 oprint('Index:',np.argmax(pred[0]))
+ m: o. o3 i* L& }% m1 U
3 g2 l1 W4 l9 v" Z1 ?6 J; p7 E" [& X ) g. }; R0 @: d0 @3 Q' O
) V. p6 `8 v8 v5 L! r3 _/ b4 A1 e
因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。 将预测值与实际值进行比较以查看模型执行的正确程度。 在下图中,我们可以看到预测值与实际值的差异。 y_classes = [np.argmax(element) for element in pred]6 s) t! e) [7 Y/ \
print('Predicted_values:',y_classes[:10])! S, M/ {7 u* v9 P
print('Actual_values:',y_test[:10])
% T& v$ x" W V
& b8 }! c, J5 S : `9 o4 F5 v# @, }+ P/ n7 P
当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。 在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。 7 H2 g! b; E! d" J$ b/ ^
model4=Sequential()
: |6 R. ]. H( I0 ^ ], o9 ?( c#adding the first Convolution layer! m7 y: h3 {* J3 m8 _1 \3 h/ D: M
model4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
8 |, N: A, a# U/ d6 |5 i#adding Max pooling layer4 [* l: A$ u3 f9 O% t0 C0 L% y3 _
model4.add(MaxPool2D(2,2))
1 q. A- m, S% e/ p: {) w8 Z#adding dropout
4 l3 Y. ?, _3 J8 M) kmodel4.add(Dropout(0.2))
' @3 A( n$ z8 M3 y$ J#adding another Convolution layer$ I) X% w' s8 |+ }: c! G; x& b
model4.add(Conv2D(64,(3,3),activation='relu')); |$ M6 x. H$ X; @
model4.add(MaxPool2D(2,2)). c) k# d) R$ D. v
#adding dropout
6 @/ ]) K- G% w! g' v. \model4.add(Dropout(0.2))) m% b3 d. i# Q
model4.add(Flatten()) q" y3 w6 A2 F3 [/ m# b- W. _
#adding dense layer9 w' b d0 @' ~+ m' k! c$ I
model4.add(Dense(216,activation='relu')): n9 A0 b( _7 y4 R) i! [
#adding dropout
6 b8 \1 ~ O1 X5 b- u' bmodel4.add(Dropout(0.2))
) x2 S& H4 J9 h: y2 @5 `& P#adding output layer- @! J+ T" I7 N# c y7 E+ V! p. L8 A
model4.add(Dense(10,activation='softmax'))' {7 A1 I3 Y; P& F
model4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
- t; a2 j1 c& T, rmodel4.fit(X_train,y_train,epochs=10)
9 V0 V* j; B4 x. p3 E
7 h! ]; }, V4 k; h& g9 i![]()
; n) X, j {' z7 t$ ?8 K) Z) }model4.evaluate(X_test,y_test)
2 q+ D# n6 k/ I; L5 K! `9 m" X2 O![]()
9 {& D% {3 K% p& c8 ~0 @6 |) w3 y6 S通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。7 I, A8 g" Z' ]" R& _ I0 H
( k. X: E: S ?- j1 }3 g尾注
# Y1 ?% h+ j" Z% Z这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。$ z/ Q8 P6 ~+ G- n) l
W1 O- t4 Z) D& u7 A5 A
% e+ S7 z7 A! u; o& B# A) ?: r+ w& e* }' p5 B
|