数学建模社区-数学中国
标题: 使用卷积神经网络开发图像分类模型 [打印本页]
作者: 1047521767 时间: 2021-10-29 17:31
标题: 使用卷积神经网络开发图像分类模型
使用卷积神经网络开发图像分类模型2 o5 T- h$ \- `' u# n+ v/ j2 x, e
简介 K3 W, |& K0 e! d* M
/ _# Z* F* _# i5 {" A$ {' g
这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。 l, k" W& q5 [0 }
1 w; R1 g$ |6 l简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。
+ b& ]" X6 ?# n$ u6 G) O0 W# w% |, w# i. l) X) P/ [+ _
今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。2 |* Z% s" B: [2 ]1 t) ?' W
. O# T& a/ i( g/ e* J/ o+ v* Q0 A- G实施
. o7 N6 p* l: f3 g
) y+ s; L/ D( j# importing necessary libraries
0 F$ H$ k* J% c7 D; Pimport numpy as np
b7 U, a N; i/ O1 v" Simport matplotlib.pyplot as plt$ k, c2 n5 J4 {) ]2 ?
%matplotlib inline$ @# m6 {' j; F3 e9 K
# To convert to categorical data
" Z$ |3 v& \4 ?% bfrom tensorflow.keras.utils import to_categorical
" W% a' A0 I# N3 e4 f4 c) A% F#libraries for building model
! m- _- g }' k; lfrom tensorflow.keras.models import Sequential
0 m/ {' n7 @+ r- z$ w X9 cfrom tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten
- s0 Q. b- @& V1 F9 m( |from tensorflow.keras.datasets import cifar10
9 f, C' \% r3 C: N6 e9 T% a, Z$ g8 N3 d* f! \, \) f k9 |' e. c
#loading the data
K; [8 P* M4 l9 p6 n(X_train, y_train), (X_test, y_test) = cifar10.load_data()
$ I! R+ Q! T9 Y5 s; W7 ~3 B( V- q3 R* J4 S6 h! x
探索性数据分析
8 B' y7 p+ _% @1 y# ^#shape of the dataset
" B) |& G/ X1 E( T1 _5 U+ _& i0 Yprint(X_train.shape)
) g5 ?( c# P6 b* d) _& ]+ D- iprint(y_train.shape)3 `5 C6 a3 `7 x `$ @- G
print(X_test.shape)
8 ?! A# l$ q0 ~2 z+ cprint(y_test.shape)
2 x7 `" `+ o5 e" s/ r# S4 P8 g6 X Q) `( k+ E

