基于深度学习神经网络的AI图像PSD去雾系统源码

第一步:PSD介绍

        以往的研究主要集中在具有合成模糊图像的训练模型上,当模型用于真实世界的模糊图像时,会导致性能下降。

        为了解决上述问题,提高去雾的泛化性能,作者提出了一种Principled Synthetic-to-real Dehazing (PSD)框架。

        本文提出的PSD适用于将现有的去雾模型推广到实际领域,包括两个阶段:有监督的预训练无监督的微调

        预训练阶段,作者将选定的去雾模型主干修改为一个基于物理模型的网络,并用合成数据训练该网络。利用设计良好的主干,我们可以得到一个预先训练的模型,在合成域上具有良好的去雾性能。

        微调阶段,作者利用真实的模糊图像以无监督的方式训练模型。

本文的贡献:

  1. 作者将真实世界的去雾任务重新定义为一个合成到真实的泛化框架:首先一个在合成配对数据上预先训练的去雾模型主干,真实的模糊图像随后将被利用以一种无监督的方式微调模型。PSD易于使用,可以以大多数深度去雾模型为骨干。
  2. 由于没有清晰的真实图像作为监督,作者利用几个流行的、有充分根据的物理先验来指导微调。作者将它们合并成一个预先的损失committee,作为具体任务的代理指导,这一部分也是PSD的核心。
  3. 性能达到SOTA

第二步:PSD网络结构

        首先对两个框架大的方向做一个整体概述:

        Pre-training

        首先采用目前性能最好的框架之一作为网络的主干

        然后我们将主干修改为一个基于物理的网络,根据一个单一的雾图同时生成干净的图像 J,传输图 t 和大气光 A,为了共同优化这三个分量,作者加入了一个重建损失,它引导网络输出服从物理散射模型。

        在这个阶段,只使用标记的合成数据进行训练,最终得到一个在合成域上预训练的模型。

        Fine-tuning

        作者利用未标记的真实数据将预训练模型从合成域推广到真实域。受去雾强物理背景的启发,作者认为一个高质量的无雾图像应该遵循一些特定的统计规则,这些规则可以从图像先验中推导出来。此外,单一先验提供的物理知识并不总是可靠的,所以作者的目标是找到多个先验的组合,希望它们能够相互补充。

        基于上述,作者设计了一个先验损失committee来作为任务特定的代理指导,用于训练未标记的真实数据

        此外,作者应用了一种learning without forgetting (LwF)的方法,该方法通过将原始任务的训练数据(即合成的模糊图像)通过网络运转到同真实的模糊数据一起,从而强行使得模型记忆合成领域的知识。

第三步:模型代码展示

import torch
import torch.nn as nn
import torch.nn.functional as F

class BlockUNet1(nn.Module):
    def __init__(self, in_channels, out_channels, upsample=False, relu=False, drop=False, bn=True):
        super(BlockUNet1, self).__init__()

        self.conv = nn.Conv2d(in_channels, out_channels, 4, 2, 1, bias=False)
        self.deconv = nn.ConvTranspose2d(in_channels, out_channels, 4, 2, 1, bias=False)

        self.dropout = nn.Dropout2d(0.5)
        self.batch = nn.InstanceNorm2d(out_channels)

        self.upsample = upsample
        self.relu = relu
        self.drop = drop
        self.bn = bn

    def forward(self, x):
        if self.relu == True:
            y = F.relu(x)
        elif self.relu == False:
            y = F.leaky_relu(x, 0.2)
        if self.upsample == True:
            y = self.deconv(y)
            if self.bn == True:
                y = self.batch(y)
            if self.drop == True:
                y = self.dropout(y)

        elif self.upsample == False:
            y = self.conv(y)
            if self.bn == True:
                y = self.batch(y)
            if self.drop == True:
                y = self.dropout(y)

        return y

