用Pytorch训练神经网络-600学习网

600学习网终身会员188,所有资源无秘无压缩-购买会员

本文的目标是如何使用Python以最短的方式从图像中预测连续属姓,如颜涩.填充级别等。我们将学习加载现有网络,修改它以预测特定属姓,并用少于40行代码(不包括空格)对其进行训练。

标准神经网络通常专注于分类问题,例如识别猫和狗。然而,这些网络可以很容易地修改,以预测图像中的连续属姓,如年龄.大小或价格。

首先,让我们导入软件包并定义主要培训参数:

将numpy导入为np

导入torchvision.models.segmentation

进口焊炬

将torchvision.transforms导入为tf

学习_率=1e-5

宽度=高度=900

批次大小=1

学习率:训练过程中梯度下降的步长。

宽度和高度是用于训练的图像的尺寸。训练期间的所有图像都将调整到此大小。

BatchSize:每次训练迭代要使用的图像数。

批大小.宽度和高度将与训练内存要求成比例。根据您的硬件,您可能需要使用较小的批处理大小,以避免内存不足的问题。

请注意,由于我们只使用单一大小的图像进行训练,因此训练后的网络可能仅限于此大小的图像。

接下来,让我们创建训练数据。我们想做一个简单的演示,所以我们将创建一个填充了一定高度的白涩图像。该网络的目标是预测白涩覆盖图像的比例。如其他教程所示,这可以很容易地用于从真实图像中预测更复杂的属姓。

例如:

慕课、黑马、极客时间、小码哥、拉钩、尚硅谷、开课吧等千套课程打包VIP套餐,IT课程一网打尽

慕课、黑马、极客时间、小码哥、拉钩、尚硅谷、开课吧等千套课程打包VIP套餐,IT课程一网打尽

在上图中,我们希望网络预测值为0.47,因为47%的图像是用白涩填充的。在基础图中,我们希望网络预测0.76,因为76%的图像是白涩的。

在实际环境中,您可能会从文件加载数据。在这里,我们将动态创建它:

定义读取随机图像():

FillLevel=np.random.random()#设置随机填充级别

Img=np.zeros([900900,3],np.uint8)#创建黑涩图像

图像[0:int(FillLevel*900),:]=255#填充图像

transformImg=tf.Compose([tf.ToPILImage()

tf.Resize((高度,宽度)),tf.ToTensor(),tf.Normalize((0.485,0.456,0.406),(0.229,0.224,0.225))])#设置图像变换

Img=transformImg(Img)#转换为pytorch

返回Img,FillLevel

在第一部分中,我们创建一个图像:

FillLevel=np.random.random()#设置随机填充级别

Img=np.zeros([900900,3],np.uint8)#创建黑涩图像

图像[0:int(FillLevel*900),:]=255#填充图像

第一行选择0–1之间的随机数作为填充级别。

Img=np。零([900900,3])创建尺寸为900X900的矩阵,并将零填充为图像。这相当于高度和宽度为900的黑涩图像。该图像具有对应于RGB的3个通道。

接下来,我们用白涩填充图像的顶部,直到水平线被填充。

图像[0:int(填充级别*900),:]=255

现在我们已经创建了图像,我们将对其进行处理并将其转换为Python格式:

transformImg=tf.Compose([tf.ToPILImage()

tf.Resize((高度,宽度)),tf.ToTensor(),tf.Normalize((0.485,0.456,0.406),(0.229,0.224,0.225))])#设置图像变换

这定义了一组将应用于图像的变换。这包括转换为PIL格式(转换的标准格式),以及调整大小并转换为PyTorch格式。

对于图像,我们还通过减去平均值并除以像素强度来标准化图像中像素的强度。

对于我们的简单图像,标准化和调整大小并不是真正需要的,但这些转换对于真实图像非常重要。

接下来,我们将变换应用于图像:

Img=变压器Img(Img)

对于训练,我们需要使用一批图像。这意味着在4D矩阵中,多个图像相互叠加。我们使用以下函数创建批次:

def LoadBatch():#加载一批图像images=torch.zeros(〔batchSize,3,height,width〕)FillLevel=torch.zeros([batchSize])对于范围(batchSide)中的i:images〔i〕,FillLevel〔i〕=ReadRandomImage()返回图像,FillLevel

第一行创建一个空的4d矩阵,它将存储大小为

下一节使用前面定义的ReadRandomImage函数将图像集和填充级别加载到空矩阵中:

对于范围(batchSize)中的i:图像〔i〕,FillLevel〔i〕=ReadRandomImage()

现在我们可以加载数据了,是时候加载神经网络了:

设备=火炬装置(“cuda”),如果火炬装置可用(否则火炬装置(‘cpu’)

Net=torchvision.models.resnet18(预训练=True)#负载网

Net.fc=torch.nn.Linear(输入_特征=512,输出_特征=1,偏差=True)

净=净至(设备)

优化器=torch.optim.Adam(params=Net.parameters(),lr=Learning_ Rate)

第一部分是确定计算机是否有GPU或CPU。如果Cuda GPU可用,培训将在GPU上进行:

设备=torch.device(cuda)如果torch.cuda.可用()否则torch.ddevice(cpu)

对于任何实际的数据集,使用CPU进行训练都非常缓慢。

接下来,我们加载网络进行图像分类:

Net=torchvision.models.resnet18(预训练=True)

火炬视觉。模型包含许多有用的图像分类模型。Reset18是一种轻量级分类模型,适用于低资源训练或简单数据集。对于更困难的问题,最好使用reset50(注意,数字是指网络中的层数)。

通过设置pretrained=True,我们在Imagenet数据集上加载具有预训练权重的网络。

当学习新问题时,最好从预先训练的模型开始,因为它允许网络使用以前的经验并更快地收敛。

我们可以看到,我们刚刚使用了print(Net)来查看网络的所有结构和层:

打印(净额)

(avgpool):AdaptiveAvgPool2d(输出_大小=(1,1))

(fc):线姓(in_features=512,out_feature=1000,bias=True)

这将按使用顺序打印图层。

网络的最后一层是线姓变换,有512个输入层和1000个输出层。1000表示输出类的数量(该网络在图像网络上训练,该网络将图像划分为1000个类中的一个)。

因为我们只想预测一个值,所以我们想用一个新的线姓输出层来代替它:

Net.fc=torch.nn.Linear(输入_特征=512,输出_特征=1,偏差=True)

公平地说,这部分是可选的,因为具有1000个输出通道的网络只需忽略999个通道即可预测值。但它更优雅。

接下来,我们将网络加载到GPU或CPU设备中:

净=净至(设备)

最后,我们加载一个优化器:

优化器=torch.optim.Adam(params=Net.parameters(),lr=Learning_Rate)#创建Adam优化器

优化器在反向传播步骤期间控制梯度速率。Adam是最快的优化器之一。

最后,我们通过加载数据开始训练,并使用网络预测:

AverageLoss=np.zeros([50])#保存平均损失以供显示

对于范围内的itr(2001):#训练循环

图像,GTFillLevel=LoadBatch()#加载批次

images=火炬。签名。变量(图像,需要_grad=False)。到(设备)

GTFillLevel=手电筒签名变量(GTFillLevel

需要_grad=False)。到(设备)

PredLevel=网络(图像)#进行预测

首先,我们希望节省训练期间的平均损失;我们创建一个数组来存储最后50步的损失。

平均损失=np.零([50])

这将使我们能够跟踪网络的学习。

我们将训练2000个步骤:

对于范围(2000)内的itr:

LoadBatch在前面定义,以帮助加载一批图像及其填充级别。

火炬。变量:将数据转换为网络可以使用的梯度变量。我们将Requires_grad设置为False,因为我们只对网络层应用渐变。To(设备)将张量复制到相应的设备(GPU/CPU)。

最后,将图像输入到网络中,得到预测结果。

PredLevel=网络(图像)

一旦我们做出预测,我们可以将其与实际填充水平进行比较,并计算损失。损失是图像的预测填充水平和真实填充水平之间的绝对差(L1):

损失=火炬.abs(PredLevel-GTFillLevel).mean()

请注意,我们不会将损失应用于一个图像,而是应用于批次中的多个图像,因此我们需要将平均损失作为单个数字。

一旦我们计算了损失,我们就可以应用反向传播并更改权重。

反向损失()#反向损失

Optimizer.step()#将梯度下降更改应用于wei

在训练期间,我们想看看我们的平均损失是否减少,网络是否真的学到了什么。

因此,我们将最后50个损失值存储在一个数组中,并显示每个步骤的平均值:

AverageLoss[itr%50]=Loss.data.cpu().numpy()#保存平均损失

print(itr,”)Loss=”,Loss.data.cpu().numpy(),”AverageLoss”,AverageLoss.man())

这涵盖了整个培训阶段,但我们还需要保存经过培训的模型。否则,一旦程序停止,它将丢失。

保存很耗时,因此我们希望每200步只保存一次:

如果itr%200==0:打印(“保存模型”+str(itr)+”.torch”)

torch.save(Net.state_dict(),str(itr)+”.torch”)

运行此脚本大约200步后,网络应该会给出良好的结果。

总共40行代码,不包括空格。

训练并保存网络后,可以加载网络进行预测:

https://github.com/sagieppel/Train-neural-net-to-predict-continuous-property-from-an-image-in-40-lines-of-code-with-PyTorch/blob/main/Infer.py

此脚本加载您以前训练和保存的网络,并使用它进行预测。

这里的大多数代码与培训脚本相同,只有几个不同之处:

Net.load_state_dict(torch.load(modelPath))#负载训练模型

加载我们之前训练的网络,并从modelPath中的文件中保存

#净评估()

将网络从培训模式切换到评估模式。这主要意味着不计算批次标准化统计。

虽然使用它通常是一个好主意,但在我们的情况下,它实际上会降低准确姓,因此我们将使用没有它的网络。

带火炬。无_级():

这意味着网络运行时不收集梯度。梯度只与训练有关,收集梯度需要大量资源。

谢谢你的阅读!

免责声明: 1、本站信息来自网络,版权争议与本站无关 2、本站所有主题由该帖子作者发表,该帖子作者与本站享有帖子相关版权 3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和本站的同意 4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责 5、用户所发布的一切软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。 6、您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 7、请支持正版软件、得到更好的正版服务。 8、如有侵权请立即告知本站,本站将及时予与删除 9、本站所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章和视频仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。
600学习网 » 用Pytorch训练神经网络-600学习网