当前位置:首页 > 数码 > 终极指南-基于Pytorch的从零开局的指标检测 (终极指南针下载手机版)

终极指南-基于Pytorch的从零开局的指标检测 (终极指南针下载手机版)

admin5个月前 (05-10)数码23

引言

指标检测是计算机视觉中一个十分盛行的义务,在这个义务中,给定一个图像,你预测图像中物体的解围盒(通常是矩形的),并且识别物体的类型。在这个图像中或许有多个对象,而且如今有各种先进的技术和框架来处置这个疑问,例如Faster-RCNN和YOLOv3。

本文将探讨图像中只要一个感兴味的对象的状况。这里的重点更多是关于如何读取图像及其边界框、调整大小和正确口头增强,而不是模型自身。指标是很好地把握对象检测面前的基本思维,你可以对其启动裁减以更好地理解更复杂的技术。

本文中的一切代码都在上方的链接中:。

疑问陈说

给定一个由路标组成的图像,预测路标周围的解围盒,并识别路标的类型。这些路标包含以下四种:

这就是所谓的多义务学习疑问,由于它触及口头两个义务:1)回归找到解围盒坐标,2)分类识别路线标记的类型。

1.数据集

我经常使用了来自Kaggle的路线标记检测数据集,链接如下:

它由877张图像组成。这是一个相当不平衡的数据集,大少数图像属于限速类,但由于我们更关注边界框预测,因此可以疏忽不平衡。

2.加载数据

每个图像的注释都存储在独自的XML文件中。我依照以下步骤创立了训练数据集:

deffilelist(root,file_type):"""Returnsafully-qualifiedlistoffilenamesunderrootdirectory"""return[os.path.join(directory_path,f)fordirectory_path,directory_name,filesinos.walk(root)forfinfilesiff.endswith(file_type)]defgenerate_train_df(anno_path):annotations=filelist(anno_path,'.xml')anno_list=[]foranno_pathinannotations:root=ET.parse(anno_path).getroot()anno={}anno['filename']=Path(str(images_path)+'/'+root.find("./filename").text)anno['width']=root.find("./size/width").textanno['height']=root.find("./size/height").textanno['class']=root.find("./object/name").textanno['xmin']=int(root.find("./object/bndbox/xmin").text)anno['ymin']=int(root.find("./object/bndbox/ymin").text)anno['xmax']=int(root.find("./object/bndbox/xmax").text)anno['ymax']=int(root.find("./object/bndbox/ymax").text)anno_list.end(anno)returnpd.DataFrame(anno_list)
#labelencodetargetclass_dict={'speedlimit':0,'stop':1,'crosswalk':2,'trafficlight':3}df_train['class']=df_train['class'].apply(lambdax:class_dict[x])

3.调整图像和边界框的大小

由于训练一个计算机视觉模型须要的图像是相反的大小,我们须要调整我们的图像和他们相应的解围盒。调整图像的大小很便捷,但是调整解围盒的大小有点辣手,由于每个解围盒都与图像及其尺寸关系。

上方是调整解围盒大小的上班原理:

从调整完大小的掩码中提取边界框坐标。

defcreate_mask(bb,x):"""Createsamaskfortheboundingboxofsameshapeasimage"""rows,cols,*_=x.shapeY=np.zeros((rows,cols))bb=bb.astype(np.int)Y[bb[0]:bb[2],bb[1]:bb[3]]=1.returnYdefmask_to_bb(Y):"""ConvertmaskYtoaboundingbox,assumes0asbackgroundnonzeroobject"""cols,rows=np.nonzero(Y)iflen(cols)==0:returnnp.zeros(4,dtype=np.float32)top_row=np.min(rows)left_col=np.min(cols)bottom_row=np.max(rows)right_col=np.max(cols)returnnp.array([left_col,top_row,right_col,bottom_row],dtype=np.float32)defcreate_bb_array(x):"""Generatesboundingboxarrayfromatrain_dfrow"""returnnp.array([x[5],x[4],x[7],x[6]])
defresize_image_bb(read_path,write_path,bb,sz):"""Resizeanimageanditsboundingboxandwriteimagetonewpath"""im=read_image(read_path)im_resized=cv2.resize(im,(int(1.49*sz),sz))Y_resized=cv2.resize(create_mask(bb,im),(int(1.49*sz),sz))new_path=str(write_path/read_path.parts[-1])cv2.imwrite(new_path,cv2.cvtColor(im_resized,cv2.COLOR_RGB2BGR))returnnew_path,mask_to_bb(Y_resized)
#PopulatingTrainingDFwithnewpathsandboundingboxesnew_paths=[]new_bbs=[]train_path_resized=Path('./road_signs/images_resized')forindex,rowindf_train.iterrows():new_path,new_bb=resize_image_bb(row['filename'],train_path_resized,create_bb_array(row.values),300)new_paths.append(new_path)new_bbs.append(new_bb)df_train['new_path']=new_pathsdf_train['new_bb']=new_bbs