class G2(nn.Module):
    def __init__(self, in_channels, out_channels):
        super(G2, self).__init__()

        self.conv = nn.Conv2d(in_channels, 8, 4, 2, 1, bias=False)
        self.layer1 = BlockUNet1(8, 16)
        self.layer2 = BlockUNet1(16, 32)
        self.layer3 = BlockUNet1(32, 64)
        self.layer4 = BlockUNet1(64, 64)
        self.layer5 = BlockUNet1(64, 64)
        self.layer6 = BlockUNet1(64, 64)
        self.layer7 = BlockUNet1(64, 64)
        self.dlayer7 = BlockUNet1(64, 64, True, True, True, False)
        self.dlayer6 = BlockUNet1(128, 64, True, True, True)
        self.dlayer5 = BlockUNet1(128, 64, True, True, True)
        self.dlayer4 = BlockUNet1(128, 64, True, True)
        self.dlayer3 = BlockUNet1(128, 32, True, True)
        self.dlayer2 = BlockUNet1(64, 16, True, True)
        self.dlayer1 = BlockUNet1(32, 8, True, True)
        self.relu = nn.ReLU()
        self.dconv = nn.ConvTranspose2d(16, out_channels, 4, 2, 1, bias=False)
        self.lrelu = nn.LeakyReLU(0.2)

    def forward(self, x):
        y1 = self.conv(x)
        y2 = self.layer1(y1)
        y3 = self.layer2(y2)
        y4 = self.layer3(y3)
        y5 = self.layer4(y4)
        y6 = self.layer5(y5)
        y7 = self.layer6(y6)
        y8 = self.layer7(y7)

        dy8 = self.dlayer7(y8)
        concat7 = torch.cat([dy8, y7], 1)
        dy7 = self.dlayer6(concat7)
        concat6 = torch.cat([dy7, y6], 1)
        dy6 = self.dlayer5(concat6)
        concat5 = torch.cat([dy6, y5], 1)
        dy5 = self.dlayer4(concat5)
        concat4 = torch.cat([dy5, y4], 1)
        dy4 = self.dlayer3(concat4)
        concat3 = torch.cat([dy4, y3], 1)
        dy3 = self.dlayer2(concat3)
        concat2 = torch.cat([dy3, y2], 1)
        dy2 = self.dlayer1(concat2)
        concat1 = torch.cat([dy2, y1], 1)
        out = self.relu(concat1)
        out = self.dconv(out)
        out = self.lrelu(out)

        return F.avg_pool2d(out, (out.shape[2], out.shape[3]))
    
