数学建模社区-数学中国
标题: 使用卷积神经网络开发图像分类模型 [打印本页]
作者: 1047521767 时间: 2021-10-29 17:31
标题: 使用卷积神经网络开发图像分类模型
使用卷积神经网络开发图像分类模型$ i, f7 a' }( R' a
简介
/ B; v) A9 @* ^8 M; d: R, b' _% f4 s& D7 v+ e/ V% v P8 i8 v2 v* g" \2 F
这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。; \! {+ c w0 z! ]
9 T; z+ J4 c* i4 N' j0 c; d简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。8 N: C# f0 o0 F3 l
( _5 I, H6 d2 V8 r& v今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。# I" _6 S1 v* k" Z! L$ ?# O
6 k( Q6 n2 {6 w' x- x实施
- U; O! s0 `6 o) o. [, u2 w# G1 f* C
# importing necessary libraries6 f3 O& H$ p0 C# e8 Y) O8 ~
import numpy as np: P/ N, e( a( T! ^/ ^8 x
import matplotlib.pyplot as plt
' E& M& ~+ [5 T; t1 c0 A, A6 l%matplotlib inline# B+ h) _. ?: y9 o/ ~5 m
# To convert to categorical data
4 b4 [6 b* c! _8 i+ k2 n) q- d; vfrom tensorflow.keras.utils import to_categorical+ K0 Z. i: |4 l# C+ {- Z
#libraries for building model. s7 B! R g! K* [, E: m
from tensorflow.keras.models import Sequential0 O* Y) {" P/ i8 j1 _: e
from tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten+ }* ]5 s! x$ u
from tensorflow.keras.datasets import cifar10/ L9 o! v* X6 [$ C7 v- s9 f' v
7 E0 a# E8 d! P; B/ S4 m1 q#loading the data f+ q, t( s/ S2 A- o
(X_train, y_train), (X_test, y_test) = cifar10.load_data()- B* b" ^2 E- a
' u7 x' f5 i2 r' u探索性数据分析$ z7 e& u7 d: S, g# e
#shape of the dataset
. [9 Y, _# r$ A0 z3 G* dprint(X_train.shape). M5 `3 h w& `
print(y_train.shape); M7 z0 C. X2 W9 [) w0 r
print(X_test.shape)9 F, a/ G& _0 G+ M* W7 ?. I! n
print(y_test.shape)
% L* V- U7 n5 Q% H
! x- l" P$ |1 W* k; i/ y
l% _2 l1 O, [' W6 e我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝)
- z( [0 i9 C) E- ]* p#checking the labels ( ^4 x! k$ Q3 |9 o/ [
np.unique(y_train) s2 u+ m" K: ^$ V. i0 r6 o" R
2 X0 e& ?& f; T# O. p: O9 h
0 H- w* n z; r
#first image of training data
5 a6 z* R% X+ _- [" F8 A1 k' Bplt.subplot(121)# r* g& j1 h, l6 _' _/ ^
plt.imshow(X_train[0])
1 Q) b) z! M, Z Cplt.title("Label : {}".format(y_train[0])) N$ m7 O. h9 d8 J: J( j+ u
#first image of test data. z4 D6 l. }( [- a* P
plt.subplot(122)5 C- L+ h* }- [
plt.imshow(X_test[0])
5 J, v# S+ ?" U/ M8 o! }" @plt.title("Label : {}".format(y_test[0]));
! n1 _$ Z0 G5 g& V v* N5 B9 T5 L8 Y0 ]" ]

& y; x( Q$ O7 i3 B& ?" ?: V1 P#visualizing the first 20 images in the dataset1 \- X, ]& _9 |' c' x6 C4 n
for i in range(20):% }+ q( b) |5 O
#subplot
' D" U* p/ o0 o6 M/ j- l plt.subplot(5, 5, i+1) x% T, f! n- ?% ]
# plotting pixel data
* J" c4 V1 v" S( \0 x( E: ~4 X: w plt.imshow(X_train, cmap=plt.get_cmap('gray')), K8 |; c2 m% F6 P
# show the figure
! ~, ]% w. ]& ^0 {& c' dplt.show(). B& o8 {. G: a! b( A
- t; I: f. @) P6 T# d+ r4 E! x8 n
/ o3 ]8 A' i9 s" y& G' x% I预处理数据对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D
( l4 N! z/ F7 z% a# X% t# Scale the data to lie between 0 to 15 _2 N5 ?. t) L6 W
X_train = X_train/2552 U6 ^% e4 C* R5 v7 k
X_test = X_test/255& e+ I: s# b& a/ J. N
print(X_train), ?: M, H7 `, |- M" W4 X
% p6 c$ Y/ f$ S) a' g' E" @
% u; K! N' u$ I6 |
#reshaping the train and test lables to 1D* T1 X! O, n6 n* h& N1 i
y_train = y_train.reshape(-1,)
' _2 e/ M# a/ {1 R9 my_test = y_test.reshape(-1,)
5 G7 C# y/ {. a, f* j% s B* w; C( A4 u; s; q
我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。
( m9 @/ I( {& D模型搭建正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。
8 q4 A6 y# h( W7 K
model=Sequential()" b ]. c# P- M% |* t: w
#adding the first Convolution layer0 ~! n7 F9 v1 F, E/ a* [
model.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
1 u+ t% {' }/ _/ I o; E#adding Max pooling layer
- K1 C; \9 ?+ L5 Z2 g4 S1 {. Bmodel.add(MaxPool2D(2,2))
3 h$ K0 t6 [# k4 }) j! L& } G#adding another Convolution layer, f% E7 `9 ]& u* P2 b! n* {
model.add(Conv2D(64,(3,3),activation='relu'))( i# p2 R- @2 p8 F! Q
model.add(MaxPool2D(2,2))
. t, u3 R% }2 h9 @+ tmodel.add(Flatten())2 O/ {, p, K3 }9 Q" a/ J/ N# }& F+ h
#adding dense layer
5 k: a( h4 l! P+ ?$ J" Rmodel.add(Dense(216,activation='relu'))2 H v% _1 S! E3 W7 l/ c
#adding output layer
, L, ?8 Y6 e7 K' O* G* Cmodel.add(Dense(10,activation='softmax'))
; C/ _. x4 k3 L/ c) ~/ J
# b$ V3 [ r% J1 E我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。
0 m7 {0 q" k# J
1 ~" i: Y( J( r8 n接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/
" G5 J: Q( ^0 m+ l
9 d: J/ f/ x% \2 k然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层
8 x) j; @& ?) C$ D- j% H: |1 u" U! e3 W2 ?5 ~* {
在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。4 e: T! ^. ?& ?- ?) b& B
) y; J- \; o8 D7 H) U& j- r- K- R最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。
- ]0 p0 Y {( e$ _
/ q. {. h* n8 f+ j" V第 2 步:编译模型
* A8 U* t" }, i' }0 v2 a/ omodel.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy'])' V8 i9 D, D: f( s5 k: I# L
; `7 e* U9 \ \( a% g u% S
第 3 步:拟合模型model.fit(X_train,y_train,epochs=10)
* X5 _# c$ z4 k' Y8 w% b0 }6 Z
- o6 v% r- [) x- z
- a/ z$ W5 |- k5 B0 e$ w如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。
4 F& P+ [7 k* |. a! \9 D第 4 步:评估模型model.evaluate(X_test,y_test)
6 M3 {# Y. |( r7 v6 Y. {
7 }* J9 U& Y9 w9 q$ y: W" {3 M* |7 E" T) G ~: \) n3 F
测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。
) X& r1 @3 T% r6 I6 Z, x第 5 步:进行预测
. Z6 K7 x9 E2 V1 F0 g# D/ H/ A8 ypred=model.predict(X_test)7 b; s0 }5 [3 L' n4 y
#printing the first element from predicted data1 P3 T F2 v5 D5 G) K% j% M
print(pred[0])
, a5 V( j& o" R0 R* W' I3 U#printing the index of * T0 N6 G6 y3 U; A; \4 B
print('Index:',np.argmax(pred[0]))! F2 E! _ [- f( c3 D
@9 G5 B( d4 L6 A% y) l
6 w. d( g+ \" b: X8 z! y
' [2 S* Q6 Y& A因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。
将预测值与实际值进行比较以查看模型执行的正确程度。
在下图中,我们可以看到预测值与实际值的差异。
y_classes = [np.argmax(element) for element in pred]
H- r' l* A7 c6 f, ~- }) }print('Predicted_values:',y_classes[:10])5 Q; w3 r$ j0 Y1 ]- s
print('Actual_values:',y_test[:10])
. }) n, @7 M! E7 W, ?$ `1 f6 D- i# f) W+ D0 i1 Q
5 K. t, U# B& I9 T: i
当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。
在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。
8 ~4 S9 Y9 s+ W* Y! Smodel4=Sequential()
. Q( ~+ J5 }+ G8 |+ C' f, x: B' r1 w#adding the first Convolution layer4 n) o( ~! [, @
model4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))8 V! c# i. a0 l s3 ~
#adding Max pooling layer
3 u3 t: Z) I5 F" P- K5 @& Bmodel4.add(MaxPool2D(2,2))& T6 b! t5 ^# F A# Q# Z
#adding dropout
4 L' h" N5 k$ u# E. t6 vmodel4.add(Dropout(0.2)): w8 `6 K' \/ s& G* r A
#adding another Convolution layer
# u, H4 ?; S1 l D! L; Wmodel4.add(Conv2D(64,(3,3),activation='relu'))7 c/ \& @2 }9 s8 h, d3 K, Z( c
model4.add(MaxPool2D(2,2))( t+ x! K( T3 a# t: P0 q- s6 {2 l7 _# \
#adding dropout$ k4 }; v) ]1 J+ g& p( t& K
model4.add(Dropout(0.2))) v( Q P2 ^3 d, }: g5 x$ Q z
model4.add(Flatten()) x) }) d6 u- H" ^- r3 J
#adding dense layer9 z5 N# \9 G; B( T3 ~7 `
model4.add(Dense(216,activation='relu'))2 b% `' \ l+ M) v7 x9 s5 Q
#adding dropout
' H8 V5 e; D- j5 Z, o; {$ \model4.add(Dropout(0.2))% h7 r- S5 y- U, P4 F
#adding output layer0 G* x3 z$ o% k+ L
model4.add(Dense(10,activation='softmax'))* l' I0 N5 o; M/ j2 q
model4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
( `$ n$ D" u. s+ j/ Mmodel4.fit(X_train,y_train,epochs=10)
- L2 [$ a- b' b5 [4 ?7 `7 W# ]( [: ~ y j7 M

1 V1 A7 ~" L0 imodel4.evaluate(X_test,y_test)
0 E, ~8 B, t2 T: M9 O
/ ^) c# [7 G) a0 Y通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。0 V' D2 t+ o* n7 }3 r
* I N: S: o: b( M$ t尾注
7 T- m. k. p L2 E这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。
( H' v! `* n$ i! O! z' s! ]0 F, F% u) U! J
* k4 S W% ?" L; f. C1 i" o: L' g$ p
) L0 s, @$ M) s! s w" w
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) |
Powered by Discuz! X2.5 |