全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 数据分析与数据挖掘
1287 0
2020-12-18
使用Python和Keras创建自己的图像分类模型
您是否曾经偶然发现过数据集或图像,并且想知道是否可以创建一个能够区分或识别图像的系统?
图像分类的概念将为我们提供帮助。图像分类是计算机视觉最热门的应用之一,也是任何想在该领域扮演重要角色的人都必须知道的概念。
影像分类
在本文中,我们将看到一个非常简单但使用率很高的应用程序,即图像分类。我们不仅会看到如何制作一个简单而有效的模型来对数据进行分类,而且还将学习如何实现预先训练的模型并比较两者的性能。
到本文结尾,您将能够找到自己的数据集并轻松实现图像分类。
开始之前的先决条件:
Python编程
Keras及其模块
对图像分类的基本了解
卷积神经网络及其实现
对转学的基本了解
听起来很有趣?因此,准备创建自己的图像分类器吧!
目录
影像分类
了解问题陈述
设置图像数据
让我们建立图像分类模型
数据预处理
数据扩充
模型定义和培训
评估结果
转移学习的艺术
导入基本的MobileNetV2模型
微调
训练
评估结果
下一步是什么?
什么是图像分类?
图像分类是分配输入图像(一组固定类别中的一个标签)的任务。这是Computer Vision的核心问题之一,尽管它很简单,却具有多种实际应用。
让我们举个例子来更好地理解。当我们执行图像分类时,我们的系统将接收图像作为输入,例如Cat。现在,系统将知道一组类别,其目标是为图像分配一个类别。
这个问题看似简单或容易,但是对于计算机而言,这是一个非常棘手的问题。如您所知,计算机看到的是数字网格,而不是我们看到的猫的图像。图像是从0到255的整数的3维数组,大小为宽x高x3。3表示红色,绿色,蓝色三个颜色通道。
那么我们的系统如何学习识别该图像?通过使用卷积神经网络。卷积神经网络或CNN是一类深度学习神经网络,在图像识别方面取得了巨大突破。到目前为止,您可能已经对CNN有了基本的了解,并且我们知道CNN包括卷积层,Relu层,Pooling层和完全连接的密集层。
要详细了解图像分类和CNN,可以查看以下资源:-
https://www.analyticsvidhya.com/blog/2020/02/learn-image-classification-cnn-convolutional-neural-networks-3-datasets/
https://www.analyticsvidhya.com/blog/2019/01/build-image-classification-model-10-minutes/
既然我们已经了解了这些概念,那么让我们深入研究如何构建图像分类模型以及如何实现它。
了解问题陈述
考虑下图:
图像分类器
精通运动的人将能够将图像识别为橄榄球。图像的不同方面可以帮助您将其识别为橄榄球,可能是球的形状或球员的服装。但是您是否注意到该图像很可能被识别为足球图像?
让我们考虑另一张图片:
图片
您认为这张图片代表什么?很难猜对吧?未经训练的人眼图像很容易被误分类为足球,但实际上,这是橄榄球图像,因为我们可以看到背后的球门柱不是网且尺寸更大。现在的问题是,我们能否建立一个可以对图像进行正确分类的系统。
这就是我们这里项目背后的想法,我们想要构建一个能够识别该图像中所代表的运动的系统。这里的两个分类是橄榄球和足球。由于体育运动有很多共同的方面,因此问题陈述可能有些棘手,尽管如此,我们仍将学习如何解决问题并创建一个性能良好的系统。
设置我们的图像数据
由于我们正在研究图像分类问题,因此我使用了图像数据的两个最大来源,即ImageNet和Google OpenImages。我实现了两个python脚本,使我们能够轻松下载图像。总共下载了3058张图像,分为训练和测试。我对Train文件夹进行了80-20的拆分,其中包含2448张图像,而test文件夹中包含610张图像。橄榄球和Soccer类均具有1224张图像。
我们的数据结构如下:
输入– 3058
火车– 2048
橄榄球– 1224
足球– 1224
测试– 610
橄榄球– 310
足球– 310
让我们建立图像分类模型!
步骤1:-导入所需的库
在这里,我们将利用Keras库创建模型并进行训练。我们还使用Matplotlib和Seaborn可视化我们的数据集,以更好地了解我们将要处理的图像。另一个处理图像数据的重要库是Opencv。
导入matplotlib.pyplot作为plt
将seaborn导入为sns
进口喀拉拉邦
从keras.models导入顺序
从keras.layers导入Dense,Conv2D,MaxPool2D,Flatten,Dropout
从keras.preprocessing.image导入ImageDataGenerator
从keras.optimizers导入Adam
从sklearn.metrics导入category_report,confusion_matrix
将tensorflow作为tf导入
导入cv2
导入操作系统
将numpy导入为np
步骤2:-加载数据
接下来,让我们定义数据的路径。让我们定义一个名为get_data()的函数,该函数使我们更容易创建训练和验证数据集。我们定义了我们将使用的两个标签“橄榄球”和“足球”。我们使用Opencv读取功能读取RGB格式的图像,并将图像的大小调整为我们所需的宽度和高度,在这种情况下均为224。
标签= ['橄榄球','足球']
img_size = 224
def get_data(data_dir):
    数据= []
    用于标签中的标签:
        路径= os.path.join(data_dir,标签)
        class_num = labels.index(label)
        对于os.listdir(path)中的img:
            尝试:
                img_arr = cv2.imread(os.path.join(path,img))[...,::-1]#将BGR转换为RGB格式
                resized_arr = cv2.resize(img_arr,(img_size,img_size))#将图像重塑为首选大小
                data.append([resize_arr,class_num])
            例外,例如e:
                打印(e)
    返回np.array(data)
