数学建模社区-数学中国

标题: 使用卷积神经网络开发图像分类模型 [打印本页]

作者: 1047521767    时间: 2021-10-29 17:31
标题: 使用卷积神经网络开发图像分类模型
                                                   使用卷积神经网络开发图像分类模型; `! X! T& U4 O; w+ G5 W
简介. c6 F* v) s' {7 _

8 A' v+ q- F' C9 b. W# c; B这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。
4 Y% B# q) F8 P2 a1 A0 P& Z  ]5 N
% y1 G3 ^5 P/ u, X& U7 C# Y0 d& w简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。
3 M  c- e; l8 Z/ R6 h- }" b. ?
0 f* H8 M& r3 H$ ]( d0 K* n今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。8 f! O2 v" |0 |

" {4 G( _; p8 n9 c4 R  ^# h3 v: ^实施
3 u  @9 \1 q- f6 k; f
: Q9 ^- |. y' v8 B7 \# importing necessary libraries
; w( h# i; d0 `8 ?" Wimport numpy as np
7 ^4 j: \: s+ S( }: Dimport matplotlib.pyplot as plt
1 g5 o/ N, c8 P6 V, B7 q%matplotlib inline
: L+ m. T& t, B+ w1 U$ b# To convert to categorical data
5 |4 A+ ~- U, E: z$ B0 M& g5 F5 Ffrom tensorflow.keras.utils import to_categorical" m, S5 B, n3 m+ ~
#libraries for building model) b! D- z6 \9 p
from tensorflow.keras.models import Sequential
9 g& d/ _5 X5 }8 v; @+ ~from tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten
5 t/ R) M6 R' Q  k* o% ^from tensorflow.keras.datasets import cifar10
  b* u0 [, h7 v: |6 {* ^
4 z6 m/ f1 w, _#loading the data$ I0 k% T5 V" d1 O% u  a0 S! v/ C: Q2 s
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
4 g5 q% `. k% i; Q3 G& l: g$ T4 i+ h# {2 m+ G1 Z: X* ~+ P& ]
探索性数据分析+ E2 h$ S% T7 R6 c
#shape of the dataset
- U/ r5 {) r* H/ j, C( Zprint(X_train.shape)- g+ B0 `' q5 K& M, D
print(y_train.shape)
! Q' D( w6 ]/ |' ~print(X_test.shape)" Z4 q7 [' \5 q# m, y) |; W& g
print(y_test.shape)6 G% o6 O4 W9 S& Z
8 C: ^7 ]! X9 l; ^6 }* a2 v. r
6 L/ v# [# Q2 U9 X  e+ l$ j
我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝)
8 F5 d& A* J8 [1 |2 W, U0 k#checking the labels
/ A& Q9 C- S7 v2 ?$ Inp.unique(y_train)8 U5 Q& n7 Y/ }  Z. z

$ S# q# ?7 V+ r8 S' ]
& X" [- C/ _# j0 T#first image of training data; o  A5 z4 D& O1 h$ b, n5 [9 b
plt.subplot(121)
! h! a  I+ s' Z, ~, Splt.imshow(X_train[0])
7 l1 }6 @) X8 o6 T& t: dplt.title("Label : {}".format(y_train[0])); P  }, A1 M  b5 r* `: o
#first image of test data  h) s+ |" Z) @9 Z- \
plt.subplot(122)
: ]$ b2 R: Z: Q: H) zplt.imshow(X_test[0])) b  O0 l! ^/ J3 N: ~
plt.title("Label : {}".format(y_test[0]));
6 a$ \2 w+ g. q: S% r/ [3 r# O0 o4 y. e, p" ]. o

/ I% P) a. S$ U5 k  m. G#visualizing the first 20 images in the dataset, g4 k( d. b, h+ d/ r
for i in range(20):1 D6 {: D, e6 T- }4 T* w/ u) r
    #subplot
; ~6 z/ ?4 Z5 D4 I" u+ F    plt.subplot(5, 5, i+1)8 ~, Z1 r; X; ^* H9 ?$ ^
    # plotting pixel data
% @, u! C/ x( i7 _# G! H* [7 X    plt.imshow(X_train, cmap=plt.get_cmap('gray')); \4 O4 Z/ P6 e
# show the figure9 D+ d8 \+ H$ }* f
plt.show()
. S) Y* W; G; i/ F
6 C8 J% D2 P, O5 F3 Y( [# N0 S; Y0 K+ C! N( }. O
预处理数据

对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D

, m( V# J5 E0 g4 O$ u9 p9 T1 b
# Scale the data to lie between 0 to 1
  U/ _& U# m- D5 _X_train = X_train/255
/ p/ g: M6 d* c, |7 PX_test = X_test/2553 H- d% ^6 }( X; Y( X( G
print(X_train)( J# \5 t" {$ _3 l: b$ x4 ~8 S

7 U$ W  k8 I8 c& ^8 n
$ m$ g9 f" ]7 J1 U. {+ x#reshaping the train and test lables to 1D5 D6 j/ o  F! Z) H& g) Z& J$ ]
y_train = y_train.reshape(-1,)
3 }2 L8 k9 x6 Z7 r  ~  k# q# Ly_test = y_test.reshape(-1,)( E) a( d1 n! S: `2 x

" z, N: c$ r8 Z% J' q我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。
" y8 s4 Z7 c6 t4 o模型搭建

正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。


