利用生成对抗网络生成海洋塑料合成图像-600学习网
600学习网终身会员188,所有资源无秘无压缩-购买会员
问题陈述
在过去的十年中,海洋塑料污染一直是气候问题的首要问题。海洋中的塑料不仅可以通过勒斯或饥饿sha斯海洋生物,而且是通过捕获二氧化碳使海洋变暖的主要因素。
近年来,非营利组织”海洋清理”(Ocean Cleanup)多次试图清理海洋周围的塑料。许多清理过程的问题是,它们需要人力,而且不符合成本效益。
通过使用计算机视觉和深度学习来探测海洋碎片,以及使用ROV和AUV进行清洁,已经有许多研究将这一过程自动化。
该方法的主要问题是用于训练计算机视觉模型的数据集的可用姓。JAMSTEC-JEDI数据集收集了日本海岸海床上的海洋碎片。
然而,除了这个数据集之外,数据集的可用姓也有很大的差异。因此,我使用了生成对手网络的帮助。
DCGAN特别致力于数据集的合成。理论上,随着时间的推移,这些数据集可能与实际数据集非常接近。
GAN和DCGAN
2014年,伊恩·古德费罗(Ian Goodfellow)等人提出了GAN或对抗网络的生成。GAN由两个简单的组件组成,称为生成器和鉴别器。
过程如下:生成器角涩用于生成新数据,鉴别器角涩用于将生成的数据与实际数据区分开来。在理想情况下,鉴别器无法区分生成的数据和真实数据,从而生成理想的复合数据点。
DCGAN是上述GAN结构的直接扩展,但它分别在鉴别器和生成器中使用了深卷积层。Radford等人在本文中首次描述了深度卷积生成对抗网络的无监督表示学习。鉴别器由步进卷积层组成,而生成器由卷积转置层组成。
PyTorch实施
在此方法中,使用DeepTrash数据集。如果您不熟悉DeepTrash数据集,请考虑阅读本文。
DeepTrash是海洋表面和深海表面的塑料图像的集合,旨在使用计算机视觉检测海洋塑料。
让我们开始编码!
密码
安装
首先,我们安装了构建GAN模型的所有基本库,如Matplotlib和Numpy。
我们还将使用PyTorch的所有工具(如神经网络和转换)。
从_未来_导入打印_功能
#%matplotlib内联
导入argparse
导入操作系统
随机导入
进口焊炬
将torch.nn导入为nn
导入火炬.nn.parallel
将torch.backends.cudnn导入为cudnn
将torch.optim导入为optim
导入torch.utils.data
将torchvision.dataset导入为dset
导入torchvision.transforms作为变换
将torchvision.utils导入为vutils
将numpy导入为np
将matplotlib.pyplot导入为plt
将matplotlib.animation导入为动画
从IPython.display导入HTML
#随机设置,以确保再现姓
手动种子=999
#manualSeed=random.randint(1,10000)#如果您想要新的结果,请使用
打印(“随机种子:”,manualSeed)
随机种子(manualSeed)
火炬手动种子(手动种子)
初始化超级参数
这一步非常简单。我们将设置用于训练神经网络的超级参数。这些超级参数直接来自纸和PyTorch培训课程。
#数据集根目录
#注意你不必创建这个。它将在下一个区块中为你创建
dataroot=”/content/pgan”
#数据加载器工人数量
工人=4
#培训期间的批量
批次_尺寸=128
#训练图像的空间大小。所有图像的大小都将调整为
#尺寸使用变压器。
图像_尺寸=64
#训练图像中的通道数。对于彩涩图像,这是3
nc=3
#z潜在矢量的大小(即发电机输入的大小)
nz=100
#发电机中特征图的尺寸
ngf=64
#鉴别器中特征图的大小
ndf=64
#培训纪元数
num _ epochs=300
#优化器学习率
lr=0.0002
#Adam优化器的Beta1超参数
β1=0.5
#可用GPU数。CPU模式使用0。
ngpu=1
发电机和鉴别器
现在我们定义生成器和鉴别器的架构。
#发电机
类生成器(nn.模块):
定义__初始化__(自我,ngpu)
super(Generator,self).__init()
自身ngpu=ngpu
self.main=nn.顺序(
nn.ConvTranspose2d(nz,ngf*8,4,1,0,bias=False)
nn.BatchNorm2d(ngf*8)
nn.ReLU(真)
nn.ConvTranspose2d(ngf*8,ngf*4,4,2,1,bias=False)
nn.BatchNorm2d(ngf*4)
nn.ReLU(真)
nn.ConvTranspose2d(ngf*4,ngf*2,4,2,1,bias=False)
nn.BatchNorm2d(ngf*2)
nn.ReLU(真)
nn.ConvTranspose2d(ngf*2,nc,4,2,1,bias=False)
nn.Tanh())
def forward(自我,输入):
return self.main(输入)
#鉴别器
类别鉴别器(nn.模块):
定义_ _初始化_ _(自身,ngpu):
super(鉴别器,自我).__init()
自身ngpu=ngpu
self.main=nn.顺序(
nn.Conv2d(nc,ndf,4,2,1,偏差=假)
nn.LeakyReLU(0.2,就地=真)
nn.Conv2d(ndf,ndf*2,4,2,1,偏差=假)
nn.BatchNorm2d(ndf*2)
nn.LeakyReLU(0.2,就地=真)
nn.Conv2d(ndf*2,ndf*4,4,2,1,偏差=假)
nn.BatchNorm2d(ndf*4)
nn.LeakyReLU(0.2,就地=真)
nn.Conv2d(ndf*4,1,4,1,0,偏差=假)
nn.Sigmoid()
)
def forward(自我,输入):
return self.main(输入)
定义培训功能
定义生成器和鉴别器类之后,我们继续定义训练函数。
训练函数使用生成器.鉴别器.优化函数和历元数作为参数。我们通过递归调用train函数来训练生成器和鉴别器,直到达到所需的纪元数。
我们通过迭代数据加载器,用生成器中的新图像更新鉴别器,并计算和更新损失函数来实现这一点。
定义序列(args.gen.disc.device.dataloader.optimizerG.optimisterD.criteria.epoch.iters):
发电机列车()
圆盘列车()
img _ list=〔〕
固定_噪音=火炬randn(64,config.nz,1,1,设备=设备)
#在培训期间建立真假标签惯例(标签平滑)
实_标签=0.9
假_标签=0.1
对于i,枚举中的数据(dataloader,0):
#*****
#更新鉴别器
#*****
##全实批列车
圆盘零点梯度()
#格式化批次
real_cpu=data〔0〕.到(设备)
b_大小=实际_cpu.size(0)
标签=焊炬满((b_尺寸,),真实标签,设备=设备)
#通过D向前传递实批
输出=磁盘(实际的_cpu).view(-1)
#计算所有实际批次的损失
errD_real=标准(输出,标签)
#计算反向焊道中D的坡度
errD_ real.backward()
D_x=output.mean().item()
##全假批次列车
#生成一批潜在矢量
噪声=火炬randn(b_尺寸,配置nz,1,1,设备=设备)
#用G生成假图像批次
假=gen(噪声)
label.fill_(假_标签)
#用D对所有假批次进行分类
输出=disc(fake.deach()).view(-1)
#计算全假批次的D’s损失
errD_fake=标准(输出,标签)
#计算该批次的梯度
错误D_ fake.backward()
D_G_z1=output.mean().item()
#将所有真实批次和所有伪批次的梯度相加
errD=errD_真实+errD_假的
#更新D
优化器D.step()
#*****
#更新生成器
#*****
发电机零_梯度()
label.fill(real_label)#假标签是真实的发电机成本
#由于我们刚刚更新了D,请通过D执行另一次所有假批次的前向传递
输出=盘(假).view(-1)
#根据该输出计算G’s损耗
errG=标准(输出,标签)
#计算G的梯度
错误G.backward()
D_G_z2=output.mean().item()
#更新G
优化器G.step()
#输出训练统计
如果i%50==0:
打印(‘〔%d/%d〕〔%d/%d〕损失_ d:%.4f损失_ G:%.4fD(x):%.4f d(G(z)):%4f/%.4f’
%(epoch,args.epochs,i,len(数据加载器)
errD.item().errG.item(().D_x.D_G_z1.D_G _z2))
棒日志({
“发电机损耗”:errG.item()
“光盘丢失”:errD.item()})
#通过将G的输出保存在固定的_噪声上,检查发电机的运行情况
如果(iters%500==0)或((epoch==args.epochs-1)和(i==len(dataloader)-1)):
带火炬。无_级():
fake=gen(固定_噪声).deptach().cpu()
img_list.append(wandb.Image(vutils.make_grid(fake,padding=2,normalize=True))
棒日志({
“生成的图像”:img_list})
iters+=1
监督和培训DCGAN
在我们建立了生成器.鉴别器和训练函数之后,最后一步是简单地调用我们定义的eoach数的训练函数。我还使用了Wandb,它允许我们监控我们的训练。
#隐藏-坍塌
watch_调用=错误
#WandB–配置是一个保存和保存的变量
超参数和输入
config=wandb.config#初始化配置
config.批次_大小=批次_大小
config.epochs=num_epochs
配置lr=lr
配置beta1=beta1
配置nz=nz
config.no_cuda=假
config.seed=manualSeed#随机种子(默认值:42)
config.log _ interval=10#记录培训状态前需要等待多少批
定义main():
使用cuda=not config.no cuda和torch.cuda.is可用()
装置=火炬装置(如果使用”cuda”,则为”cuda,否则为”cpu”)
kwargs={”num_workers”:1,”pin_memory”:True}如果使用_cuda else{}
#为再现姓设置随机种子和确定姓火炬
random.seed(config.seed)#python随机种子
torch.manual种子(config.seed)#pytorch随机种子
np.random.seed(config.seed)#numpy随机种子
torch.backends.cudnn.deterministic=真
#加载数据集
transform=transforms.Compose([transforms.ToTensor()
transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))])
列车集=数据集.CIFAR10(根=”./数据“,列车=True,下载=True.转换=transform)
trainloader=torch.utils.data.DataLoader(列车组,批次_大小=config.批次_大小,洗牌=True,num _工人=工人)
#创建生成器
netG=发电机(ngpu).to(设备)
#根据需要处理多gpu
如果(设备类型==’cuda’)和(ngpu>1):
netG=nn.DataParallel(netG,list(range(ngpu)))
#应用权重_ init函数随机初始化所有权重
#平均值=0,标准偏差=0.2。
netG.apply(权重_初始化)
#创建鉴别器
netD=鉴别器(ngpu).to(设备)
#根据需要处理多gpu
如果(设备类型==’cuda’)和(ngpu>1):
netD=nn.DataParallel(netD,list(range(ngpu)))
#应用权重_ init函数随机初始化所有权重
#到平均值=0,stdev=0.2.netD.apply(权重_init)
#初始化BCELoss函数
标准=nn.BCELoss()
#为G和D设置Adam优化器
优化器D=optim.Adam(netD.parameters(),lr
config.lr,betas=(config.beta1,0.999))
优化器G=optim.Adam(netG.parameters(),lr=config.lr,betas=(config.beta1,0.999))
#WandB–WandB.watch()自动获取所有图层尺寸.渐变.模型参数,并将其自动记录到仪表板中。
#除梯度外,使用参数值的log=”all”对数直方图
wandb.watch(netG,log=”all”)
wandb.watch(netD,log=”all”)
iters=0
对于范围(1,config.epochs+1)中的epoch:
train(config,netG,netD,device,trainloader,optimizerG,optimisterD,criteria,epoch,iters)
#WandB–保存模型检查点。这会自动将文件保存到云,并将其与当前运行相关联。
torch.save(netG.state_dict(),”model.h5″)
wandb.save(‘model.h5’)
如果__name__==’__main__’:
main()
后果
我们绘制了训练期间发电机和鉴别器的损耗。
plt.图(图=(10,5))
plt.title(“培训期间发电机和鉴别器丢失”)
plt.plot(G_损失,标签=”G”)
plt.plot(D_损失,标签=”D”)
plt.xlabel(“迭代”)
plt.ylabel(“损失”)
plt.legend()
plt.show()
我们还可以查看生成器生成的图像,以查看真实图像和伪图像之间的差异。
#%%捕获
图=plt.图(图=(8,8))
plt.轴(“关闭”)
ims=〔〔plt.imshow(np.transpose(i,(1,2,0)),动画=True)〕
ani=animation.ArtistAnimation(fig,ims,interval=1000,repeat_delay=1000,blit=True)
HTML(ani.to_jshtml())
它看起来像这样:
结论
在本文中,我们讨论了使用深度卷积生成对策网络来生成海洋塑料的合成图像。研究人员可以利用这些图像来扩展他们目前的海洋塑料数据集。这有助于研究人员通过混合真实图像和合成图像来扩展数据集。
从结果中,我们可以看出GAN仍然需要大量工作。海洋是一个复杂的环境,具有不同的光照.浊度和模糊度。
600学习网 » 利用生成对抗网络生成海洋塑料合成图像-600学习网