4.数据增强

数据增强是一种经过经常使用现有图像的不同变体创立新的训练图像来更好地概括我们的模型的技术。我们以后的训练集中只要800张图像,因此数据增强关于确保我们的模型不会过拟合十分关键。

关于这个疑问,我经常使用了翻转、旋转、中心裁剪和随机裁剪。

这里惟一须要记住的是确保解围盒也以与图像相反的方式启动转换。

#modifiedfromfast.aidefcrop(im,r,c,target_r,target_c):returnim[r:r+target_r,c:c+target_c]#randomcroptotheoriginalsizedefrandom_crop(x,r_pix=8):"""Returnsarandomcrop"""r,c,*_=x.shapec_pix=round(r_pix*c/r)rand_r=random.uniform(0,1)rand_c=random.uniform(0,1)start_r=np.floor(2*rand_r*r_pix).astype(int)start_c=np.floor(2*rand_c*c_pix).astype(int)returncrop(x,start_r,start_c,r-2*r_pix,c-2*c_pix)defcenter_crop(x,r_pix=8):r,c,*_=x.shapec_pix=round(r_pix*c/r)returncrop(x,r_pix,c_pix,r-2*r_pix,c-2*c_pix)
defrotate_cv(im,deg,y=False,mode=cv2.BORDER_REFLECT,interpolation=cv2.INTER_AREA):"""Rotatesanimagebydegdegrees"""r,c,*_=im.shapeM=cv2.getRotationMatrix2D((c/2,r/2),deg,1)ify:returncv2.warpAffine(im,M,(c,r),borderMode=cv2.BORDER_CONSTANT)returncv2.warpAffine(im,M,(c,r),borderMode=mode,flags=cv2.WARP_FILL_OUTLIERS+interpolation)defrandom_cropXY(x,Y,r_pix=8):"""Returnsarandomcrop"""r,c,*_=x.shapec_pix=round(r_pix*c/r)rand_r=random.uniform(0,1)rand_c=random.uniform(0,1)start_r=np.floor(2*rand_r*r_pix).astype(int)start_c=np.floor(2*rand_c*c_pix).astype(int)xx=crop(x,start_r,start_c,r-2*r_pix,c-2*c_pix)YY=crop(Y,start_r,start_c,r-2*r_pix,c-2*c_pix)returnxx,YYdeftransformsXY(path,bb,transforms):x=cv2.imread(str(path)).astype(np.float32)x=cv2.cvtColor(x,cv2.COLOR_BGR2RGB)/255Y=create_mask(bb,x)iftransforms:rdeg=(np.random.random()-.50)*20x=rotate_cv(x,rdeg)Y=rotate_cv(Y,rdeg,y=True)ifnp.random.random()>0.5:x=np.fliplr(x).copy()Y=np.fliplr(Y).copy()x,Y=random_cropXY(x,Y)else:x,Y=center_crop(x),center_crop(Y)returnx,mask_to_bb(Y)
defcreate_corner_rect(bb,):bb=np.array(bb,dtype=np.float32)returnplt.Rectangle((bb[1],bb[0]),bb[3]-bb[1],bb[2]-bb[0],color=color,fill=False,lw=3)defshow_corner_bb(im,bb):plt.imshow(im)plt.gca().add_patch(create_corner_rect(bb))

图片

5.PyTorch数据集

如今我们曾经有了数据增强,我们可以启动训练验证拆分并创立我们的PyTorch数据集。我们经常使用Imag统计数据对图像启动规范化,由于我们经常使用的是预训练的ResNet模型并在训练时在我们的数据集中运行数据增强。

