IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 目标检测学习--YOLOv2 -> 正文阅读

[人工智能]目标检测学习--YOLOv2

论文地址:

《YOLO9000:Better,Faster,Stronger》

在这篇论文中,作者首先在YOLOv1的基础上提出了改进的YOLOv2,然后提出了一种检测与分类联合训练方法,使用这种联合训练方法在COCO检测数据集和ImageNet分类数据集上训练出了YOLO9000模型,其可以检测超过9000多类物体;所以,这篇文章其实包含两个模型:YOLOv2和YOLO9000,不过后者是在前者基础上提出的,两者模型主体结构是一致的;YOLOv2相比YOLOv1做了很多方面的改进,这也使得YOLOv2的mAP有显著的提升,并且YOLOv2的速度依然很快,保持着自己作为one-stage方法的优势。

YOLOv2的改进策略?

如下图所示,YOLOv2相比YOLOv1的改进策略:

Batch Normalization(批归一化)

Batch Normalization可以提升模型收敛速度,而且可以起到一定正则化效果,降低模型的过拟合;

在YOLOv2中,每个卷积层后面都添加了Batch Normalization层,并且不再使用droput;

使用Batch Normalization后,YOLOv2的mAP提升了2.4%;

High Resolution Classifier(高分辨率分类器)

目前的大部分目标检测模型都会先在ImageNet分类数据集上预训练初始化得到初始权重,该模型的主体部分为CNN特征提取器,由于之前的CNN网络结构基本使用固定输入(有全连接层),因此ImageNet分类模型基本采用大小为224*224的图片作为输入,分辨率相对较低,不利于检测模型;

所以YOLOv1在采用224*224分类模型预训练初始化后,将分辨率增加至448*448,并使用这个高分辨率在检测数据集上finetune,但是直接切换分辨率,检测模型可能难以快速适应高分辨率;

因此YOLOv2增加了在ImageNet数据集上使用448*448输入来finetune分类网络这一中间过程(10 epochs),这可以使得模型在检测数据集上finetune之前已经适用高分辨率输入;

YOLOv2则将预训练分成两步:先用224*224的输入从头开始训练网络,将所有训练数据循环跑160次epoch,然后再将输入调整到448*448,再训练10个epoch,这两步都是在ImageNet数据集上进行,最后再在检测的数据集上进行fine-tuning,也就是detection的时候用448*448的图像作为输入就可以顺利过渡了;

使用高分辨率分类器后,YOLOv2的mAP提升了约4%;

Convolutional With Anchor Boxes

在YOLOv1中,输入图片最终被划分为7*7网格,每个单元格预测2个边界框,YOLOv1最后采用的是全连接层直接对边界框进行预测,其中边界框的宽与高是相对整张图片大小的,而由于各个图片中存在不同尺度和长宽比(scales and ratios)的物体,YOLOv1在训练过程中学习适应不同物体的形状是比较困难的,这也导致YOLOv1在精确定位方面表现较差;

YOLOv2借鉴了Faster R-CNN中RPN网络的先验框(anchor boxes),RPN对CNN特征提取器得到的特征图(feature map)进行卷积来预测每个位置的边界框以及置信度(是否含有物体),并且各个位置设置不同尺度和比例的先验框,所以RPN预测的是边界框相对于先验框的偏移值,采用先验框使得模型更容易学习;

所以YOLOv2移除了YOLOv1中的全连接层而采用了卷积和anchor boxes来预测边界框;为了使检测所用的特征图分辨率更高,移除其中的一个pool层;

在检测模型中,YOLOv2不是采用448*448图片作为输入,而是采用416*416大小。因为YOLOv2模型下采样的总步长为32,对于416*416大小的图片,最终得到的特征图大小为13*13,维度是奇数,这样特征图恰好只有一个中心位置(如果为偶数,就有4个中心位置);对于一些大物体,它们中心点往往落入图片中心位置,此时使用特征图的一个中心点去预测这些物体的边界框相对容易些;