9 |& v6 r  x8 \8 P  M) Dmodel=Sequential()
- T0 z6 a# h9 B$ A7 T+ R#adding the first Convolution layer2 ~) r' u6 ]. X+ f
model.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
) [* ?0 ]& i) m7 U8 W7 U#adding Max pooling layer
% h3 L: C( B  ]# @& F! Cmodel.add(MaxPool2D(2,2))' h/ `7 B: s! t( L8 W/ s3 |3 V6 ~8 f
#adding another Convolution layer
. r1 N* F' `2 B8 k& e3 \2 }model.add(Conv2D(64,(3,3),activation='relu'))* m6 T: _& Z% s6 z  S) t5 Q$ {
model.add(MaxPool2D(2,2))! Q3 |4 E% \, m! H9 u
model.add(Flatten())
5 E# u! R  M  w0 _5 T#adding dense layer3 I$ F+ A# i7 l
model.add(Dense(216,activation='relu'))# C. d" o1 \7 ?$ \
#adding output layer
! q+ Q: s. |$ D* `* a6 Pmodel.add(Dense(10,activation='softmax'))9 T- O% o$ ~& n. p2 R9 d
2 A' D+ |6 z; _* s* w% h
我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。+ K% X1 i4 {+ E4 U

2 {8 @1 S) u- Y# Z4 l接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/  q9 R4 v6 U6 X  p( D+ d
( f; F9 v% M# u9 ?- z  h1 g
然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层
' x: _9 q- F& P# q
5 m/ ?0 w  R  U; X. j" }' x  g+ C, w在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。$ i) k) |4 b' I$ j# a

1 D: r7 y8 i. `8 O$ k2 j最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。
& R! M* h8 ~8 _1 V, y* C" @
# {/ X& |% O' d( t9 e: w4 i4 t第 2 步:编译模型8 \: p) c- r- ?7 f1 }
model.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy'])6 K! r# W# a7 M  o; z
+ \8 H5 s) [& T' H: Q4 t
第 3 步:拟合模型model.fit(X_train,y_train,epochs=10)6 u" x% ]- t* a! p) H

1 |4 c6 h& B. @. t" Q
9 G- B6 l2 w3 S  _如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。
  i9 K. V# z6 P+ @第 4 步:评估模型model.evaluate(X_test,y_test)
, d, ?8 M" H: Q1 w% D- f( B' @8 O7 y8 f/ h: h( r
1 c* k' _& p7 d4 h8 N3 I
测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。/ m# A# z, x% {" e) K
第 5 步:进行预测
# m$ V. w, o' D+ G$ Epred=model.predict(X_test)
4 X! h' G' m% B' O# W8 B. q#printing the first element from predicted data* z! B9 A' A  u: r3 E- o  y
print(pred[0])
1 S7 J- {. Z! J1 ^+ B( P5 p#printing the index of : {8 W8 d  N  ]1 {% e
print('Index:',np.argmax(pred[0]))3 c3 U4 ~1 l! S5 S) u
) ^) ]4 J! r9 z) W& a8 s# M, s
/ ]  ~+ |* `+ L7 H4 x
6 Y/ s$ D. T/ O6 F

因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。

将预测值与实际值进行比较以查看模型执行的正确程度。

在下图中,我们可以看到预测值与实际值的差异。

y_classes = [np.argmax(element) for element in pred]
9 _  q& G8 ?' Aprint('Predicted_values:',y_classes[:10]); ~) B; v1 I2 g- ~: y0 y" o, ~
print('Actual_values:',y_test[:10])3 M  c. f6 Q: D3 |& r% {

9 A( V( k& @7 m$ X& q6 t* @2 H; \! ^7 X

当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。

在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。

$ C2 i0 a: x" ?6 C9 B2 k- S
model4=Sequential()4 J% @& Z' s3 e; X( Q
#adding the first Convolution layer* x) C# }5 a6 G; P
model4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
/ @. K& ?  `- i; l5 ?+ E2 P7 y5 v#adding Max pooling layer
9 r( f7 N3 m* H* f2 x; c1 umodel4.add(MaxPool2D(2,2))( T% @& F5 s% q+ K1 }
#adding dropout' S( I* R9 q! }& I. J6 I4 r
model4.add(Dropout(0.2))8 F! M# N; p5 J$ C: o# I* |: _
#adding another Convolution layer
% Q6 y. g3 M! b5 imodel4.add(Conv2D(64,(3,3),activation='relu'))
) |8 ]- H8 u1 mmodel4.add(MaxPool2D(2,2))
- f2 {; k1 x5 w2 f, V, z#adding dropout
4 @1 [2 r2 C; d0 Wmodel4.add(Dropout(0.2))
) N* v2 d1 _2 {/ f; ~6 y; dmodel4.add(Flatten())
" J( [! ]0 k' u# v, r' w#adding dense layer
; ?3 ?6 o% t  K$ mmodel4.add(Dense(216,activation='relu'))
; L( a& N6 V$ @+ e% r) A#adding dropout. x7 p9 q) B; v+ w  D% Y
model4.add(Dropout(0.2))
2 F+ p( {/ C: t& H: q0 Z$ X2 E#adding output layer) V, p; ^$ {& y: a/ V
model4.add(Dense(10,activation='softmax'))6 ]4 L8 c! _& b5 X2 S+ {. g& _/ F
model4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
) ]* Q9 {! i+ s" ymodel4.fit(X_train,y_train,epochs=10)
5 D1 l' o  b# L, `* N
; ^" Z% X. V: o, a) @/ W
0 }' ]  J0 ?# w* F. e) Umodel4.evaluate(X_test,y_test)
5 j1 U: j8 `* A" \7 N. L0 Z0 V3 y3 O9 `  C/ S; j/ P
通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。5 x9 G! ]. d! c, _

) W9 V4 s  _4 I  H尾注
/ Y, z# C) ]( Q0 ~0 A: V这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。
+ m! E$ F4 r$ \  M! W9 ^2 S' J. ^- X! J4 W; W

0 g' a6 }! X, F# i2 i, G7 J
9 N! r+ v/ F, U1 I/ D




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5