图像分类(Classification):即是将图像结构化为某一类别的信息,用事先确定好的类别(category)来描述图片。
目标检测(Detection):分类任务关心整体,给出的是整张图片的内容描述,而检测则关注特定的物体目标,要求同时获得这一目标的类别信息和位置信息(classification + localization)。
图像分割(Segmentation):分割是对图像的像素级描述,它赋予每个像素类别(实例)意义,适用于理解要求较高的场景,如无人驾驶中对道路和非道路的分割。
比如上面的照片,分类任务就是给出这个图片的动物有多大概率是什么东西。比如:dog:1%,cat:4%,panda:95%。然后我们取达到阈值并且最高的那个指标,也就是panda
CIFAR-10数据集5万张训练图像、1万张测试图像、10个类别、每个类别有6k个图像,图像大小32×32×3。
CIFAR-100数据集也是有5万张训练图像、1万张测试图像、包含100个类别、图像大小32×32×3。
使用方法:
import torchvision
"""
使用CIFAR10这个数据集,
root="./dataset": 会在当前目录下创建dataset文件夹,同时把数据保存进去
train=True: 这是一个训练集,为False, 则表明这是一个测试集
download=True: 数据集会从网上下载
"""
train_set = torchvision.datasets.CIFAR10(root="./dataset",
train=True,
download=True)
test_set = torchvision.datasets.CIFAR10(root="./dataset",
train=False,
download=True)
ImageNet数据集是ILSVRC竞赛使用的是数据集,由斯坦福大学李飞飞教授主导,包含了超过1400万张全尺寸的有标记图片,大约有22000个类别的数据。ILSVRC全称ImageNet Large-Scale Visual Recognition Challenge,是视觉领域最受追捧也是最具权威的学术竞赛之一,代表了图像领域的最高水平。从2010年开始举办到2017年最后一届,使用ImageNet数据集的一个子集,总共有1000类。
AlexNet包含8层变换,有5层卷积和2层全连接隐藏层,以及1个全连接输出层
AlexNet第一层中的卷积核形状是[Math Processing Error]。第二层中的卷积核形状减小到[Math Processing Error],之后全采用[Math Processing Error]。所有的池化层窗口大小为[Math Processing Error]、步幅为2的最大池化。
AlexNet将sigmoid激活函数改成了ReLU激活函数,使计算更简单,网络更容易训练
AlexNet通过dropOut来控制全连接层的模型复杂度。
AlexNet引入了大量的图像增强,如翻转、裁剪和颜色变化,从而进一步扩大数据集来缓解过拟合。
GoogLeNet中的基础卷积块叫作Inception块,得名于同名电影《盗梦空间》(Inception)。Inception块在结构比较复杂。
结构图如下:
GoogLeNet主要由Inception模块构成
B1模块:使用一个64通道的7×7卷积层
B2模块:使用2个卷积层:首先是64通道的1×1卷积层,然后是将通道增大3倍的3×3
卷积层。
B3模块:串联2个完整的Inception块, 分别是Inception3a和Inception3b
B4模块:串联了5个Inception块,分别是Inception4a,Inception4b,Inception4c,Inception4d和Inception4e,并且在4b和4e模块添加了辅助输出端,用于模型训练
B5模块:串联了2个Inception块,分别是Inception5a,Inception5b,后面紧跟输出层,该模块使用全局平均池化层(GAP)来将每个通道的高和宽变成1。最后输出变成二维数组后接输出个数为标签类别数的全连接层。
# 导入工具包
import torch
import torchvision.models as models
from torchvision import transforms
from torch.utils.data import DataLoader
from torchvision.datasets import ImageFolder
def main():
# 模型实例化
model = models.googlenet()
# 以鲜花为列
# 指定批次大小
batch_size = 2
# 指定数据集路径
flower_train_path = './dataset/flower_datas/train/'
flower_test_path = './dataset/flower_datas/val/'
# 先将数据转换为tensor类型,并调整数据的大小为224x224
dataset_transform = transforms.Compose(
[transforms.ToTensor(),
transforms.Resize((224, 224))])
# 获取训练集数据和测试集数据
flower_train = ImageFolder(flower_train_path, transform=dataset_transform)
flower_test = ImageFolder(flower_test_path, transform=dataset_transform)
# 获取数据的迭代
train_loader = DataLoader(dataset=flower_train,
batch_size=batch_size,
shuffle=True)
test_loader = DataLoader(dataset=flower_test,
batch_size=batch_size,
shuffle=False)
# 模型实例化
model = models.googlenet(num_classes=5)
# 参数的设置
# 学习率
learning_rate = 1e-3
# 训练轮数
num_epochs = 3
# 优化算法Adam = RMSProp + Momentum
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
# 交叉熵损失函数
loss_fn = torch.nn.CrossEntropyLoss()
# 模型评估方法
# 计算模型预测精度:测试集数据,模型
def evaluate_accuracy(data_iter, model):
total = 0
correct = 0
# 不进行梯度计算
with torch.no_grad():
# 模型是验证模式
model.eval()
# 获取每一个batch的数据,进行预测
for images, labels in data_iter:
# google进行模型预测时只返回最终的结果
outputs = model(images)
# 获取预测结果
_, predicts = torch.max(outputs.data, dim=1)
# 预测的次数
total += labels.size(0)
# 预测正确的个数
correct += (predicts == labels).cpu().sum()
# 获取准确率
return correct / total
# 模型训练
def train(data_loader=train_loader, optim=optimizer, loss_fn=loss_fn, epochs=num_epochs):
# 遍历每个轮次
for i in range(epochs):
# 准确率和loss
total_image = 0
correct_image = 0
loss_sum = 0
iter = 0
# 遍历每个bacth
for b, (images, labels) in enumerate(data_loader):
model.train()
# 模型预测
output, aux2, aux1 = model(images)
loss_0 = loss_fn(output, labels)
loss_2 = loss_fn(aux2, labels)
loss_1 = loss_fn(aux1, labels)
loss = loss_0 + 0.3 * loss_2 + 0.2 * loss_1
loss_sum += loss.item()
# 反向传播
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_image += labels.size(0)
_, pred = torch.max(output.data, dim=1)
correct_image += (pred == labels).cpu().sum().item()
iter += 1
test_acc = evaluate_accuracy(test_loader, model)
print('epoch:{0}, loss:{1:.4f}, train accuracy:{2:.3f}, test accuracy:{3:.3f}'
.format(i, loss_sum / (iter + 0.01),
correct_image / total_image, test_acc))
train()
if __name__ == '__main__':
main()
1、极坐标表示:(xmin, ymin, xmax, ymax)
xmin,ymin:x,y坐标的最小值
xmin,ymin:x,y坐标的最大值
2、中心点坐标:(x_center, y_center, w, h)
x_center, y_center:目标检测框的中心点坐标
w,h:目标检测框的宽、高
PASCAL VOC数据集 和 MS COCO数据集
IoU = 两个矩形框相交的面积 / 两个矩形框相并的面积
比如下图
mAP即Mean Average Precision
mAP是多个分类任务的AP的平均值,而AP(average precision)是PR曲线下的面积
查准率(Precision): TP/(TP + FP) 这个就是P
查全率(Recall): TP/(TP + FN) 这个就是R
把PR放到直角坐标系即可得到PR曲线
非极大值抑制(Non-Maximum Suppression,NMS),顾名思义就是抑制不是极大值的元素。例如在行人检测中,滑动窗口经提取特征,经分类器分类识别后,每个窗口都会得到一个分数。但是滑动窗口会导致很多窗口与其他窗口存在包含或者大部分交叉的情况。这时就需要用到NMS来选取那些邻域里分数最高(是行人的概率最大),并且抑制那些分数低的窗口。 NMS在计算机视觉领域有着非常重要的应用,如视频目标跟踪、数据挖掘、3D重建、目标识别以及纹理分析等
目标检测算法主要分为two-stage(两阶段)和one-stage(单阶段)两类
先由算法生成一系列作为样本的候选框,再通过卷积神经网络进行样本分类。如下图所示,主要通过一个卷积神经网络来完成目标检测过程,其提取的是CNN卷积特征,进行候选区域的筛选和目标检测两部分。网络的准确度高、速度相对较慢。
直接通过主干网络给出目标的类别和位置信息,没有使用候选区域的筛选网路,这种算法速度快,但是精度相对Two-stage目标检测网络降低了很多。
Yolo意思是You Only Look Once,它并没有真正的去掉候选区域,而是创造性的将候选区和目标分类合二为一,看一眼图片就能知道有哪些对象以及它们的位置。
优点
速度非常快,处理速度可以达到45fps,其快速版本(网络较小)甚至可以达到155fps。
训练和预测可以端到端的进行,非常简便。
缺点
准确率会打折扣
对于小目标和靠的很近的目标检测效果并不好
假设我们只需要yolo识别MP4中的各个事物(不写的话,全部默认官方参数)截图如下
点我下载
点我观看