所以在YOLOv2设计中要保证最终的特征图有奇数个位置,对于YOLOv1,每个cell都预测2个boxes,每个boxes包含5个值:x, y, h, w, c,前4个值是边界框位置与大小,最后一个值是置信度(confidence scores,包含两部分:含有物体的概率以及预测框与ground truth的IOU),但是每个cell只负责预测一套分类概率值(class predictions,其实是置信度下的条件概率值),供2个boxes共享;可以看看我之前的博客:地址

YOLOv2使用了anchor boxes之后,每个ceil的各个anchor box都负责单独预测一套分类概率值,YOLOv1只能预测98个边界框(7*7*2),而YOLOv2使用anchor boxes之后可以预测上千个边界框(13*13*num_anchors);

使用anchor boxes之后,YOLOv2的mAP有稍微下降(可能是YOLOv2尽管使用anchor boxes,但是依然采用YOLOv1的训练方法),同时YOLOv2的召回率大大提升,由原来的81%升至88%;

Dimension Clusters

在Faster R-CNN中,先验框的维度(长和宽)都是手动设定的,带有一定的主观性,如果选取的先验框维度比较合适,那么模型更容易学习,从而做出更好的预测;

因此,YOLOv2采用k-means聚类方法对训练集中的边界框做了聚类分析,因为设置先验框的主要目的是为了使得预测框与ground truth的IOU更好,所以聚类分析时选用box与聚类中心box之间的IOU值作为距离指标:

d(box, centroid) = 1 - IOU(box, centroid)

下图为在VOC和COCO数据集上的聚类分析结果,随着聚类中心数目的增加,平均IOU值(各个边界框与聚类中心的IOU的平均值)是增加的,但是综合考虑模型复杂度和召回率,作者最终选取5个聚类中心作为先验框,其相对于图片的大小如下右边图所示:?

作者采用的5种anchor(Cluster IOU)的Avg IOU是61,而采用9种Anchor Boxes的Faster RCNN的Avg IOU是60.9,也就是说论文仅选取5种box就能达到Faster RCNN的9种box的效果;?

?New Network: Darknet-19

YOLOv2采用了一个新的基础模型(特征提取器),称为Darknet-19,包括19个卷积层和5个maxpooling层,如下图所示:

Darknet-19主要采用3*3卷积,采用2*2的maxpooling层之后,特征图维度降低2倍,而同时将特征图的channles增加两倍,Darknet-19最终采用global avgpooling做预测,并且在3*3卷积之间使用1*1卷积来压缩特征图channels以降低模型计算量和参数,Darknet-19每个卷积层后面同样使用了bn层以加快收敛速度,降低模型过拟合;

在ImageNet分类数据集上,Darknet-19的top-1准确度为72.9%,top-5准确度为91.2%,但是模型参数相对小一些,使用Darknet-19之后,YOLOv2的mAP值没有显著提升,但是计算量却可以减少约33%;

Direct location prediction

边界框的实际中心位置为(x, y),需要根据预测的坐标偏移值(t_{x}, t_{y})、先验框的尺度(w_{a}, h_{a})以及特征图每个位置的中心点坐标(x_{a}, y_{a})来进行计算,YOLOv2论文中写的是"-",而Faster R-CNN论文中是"+":

x = (t_{x} * w_{a}) - x_{a}

y = (t_{y} * h_{a}) - y_{a}?

上面的公式是无约束的,预测的边界框很容易向任何方向偏移,例如当t_{x} = 1时边界框将向右偏移先验框的一个宽度大小,而当t_{x} = -1时边界框将向左偏移先验框的一个宽度大小,因此每个位置预测的边界框可以落在图片任何位置,这导致模型的不稳定性,在训练时需要很长时间来预测出正确的偏移;

YOLOv2继续沿用YOLOv1的方法,即预测边界框中心点相对于对应cell左上角位置的相对偏移值,为了将边界框中心点约束在当前cell中,使用sigmoid函数处理偏移值,这样预测的偏移值在(0,1)范围内;

根据边界框预测的4个偏移值t_{x}, t_{y}, t _{w}, t_{h},可以按如下公式计算出边界框实际位置和大小:

b_{x} = \sigma (t_{x}) + c_{x}

b_{y} = \sigma (t_{y}) + c_{y}

b_{w} = p_{w} * e^{t_{w}}

b_{h} = p_{h} * e^{t_{h}}

Pr(object) * IOU(b, object) = \sigma (t_{o})?

其中b_{x}, b_{y}, b_{w}, b_{h}是bbox的中心和宽高,Pr(object) * IOU(b, object)是bbox的置信度,YOLO1是直接预测置信度的值,这里对预测参数t_{o}进行σ变换后作为置信度的值。(c_{x}, c_{y})为cell的左上角坐标,在计算时每个cell的尺度为1,所以当前cell的左上角坐标为(1, 1),由于sigmoid函数\sigma ()的处理,边界框的中心位置会约束在当前cell内部,防止偏移过多;而p_{w}p_{h}是先验框的宽度与长度,它们的值也是相对于特征图大小的,在特征图中每个cell的长和宽均为1,t_{x}, t_{y}, t_{w}, t_{h}, t_{o}是要学习的参数,分别用于预测边框的中心和宽高,以及置信度;

特征图的大小为(W, H),其在论文是(13, 13),这样我们可以将边界框相对于整张图片的位置和大小计算出来(4个值均在0和1之间):

b_{x} = \sigma (t_{x}) + c_{x}/W

b_{y} = \sigma (t_{y}) + c_{y}/H

b_{w} = p_{w} * e^{t_{w}}/W

b_{h} = p_{h} * e^{t_{h}}/H

?Pr(object) * IOU(b, object) = \sigma (t_{o})

将上面的4个值分别乘以图片的宽度和长度就可以得到边界框的最终位置和大小了,约束了边界框的位置预测值使得模型更容易稳定训练,结合聚类分析得到先验框与这种预测方法,YOLOv2的mAP值提升了约5%?;

Fine-Grained Features

YOLOv2的输入图片大小为416*416,经过5次maxpooling之后得到13*13大小的特征图,并以此特征图采用卷积做预测,13*13大小的特征图对检测大物体是足够了,但是对于小物体还需要更精细的特征图(Fine-Grained Features);

SSD使用了多尺度的特征图来分别检测不同大小的物体,前面更精细的特征图可以用来预测小物体;

YOLOv2提出了一种passthrough层来利用更精细的特征图,YOLOv2所利用的Fine-Grained Features是26*26大小的特征图(即最后一个maxpooling层的输入),对于Darknet-19模型来说就是大小为26*26*512的特征图,passthrough层与ResNet的shortcut类似,以前面更高分辨率的特征图为输入,然后将其连接到后面的低分辨率特征图上。前面的特征图维度是后面的特征图的2倍,passthrough层抽取前面层的每个2*2的局部区域,然后将其转化为channel维度,对于26*26*512的特征图,经passthrough层处理之后就变成了13*13*2048的新特征图(特征图大小降低4倍,而channles增加4倍,图6为一个实例),这样就可以与后面的13*13*1024特征图连接在一起形成13*13*3072大小的特征图,然后在此特征图基础上卷积做预测;

另外,作者在后期的实现中借鉴了ResNet网络,不是直接对高分辨特征图处理,而是增加了一个中间卷积层,先采用64个1*1卷积核进行卷积,然后再进行passthrough处理,这样26*26*512的特征图得到13*13*256的特征图;

passthrough层实例:特征图大小降低4倍,而channles增加4倍

使用Fine-Grained Features之后,YOLOv2的性能有1%的提升;

Multi-Scale Training

由于YOLOv2模型中只有卷积层和池化层,所以YOLOv2的输入可以不限于416*416大小的图片,为了增强模型的鲁棒性,YOLOv2采用了多尺度输入训练策略,具体来说就是在训练过程中每间隔一定的迭代次数之后改变模型的输入图片大小;

由于YOLOv2的下采样总步长为32,输入图片大小选择一系列为32倍数的值:{320, 352, ..., 602},输入图片最小为320*320,此时对应的特征图大小为10*10,而输入图片最大为608*608,对应的特征图大小为19*19,在训练过程,每隔10个迭代次数随机选择一种输入图片大小,然后只需要修改对最后检测层的处理就可以重新训练;

