机器学习——图像分类

article/2025/11/7 14:46:09

1 图像分类的概念

1.1 什么是图像分类?

图像分类,根据图像信息中所反映出来的不同特征,把不同类别的目标区分开来的图像处理方法

1.2 图像分类的难度

●任何拍摄情 况的改变都将提升分类的难度

 1.3 CNN如何进行图像分类

        ●数据驱动型方法通用流程
                1.收集图像以及对应的标签,形成数据集
               2.使用机器学习训练一个分类器
                3.在新的图像.上测试这个分类器

 ​​​

 1.4 图像分类指标

精确率:查得准不准?        
召回率:查得全不全?        

 True positives (TP):飞机的图片被正确的识别成了飞机
True negatives (TN): 大雁的图片没有被识别出来,系统正确地认为它们是大雁
False positives (FP):大雁的图片被错误地识别成了飞机
False negatives (FN):飞机的图片没有被识别出来,系统错误地认为它们是大雁

 True negatives (TN): 4,四个大雁                        False negatives (FN): 2,二个飞机

True positives (TP): 3,绿框.                                False positives (FP): 1,红框,

percision=\frac{TP}{TP+FP}=\frac{3}{3+1}=0.75        recall=\frac{TP}{TP+FN}=\frac{3}{3+2}=0.6

准确率:        ACC=\frac{TP+TN}{TP+TN+FP+FN}

平均精确度( Average Precision,AP) :PR曲线下的面积,这里的average,等于是对precision进行取平均。

 1.5 经典CNN网络性能演化

2 GoogleNet   

2.1 深度网络有什么好处?

1.丰富了低、中、高等级的特征
边缘、纹理、形状、颜色.....高纬度的人类无法理解的特征
2.越深、越宽的网络具有越强的表达能力

  • 日有学者证明,一个宽度为K、深度为H的网络,能够产生至少K^{H}条线段
  • 线段越多,拟合得越准确
  • 因此,网络加宽、加深可以提升性能,并且加深效果比加宽好:

2.2 如何设计一个卷积层?

        ●选择什么样的层(Layer ) ?
                3x3卷积核
                5X5卷积核
                池化层( Pooling Layer )

2.2.1 感受层

         在卷积神经网络中,感受野( Receptive Field )的定义是卷积神经网络每- -层输出的特征图.上的像素点在输入图片.上映射的区域大小。换句话说,感受野是特征图上的一个点对应输入图上的区域。

  • 假设两个卷积层的卷积核尺寸都为2x2,步长都为1,输入为4x4
  • 经过两次卷积后,特征图的尺寸分别为3x3和2x2
  • 对于特征图2的左上角像素点,它在特征图1上的感受范围为左上方的2x2区域,而此区域在输入。上的感受范围是左,上方的3x3区域,因此,感受野尺寸为3x3。
     

  •   日越深层的特征图, 感受野越大
  • 对同层而言,卷积核尺寸越大,感受野越大
  • 大的感受野对大的物体更敏感,反之,小的感受野对小的物体更敏感

 猫可以在图片里有大有小,可以在图片的局部,也可以整张图片都是;对一张图片而言,至少有RGB三个通道,如果这几多个卷积核则会导致计算量过大。 

2.2.2 如何降低计算量——1x1卷积核

1 x 1卷积做了什么?

它在深度( Depth). 上进行了融合深度为D的输入经过一-个1 x 1卷积核,得到深度为1的输出(S=1, P=0);同理,尺寸为DxHxW的输入,经过D/2个1 X 1卷积核,将会得到D/2xHxW的输出(S=1,P=0);最终,在不损失太多信息的情况下,对输入进行了降维。

 小结:1X1的卷积是--个非常优秀的结构它可以跨通道组织信息提高网络的表达能力,同时可以对输出通道升维和降维。[想象一下:两片面包压缩成一-片的宽度又或者加点膨化剂,膨胀成4片的宽度]

