使用卷积神经网络开发图像分类模型
0 k! q. {* X. v# w简介
/ W7 F3 r$ R" V2 o( U% K+ |2 }! y
/ \+ k9 @4 o0 p$ m7 R: M这篇文章是关于卷积网络、它的工作和组件: 在本文中,我们将使用卷积神经网络执行图像分类,并详细了解所有步骤。因此,如果你对此不熟悉,请继续阅读。- H: Q) q' g! s+ r! b2 O, a
6 T$ z7 b% Y9 m8 T7 W( ~
简而言之,CNN 是一种深度学习算法,也是适用于图像和视频的神经网络类型之一。我们可以从 CNN 中实现各种功能,其中一些是图像分类、图像识别、目标检测、人脸识别等等。& q- D- F& c% r# [, d* N6 U
2 J% z; S. ^6 `0 w9 ~今天,我们将对CIFAR10 数据集执行图像分类,它是 Tensorflow 库的一部分。它由各种物体的图像组成,如船舶、青蛙、飞机、狗、汽车。该数据集共有 60,000 张彩色图像和 10 个标签。现在让我们进入编码部分。
" d. c1 W: r/ ?
7 i: \7 i/ [" ?实施
' _/ D8 d9 W! N1 _+ l5 f( a/ s: {9 ~0 {$ Q1 }
# importing necessary libraries1 t- ^. H) S" b% G6 D8 T; w, o/ l# h( J& i
import numpy as np
5 b+ N" i8 l5 I4 I, B9 Mimport matplotlib.pyplot as plt/ u/ }6 U2 O9 h7 g
%matplotlib inline
) d% @' \- @' Z; j- J1 K8 c# To convert to categorical data9 A2 ~" Z* ~4 d" |* z! I' u' k! x
from tensorflow.keras.utils import to_categorical
% \$ g5 j* ~. D: |5 J' `#libraries for building model! L+ U2 D7 s/ q& C# P# I
from tensorflow.keras.models import Sequential; I. v! u/ ]; C3 p9 L% T) Q
from tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Dropout,Flatten
8 |' I1 M8 G$ hfrom tensorflow.keras.datasets import cifar108 D, L) M1 p: v" ?# B; K" @
C. D( a3 G" ?4 ]* V$ H#loading the data
+ P, L: N% G6 @5 \; M(X_train, y_train), (X_test, y_test) = cifar10.load_data()9 }1 k" I) o3 i( J
* X* a- G2 C5 `; @ b" F
探索性数据分析
& r7 ~( ^& v9 F# |; [: v#shape of the dataset5 x U* D' s' [7 S7 f' n7 }% }: m' Z
print(X_train.shape)6 @7 j+ d+ F) P/ S& R
print(y_train.shape)
9 W, r* J2 r% L+ ~- `; i% xprint(X_test.shape)+ {. ^0 h4 q: l8 U6 z. M4 n
print(y_test.shape)
5 g4 v1 F0 w2 _) m- R( s1 X
9 O. X) j% F" U! J3 D![]()
/ Y% k8 y9 Z/ a我们的训练数据有 50,000 张图像,测试数据有 10,000 张图像,大小为 32*32 和 3 个通道,即 RGB(红、绿、蓝)+ n, v" d$ Q! |
#checking the labels & L$ d9 n; }- b$ Z
np.unique(y_train)
9 u5 s2 b) e k' R% W3 [; z9 r
r+ @4 @& e$ f& I/ a# n0 n* m # s5 Q8 F7 U. _% l! O% z8 J
#first image of training data
+ G" h0 R. p- d7 y% E1 E" a. cplt.subplot(121)9 Z+ u. f% `$ ]& t p
plt.imshow(X_train[0])
' n2 `- h6 B# }! _! O. Y: [- Iplt.title("Label : {}".format(y_train[0])); E' S4 |1 V. a1 S% B9 ~: V0 s
#first image of test data; W/ Y. ]% y. u6 S5 `
plt.subplot(122)
2 X% y0 I' b6 Q- t7 ` vplt.imshow(X_test[0])
1 ]- E1 F1 W T$ R3 q0 gplt.title("Label : {}".format(y_test[0]));
; O5 P7 H1 l* F8 L% h3 g) T, A5 b) G" K- z" u
![]()
+ B1 y" ]/ g) h+ w* [, y#visualizing the first 20 images in the dataset. i P3 u7 m6 \
for i in range(20):
3 u% b$ r% x6 k4 s) | h1 R4 ? #subplot7 O2 B. c0 E8 l1 i9 g7 A
plt.subplot(5, 5, i+1)- u4 R4 }$ e3 ]3 z1 m& E
# plotting pixel data- @" ?. }9 @, ~* h( _- Q
plt.imshow(X_train, cmap=plt.get_cmap('gray'))
! ^9 h5 @* _/ e, h# show the figure8 O+ z. M9 I2 c# U& {
plt.show() B! h/ {( I# P- q
9 P* P! \& p7 ?
![]()
! u1 M) F$ f7 i2 O预处理数据对于数据预处理,我们只需要在这里执行两个步骤,首先是缩放图像的像素值到0到1之间,然后是将标签从 2D 重塑为 1D 7 t, y: f9 T' k9 H
# Scale the data to lie between 0 to 1
. X* U. s/ ~' Y- qX_train = X_train/255
9 g O0 S( r: x+ @. F. c3 mX_test = X_test/2557 _( o8 D5 l, e4 G' d3 G5 [
print(X_train) H- y& ^, m+ _' e
[+ D9 i F+ M2 t; j5 b
![]()
. D& c( g9 D1 P7 k# a: \* j2 ~1 T#reshaping the train and test lables to 1D- V: D3 m2 l0 A% P, @
y_train = y_train.reshape(-1,)0 H1 a# Z4 n, l) |$ A
y_test = y_test.reshape(-1,), }* d" k9 c) p9 ]% C) m( s
c. h6 f! b+ p; Z& J/ f我们在上图中可以看到,图像的像素值已经进行了缩放,其数值在 0 到 1 之间,并且标签也进行了重塑。数据已准备好建模,现在让我们构建 CNN 模型。
: T! f8 G9 m. y8 n0 c3 e, b模型搭建正如我们之前讨论的,深度学习模型的构建分为 5 个步骤,即定义模型、编译模型、拟合模型、评估模型和进行预测,这也是我们在这里要做的。 $ R. {2 u- C& x# A% D [
model=Sequential()
_. b& i4 n0 d& @0 c3 n#adding the first Convolution layer
5 N0 B; M" O; j; @7 @' Mmodel.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
7 j1 N' y# o, |+ O8 N1 i#adding Max pooling layer- B( O' M6 \9 c, M( ?. t: g
model.add(MaxPool2D(2,2))$ i& T6 l X) N# _) G
#adding another Convolution layer {: }# O- o9 c0 [1 D
model.add(Conv2D(64,(3,3),activation='relu'))6 ^2 p( n5 [( Z; B
model.add(MaxPool2D(2,2))- \9 I$ h. I6 s! {5 c
model.add(Flatten())7 `0 i- |4 u% P/ c3 W5 {
#adding dense layer
' ?$ ]9 v+ X. {6 rmodel.add(Dense(216,activation='relu'))
3 z9 L2 e$ B3 V* U#adding output layer
% y. m( F0 M( G, F$ u+ @model.add(Dense(10,activation='softmax'))! d6 T$ y3 x: r7 R. n0 C' c- w
: I, }3 A+ C2 k5 I) e5 ^0 s我们添加了第一个带有 32 个大小为 (3*3) 的过滤器的卷积层,使用的激活函数是 Relu,并为模型提供输入形状。3 ~; Q! L& J$ w$ [% V. f( t& Q3 m" f
, [8 O6 c- `2 A2 E3 T1 M0 J
接下来添加了大小为 (2*2)的Max Pooling 层。最大池化有助于减少维度。CNN 组件的解释请参考:https://www.analyticsvidhya.com/blog/2021/08/beginners-guide-to-convolutional-neural-network-with-implementation-in-python/
8 g+ Y. {, l/ d$ W' A+ R: Z0 k
6 g, j) l& V) E! B. A然后我们又添加了一个卷积层, 其中包含 64 个大小为(3*3) 的过滤器 和一个大小为 (2*2)的 最大池化层$ E7 P$ P; h$ V7 T' r; h$ }
& y9 t7 x* m, |% |在下一步中,我们将层展平以将它们传递到 Dense 层,并添加了一个包含 216 个神经元的Dense 层。
1 G5 |- j& N( \1 e1 Y/ {, b5 R
最后,输出层添加了一个 softmax 激活函数,因为我们有 10 个标签。
* r3 A3 C9 |5 O' u- F, `* p8 C: u& m+ p6 I5 E# Y
第 2 步:编译模型
# T/ C# ~1 U8 M$ Y* ^6 x2 Fmodel.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['accuracy'])6 ?1 U/ j& E& J. a
: P% s- L4 y* i' V4 P9 `2 m$ ]' B' C第 3 步:拟合模型model.fit(X_train,y_train,epochs=10)
0 F9 f1 A# A$ G6 f- d 8 m% E1 N3 @' p) m2 B
! Z( S* g/ U" T( y' f5 ?
如上图所示,我们的准确率为 89%,损失为 0.31。让我们看看测试数据的准确性。
/ ?9 ~+ a, q- d( Z L第 4 步:评估模型model.evaluate(X_test,y_test)
; s) i" Q+ t5 j: d& o$ @; C![]()
; Y. Z. _% L1 f: r$ A! c7 a; h, T3 J. ~- t/ I
测试数据的准确率为 69%,与训练数据相比非常低,这意味着我们的模型过度拟合。9 h; I# K* E# ]$ ?, u! _
第 5 步:进行预测( y2 A7 b; m2 V( O& i1 F# @
pred=model.predict(X_test)3 j1 J! } y& i P$ Q0 c
#printing the first element from predicted data
" N6 ]) G2 G% M& ^; s" u. uprint(pred[0])+ w5 A% s2 ~: {- {: n1 }
#printing the index of
+ o1 f0 `; F9 i$ v* A$ V' Bprint('Index:',np.argmax(pred[0]))0 C1 R" ~/ `% q2 q; @/ `3 C
$ o: P1 H9 l' a
![]()
9 ^0 |- M7 d6 [" T9 I) j7 S$ s, k- Z, y! S4 _( U
因此,预测函数给出的是所有10个标签的概率值,概率最高的标签是最终预测。在我们的例子中,我们得到了第三个索引处的标签作为预测。 将预测值与实际值进行比较以查看模型执行的正确程度。 在下图中,我们可以看到预测值与实际值的差异。 y_classes = [np.argmax(element) for element in pred]& S$ j) U7 S; p( ^' |2 V
print('Predicted_values:',y_classes[:10])1 |9 Y, O; W$ c% h; [
print('Actual_values:',y_test[:10])
7 k1 R( x' [. u# Y1 F4 d
% G9 s. Y: G# E2 h( v. E - x' W8 T a, w% n$ I/ M
当我们看到我们的模型过度拟合时,我们可以使用一些额外的步骤来提高模型性能并减少过度拟合,例如向模型添加 Dropouts或执行数据增强,因为过度拟合问题也可能是由于可用数据量较少。 在这里,我将展示我们如何使用 Dropout 来减少过拟合。我将为此定义一个新模型。
7 ?3 u" V+ |! h) @model4=Sequential()
1 C ~" ~% z! v( a/ q#adding the first Convolution layer
# b" p ]5 N" [' t& B# kmodel4.add(Conv2D(32,(3,3),activation='relu',input_shape=(32,32,3)))
; I3 m: _, s2 c- Y#adding Max pooling layer
( N0 }* X9 B# ~$ l2 j" m/ ^model4.add(MaxPool2D(2,2))
Y" }" I1 ` N3 p7 g#adding dropout
|+ r! h7 ]2 E( _model4.add(Dropout(0.2)) }) P# i9 ~% @
#adding another Convolution layer" l! S* h9 E% h5 E
model4.add(Conv2D(64,(3,3),activation='relu'))* ^4 y% E% g. _5 T* A. t5 O d
model4.add(MaxPool2D(2,2))
( s* E- y% d. O! v) Y9 b#adding dropout
0 R: F: H9 `7 i4 c( W' I& c) kmodel4.add(Dropout(0.2)). ~/ n0 n$ a! S% K9 b# d
model4.add(Flatten())/ g9 z5 _% I3 H
#adding dense layer
% ?5 @; q) l0 ~6 P, c* Ymodel4.add(Dense(216,activation='relu'))+ @$ ^) l$ S4 G- i+ w
#adding dropout
! G8 F1 a8 b6 ^3 V, r5 f7 }7 D- Cmodel4.add(Dropout(0.2))
. H' f; C- A" q$ M7 i#adding output layer
$ s0 v, q4 R) J+ G, K# ~- omodel4.add(Dense(10,activation='softmax'))) Y# h7 g I' B+ o
model4.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
p8 d" R0 F: o) N Tmodel4.fit(X_train,y_train,epochs=10)
5 h0 x1 x4 V+ p& y. s" n+ w! k7 B$ @, D8 v
, K! {$ B" [. ~9 E N
model4.evaluate(X_test,y_test)
0 P, M6 ?4 c# u+ m. B![]()
6 ]7 I/ U6 L* y! {通过这个模型,我们得到了76%的训练准确率(低于第一个模型),但我们得到了72%的测试准确率,这意味着过拟合的问题在一定程度上得到了解决。# I, i2 T4 T7 u* |- h' F! P0 U
" F2 \9 c8 {3 p3 g
尾注
0 ^' l& [. U5 D4 c这就是我们在 Python 中实现 CNN 的方式。这里使用的数据集是一个简单的数据集,可用于学习目的,但一定要尝试在更大和更复杂的数据集上实现 CNN。这也将有助于发现更多挑战和解决方案。
- q: h4 ^ N- s* k) J" l& a7 p* h* b0 q) b4 D
" R b8 B# S1 p. N" h4 x" S8 l: M6 H, @4 k6 m; R
|