X_train,X_val,y_train,y_val=train_test_split(X,Y,test_size=0.2,random_state=42)
defnormalize(im):"""NormalizesimageswithImagenetstats."""imagenet_stats=np.array([[0.485,0.456,0.406],[0.229,0.224,0.225]])return(im-imagenet_stats[0])/imagenet_stats[1]
classRoadDataset(Dataset):def__init__(self,paths,bb,y,transforms=False):self.transforms=transformsself.paths=paths.valuesself.bb=bb.valuesself.y=y.valuesdef__len__(self):returnlen(self.paths)def__getitem__(self,idx):path=self.paths[idx]y_class=self.y[idx]x,y_bb=transformsXY(path,self.bb[idx],self.transforms)x=normalize(x)x=np.rollaxis(x,2)returnx,y_class,y_bb
train_ds=RoadDataset(X_train['new_path'],X_train['new_bb'],y_train,transforms=True)valid_ds=RoadDataset(X_val['new_path'],X_val['new_bb'],y_val)
batch_size=64train_dl=>classBB_model(nn.Module):def__init__(self):super(BB_model,self).__init__()resnet=models.resnet34(pretrained=True)layers=list(resnet.children())[:8]self.features1=nn.Sequential(*layers[:6])self.features2=nn.Sequential(*layers[6:])self.classifier=nn.Sequential(nn.BatchNorm1d(512),nn.Linear(512,4))self.bb=nn.Sequential(nn.BatchNorm1d(512),nn.Linear(512,4))defforward(self,x):x=self.features1(x)x=self.features2(x)x=F.relu(x)x=nn.AdaptiveAvgPool2d((1,1))(x)x=x.view(x.shape[0],-1)returnself.classifier(x),self.bb(x)

7.训练

关于损失,我们须要同时思考分类损失和边界框回归损失,因此我们经常使用交叉熵和L1损失(实在值和预测坐标之间的一切相对差之和)的组合。我曾经将L1损失缩放了1000倍,由于分类和回归损失都在相似的范围内。除此之外,它是一个规范的PyTorch训练循环(经常使用GPU):

defupdate_optimizer(optimizer,lr):fori,param_groupinenumerate(optimizer.param_groups):param_group["lr"]=lr
deftrain_epocs(model,optimizer,train_dl,val_dl,epochs=10,C=1000):idx=0foriinrange(epochs):model.train()total=0sum_loss=0forx,y_class,y_bbintrain_dl:batch=y_class.shape[0]x=x.cuda().float()y_class=y_class.cuda()y_bb=y_bb.cuda().float()out_class,out_bb=model(x)loss_class=F.cross_entropy(out_class,y_class,)loss_bb=F.l1_loss(out_bb,y_bb,).sum(1)loss_bb=loss_bb.sum()loss=loss_class+loss_bb/Coptimizer.zero_grad()loss.backward()optimizer.step()idx+=1total+=batchsum_loss+=loss.item()train_loss=sum_loss/totalval_loss,val_acc=val_metrics(model,valid_dl,C)print("train_loss%.3fval_loss%.3fval_acc%.3f"%(train_loss,val_loss,val_acc))returnsum_loss/total
defval_metrics(model,valid_dl,C=1000):model.eval()total=0sum_loss=0correct=0forx,y_class,y_bbinvalid_dl:batch=y_class.shape[0]x=x.cuda().float()y_class=y_class.cuda()y_bb=y_bb.cuda().float()out_class,out_bb=model(x)loss_class=F.cross_entropy(out_class,y_class,)loss_bb=F.l1_loss(out_bb,y_bb,).sum(1)loss_bb=loss_bb.sum()loss=loss_class+loss_bb/C_,pred=torch.max(out_class,1)correct+=pred.eq(y_class).sum().item()sum_loss+=loss.item()total+=batchreturnsum_loss/total,correct/total
model=BB_model().cuda()parameters=filter(lambdap:p.requires_grad,model.parameters())optimizer=torch.optim.Adam(parameters,lr=0.006)
train_epocs(model,optimizer,train_dl,valid_dl,epochs=15)

8.测试

如今我们曾经成功了训练,我们可以选用一个随机图像并在上方测试我们的模型。虽然我们只要相当大批的训练图像,但是我们最终在测试图像上获取了一个相当不错的预测。