+ E% L8 [$ g, E我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝)9 t4 }" j' y; n e4 A; M
#checking the labels $ [ H: O6 i& x/ X. V# w
np.unique(y_train)+ {4 u2 x* {7 A$ {- n2 V, R: ~& g
|) A: k* u* V$ y; o2 I- {, V
. f, u9 ]$ q/ s* N
#first image of training data
1 f6 m" |2 I; Nplt.subplot(121): X" l& k7 f |7 p* A
plt.imshow(X_train[0])$ \$ X2 W* w# o# j/ _
plt.title("Label : {}".format(y_train[0]))* N8 O, b( p" Y5 |0 I( F7 @
#first image of test data
( d1 O; F/ n# {% q) r1 D* Iplt.subplot(122)
( ]* M4 }* p5 p' @# \- X! [plt.imshow(X_test[0])/ i2 d: V" J: e
plt.title("Label : {}".format(y_test[0]));6 D$ E9 R' ^$ w; Q
) d0 H% A& y5 H- V
+ ?* J' C3 x* N- N
#visualizing the first 20 images in the dataset3 k. S5 x+ z: t* I$ b
for i in range(20):
; V* T9 u' u, x: u4 m* r5 Z #subplot9 v# G. t! e9 r/ ~3 @. x: }
plt.subplot(5, 5, i+1); J9 M& B% G) F# K
# plotting pixel data
- N4 D" ?. g7 U. ]: R% W plt.imshow(X_train, cmap=plt.get_cmap('gray'))
( M, `, Z0 J6 Y. D! a1 A, j# show the figure1 t4 l; f' T1 q3 o( m/ z
plt.show()
# p4 Z4 ` t* f2 ?6 w' T- [1 t+ U; P2 l

( m* @4 I. @3 F: P! m7 d; s预处理数据对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D
: \0 l: g8 h5 ~
# Scale the data to lie between 0 to 1
# T% ]$ b/ n6 w4 j( BX_train = X_train/2555 o6 g6 }# ~: w
X_test = X_test/255
0 T+ Q. {: u, z6 N7 E1 t4 Q+ Uprint(X_train)
3 O# [2 ]9 Z. |" {: ~
2 s7 C$ z% L+ }+ m0 t7 R3 Z& F
5 Z) p2 ]9 K% l+ W& U( j7 n7 ^, n#reshaping the train and test lables to 1D
4 ?. T6 }3 x6 Q9 `4 l4 g/ Cy_train = y_train.reshape(-1,)
! y; T6 _$ q' Sy_test = y_test.reshape(-1,)
# H; V/ S |: s: m9 `. q# I1 ]1 Y& n* V4 W
我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。
* v: q' R* L1 e2 o( m! F9 ] _+ D9 k \模型搭建正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。
. L; @1 v! u; \9 o" S% ^/ Vmodel=Sequential()
) A8 y7 |7 Y% X- w#adding the first Convolution layer
6 E$ W6 g$ h$ I% pmodel.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
# g7 e1 v- Z$ Z5 P4 |6 U. D! N1 c#adding Max pooling layer. l; h; u- h3 ^) R! M
model.add(MaxPool2D(2,2))
4 [1 x7 p$ X! o% G; C. W#adding another Convolution layer# M" H# N% z- d" B% _9 X: q
model.add(Conv2D(64,(3,3),activation='relu'))& D# q- ~ _& A R- ~( I8 n
model.add(MaxPool2D(2,2))
# d& Y _0 ~5 e; }6 r$ Emodel.add(Flatten())
: v3 K$ V/ O7 P& Q. U6 v$ p#adding dense layer
) [6 O9 O- S S! O/ h+ J( Kmodel.add(Dense(216,activation='relu'))
g! ]$ ]/ J* {#adding output layer- O2 b. A7 r! r( ~" V
model.add(Dense(10,activation='softmax'))
( U/ a; K) s+ l2 q% P0 m0 p
5 y8 x6 V; u% W% A7 c$ |我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。
9 F9 F( ?% t. _( S& I2 f0 u& ~8 s0 ]0 p
接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/2 n* a( G7 T+ u; B( W+ q! _
. u) O8 u; D9 @* ]* d) w& e8 O0 `
然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层7 D& [4 o* h( e5 P, j
+ w9 T7 _) j: A+ ^9 R在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。. o; a/ h7 \3 C8 B, _5 E* Z
7 j9 M8 W! v) K6 g6 n) r& |3 M最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。0 G! n5 U4 d' @, |* E d
# x( @: h! s7 g: H3 `. @$ x
第 2 步:编译模型0 Y, w2 E3 l6 a' ?! R
model.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy'])1 R. P8 d+ ?- \6 j* }" e* W% L' |
( k U& J" U/ M, x' S
第 3 步:拟合模型model.fit(X_train,y_train,epochs=10)5 j: f- S, `- `3 o( k' p3 o9 N
" Q/ o- t0 r+ X0 j

: ^ i; E w8 I3 u; N: H+ @6 q如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。
9 L* r, S' `/ A- V* M第 4 步:评估模型model.evaluate(X_test,y_test)
% y3 W! `) M8 k( y& b
8 v2 `9 s; x% W7 } k7 C! S: v3 b
% w2 P; f$ w' U9 v- m# B
测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。
2 u @- R# G, b% m8 i% u第 5 步:进行预测$ M9 J- G. }, o6 O( b& M
pred=model.predict(X_test)- C! H( h/ ]- T. ^
#printing the first element from predicted data! A# ~5 M, f K# D7 w
print(pred[0])& |; U. {! D; ^& T" i
#printing the index of & g: z" [6 ?& Y2 I
print('Index:',np.argmax(pred[0]))4 X7 n4 B8 ]( m d6 v
- u7 c5 q3 C& T8 g2 M
! \% L9 X! M# I; W' z) ?6 x C5 W8 m6 s
因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。
将预测值与实际值进行比较以查看模型执行的正确程度。
在下图中,我们可以看到预测值与实际值的差异。
y_classes = [np.argmax(element) for element in pred]
' X7 I4 K, p5 q$ f5 W3 P3 `print('Predicted_values:',y_classes[:10])
0 d' ^9 p6 M0 ]/ l8 dprint('Actual_values:',y_test[:10])8 W) p3 H+ E( Y" [) d
& @! t) p% W9 U! a) {
: j* J# @& W/ @) d
当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。
在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。
/ d6 ]+ i/ U* G, \9 L$ tmodel4=Sequential()5 y3 W4 h% G1 {" W: Y* x, |! g
#adding the first Convolution layer
. A% {) z6 s# |3 `5 s- h* M" Q Xmodel4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3))) O' P! T3 L/ s* }2 o& t7 K1 h
#adding Max pooling layer
, c4 L+ @7 ?6 |# T. n }( [" A6 smodel4.add(MaxPool2D(2,2))
0 M, }8 {/ i: C7 q6 y, {$ j' C# v; T#adding dropout
" U" y+ a6 X3 {5 {& S1 [model4.add(Dropout(0.2))
& H4 L, L. _3 W5 N% l7 B& d1 C#adding another Convolution layer. f0 V% O* }9 e2 I; Q
model4.add(Conv2D(64,(3,3),activation='relu'))
! ~3 z$ \# I! |% P! t8 |$ |1 }model4.add(MaxPool2D(2,2))
7 j0 ^8 _3 `, R#adding dropout+ {9 G; l* r" Q4 D6 }4 {$ C f- `
model4.add(Dropout(0.2))# X. F* {! w6 S( ?
model4.add(Flatten())0 k( R0 A s5 Z
#adding dense layer
8 @0 }' G" \7 U) H# Imodel4.add(Dense(216,activation='relu'))
& l; ?$ [8 e; T#adding dropout
& B# o. O! B5 hmodel4.add(Dropout(0.2))
% L1 E2 h- h) C, e2 ]#adding output layer
6 E% U- q1 M" J- @model4.add(Dense(10,activation='softmax'))1 r: ^7 ]) f$ S* t4 S
model4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])% g+ q" k. G8 F- ?5 Z( F
model4.fit(X_train,y_train,epochs=10)( z. n; |3 X! }5 P
& `( X% B+ ^. a/ q
( p7 t* o( V# N6 k3 Jmodel4.evaluate(X_test,y_test)
- J, J. ?. }" P% Y+ H; |- ~: B
3 a1 f4 s) ]. H- H! l- v通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。
# u/ L3 r4 q$ _. y( w; s+ l
$ |1 o% E+ L3 P% }1 m尾注! [5 |6 u' B4 _" X# Z7 k
这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。. c. `# T- R8 e( t% r% O
% B, W, q9 Y/ y: ]" }3 j7 M
( M* `/ o3 T" l# s2 y6 X0 s
& }4 b# a1 P: Y! q7 e$ a, F9 O1 Y
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) |
Powered by Discuz! X2.5 |