2.3 Inception模块

  • 在1x1卷积后,添加不同的卷积分支
  • 实现同一卷积层的多尺度特征提取与融合

2.4 整体网络结构

  •  一个潜在的问题

        ➢在较深的网络中进行反向传播可能会出现“梯度消失”,导致训练无法继续进行

  • 一种解决方案

        ➢网络的中间层具有很高的判别能力
        ➢在这些中间层增加辅助分类器
        ➢在训练中,这些中间层分类器得到的L .oss以0.3的权重加到最终Loss

3 GoogleNet的keras实现

3.0 猫狗大战

本次实战采用的数据集来自kaggle . 上的一一个竞赛: Dogs Vs. Cats

 

 3.1 图像读取一图像增 强-图像生成器

 数据增强策略
        ●翻转变换(lip):沿着水平或者垂直方向翻转图像;
        ●缩放变换(zoom):按照一定的比例放大或者缩小图像;
        ●平移变换(shift):在图像平面上对图像以一定方式进行平移;
        ●可以采用随机或人为定义的方式指定平移范围和平移步长,沿水平或竖直方向进行平移.图像内容的位置
        ●尺度变换(scale):对图像按照指定的尺度因子,进行放大或缩小;或者参照SIFT特征提取思想,利用指定的尺度因子对图像滤波构造尺度空间.改变图像内容的大小或模糊程度;
        ●对比度变换(contrast):在图像的HSV颜色空间,改变饱和度S和V亮度分量,保持色调H不变.对每个像素的S和V分量进行指数运算(指数因子在0.25到4之间),增加光照变化;
        ●噪声扰动(noise):对图像的每个像素RGB进行随机扰动,常用的噪声模式是椒盐噪声和高斯噪声;

代码如下:

import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from PIL import Image
import matplotlib.pyplot as plt
%matplotlib inline
train_dir="train" #训练集路径
test_dir="test"
#测试集路径
IM_WIDTH=224 #图像宽度
IM_HEIGHT=224 #图像高度
batch_size=32
#定义训练和测试的图像生成器
#train and val data
train_val_datagen = ImageDataGenerator (rotation_range=30,width_shift_range=0.2,height_shift_range=0.2,shear_range=0.2,z0om_range=0.2,horizontal_flip=True,validation__split=0.1)   #划分出验证集
#test data
test_datagen=ImageDataGenerator()   #测试集就不用数据增强了#训练集图像生成器
train_generator=train_val_datagen.flow_from_directory(train_dir,target_size=(IM_WIDTH,IM_HEIGHT),    #将目标图片缩放多大的尺寸batch_size=batch_size,   #分批次抽取subset='training')
#验证集图像生成器
vaild_generator=train_val_datagen.flow_from_directory(train_dir,target_size=(IM_WIDTH,IM_HEIGHT),batch_size=batch_size,subset='validation')
#测试集图像生成器
test_generator=test_datagen.flow_from_directory(test_dir,target__size=(IM_WIDTH,IM_HEIGHT),batch_size=batch_size,)
#验证图片生成器的效果,选取生成器的下一个图片并打印出来
samples_batch=train_generator.next()
print(samples_batch[0].shape)#第0位保存的是图像
print(samples_batch[1].shape)#第1位保存的是标签#显示一张图片
fig1=samples_batch[0][0]
r=Image.fromarray(fig1[:,:,0]).convert('L')#读第0个通道内的值,转为灰度值
g=Image.fromarray(fig1[:,:,1]).convert('L')
b=Image.fromarray(fig1[:,:,2]).convert('L')
image=Image.merge("RGB",(r,g,b))#RGB合并起来
plt.imshow(image)
plt.show()
print(samples_batch[1][0])#打印标签——热编码

运行结果:

3.2 自定义图像生成器

#自定义训练集生成器
def myTrainDataGenerator():while True:trainDataBatch=train_generator.next()   #取出一个批次的数据images=trainDataBatch[0]    #取图像labels= [trainDataBatch[1] , trainDataBatch[1] , trainDataBatch[1]]#取标签yield images, labels
#自定义验证集生成器
def myVaildDataGenerator():while True:vaildDataBatch=vaild_generator.next()   #取出一个批次的数据images=vaildDataBatch[0]    #取图像labels= [vaildDataBatch[1] , vaildDataBatch[1] , vaildDataBatch[1]]#取标签yield images, labels
#自定义测试集生成器
def myTestDataGenerator():while True:testDataBatch=test_generator.next()   #取出一个批次的数据images=testDataBatch[0]    #取图像labels= [testDataBatch[1] , testDataBatch[1] , testDataBatch[1]]#取标签yield images, labelsmy_train_generator=myTrainDataGenerator()
my_vaild_generator=myVaildDataGenerator()
my_test_generator=myTestDataGenerator()a=my_train_generator.__next__()
#显示一张图片
fig1=a[0][0]
r=Image.fromarray(fig1[:,:,0]).convert('L')#读第0个通道内的值,转为灰度值
g=Image.fromarray(fig1[:,:,1]).convert('L')
b=Image.fromarray(fig1[:,:,2]).convert('L')
image=Image.merge("RGB",(r,g,b))#RGB合并起来
plt.imshow(image)
plt.show()
print(samples_batch[1][0][0])

3.3 模型实现

#导入需要使用的包
from keras.models import Model
from keras.layers import Input , Dense, Dropout , BatchNormalization, Conv2D , MaxPool2D , AveragePooling2D, concatenate, Flatten
from keras.layers.convolutional import Conv2D ,MaxPooling2D, AveragePooling2D
from keras.callbacks import ReduceLROnPlateau,ModelCheckpoint , EarlyStopping
from keras.preprocessing.image import ImageDataGenerator
from keras.models import load_model
from keras.preprocessing.image import ImageDataGenerator
from PIL import Image
#若需要复现,可以把随机数固定下来
seed=42
np.random.seed(seed)#卷积+BN
def Conv2d_BN(prev_layer,   #卷积前一层网络filters,  #卷积核数量kernel_size,  #卷积核大小padding='same',   #‘sanme'指卷积填充是大小保持不小strides=(1,1) , #步长name=None #名字):if name is not None:bn_name = name+'_bn'conv_name = name +'_conv'else:bn_name = Noneconv_name = Nonex = Conv2D(filters, kernel_size, padding=padding,strides=strides , activation='relu',name=conv_name) (prev_layer)     #2D图像卷积参数x = BatchNormalization(axis=3, name=bn_name)(x) #批次归一化,- -种标准化操作,防止过拟合的手段return x#inception模块
def inception_block(prev_layer, num_filters, name, use_whistle = False, numclasses = -1):
#num_filters: [b0,(b11, b12)。(b21,b22)。 b3] 代表不同分支的通道数,即卷积核个数
#use_ whistle:是否要输出辅助分类器#1x1卷积分支branch0=Conv2d_BN(prev_layer=prev_layer,filters=num_filters[0],kernel_size=(1,1),name=name+'-br0-1x1')#3x3卷积分支,1x1-3x3branch1=Conv2d_BN(prev_layer=prev_layer,filters=num_filters[1][0],kernel__size=(1,1),name=name+'-br1-1x1')branch1=Conv2d_BN(prev__layer=branch1,filters=num_filters[1][1],kernel_size=(3,3),name=name+'-br1-3x3')#5x5卷积分支,1x1-5x5branch2=Conv2d_BN(prev__layer=prev_layer,filters=num_filters[2][0],kernel_size=(1,1),name=name+'-br2-1x1')branch2=Conv2d_BN(prev_layer=branch2,filters=num_filters[2][1],kernelsize=(5,5),name=name+'-br2-5x5')#池化分支branch3=MaxPool2D(pool_size=(3,3),strides=(1,1),padding='same',name=name+'-br3-pooL')(prev_layer)branch3=Conv2d_BN(branch3,filters=num_filters[3],kernel__size=(1,1),name=name+'-br3-1x1')#融合x = concatenate([branch0, branch1, branch2, branch3], axis = 3,name = name)#是否输出辅助分类器if(use_whistle):out = aux_whistle(prev_layer, numclasses = numclasses, name = name + '-whistle')return x,outreturn x#辅助分类器
def aux_whistle(prev_layer,numclasses,name):aux_clf=AveragePooling2D(pool_size=(5,5),strides=(3,3),name=name+'-averagePool')(prev_layer)    #池化aux_clf=Conv2d_BN(aux_clf,filters=128,kernel__size=(1,1),name=name+'-1x1conv')  #卷积aux_clf=Flatten(name=name+'-flatten')(aux_clf)aux_clf=Dense(1024,activation='relu')(aux_clf)  #全连接aux_clf=Dropout(0.3,name=name+'-dropout')(aux_clf)aux_clf=Dense(num_classes,activation='softmax',name=name+'-predictions')(aux_clf)return aux_clfdef inceptionNet(input_shape,numclasses):inp=Input(shape=input_shape)#「卷积+池化」x2x=Conv2d_BN(inp,filters=64,kernel_size=(7,7),strides=(2,2),name='2a')x=MaxPool2D(poolsize=(3,3),strides=(2,2),padding='same',name='2pool-1')(x)x=Conv2d_BN(x,filters=192,kernel_size=(3,3),name='2b')x=MaxPool2D(pool__size=(3,3),strides=(2,2),padding='same',name='2pool-2')(x)#第-Inception模块组,3a.3bx=inception_block(x,(64,(96,128),(16,32),32),name='inception3a')x=inception_block(x,(128,(128,192),(32,96),64),name='inception3b')x=MaxPoo12D(pool_size=(3,3),strides=(2,2),padding='same',name='3pool')(x)#第二Inception模块组,4a、4b(辅助)、4c.4d(辅助)、4ex=inception_block(x,(192,(96,208),(16,48),64),name='inception4a')x,whistle1=inception_block(x,(160,(112,224),(24,64),64),name='inception4b',use_whistle=True,numclasses=numclasses)x=inception_block(x,(128,(128,256),(24,64),64),name='inception4c')x,whistle2=inception_block(x,(112,(144,288),(32,64),64),name='inception4d',use_whistle=True,numclasses=numclasses)x=inception_block(x,(256,(160,320),(32,128),128),name='inception4e')x=MaxPool2D(poolsize=(3,3),strides=(2,2),padding='same',name='4pool')(x)#第三Inception模块组,5a.5bx=inception_block(x,(256,(160,320),(32,128),128),name='inception5a')x=inception_block(x,(384,(192,384),(48,128),128),name='inception5b')#全局平均池化x=AveragePooling2D(pool_size=(7,7),strides=(1,1),padding='valid',name='avg7x7')(x)#X=Dropout(0.4)(x)# FC+Softmax分类x = Flatten (name='flatten')(x)x = Dense(numclasses, activation= 'softmax',name= 'predictions')(x)model = Model( inp, [x, whistle1,whistle2] ,name=' inception_v1')return model

3.4 模型编译

num_classes=len(train_generator.classindices)   #获取类别数
model=inceptionNet(input_shape=(224,224,3),numclasses=num_classes)#获取model对象
model.compile(optimizer='adam', #优化器loss='categorical_crossentropy', #损失函数loss_weights=[1.0,0.3,0.3],    #损失函数权重metrics=['accuracy'])     #评价标准(错误率),如果要用top-k:['accuracy',metric.top_k__categorical_accuracy]
model.summary()#打印出模型概述信息

3.5 模型训练

EPOCH=10    #一个Epoch代表遍历- -次所有数据
batch_size=32 #一 个批次内的图片数量
modelfilepath='model.best.hdf5' #保存路劲
#无法更优则自动终止
earlyStop=EarlyStopping(monitor='val_predictions__acc',patience=30,verbose=1,mode='auto')
#保存最好的模型
checkpoint=ModelCheckpoint(modelfilepath,monitor='val_predictions__acc',verbose=1,save__best_only=True,mode='max')
#根据不同阶段,降低学习率
reduce_Ir=ReduceLROnPlateau(monitor='val_predictions_loss',factor=0.1,patience=10,verbose=1,mode='auto',min_delta=0.00001,C0oldown=0,min__lr=0)
history=model.fit_generator(my_train_generator,validation_data=my_vaild_generator,epochs=EPOCH,steps_per_epoch=train_generator.n/batch_size
,validation_steps=vaild_generator.n/batch_size,callbacks=[checkpoint,reduce_lr,earlyStop])

训练结果:

3.6 模型测试

#=====模型测试=========
testmodel=load_model (modelfilepath)
loss,predictions_loss,aux1_loss, aux2_loss, predictions_acc,aux1_acc, aux2_acc=testmodel. evaluate_generator(my_test_generator,steps=test_generator.n/batch_size)
#绘制训练&验证的准确率值
plt.plot(history.history['predictions_acc'])
plt.plot(history.history['val_predictions_acc'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train','Val'],loc='upper left')
plt.show()
#绘制训练&验证的损失值
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train','Val'],loc='upper left')
plt.show()

测试结果:

 


http://chatgpt.dhexx.cn/article/pjHIiJVX.shtml

相关文章

图像分类算法

图像分类 参考链接1.前言2.K近邻与KMeans算法比较KNN原理和实现过程(1) 计算已知类别数据集中的点与当前点之间的距离:(2) 按照距离递增次序排序(3) 选取与当前点距离最小的k个点(4) 确定前k个点所在类别的出现频率(5) 返回前k个点出现频率最高的类别作为当前点的预…

图像分类方法总结

1. 图像分类问题描述 图像分类问题是计算机视觉领域的基础问题,它的目的是根据图像的语义信息将不同类别图像区分开来,实现最小的分类误差。具体任务要求是从给定的分类集合中给图像分配一个标签的任务。总体来说,对于单标签的图像分类问题&…

9.图片分类数据集

1. 图像分类数据集 MNIST数据集 [LeCun et al., 1998] 是图像分类中广泛使用的数据集之一,但作为基准数据集过于简单。 我们将使用类似但更复杂的Fashion-MNIST数据集。 %matplotlib inline import torch import torchvision from torch.utils import data from t…

CNN实现花卉图片分类识别

CNN实现花卉图片分 前言 本文为一个利用卷积神经网络实现花卉分类的项目,因此不会过多介绍卷积神经网络的基本知识。此项目建立在了解卷积神经网络进行图像分类的原理上进行的。 项目简介 本项目为一个图像识别项目,基于tensorflow,利用C…

常用图像分类网络

想对图像分类网络写个简要的概括,如有介绍不当之处,还望指出。 一、VGG网络 更新于2018年10月20日 参考博客:深度学习经典卷积神经网络之VGGNet 论文地址:VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITIO…

干货——图像分类(上)

这是译自斯坦福CS231n课程笔记image classification notes,由课程教师Andrej Karpathy授权进行翻译。本篇教程由杜客翻译完成。非常感谢那些无偿奉献的大师,在此代表所有爱好学习者向您们致敬,谢谢! 这是斯坦福大学的课程&#xf…

图像分类

图像物体分类与检测算法综述 转自《计算机学报》 目录 图像物体分类与检测算法综述 目录图像物体分类与检测概述物体分类与检测的难点与挑战物体分类与检测数据库物体分类与检测发展历程 图像物体分类与检测是计算机视觉研究中的两个重要的基本问题,也是图像分割、…

【图像分类数据集】非常全面实用的垃圾分类图片数据集共享

【图像分类数据集】非常全面实用的垃圾分类图片数据集共享 数据集介绍: 训练集 文件夹结构如下(部分: 第0类文件夹下数据展示如下(部分: 测试集 大致如下: 数据集获取方式: 总结&#xf…

python学习(18)--图片分类

图片分类 学习动机. 在这一节中我们会引入图片分类为题。这也是从一个合适的集合中分配给图片一个标记的任务。这是计算机视觉的核心问题之一。鉴于它的简单性,有一大批实用应用。更多的是,我们可以在以后的章节中看到,一些看似分离的计算机…

【OpenMMLab】图片分类发展简史

一、发展简述 图片分类是CV领域的基础任务,也是检测、分割、追踪等任务的基石。简而言之,图片分类就是给定一张图片,判断其类别,一般而言所有的候选类别是预设的。 从数学上描述,图片分类就是寻找一个函数&#xff0…

深度学习(1) ——图像分类

图像分类概述 图像分类实质上就是从给定的类别集合中为图像分配对应标签的任务,当我们输入一张图片,返回一个该图像类别的标签。限制条件:只能输入单目标图像。常用数据集:mnist、CIFAR-10、CIFAR-100、ImageNet 图像分类算法 …

CNN图片分类(Pytorch)

这篇文章主要讲述用 pytorch 完成简单 CNN 图片分类任务,如果想对 CNN 的理论知识进行了解,可以看我的这篇文章,深度学习(一)——CNN卷积神经网络。 图片分类 我们以美食图片分类为例,有testing、training、validation文件夹。下…

JavaWeb学习思维导图

这是我最近总结的JavaWeb学习思维导图,希望可以帮到大家:

javaweb学习总结

重定向 请求转发 区别:重定向后浏览器地址值会发生改变。 重定向request域对象不能共享数据,因为request域的范围是一次请求一次响应。而转发能够共享数据 请求转发的路径写法,只是需要写url-pattern的地址即可,不用带项目名&am…

JavaWeb学习心得总结

JavaWeb(JSPServlet)新手学习心得总结 说明: 由于篇幅的原因,本文只是对于JavaWeb项目的大致数据流程做一个介绍,同时引出一些JavaWeb开发中很基础的知识点,且不会精确到具体代码实现。 所以本文的适合读…

JavaWeb学习笔记总结(一)

前言:因为我是大三,这学期开课是JavaWeb,前端三剑客htmlcssjs,还有一个springboot框架的课,大二下学期才学的java跟sql,所以跨度直接到springboot有点大吧,ssm框架都没学,但是b站上有挺多教程的&#xff0c…

一.JavaWeb学习路线

Java系统学习路线: 第一阶段 第一阶段: Java 基础,包括 Java 语法,面向对象特征,常见API,集合框架。(基础) 第二阶段:Java API:输入输出,多线程,网络编程,反…

java web学习_JavaWeb学习路线

Java web,是用Java技术来解决相关web互联网领域的技术综合。Web包括:web服务器和web客户端。Java在客户端的应用有Java applet,不过使用很少。Java在服务器端的应用非常的丰富,比如Servlet,JSP和第三方框架等等。java技…

JavaWeb学习笔记

JavaWeb 1.ASP、PHP、JSP ASP: 微软&#xff1a;最早流行的就行ASP 在HTML嵌入VB的脚本 在ASP中&#xff0c;基本一个界面就有几千行代码&#xff0c;页面极其混乱&#xff0c;维护成本高 c#编程语言 IIS服务器 <h1> <% system.out.println("hello") …

javaweb学习路线

一、学习顺序 1、java语法&#xff0c;语法很重要&#xff0c;没有这个根本后面的也进行不下去&#xff0c;建议先学会应用了再去研究jdk源码&#xff0c;本身就是新手就想从原理开始了解&#xff0c;估计非常吃力&#xff0c;效果也不一定好。 2、数据库&#xff0c;首先学关…