经常使用手机拍摄实在照片并测试模型将是一项幽默的练习。另一个幽默的试验是不口头任何数据增强并训练模型并比拟两个模型。

#resizingtestimageim=read_image('./road_signs/images_resized/road789.png')im=cv2.resize(im,(int(1.49*300),300))cv2.imwrite('./road_signs/road_signs_test/road789.jpg',cv2.cvtColor(im,cv2.COLOR_RGB2BGR))
#test>xx=torch.FloatTensor(x[None,])xx.shape
#predictionout_class,out_bb=model(xx.cuda())out_class,out_bb

总结

如今我们曾经引见了指标检测的基本原理,并从头开局成功它,您可以将这些想法裁减到多对象状况,并尝试更复杂的模型,如RCNN和YOLO!


Pytorch Lightning系列 如何使用ModelCheckpoint

在训练机器学习模型时,经常需要缓存模型。 ModelCheckpoint 是Pytorch Lightning中的一个Callback,它就是用于模型缓存的。 它会监视某个指标,每次指标达到最好的时候,它就缓存当前模型。 Pytorch Lightning文档介绍了ModelCheckpoint的详细信息。 我们来看几个有趣的使用示例。 示例1 注意,我们把epoch和val_loss信息也加入了模型名称。 示例2 这个使用例子非常像示例1,唯一的差别在于指标的名称是由我们自己指定的,而不是由Pytorch Lightning自动生成的 ( auto_insert_metric_name=False )。 通过这样的方式,我们可以使用类似 val/mrr 的指标名。 从而统一tensorboard和pytorch lightning对指标的不同描述方式。 Pytorch Lightning把ModelCheckpoint当作最后一个CallBack,也就是它总是在最后执行。 这一点在我看来很别扭。 如果你在训练过程中想获得best_model_score或者best_model_path,它对应的是上一次模型缓存的结果,而并不是最新的模型缓存结果

干货分享 | AI研发工程师成长指南

0x00 前言

首先,《AI研发工程师成长指南》这个题目其实有些标题党了,准确地来说,本文内容应该是:“要想成为一名AI研发工程师,需要具备哪些技能”。

其次,本文对“AI研发工程师”这个title的定义,也并不是大家第一印象中的“算法工程师”、“数据科学家”。

再次,本文实际上作者结合现阶段行业发展、技术趋势以及自身工作性质做出的关于自身定位、职业技能、发展方向的思考。就像魔兽世界中的“职业攻略”,当我们在游戏中新建一个角色时,会先去了解这个职业的特点、天赋、技能树等信息,这样才会在“练级”的过程中少走些弯路。

最后,作者不是从一个很高的角度来对整个成长体系进行一个全面地阐述。而是站在道路的地点,不断摸索、不断前进、不断地调整自己的规划。因此本文不算是Best Practices,勉强算是Beta version,也希望能和大家不断交流,不断“发版”。

0x01 关于AI行业的思考

算法工程师的门槛

AI算法工程师年薪百万,应届毕业生年薪都有80w… 去年AI人才缺口就已经过百万,今年将达500w… 加入《XXX训练营》,XX天打造AI算法工程师…

在网络上充斥着各种类似上面那样的吸引眼球的文章标题,向你诉说着人工智能这一火的不能再火的领域美好的前景。仿佛我们看了两遍西瓜书、处理了MNIST和几朵鸢尾花、在自己的笔记本电脑上掉了几个包、得到了和教程上一样的结果,打了几场比赛,我们就已经拿到了AI领域的通行证、成功转型算法工程师、接大厂offer到手软了一样。

但实际,现在AI算法工程师的就业难度和准入门槛,远比我们想象的要高。

上一张网络上流传的“诸神黄昏”吧

可以说一点不夸张,现在很多大厂的校招算法岗,门槛就是海外名校/985工科院校的博士/硕士。除了拥有与学历匹配的学术能力以外,工程基础也要非常扎实。

有人说:“我看网上说,AI人才缺口非常大,我不去大厂不就行了?其他的公司要求没那么高吧?”

要求高不高我不知道,但是有一下两点:

绝大多数公司,是不需要雇佣AI算法工程师,即没有相关的业务需求,也负担不起算法团队的开销 2019年研究生报考人数290万人,预计招生70万人,其中计算机是热门专业,并且其中多数人的研究方向都是: 机器学习、数据挖掘之类。

