数学建模社区-数学中国
标题: 使用卷积神经网络开发图像分类模型 [打印本页]
作者: 1047521767 时间: 2021-10-29 17:31
标题: 使用卷积神经网络开发图像分类模型
使用卷积神经网络开发图像分类模型7 n* a# Q& }& a
简介
2 ^- ~: q6 z) L8 X- S: S2 {) B5 C" q4 z
这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。
% l( ?& |# i n2 Q% v7 x9 A/ C' l" d3 h' r8 n. m8 {3 u! ~( t
简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。' Z+ l$ \5 L2 E- @9 [" [
2 l8 d) Q4 V2 I* q, d2 e9 O
今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。7 X4 W; C6 N1 U: y+ S% d2 a
* i! A. |8 Z0 g- Z# Y! U7 N8 I实施5 b3 `2 [7 y# I, g1 \
* p" A4 [% u. Z$ o/ I
# importing necessary libraries5 W7 I4 P/ k8 K! l0 @0 v, E
import numpy as np
7 t1 J! l5 [) O. `- A. Z. nimport matplotlib.pyplot as plt
2 k! {6 ?6 E/ b%matplotlib inline
1 p8 ~( A- R4 U& z7 Y# To convert to categorical data
% y* j/ a' x Lfrom tensorflow.keras.utils import to_categorical
, M! U% j* v; w; E8 J( y#libraries for building model
$ W& m% _! c( `8 H: E+ _/ Gfrom tensorflow.keras.models import Sequential, a9 _: }5 d. V8 T* {
from tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten
- v S6 A. y4 n* E k& u4 x' rfrom tensorflow.keras.datasets import cifar100 O: E$ V6 r$ h O% ~
! }: [: _' M: C u3 R#loading the data) E- J1 T- n, f& T g+ \
(X_train, y_train), (X_test, y_test) = cifar10.load_data()5 Z& i, L" h( b
0 u$ u8 @$ k3 R; m* k探索性数据分析! S3 y; _6 Y3 m) S: P! u. E
#shape of the dataset9 m$ s3 U6 C; k, h% x% q f ?& {
print(X_train.shape)
V2 A' X- y" l3 c# f {print(y_train.shape)9 J5 z2 A2 X* x) }1 J
print(X_test.shape)$ f2 y) ~" q! H7 ~
print(y_test.shape)
0 s `0 C+ D: M" d+ R1 s! ~9 B1 \2 h. @" A* d3 C! P5 H
& i: A) z, x! A( f2 f
我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝)
4 X2 I: x. I; G9 r#checking the labels ! E) E3 H9 I4 \' T! f
np.unique(y_train)
$ W7 `+ a: F( K4 W) V' Q9 d- ]
: v2 `' ?0 Y5 m/ [6 \
1 n2 a1 W4 B, `( v- I7 }+ Z% W; K
#first image of training data: X1 @' u( x9 @6 r. [3 l5 `! J
plt.subplot(121)7 F% u$ m! O; `) ~0 L4 C3 x
plt.imshow(X_train[0])
% S+ C. w- R$ l! H( n# A: d/ rplt.title("Label : {}".format(y_train[0]))- ^- b6 S- h1 M) l' X/ v
#first image of test data
1 a) M; ~ |& c$ S& H: J2 ^. x- Zplt.subplot(122)! v4 _% T( ~( u }; u' L
plt.imshow(X_test[0])
2 s4 V/ q1 \ E W4 w/ {7 ]plt.title("Label : {}".format(y_test[0]));
+ Z. f6 s7 n5 a/ J' S3 i1 L* ?! K6 [ K g0 H* q

4 Z* U2 m Q) d4 T0 z, p9 t#visualizing the first 20 images in the dataset" p( M' f y1 }: q6 j% K: m/ J' U7 e
for i in range(20):# K3 X: z, O6 A5 C( J& ?. i
#subplot7 D# r6 s& u" Y9 Z m: e- R/ n
plt.subplot(5, 5, i+1)
; |9 s+ i1 A8 Y) h # plotting pixel data- \0 a+ D2 S/ }* ?, S! g0 J$ l
plt.imshow(X_train, cmap=plt.get_cmap('gray'))# q7 I& K$ i5 Q) \, D, `. _
# show the figure
2 K- f4 e- o4 f. ^plt.show()& A# @3 N# a' e' H/ i- X
" C) k) |( M8 P. z
9 J( H1 i' ~) a& S预处理数据对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D
% R+ u& l3 b5 Y' ]: Z I
# Scale the data to lie between 0 to 10 Z) o, ]& _+ B9 `
X_train = X_train/255
7 n7 e6 ^, P9 x4 [& r fX_test = X_test/255
7 [. Z- r! }- {- y! Sprint(X_train)8 ]& i7 U7 \6 Y) w+ A
. w) M) [: _6 ?& q& i
8 ^4 @& M4 V0 B/ M1 ^1 j
#reshaping the train and test lables to 1D* w' B8 D9 d. n# I
y_train = y_train.reshape(-1,)
; A2 j% L4 V0 v2 py_test = y_test.reshape(-1,)
/ {, M1 W) s, E$ c) X8 g/ z& f' L) u, S8 N
我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。4 \9 d9 q/ H. ]* `5 l
模型搭建正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。
# h7 P$ K7 \4 j% K3 G5 A, F1 `model=Sequential()
/ x. S; X# A( C#adding the first Convolution layer
. M- D+ }3 H- r6 q1 Smodel.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))& r8 g8 `6 |0 X9 U7 A$ t/ [+ t) j; e
#adding Max pooling layer
5 C0 t1 X! E) G1 z) Hmodel.add(MaxPool2D(2,2))+ \! F; Q6 H" @# L1 O
#adding another Convolution layer
" Q* |: M* k% c. P/ G) j! ]model.add(Conv2D(64,(3,3),activation='relu'))
- g6 [' K0 l7 m$ Vmodel.add(MaxPool2D(2,2))
& T4 s3 P/ u" X: T. [* ~model.add(Flatten())6 a+ a. W: _ f3 Q6 x+ ]
#adding dense layer
; a' L( I2 {* @1 ]7 o* c; imodel.add(Dense(216,activation='relu')): W6 O: y4 ]5 f0 W& Q: C
#adding output layer5 p9 H3 u. Y+ b/ Z- s
model.add(Dense(10,activation='softmax'))" o6 W$ S. u* ^, s8 z; i( J0 w
5 Q) F6 h! B. C6 T我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。
. j" c8 t2 b# a. s- p( X7 c, |. [+ F
接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/
! n$ j+ q3 |( H ^6 V/ S- w1 U5 w
& {6 b2 |, j8 l2 w然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层
( r1 z8 \" e/ C0 f/ b, m
3 w# q) Q: b/ l! M9 ]7 r在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。
6 L. a1 |& d% f5 F& f" J" ?9 h5 G Q* ~5 T$ z2 f
最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。
- r4 Z S b. N; X7 w# ^
, B8 H" X, B( u, P! n第 2 步:编译模型
$ B, u8 V4 Y* J5 Lmodel.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
$ I& p# h8 u7 {2 b/ } G# ^
$ C% }. ]4 m9 i+ i第 3 步:拟合模型model.fit(X_train,y_train,epochs=10)
% F# \, k* z- k
6 |0 L1 j/ r5 c. ]9 s4 d) ~
; K% n5 b! l% x* N1 j& a6 ]
如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。5 N/ E6 Z8 L0 l* f K
第 4 步:评估模型model.evaluate(X_test,y_test): L1 w p. H K1 h3 c

0 M/ Q1 |- }5 q1 e3 S$ g
% J& t. W! v1 S; Q/ |测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。
% i/ a( \8 u8 v第 5 步:进行预测0 u6 T; J6 A+ J8 S
pred=model.predict(X_test)
0 Q7 P+ q3 O s7 C/ ~ i#printing the first element from predicted data
- { i# i4 ]' o) gprint(pred[0])( T4 d6 b/ H8 l, a
#printing the index of
% j; K0 k8 ^4 {$ h: H; o3 Tprint('Index:',np.argmax(pred[0])), v3 C+ H0 P- {$ ]1 ?6 {- x! o
) L" Q" m$ l7 @! ^8 x/ H5 \1 m

. I5 n1 C" e! Q2 H8 t7 E5 q7 ^. P! w4 b$ C% B/ B
因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。
将预测值与实际值进行比较以查看模型执行的正确程度。
在下图中,我们可以看到预测值与实际值的差异。
y_classes = [np.argmax(element) for element in pred]! b0 G i. D$ ]3 D" _8 N6 {
print('Predicted_values:',y_classes[:10])
$ C% `, A- u) d- yprint('Actual_values:',y_test[:10]): ~% x0 k; h* {' Z
2 r0 g$ J$ x; f' I

' d! o/ x& d( U7 h6 L$ Y& m3 o当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。
在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。
$ o, M% g% t, [$ ]$ l6 k' mmodel4=Sequential()
7 @7 q' n/ \! P) u5 L, S. Y#adding the first Convolution layer0 T7 q5 @; T$ e+ V
model4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3))), B: p2 \, `' `
#adding Max pooling layer
8 U! {, n8 U$ @9 `9 k% Hmodel4.add(MaxPool2D(2,2))0 b$ P# q7 I: u0 N7 F. R
#adding dropout( ~$ d) m) V/ W" l' ?1 X- V# {$ n% |
model4.add(Dropout(0.2))7 q% J, F; Y! _- h2 g
#adding another Convolution layer
" ^4 R0 i6 N" ~; ]$ Z# |+ u7 s% Umodel4.add(Conv2D(64,(3,3),activation='relu'))# h( ~; J6 [( U2 p
model4.add(MaxPool2D(2,2))1 C# k5 f& D+ e
#adding dropout; G0 v1 y& j2 N* v( R* E! C" a
model4.add(Dropout(0.2))
# g, E5 h4 K! Pmodel4.add(Flatten())
% m/ o! b9 u) y% f#adding dense layer
0 ?# u8 {8 [2 K- U1 mmodel4.add(Dense(216,activation='relu'))! z6 `; s6 y9 a: k
#adding dropout
) Z0 V% q- ]$ ]% Fmodel4.add(Dropout(0.2))5 g) \ }6 ~& t8 _- ~
#adding output layer7 k6 C' N% G! D! m
model4.add(Dense(10,activation='softmax'))
: V* C/ ^& j* i; _% S1 smodel4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy']) j. d* v+ L* K, O+ L. |) M3 R B( \
model4.fit(X_train,y_train,epochs=10)
. H# `1 ^ b$ ~ C6 B) H
' s, W' G5 T( ~9 \+ k. G
; l1 [' G$ m) ^) F1 k3 {! R2 M) q
model4.evaluate(X_test,y_test)
2 a [* q% I3 l0 g1 K7 i
/ p1 |3 Z# y9 W: U# c4 o
通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。
' y3 x) m( O, N5 c
, S8 M- R$ X1 {' X" _$ E尾注# U" n: D( F/ E0 o+ |. L% ]
这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。
% Z l9 M% F( \% b0 V7 Z# t1 b$ \3 a8 Q' `3 L* t/ ~/ Q
9 h c1 Z; ^ h2 k
; S! O& b4 ]6 L+ _
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) |
Powered by Discuz! X2.5 |