采用Multi-Scale Training策略,YOLOv2可以适应不同大小的图片,并且预测出很好的结果;

在测试时,YOLOv2可以采用不同大小的图片作为输入,在VOC 2007数据集上的效果如下图所示,可以看到采用较小分辨率时,YOLOv2的mAP值略低,但是速度更快,而采用高分辨输入时,mAP值更高,但是速度略有下降,对于544*544,mAP高达78.6%;

总的来看,虽然YOLOv2做了很多改进,但是大部分都是借鉴其它论文的一些技巧,如Faster R-CNN的anchor boxes,单尺度特征图的SSD采用anchor boxes和卷积做预测等;

从某种意义上来说,YOLOv2和SSD这两个one-stage模型与RPN网络本质上无异,只不过RPN不做类别的预测,只是简单地区分物体与背景,在two-stage方法中,RPN起到的作用是给出region proposals,其实就是作出粗糙的检测,所以另外增加了一个stage,即采用R-CNN网络来进一步提升检测的准确度(包括给出类别预测);

而对于one-stage方法,它们想要一步到位,直接采用RPN网络作出精确的预测,要因此要在网络设计上做很多的tricks,

YOLOv2的一大创新是采用Multi-Scale Training策略,这样同一个模型其实就可以适应多种大小的图片;

YOLOv2的训练

YOLOv2的训练主要包括三个阶段:

第一阶段就是先在ImageNet分类数据集上预训练Darknet-19,此时模型输入为224*224,共训练160个epochs,

第二阶段将网络的输入调整为448*448,继续在ImageNet数据集上finetune分类模型,训练10个epochs,此时分类模型的top-1准确度为76.5%,而top-5准确度为93.3%,

第三个阶段就是修改Darknet-19分类模型为检测模型,并在检测数据集上继续finetune网络;

YOLOv2训练的三个阶段:

网络修改包括:移除最后一个卷积层、global avgpooling层以及softmax层,并且新增了三个3*3*2014卷积层,同时增加了一个passthrough层,最后使用1*1卷积层输出预测结果,输出的channels数为:num_anchors * (5 + num_classes),和训练采用的数据集有关系。由于anchors数为5,对于VOC数据集输出的channels数就是125,而对于COCO数据集则为425。这里以VOC数据集为例,最终的预测矩阵为T(shape为(batch size , 13, 13, 125)),可以先将其reshape为(batch size , 13, 13, 5, 25),其中T(:, :, :, :, 0:4)为边界框的位置和大小(t_{x}, t_{y}, t_{w}, t_{h})T(:, :, :, :, 4)为边界框的置信度,而T(:, :, :, :, 5:)为类别预测值;

Training for classi?cation

作者使用Darknet-19在标准1000类的ImageNet上训练了160次,用随机梯度下降法,starting learning rate为0.1,polynomial rate decay为4,weight decay为0.0005 ,momentum为0.9。训练的时候仍然使用了很多常见的数据扩充方法(data augmentation),包括random crops, rotations, and hue, saturation, and exposure shifts,初始的224*224训练后把分辨率上调到了448*448,使用同样的参数又训练了10次,学习率调整到了0.001,高分辨率下训练的分类网络top-1准确率76.5%,top-5准确率93.3%;

Training for detection

为了把分类网络改成检测网络,去掉原网络最后一个卷积层,增加了三个 3 * 3 * 1024 ?lters的卷积层,并且在每一个卷积层后面跟一个1 * 1的卷积层,输出维度是检测量,也添加了passthrough layer,从最后3*3*512的卷积层连到倒数第二层,使模型有了细粒度特征,对于VOC数据集,预测5种boxes,每个box包含5个坐标值和20个类别,所以总共是5*(5+20)= 125个输出维度;