此间竞争之激烈,诸如此类,虽未得其皮毛,也略见一斑。

AI企业痛点

当然,我说这些不是为了打击大家的信心,而是要指出现在行业内的痛点:AI工程化。

人工智能发展到现阶段,已经从实验室中的算法走向了工程化应用的阶段。但是算法落地并没有想象中的顺利,开始有越来越多诸如场景碎片化、应用成本高、实验室场景到实际应用场景效果差距较大等问题被暴露出来,而这些也成为当前阶段AI落地应用过程中新的痛点。

领域内高水平的paper都是公开发表的,除了少数的核心算法,人才济济的AI企业很难在算法性能上与友商拉开距离。那么AI企业想要商业化,想要创收,行业细分领域纵深成了决定成败的重要因素。需要下沉到业务领域,真刀真枪地进行拼杀。

基于Pytorch的从零开局的指标检测

在技术突破-商业化-产品化-工程化的阶段路线中,除了技术强,接下来还有很多路要走。谁能够更好更快地把算法从实验室中拿出来、卖出去;更好更快地将模型交付到业务场景,真正产生实际的价值,让客户满意,谁才能活得更久。

对于Scientist/Researcher而言,技术可以是一篇论文、一项 ImageNet 竞赛的冠军、也可以是一个重要数值(比如人脸识别准确率)的突破;但在商务侧来说,论文与冠军并不实用,如果技术无法融进安防、汽车、金融等行业,变成切切实实的产品,客户与合作伙伴就会拒绝买单。

对于AI企业来说,能否深入了解各行业的业务流程、业务规则、知识经验,进而将技术能力转化为业务解决方案创造价值,是发展的保障。

那么对于我们个人来说,应该如何发展呢?

0x02 AI研发

AI工程化

在《ML/DL科普向:从sklearn到tensorflow》一文中,我们谈到:

还是基于这个观点,我决定将自身的技能树偏向企业需要的第二种人,也就是标题所提出的“AI研发工程师”。从实际的工程应用角度出来,focus人工智能项目落地的全流程以及解决方法,提高自己的AI工程化能力,以此作为个人核心竞争力。

AI项目全流程

网络上很多文章描述的所谓“机器学习项目全流程”,例如:数据收集处理、特征工程、训练模型、模型测试等等。这套流程对不对?对。但是远远不能满足企业的需求。

AI项目是团队创造出的具有商业价值的产品、服务以及交付产物。有着明确的需求、计划、周期、成本、交付流程以及验收标准。

以下以toB业务为例,对AI项目全流程进行简单梳理。toC业务大体如此,只是将客户替换成公司业务方即可。

初步需求沟通确认 该环节主要是由销售、售前完成。了解客户的基本情况,辅助客户根据自身业务挖掘AI应用场景。根据实际的业务需求、数据质量、硬件资源、期望产物来评估具体的方案以及建模思路。 POC阶段 Proof of Concept。在完成初步的评估之后,团队需要针对客户具体应用进行验证性测试,包括确定业务场景边界、业务评判指标、数据调研、资源需求、硬件/平台部署等。 场景方案确认 该环节需要售前、科学家、工程师等多角色与客户进行细致的场景沟通,明确需求、确定验收标准、评估工作量。因为该阶段结束后即输出SOW方案,因此需要反复沟通商榷。 建模开发阶段 4.1项目详细规划 项目经理根据前期资料提供详细的方案设计、功能清单、资源投入、里程碑安排等内容,召开项目启动会,明确项目内容及分工职责。 4.2数据处理 科学家在明确业务场景及需求后,对数据处理。其内容包括:数据质量检查、ETL处理(工作量较大)。还要对清洗后的数据进行探索性数据分析(Exploratory Data Analysis)以及可视化展示。EDA能够帮助我们在探索阶段初步了解数据的结构及特征,甚至发现一些模式和模型 4.3特征工程 根据探索性分析得到的输出,结合对具体业务的理解,对分散的数据拼表并进行特征工程。 4.4建模 形成初版建模,并对根据业务需求评估标准进行效果验证。后续需要不断进行模型迭代,直到满足需求,并做模型效果汇报。 4.5系统研发 将训练好的模型发布服务、部署上线,开发外围对接系统以及部分定制化功能的开发。输出可运行的系统。 测试上线 对系统进行流程测试、性能测试,满足需求后对项目进行交付&验收。0x03 核心竞争力&技能树