def default_conv(in_channels, out_channels, kernel_size, bias=True):
    return nn.Conv2d(in_channels, out_channels, kernel_size,padding=(kernel_size//2), bias=bias)
    
class PALayer(nn.Module):
    def __init__(self, channel):
        super(PALayer, self).__init__()
        self.pa = nn.Sequential(
                nn.Conv2d(channel, channel // 8, 1, padding=0, bias=True),
                nn.ReLU(inplace=True),
                nn.Conv2d(channel // 8, 1, 1, padding=0, bias=True),
                nn.Sigmoid()
        )
    def forward(self, x):
        y = self.pa(x)
        return x * y

class CALayer(nn.Module):
    def __init__(self, channel):
        super(CALayer, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.ca = nn.Sequential(
                nn.Conv2d(channel, channel // 8, 1, padding=0, bias=True),
                nn.ReLU(inplace=True),
                nn.Conv2d(channel // 8, channel, 1, padding=0, bias=True),
                nn.Sigmoid()
        )

    def forward(self, x):
        y = self.avg_pool(x)
        y = self.ca(y)
        return x * y

class Block(nn.Module):
    def __init__(self, conv, dim, kernel_size,):
        super(Block, self).__init__()
        self.conv1=conv(dim, dim, kernel_size, bias=True)
        self.act1=nn.ReLU(inplace=True)
        self.conv2=conv(dim,dim,kernel_size,bias=True)
        self.calayer=CALayer(dim)
        self.palayer=PALayer(dim)
    def forward(self, x):
        res=self.act1(self.conv1(x))
        res=res+x 
        res=self.conv2(res)
        res=self.calayer(res)
        res=self.palayer(res)
        res += x 
        return res
class Group(nn.Module):
    def __init__(self, conv, dim, kernel_size, blocks):
        super(Group, self).__init__()
        modules = [ Block(conv, dim, kernel_size)  for _ in range(blocks)]
        modules.append(conv(dim, dim, kernel_size))
        self.gp = nn.Sequential(*modules)
    def forward(self, x):
        res = self.gp(x)
        res += x
        return res

class FFANet(nn.Module):
    def __init__(self,gps,blocks,conv=default_conv):
        super(FFANet, self).__init__()
        self.gps=gps
        self.dim=64
        kernel_size=3
        pre_process = [conv(3, self.dim, kernel_size)]
        assert self.gps==3
        self.g1= Group(conv, self.dim, kernel_size,blocks=blocks)
        self.g2= Group(conv, self.dim, kernel_size,blocks=blocks)
        self.g3= Group(conv, self.dim, kernel_size,blocks=blocks)
        self.ca=nn.Sequential(*[
            nn.AdaptiveAvgPool2d(1),
            nn.Conv2d(self.dim*self.gps,self.dim//16,1,padding=0),
            nn.ReLU(inplace=True),
            nn.Conv2d(self.dim//16, self.dim*self.gps, 1, padding=0, bias=True),
            nn.Sigmoid()
            ])
        self.palayer=PALayer(self.dim)

        self.conv_J_1 = nn.Conv2d(64, 64, 3, 1, 1, bias=False)
        self.conv_J_2 = nn.Conv2d(64, 3, 3, 1, 1, bias=False)
        self.conv_T_1 = nn.Conv2d(64, 16, 3, 1, 1, bias=False)
        self.conv_T_2 = nn.Conv2d(16, 1, 3, 1, 1, bias=False)
        
        post_precess = [
            conv(self.dim, self.dim, kernel_size),
            conv(self.dim, 3, kernel_size)]

        self.pre = nn.Sequential(*pre_process)
        self.post = nn.Sequential(*post_precess)
        self.ANet = G2(3, 3)

    def forward(self, x1, x2=0, Val=False):
        x = self.pre(x1)
        res1=self.g1(x)
        res2=self.g2(res1)
        res3=self.g3(res2)
        w=self.ca(torch.cat([res1,res2,res3],dim=1))
        w=w.view(-1,self.gps,self.dim)[:,:,:,None,None]
        out=w[:,0,::]*res1+w[:,1,::]*res2+w[:,2,::]*res3
        out=self.palayer(out)
        
        out_J = self.conv_J_1(out)
        out_J = self.conv_J_2(out_J)
        out_J = out_J + x1
        out_T = self.conv_T_1(out)
        out_T = self.conv_T_2(out_T)
        
        if Val == False:
            out_A = self.ANet(x1)
        else:
            out_A = self.ANet(x2)
            
        out_I = out_T * out_J + (1 - out_T) * out_A
        #x=self.post(out)
        return out, out_J, out_T, out_A, out_I
    
if __name__ == "__main__":
    net=FFA(gps=3,blocks=19)
    print(net)

第四步:运行

第五步:整个工程的内容

代码的下载路径(新窗口打开链接)基于深度学习神经网络的AI图像PSD去雾系统源码

​​

有问题可以私信或者留言,有问必答

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/618031.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STC8增强型单片机开发【LED呼吸灯(PWM)⭐⭐】

目录 一、引言 二、硬件准备 三、PWM技术概述 四、电路设计 五、代码编写 EAXSFR: 六、编译与下载 七、测试与调试 八、总结 一、引言 在嵌入式系统开发中,LED呼吸灯是一种常见的示例项目,它不仅能够展示PWM(脉冲宽度调制…

2024 cleanmymac有没有必要买呢,全反面分析

在使用mac时,小编遇到了运行内存不足、硬盘空间不足的情况。遇到这种情况,我们可以借助经典的电脑深度清理软件——CleanMyMac X,清理不常用的软件和系统垃圾,非常好用!不过,有许多网友发现CleanMyMac X有免…

SQLite利用事务实现批量插入(提升效率)

在尝试过SQLite批量插入一百万条记录,执行时长高达20多分钟后,就在想一个问题,这样的性能是不可能被广泛应用的,更不可能出现在真实的生产环境中,那么对此应该如何优化一下呢? 首先分析一下批量插入的逻辑 …

社区送水小程序软件开发

uni-app框架:使用Vue.js开发跨平台应用的前端框架,编写一套代码,可编译到Android、小程序等平台。 框架支持:springboot/Ssm/thinkphp/django/flask/express均支持 前端开发:vue.js 可选语言:pythonjavanode.jsphp均支持 运行软件…

端午节线上活动方案怎么写?

一年一端午,一岁一安康。 如果您想组织端午活动,却不知道如何安排,可以看看何策网,有很多案例参考,仿造模板修改即可。 下面分享一个线上端午节活动策划方案,希望能帮到你! 端午节作为祭祖祈…

Remix 集成 MUI

Remix 如何接入 MUI 组件库,MUI 官网提供了一个 Remix 接入 MUI 的例子,用的是老的 Remix版本,如何接入新的 Vite 版本呢? 由于 MUI 支持 SSR,只需要改造对应的 Client 和 Server 即可实现。安装 MUI 组件组件库&…

Java类与对象(一)

类的定义与使用 在Java中使用关键字class定义一个类,格式如下: class 类名{// 成员变量/字段/属性//成员方法/行为 }Java中类和c语言中的结构体有点类似, 在Java中类名一般采用大驼峰(每个首字母大写)的形式&#xf…

Java SE基础知识(12)

知识梳理&#xff1a; package ZoomId;import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.util.Set;public class demo1 {public static void main(String[] args) {//获取所有的时区名称Set<String> availableZoneId…

Ansible剧本playbook之--------Templates 模块、roles角色详细解读

目录 一、Templates 模块 1.1准备模板文件并设置引用的变量 1.2修改主机清单文件&#xff0c;使用主机变量定义一个变量名相同&#xff0c;而值不同的变量 1.3编写 playbook 1.4ansible主机远程查看修改参数 1.5验证 二、tags 模块 always应用 三、Roles 模块 3.1ro…

公司网页设计思路

在当今互联网时代&#xff0c;公司网页设计是一个极为重要的环节。一款精心设计的公司网页可以提升企业形象&#xff0c;增加用户粘性&#xff0c;吸引更多的潜在客户和合作伙伴。下面将为大家介绍一些公司网页设计的思路。 首先&#xff0c;要确立公司网页的整体风格。网页风格…

适合优化yaml文件编辑效果的.vimrc简单配置

yaml文件编辑最重要的就是缩进对齐&#xff08;一个tab键对应2个空格&#xff09;&#xff0c;最后加上添加横&#xff0c;纵线的效果 某xx.yaml文件或者xx.yml在vim编辑器中效果如图所示&#xff1a;&#xff1a; 简单的~/.vimrc文件配置内容&#xff1a; vim ~/.vimrc set…

网络工程师练习题

网络工程师练习题 网桥怎样知道网络端口连接了那些网站?如果从端口收到一个数据帧,则将其源地址记入该端口的数据库当网桥连接的局域网出现环路时怎么办?运行生成树协议阻塞一部分端口。使用IEEE 802.1q协议,最多可以配置4094个VLAN。VLAN中继协议(VTP)有不同的工作模式,…

AI大模型探索之路-训练篇21:Llama2微调实战-LoRA技术微调步骤详解

系列篇章&#x1f4a5; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据集概…

pytorch单机多卡训练_数据并行DataParallel

1.单机多卡概述 单卡多级的模型训练&#xff0c;即并行训练&#xff0c;可分为数据并行和模型并行两种. 数据并行是指&#xff0c;多张 GPUs 使用相同的模型副本&#xff0c;但采用不同 batch 的数据进行训练. 模型并行是指&#xff0c;多张 GPUs 使用同一 batch 的数据&…

scrapy的入门

今天我们先学习一下scrapy的入门,Scrapy是一个快速的高层次的网页爬取和网页抓取框架&#xff0c;用于爬取网站并从页面中提取结构化的数据。 1. scrapy的概念和流程 1.1 scrapy的概念 我们先来了解一下scrapy的概念,什么是scrapy: Scrapy是一个Python编写的开源网络爬虫框架…

数据恢复软件 –最好的Android数据恢复软件分享

在安卓数据恢复方面&#xff0c;奇客数据恢复安卓版是最好的 Android 数据恢复公司&#xff0c;因为它的成功率为 100%。随着无数企业和个人使用智能手机和平板电脑&#xff0c;总是有很多数据丢失或损坏的机会&#xff0c;这就是它们如此受欢迎的原因。在恢复数据时&#xff0…

鸿蒙ArkUI:【从代码到UI显示的整体渲染流程】

ArkUI 方舟开发框架&#xff08;简称ArkUI&#xff09;是鸿蒙开发的UI框架&#xff0c;提供如下两种开发范式&#xff0c;我们 只学声明式开发范式 [基于ArkTS的声明式开发范式][兼容JS的类Web开发范式]开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/h…

2024最新最全【NMAP】零基础入门到精通

一、Nmap介绍 Nmap(Network Mapper&#xff0c;网络映射器)是一款开放源代码的网络探测和安全审核工具。它被设计用来快速扫描大型网络&#xff0c;包括主机探测与发现、开放的端口情况、操作系统与应用服务指纹识别、WAF识别及常见安全漏洞。它的图形化界面是Zenmap&#xff…

PyTorch的卷积和池化

卷积计算 input 表示输入的图像filter 表示卷积核, 也叫做滤波器input 经过 filter 的得到输出为最右侧的图像&#xff0c;该图叫做特征图 卷积的计算是将卷积核放入左上角&#xff0c;在局部区域间做点积&#xff0c;然后将卷积核在Input上面依次从左向右&#xff0c;从上到下…

19 分页:快速地址转换(TLB)

通过上一节中的知识&#xff0c;可以知道使用分页作为核心机制来实现虚拟内存是比较不错的&#xff0c;但是因为复杂的查询和转换逻辑&#xff0c;导致性能开销比较大。这里就要使用硬件来提升了&#xff0c;便出现了地址转换旁路缓冲存储器&#xff08;TLB&#xff09;&#x…