学习策略:先以0.001的初始学习率训练了160次,在第60次和第90次的时候学习率减为原来的十分之一,weight decay为0.0005,momentum为0.9,以及类似于Faster-RCNN和SSD的数据扩充(data augmentation)策略: random crops, color shifting, etc,使用相同的策略在COCO和VOC上训练;

先验框匹配(样本选择)

和YOLOv1一样,对于训练图片中的ground truth,若其中心点落在某个cell内,那么该cell内的5个先验框所对应的边界框负责预测它,具体是哪个边界框预测它,需要在训练中确定,即由那个与ground truth的IOU最大的边界框预测它,而剩余的4个边界框不与该ground truth匹配;YOLOv2同样需要假定每个cell至多含有一个grounth truth,而在实际上基本不会出现多于1个的情况,与ground truth匹配的先验框计算坐标误差、置信度误差(此时target为1)以及分类误差,而其它的边界框只计算置信度误差(此时target为0);

训练的损失函数

其中,W、H分别指的是特征图(13*13)的宽与高,而A指的是先验框数目(5),各个\lambda值是各个loss部分的权重系数;

第一项loss是计算background的置信度误差,但是哪些预测框来预测背景呢,需要先计算各个预测框和所有ground truth的IOU值,并且取最大值Max_IOU,如果该值小于一定的阈值(YOLOv2使用的是0.6),那么这个预测框就标记为background,需要计算noobj的置信度误差;

第二项是计算先验框与预测宽的坐标误差,但是只在前12800个iterations间计算,在训练前期使预测框快速学习到先验框的形状;

第三项计算与某个ground truth匹配的预测框各部分loss值,包括坐标误差、置信度误差以及分类误差,对于某个ground truth,首先要确定其中心点要落在哪个cell上,然后计算这个cell的5个先验框与ground truth的IOU值(YOLOv2中bias_match=1),计算IOU值时不考虑坐标,只考虑形状,所以先将先验框与ground truth的中心点都偏移到同一位置(原点),然后计算出对应的IOU值,IOU值最大的那个先验框与ground truth匹配,对应的预测框用来预测这个ground truth,在计算obj置信度时,target=1,但与YOLOv1一样而增加了一个控制参数rescore,当其为1时,target取预测框与ground truth的真实IOU值,对于那些没有与ground truth匹配的先验框(与预测框对应),除去那些Max_IOU低于阈值的,其它的就全部忽略,不计算任何误差;YOLO中一个ground truth只会与一个先验框匹配(IOU值最好的),对于那些IOU值超过一定阈值的先验框,其预测结果就忽略了,这和SSD与RPN网络的处理方式有很大不同,因为它们可以将一个ground truth分配给多个先验框,尽管YOLOv2和YOLOv1计算loss处理上有不同,但都是采用均方差来计算loss;

另外需要注意的一点是,在计算boxes的w和h误差时,YOLOv1中采用的是平方根以降低boxes的大小对误差的影响,而YOLOv2是直接计算,但是根据ground truth的大小对权重系数进行修正:l.coord_scale * (2 - truth.w*truth.h)(这里w和h都归一化到(0,1)),这样对于尺度较小的boxes其权重系数会更大一些,可以放大误差,起到和YOLOv1计算平方根相似的效果;

YOLO9000?

YOLO9000是在YOLOv2的基础上提出的一种可以检测超过9000个类别的模型,其主要贡献点在于提出了一种分类和检测的联合训练策略;

众多周知,检测数据集的标注要比分类数据集打标签繁琐的多,所以ImageNet分类数据集比VOC等检测数据集高出几个数量级;在YOLO中,边界框的预测其实并不依赖于物体的标签,所以YOLO可以实现在分类和检测数据集上的联合训练,对于检测数据集,可以用来学习预测物体的边界框、置信度以及为物体分类,而对于分类数据集可以仅用来学习分类,但是其可以大大扩充模型所能检测的物体种类;

作者选择在COCO和ImageNet数据集上进行联合训练,但是遇到的第一问题是两者的类别并不是完全互斥的,所以作者提出了一种层级分类方法(Hierarchical classification),主要思路是根据各个类别之间的从属关系(根据WordNet)建立一种树结构WordTree,结合COCO和ImageNet建立的WordTree如下图所示:

WordNet以physical object为根结点,然后再将各个标签按照关联关系来构建树的节点,节点之间的连接表示了标签之间的关系(上位/下位关系),WordNet中蓝色的节点表示COCO数据集中的标签,红色的节点表示ImageNet中的标签,树中各个父节点和子节点之间有一种包含关系:physical object包括animal等,animal包括cat、dog等,cat包括tabby、persian等。但是每个子节点和其兄弟节点之间是互斥关系,即每个节点的所有子节点之间是互斥的,因此每个节点下的所有子节点都可以进行softmax操作;

WordTree中的根节点为"physical object",每个节点的子节点都属于同一子类,可以对它们进行softmax处理。在给出某个类别的预测概率时,需要找到其所在的位置,遍历这个path,然后计算path上各个节点的概率之积;

构建WordTree

构建ImageNet和COCO的WordTree的步骤如下:

(1)对于ImageNet和COCO数据集中的每一个样本,都在WordTree中找到对应的节点,如果从根结点到该节点的路径只有一条,那么就将改路径添加到WordTree中,

(2) 经过第一步操作后,剩下的就是存在多条路径的样本,对于这些样本,那就对比每条路径的长度,选择最短的路径加入到WordTree中,

对于所有的样本都按照上述过程构建WordTree,最终树中共有9418个节点,包括ImageNet数据中的9000个标签,COCO数据集中的标签,还有为了构建树额外添加的一些中间标签;

类别表示方式

之前,我们表示一个物体的类别时都是用一个n维向量,其中物体所属类别的那一维值接近于1,其余接近0。使用这种方式的前提是这些类标签之间是互斥的,但是在WordTree中假如一个样本是狗的图片,那么dog节点的概率应该为1,但是dog属于animal,那么animal节点的概率也应该是1,依此类推,根结点physical object的概率也应该是1,所有在WordTree中应该是对应节点到根结点上每一个节点的概率都应该是1,而其余的节点的概率应该为0;

计算概率

类别表示方式不同,那么概率计算的方式肯定也要不同。在文中,计算WordTree中节点的概率时用的是条件概率:P(Norfolk terrier) = P(Norfolk terrier|terrier) * P(terrier|hunting dog) * P(hunting dog|dog) *......* P(animal|physical object) * P(physical object)

其中,P(physical object) = 1。但是在实际中,为了减少计算量,不需要计算出每个节点的概率,在预测物体所属的类别时,我们从根结点开始往下遍历,对于每一个节点,选择其子节点中概率最大的节点往下遍历,直到到达叶节点或节点的概率小于设定的阈值,那么就停止遍历,那停止遍历的这个节点对应的标签就是物体所属的类别;

联合训练

样本:由于ImageNet样本量比COCO大,所以为了平衡,就需要对COCO的样本多进行一些采样(oversampling),然后使得样本数量的比例为4:1,

网络:YOLO9000的网络结构和YOLOv2相同,都是使用Darknet-19,只是在输出上稍作了改进,首先为了减少计算量,将anchor的个数减少为3个,因此输出也变成为13*13*3*(5+9418),

loss:对于检测样本,loss的计算还是依旧,对于ImageNet中的分类样本,YOLO9000会输出只计算分类误差;

在训练时,如果是检测样本,按照YOLOv2的loss计算误差,而对于分类样本,只计算分类误差。在预测时,YOLOv2给出的置信度就是Pr(physical object),同时会给出边界框位置以及一个树状概率图。在这个概率图中找到概率最高的路径,当达到某一个阈值时停止,就用当前节点表示预测的类别,通过联合训练策略,YOLO9000可以快速检测出超过9000个类别的物体。

?

参考

RPN 解析

目标检测|YOLOv2原理与实现(附YOLOv3)?

【目标检测论文阅读】YOLOv2?

目标检测之YOLOv2,最详细的代码解析?

?

仅为学习记录,侵删!

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-07-05 23:31:36  更:2022-07-05 23:32:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/29 8:22:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计