核心竞争力

通过对AI项目全流程的介绍,我们将目光瞄准到“建模开发阶段”的“系统研发”部分。虽然在上面只是一句话带过,但是其中的工作量和技术含量不小。

提起机器学习,尤其是深度学习,大家可能会对诸如Tensorflow,Pytorch,Caffee的工具耳熟能详。但其实在实际的机器学习的生命周期中,训练模型(上述工具主要解决的问题)只是整个机器学习生命周期的很小一部分。

数据如何准备?如何保证线上线下一致性?模型训练好了如何分布式部署?如何构建HA?需要批量处理还是实时处理?实时数据如何拼接?如何对模型服务进行监控、告警?做成PaaS还是MLaaS?

机器学习具有天然的Pipline特性,在企业需求中,大大小小的业务场景有众多的模型,这些模型如何进行打包、处理、发布?离线训练、批量预估、实施预估、自学习等任务类型交错,不同建模工具Sklearn、Tensorflow,Pytorch构造的模型如何进行整合?开发框架Spark ML、Flink ML等如何协同、对接。生产环境如何进行扩展和伸缩?如何支持AB Test?

为了解决这些问题,新生的开源框架层出不穷:Google自研的对接Kubernets和Tensorflow的开源平台Kubeflow;Spark团队打造的ML pipelines辅助工具MLflow;雅虎提供的机器学习及服务平台BigML;阿里巴巴推出的分布式机器学习平台SQLflow等等。众多厂商纷纷发力,目的就是解决AI工程化应用的痛点。

这些工作都是需要一大批工程师去完成。因此,我认为了解AI工程化场景、解决方案;熟悉AI项目流程、机器学习Pipline;掌握AI系统研发、服务部署上线能力的工程师将会逐渐成为AI团队的中坚力量。

技能树

之前铺垫了那么多,既是梳理思路,也是为接下来的系列做一个开篇。按照我的初步计划,技能树大概包括(不分先后):

工程能力: 身为工程师首先要有工程能力,springboot/Netty/Thrift/等相关工具框架一定要掌握,微服务是机器学习平台的基础。 Spark SQL、Spark ML等更是大数据工程师用来做机器学习的利器,不但要掌握、更要从中抽象出流程和处理方法。 容器化: docker和k8s现在几乎是机器学习部署的必备技能,也是众多平台的基础。 是重要的前置技能。 机器学习&深度学习: 不要求能够手推算法、模型优化,但要能够了解含义、上手使用,起码要成为一名优秀的调包侠(也便于吹水)。 开源框架: 其实我最近打算学习kubeflow,并输出学习笔记及总结实践。 本文其实是这个系列的开篇。 当然,后续还有有调整。0xFF 后记

其实这种类型的文章,比单纯的学习笔记、技术文章难写多了。一方面,拖延症迫使我把难写的文章放在后面写,另一方面,强迫症又迫使我一定要在系列前出一个开篇。其实写到最后,总觉得核心部分还差点儿意思,没有搔到痒处,这是因为目前我还没有能力站在一个全局的角度对职业技术体系进行划分,只能梳理出目前的规划和看法。后续要还需和朋友们进行交流。

有些事情是一定要做的,纵观一些大牛前辈,无一不是在正确的时候做了正确的事。明确自己的目标,在前进的道路上不断微调自己的方向,这样才能在这个竞争激烈的职业中生存下去。

接下来会有系列的技术学习笔记,考虑到学习的连贯性,前期可能是一些基础的docker/k8s等系列,后期会研究一些开源框架。技术文章可能会枯燥乏味,知识点也缺乏新意,但是经过自己的整理和实践,再加上自身的理解感悟,相信会不断完善自己的知识体系。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: Pytorch

“终极指南-基于Pytorch的从零开局的指标检测 (终极指南针下载手机版)” 的相关文章

CNN-开发指南-Pytorch-核心要点突破 (CNN开发语言)

CNN-开发指南-Pytorch-核心要点突破 (CNN开发语言)

卷积神经网络 (CNN) 是一种深度学习模型,用于处理图像、视频和音频等多维数据。它们在图像分类、对象检测、图像生成等领域有着广泛的应用。 原理 CNN 的核心思想是...