现在,我们可以轻松获取火车和验证数据。
火车= get_data('../ input / traintestsports / Main / train')
val = get_data('../ input / traintestsports / Main / test')
步骤3:-可视化数据
让我们可视化我们的数据,看看我们正在使用什么。我们使用seaborn来绘制两个类中的图像数量,您可以看到输出的样子。
l = []
对于我在火车上:
    if(i [1] == 0):
        l.append(“橄榄球”)
    其他
        l.append(“足球”)
sns.set_style('darkgrid')
sns.countplot(l)
输出:
图像分类器-橄榄球vs足球
让我们还可视化橄榄球和足球课中的随机图像:
plt.figure(figsize =(5
plt.imshow(train [1] [0])
plt.title(labels [train [0] [1]])
输出:-
图像分类器-橄榄球
类似的足球图像:-
plt.figure(figsize =(5
plt.imshow(train [-1] [0])
plt.title(labels [train [-1] [1]])
输出:-
图像分类器-足球
步骤4:-数据预处理和数据扩充
接下来,我们将执行一些数据预处理和数据增强,然后才能继续构建模型。
x_train = []
y_train = []
x_val = []
y_val = []
对于功能,在火车上贴上标签:
  x_train.append(功能)
  y_train.append(标签)
对于功能,在val中标记:
  x_val.append(功能)
  y_val.append(标签)
#规范化数据
x_train = np.array(x_train)/ 255
x_val = np.array(x_val)/ 255
x_train.reshape(-1,img_size,img_size,1)
y_train = np.array(y_train)
x_val.reshape(-1,img_size,img_size,1)
y_val = np.array(y_val)
火车数据的数据扩充:-
datagen = ImageDataGenerator(
        featurewise_center = False,#在数据集中将输入均值设置为0
        samplewise_center = False,#将每个样本均值设置为0
        featurewise_std_normalization = False,#将输入除以数据集的std
        samplewise_std_normalization = False,#将每个输入除以其std
        zca_whitening = False,#应用ZCA白化
        rotation_range = 30,#在范围(度,0到180)内随机旋转图像
        zoom_range = 0.2,#随机缩放图像
        width_shift_range = 0.1,#水平随机移动图像(总宽度的分数)
        height_shift_range = 0.1,#垂直垂直移动图像(总高度的分数)
        horizo??ntal_flip = True,#个随机翻转图像
        vertical_flip = False)#随机翻转图像
datagen.fit(x_train)
步骤5:-定义模型
让我们定义一个简单的CNN模型,该模型具有3个卷积层,然后是最大合并层。在第3个maxpool操作之后添加一个辍学层,以避免过度拟合。
模型= Sequential()
model.add(Conv2D(32
model.add(MaxPool2D())
model.add(Conv2D(32,3,padding =“ same”,activation =“ relu”))
model.add(MaxPool2D())
model.add(Conv2D(64,3,padding =“ same”,activation =“ relu”))
model.add(MaxPool2D())
model.add(Dropout(0.4))
model.add(Flatten())
model.add(Dense(128,activation =“ relu”))
model.add(Dense(2,activation =“ softmax”))
model.summary()
现在让我们使用Adam作为优化器并使用SparseCategoricalCrossentropy作为损失函数来编译模型。我们使用0.000001的较低学习率来获得更平滑的曲线。
选择=亚当(lr = 0.000001)
model.compile(optimizer = opt,损失= tf.keras.losses.SparseCategoricalCrossentropy(from_logits = True),指标= ['准确性'])
现在,由于学习率很小,让我们训练500个时代的模型。
历史= model.fit(x_train,y_train,历元= 500,validation_data =(x_val,y_val))
步骤6:-评估结果
我们将绘制训练和验证准确性以及训练和验证损失的图。
acc = history.history ['accuracy']
val_acc = history.history ['val_accuracy']
损失= history.history ['loss']
val_loss = history.history ['val_loss']
epochs_range = range(500)
plt.figure(figsize =(15,15))
plt.subplot(2,2,1)
plt.plot(epochs_range,acc,label ='训练精度')
plt.plot(epochs_range,val_acc,label ='Validation Accuracy')
plt.legend(loc ='右下')
plt.title('培训和验证准确性')
plt.subplot(2,2,2)
plt.plot(epochs_range,loss,label ='Training Loss')
plt.plot(epochs_range,val_loss,label ='Validation Loss')
plt.legend(loc ='右上')
plt.title('培训和验证损失')
plt.show()
让我们看看曲线是什么样的:
培训和验证
我们可以打印出分类报告,以查看准确性和准确性。
预测= model.predict_classes(x_val)
预测=
projections.reshape (1,-1)[0]打印(classification_report(y_val,预测,target_names = ['橄榄球(0级)','足球(1级)'])) )
分类模型评估
如我们所见,我们的简单CNN模型能够达到83%的准确性。通过一些超参数调整,我们可能能够达到2-3%的精度。
我们还可以可视化一些错误预测的图像,并查看分类器出了什么问题。
转移学习的艺术
让我们看看什么是转移学习。转移学习是一种机器学习技术,其中将在一个任务上训练的模型重新用于第二个相关任务。转移学习的另一个关键应用是当数据集较小时,通过在相似图像上使用预训练模型,我们可以轻松实现高性能。由于我们的问题陈述非常适合迁移学习,因此让我们了解如何实施预训练的模型以及能够达到的精度。
步骤1:-导入模型
我们将根据MobileNetV2模型创建一个基本模型。这已在ImageNet数据集上进行了预训练,该图像数据集是一个由140万张图像和1000个类别组成的大型数据集。这些知识将帮助我们从特定数据集中对橄榄球和足球进行分类。
通过指定include_top = False参数,可以加载不包含顶部分类层的网络。
base_model = tf.keras.applications.MobileNetV2(input_shape =(224、224、3),include_top = False,权重=“ imagenet”)
在编译和训练模型之前冻结基础非常重要。冻结将防止我们的基本模型中的权重在训练期间更新。
base_model.trainable =假
接下来,我们使用base_model定义模型,然后使用GlobalAveragePooling函数将每个图像的特征转换为单个矢量。我们添加一个0.2的差值,最后添加2个神经元和softmax激活的密集层。
型号= tf.keras.Sequential([base_model,
                                 tf.keras.layers.GlobalAveragePooling2D(),
                                 tf.keras.layers.Dropout(0.2),
                                 tf.keras.layers.Dense(2,activation =“ softmax”)                                    
                                ])
接下来,让我们编译模型并开始对其进行训练。
base_learning_rate = 0.00001
model.compile(optimizer = tf.keras.optimizers.Adam(lr = base_learning_rate),
              loss = tf.keras.losses.BinaryCrossentropy(from_logits = True),
              metrics = ['accuracy'])
历史= model.fit(x_train,y_train,历元= 500,validation_data =(x_val,y_val))
步骤2:-评估结果
acc = history.history ['accuracy']
val_acc = history.history ['val_accuracy']
loss = history.history ['loss']
val_loss = history.history ['val_loss']
epochs_range = range(500)
plt.figure(figsize =(15,15))
plt.subplot(2,2,1)
plt.plot(epochs_range,acc,label ='Training Accuracy')
plt.plot(epochs_range,val_acc,label ='Validation Accuracy' ')
plt.legend(loc ='右下角')
plt.title('培训和验证准确性')
plt.subplot(
2,2,2
)plt.plot(epochs_range,loss,label ='Training Loss')plt .plot(epochs_range,val_loss,label ='Validation Loss')
plt.legend(loc ='upper right')
plt.title('Training and Validation Loss')
plt.show()
让我们看看曲线是什么样的:
让我们也打印分类报告以获得更详细的结果。
预测= model.predict_classes(x_val)
预测= projections.reshape (1,-1)[0]
print(classification_report(y_val,预测,target_names = ['橄榄球(0级)','足球(1级)']))
如我们所见,通过转移学习,我们可以获得更好的结果。橄榄球(Rugby)和足球(Soccer)的精度均高于我们的CNN模型,总体精度达到91%,这对于如此小的数据集确实非常好。通过一些超参数调整和更改参数,我们或许也可以实现更好的性能!
下一步是什么?
这只是计算机视觉领域的起点。实际上,请尝试改进您的基本CNN模型,使其达到或超过基准性能。
您可以从VGG16等架构中学习有关超参数调整的一些线索。
您可以使用相同的ImageDataGenerator来扩大图像并增加数据集的大小。
另外,您可以尝试实现更新更好的体系结构,例如DenseNet和XceptionNet。
您还可以转移到其他计算机视觉任务,例如目标检测和分割,您稍后将意识到这些任务也可以简化为图像分类。
题库
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群