U-Net for Image Segmentation

1.Unet for Image Segmentation

笔记来源:使用Pytorch搭建U-Net网络并基于DRIVE数据集训练(语义分割)

1.1 DoubleConv (Conv2d+BatchNorm2d+ReLU)

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

# nn.Sequential 按照类定义的顺序去执行模型,并且不需要写forward函数
class DoubleConv(nn.Sequential): # class 子类(父类)
# __init__() 是一个类的构造函数,用于初始化对象的属性。它会在创建对象时自动调用,而且通常在这里完成对象所需的所有初始化操作
# forward方法是实现模型的功能,实现各个层之间的连接关系的核心
    # def __init__(self) 只有一个self,指的是实例的本身。它允许定义一个空的类对象,需要实例化之后,再进行赋值
    # def __init__(self,args) 属性值不允许为空,实例化时,直接传入参数
    def __init__(self,in_channels,out_channels,mid_channels=None) # DoubleConv输入的通道数,输出的通道数,DoubleConv中第一次conv后输出的通道数
        if mid_channels is None: # mid_channels为none时执行语句
            mid_channels = out_channels
        super(DoubleConv,self).__init__(  #继承父类并且调用父类的初始化方法
            nn.Conv2d(in_channels,mid_channels,kernel_size=3,padding=1,bias=False),
            nn.BatchNorm2d(mid_channels), # 进行数据的归一化处理,这使得数据在进行Relu之前不会因为数据过大而导致网络性能的不稳定
            nn.ReLU(inplace=True), # 指原地进行操作,操作完成后覆盖原来的变量
            nn.Conv2d(in_channels,out_channels,kernel_size=3,padding=1,bias=False),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(inplace=True)
        )

1.1.1 Conv2d

直观了解kernel size、stride、padding、bias
原始图像通过与卷积核的数学运算,可以提取出图像的某些指定特征,卷积核相当于“滤镜”可以着重提取它感兴趣的特征

下图来自:Expression recognition based on residual rectification convolution neural network

1.1.2 BatchNorm2d

To understand what happens without normalization, let’s look at an example with just two features that are on drastically different scales. Since the network output is a linear combination of each feature vector, this means that the network learns weights for each feature that are also on different scales. Otherwise, the large feature will simply drown out the small feature.
Then during gradient descent, in order to “move the needle” for the Loss, the network would have to make a large update to one weight compared to the other weight. This can cause the gradient descent trajectory to oscillate back and forth along one dimension, thus taking more steps to reach the minimum.—Batch Norm Explained Visually — How it works, and why neural networks need it

if the features are on the same scale, the loss landscape is more uniform like a bowl. Gradient descent can then proceed smoothly down to the minimum. —Batch Norm Explained Visually — How it works, and why neural networks need it

Batch Norm is just another network layer that gets inserted between a hidden layer and the next hidden layer. Its job is to take the outputs from the first hidden layer and normalize them before passing them on as the input of the next hidden layer.

without batch norm
include batch norm




下图来自:BatchNorm2d原理、作用及其pytorch中BatchNorm2d函数的参数讲解

1.1.3 ReLU

How an Activation function works?

We know, the neural network has neurons that work in correspondence with weight, bias, and their respective activation function. In a neural network, we would update the weights and biases of the neurons on the basis of the error at the output. This process is known as Back-propagation. Activation functions make the back-propagation possible since the gradients are supplied along with the error to update the weights and biases. —Role of Activation functions in Neural Networks

Why do we need Non-linear Activation function?

Activation functions introduce non-linearity into the model, allowing it to learn and perform complex tasks. Without them, no matter how many layers we stack in the network, it would still behave as a single-layer perceptron because the composition of linear functions is a linear function. —Convolutional Neural Network — Lesson 9: Activation Functions in CNNs

Doesn’t matter how many hidden layers we attach in neural net, all layers will behave same way because the composition of two linear function is a linear function itself. Neuron cannot learn with just a linear function attached to it. A non-linear activation function will let it learn as per the difference w.r.t error. Hence, we need an activation function.—Role of Activation functions in Neural Networks

下图来自:Activation Functions 101: Sigmoid, Tanh, ReLU, Softmax and more

1.2 Down (MaxPool+DoubleConv)

class Down(nn.Sequential):
    def __init__(self,in_channels,out_channels):
        super(Down,self).__init__(
            nn.MaxPool2d(2,stride=2), # kernel_size核大小,stride核的移动步长
            DoubleConv(in_channels,out_channels)
        )

1.2.1 MaxPool

Two reasons for applying Max Pooling :

  1. Downscaling Image by extracting most important feature
  2. Removing Invariances like shift, rotational and scale

下图来自:Max Pooling, Why use it and its advantages.

Max Pooling is advantageous because it adds translation invariance. There are following types of it

  1. Shift Invariance(Invariance in Position)
  2. Rotational Invariance(Invariance in Rotation)
  3. Scale Invariance(Invariance in Scale(small or big))

1.3 Up (Upsample/ConvTranspose+DoubleConv)

双线性插值进行上采样

转置卷积进行上采样

class Up(nn.Module):
# __init__() 是一个类的构造函数,用于初始化对象的属性。它会在创建对象时自动调用,而且通常在这里完成对象所需的所有初始化操作
    def __init__(self,in_channels,out_channels,bilinear=True): #默认通过双线性插值进行上采样
        super(Up,self).__init__()
        if bilinear: #通过双线性插值进行上采样
            self.up = nn.Upsample(scale_factor=2,mode='bilinear',align_corners=True) #输出为输入的多少倍数、上采样算法、输入的角像素将与输出张量对齐
            self.conv = DoubleConv(in_channels,out_channels,in_channels//2)
        else #通过转置卷积进行上采样
            self.up = nn.ConvTranspose2d(in_channels,in_channels//2,kernel_size=2,stride=2)
            self.conv = DoubleConv(in_channels,out_channels) # mid_channels = none时 mid_channels = mid_channels
# forward方法是实现模型的功能,实现各个层之间的连接关系的核心
    def forward(self,x1,x2) # 对x1进行上采样,将上采样后的x1与x2进行cat
        # 对x1进行上采样
        x1 = self.up(x1)
        # 对上采样后的x1进行padding,使得上采样后的x1与x2的高宽一致
        # [N,C,H,W] Number of data samples、Image channels、Image height、Image width
        diff_y = x2.size()[2] - x1.size()[2] # x2的高度与上采样后的x1的高度之差
        diff_x = x2.size()[3] - x2.size()[3] # x2的宽度与上采样后的x1的宽度之差
        # padding_left、padding_right、padding_top、padding_bottom
        x1 = F.pad(x1,[diff_x//2, diff_x-diff_x//2, diff_y//2, diff_y-diff_y//2])
        # 上采样后的x1与x2进行cat
        x = torch.cat([x2,x1],dim=1)
        # x1和x2进行cat之后进行doubleconv
        x = self.conv(x)
        return x

1.3.1 Upsample

上采样率scale_factor

双线性插值bilinear


角像素对齐align_corners
下图来自:[PyTorch]Upsample

1.4 OutConv

class OutConv(nn.Sequential):
    def __init__(self, in_channels, num_classes):
        super(OutConv,self).__init__(
            nn.Conv2d(in_channels,num_classes,kernel_size=1) #输出分类类别的数量num_classes
        )

1.5 Unet

class UNet(nn.Module):
    def __init__(self,
                 in_channels: int = 1, # 网络输入图片的通道数
                 num_classes: int = 2, # 网络输出分类类别数
                 bilinear: bool = True, # 上采样时使用双线性插值
                 base_c: int = 64): # 基础通道数,网络中其他层的通道数均为该基础通道数的倍数
        super(UNet,self).__init__()
        self.in_channels = in_channels
        self.num_classes = num_classes
        self.bilinear = bilinear

        self.in_conv = DoubleConv(in_channels,base_c) # in_channels、out_channels、mid_channels=none
        self.down1 = Down(base_c,base_c*2) # in_channels、out_channels 
        self.down2 = Down(base_c*2,base_c*4)
        self.down3 = Down(base_c*4,base_c*8)
        factor = 2 if bilinear else 1 #如果上采样使用双线性插值则factor=2,若使用转置卷积则factor=1
        self.down4 = Down(base_c*8,base_c*16//factor)

        self.up1 = Up(base_c*16, base_c*8//factor, bilinear) # in_channels、out_channels、bilinear=True
        self.up2 = Up(base_c*8, base_c*4//factor, bilinear)
        self.up3 = Up(base_c*4, base_c*2//factor, bilinear)
        self.up4 = Up(base_c*2, base_c, bilinear)

        self.out_conv = OutConv(base_c, num_classes) # in_channels, num_classes

    def forward(self,x):
        x1 = self.in_conv(x)
        x2 = self.down1(x1)
        x3 = self.down2(x2)
        x4 = self.down3(x3)
        x5 = self.down4(x4)
        
        x = self.up1(x5,x4) # 对x5进行上采样,将上采样后的x5与x4进行cat
        x = self.up2(x,x3)
        x = self.up3(x,x2)
        x = self.up4(x,x1)
        logits = self.out_conv(x)
        return {"out": logits} # 以字典形式返回

为何没有调用forward方法却能直接使用?
nn.Module类是所有神经网络模块的基类,需要重载__init__和forward函数

self.up1 = Up(base_c*16, base_c*8//factor, bilinear) //实例化Up
....
x = self.up1(x5,x4) //调用 Up() 中的 forward(self,x1,x2) 函数

up1调用父类nn.Module中的__call__方法,__call__方法又调用UP()中的forward方法

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

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

相关文章

win10/11磁盘管理

win10/11磁盘管理 合并磁盘分区的前提是你的两个磁盘区域是相邻的,比如如下: 如果需要吧这个磁盘进行分解,你可以选择压缩一部分磁盘或者是直接删除卷 我这里的话,因为压缩出来的卷和C盘好像是不相邻的(我之前做过&…

【SpringCloud-Seata源码分析2】

文章目录 分支事务注册-客户端分支事务服务端的执行 分支事务注册-客户端 第一篇我们将全局事务启动,以及开启源码分析完成了,现在我们需要看一下分支事务注册。 我们分支事务的开始需要从PreparedStatementProxy#executeUpdate中去看。 public class…

GPT-4o一夜被赶超,Claude 3.5一夜封王|快手可灵大模型推出图生视频功能|“纯血”鸿蒙大战苹果AI|智谱AI“钱途”黯淡|月之暗面被曝进军美国

快手可灵大模型推出图生视频功能“纯血”鸿蒙大战苹果AI,华为成败在此一举大模型低价火拼间,智谱AI“钱途”黯淡手握新“王者”,腾讯又跟渠道干上了“美食荒漠”杭州,走出一个餐饮IPOGPT-4o一夜被赶超,Anthropic推出Cl…

Rocky Linux archive下载地址

Index of /vault/rocky/https://dl.rockylinux.org/vault/rocky/

利口 202. 快乐数

力扣 202. 快乐数 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为: 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果这个过程 结…

猫头虎分享已解决Bug || Null Pointer Exception: `java.lang.NullPointerException`

猫头虎分享已解决Bug || Null Pointer Exception: java.lang.NullPointerException 😺🐯 关于猫头虎 大家好,我是猫头虎,别名猫头虎博主,擅长的技术领域包括云原生、前端、后端、运维和AI。我的博客主要分享技术教程…

营业性演出许可证:直播行业规范与繁荣的关键

随着互联网和直播行业的迅猛发展,营业性演出许可证的重要性愈加凸显。《网络表演经纪机构管理办法》明确指出,任何形式的盈利性演出活动,无论是线下还是线上,都必须取得营业性演出许可证。这一规定为行业规范提供了法律基础&#…

钓鱼隐藏--文件后缀压缩文件捆绑文件

免责声明:本文仅做技术交流与学习... 目录 文件后缀-钓鱼伪装-RLO 压缩文件-自解压-释放执行 捆绑文件-打包加载-释放执行 文件后缀-钓鱼伪装-RLO 改后缀--伪装 w.exe wgpj.exe (要改的后缀反写)(jpg--->gpj) | (光标移到要改的后缀的前边)(w和g中间) …

idea导入文件里面的子模块maven未识别处理解决办法

1、File → Project Structure → 点击“Modules” → 点击“” → “Import Model” 2、可以看到很多子模块,选择子模块下的 pom.xml 文件导入一个一个点累死了,父目录下也没有pom文件 解决办法:找到子模块中有一个pom.xml文件,…

CentOS9镜像下载地址加速下载

CentOS 9 是 CentOS 项目的最新版本之一,它基于 RHEL(Red Hat Enterprise Linux)9 的源代码构建。CentOS(Community ENTerprise Operating System)是一个免费的企业级 Linux 发行版,旨在提供一个与 RHEL 兼…

基于YOLOv5的PCB板缺陷检测系统的设计与实现

简介 随着电子设备的广泛应用,PCB(印刷电路板)作为其核心部件,其质量和可靠性至关重要。然而,PCB生产过程中常常会出现各种缺陷,如鼠咬伤、开路、短路、杂散、伪铜等。这些缺陷可能导致设备故障,甚至引发严重的安全问题。为了提高PCB检测的效率和准确性,我们基于YOLOv…

【C语言】操作符(上)

目录 1. 操作符的分类 2. 原码、反码、补码 3. 移位操作符 3.1 左移操作符 3.2 右移操作符 4. 位操作符:&、|、^、~ 5. 单目操作符 6. 逗号表达式 最近准备期末考试,好久不见啦,现在回归—— 正文开始—— 1. …

基于CPWM与DPWM综合调制的光伏逆变器

1. 光伏并网逆变器矢量控制 图 1 为光伏发电系统常用的逆变器拓扑结 构,太阳能光伏电池板发电所产生的直流电能接 入光伏并网逆变器直流侧。逆变器将电能逆变, 经过滤波器与隔离升压变压器连接,最终并入电 网。其中隔离变压器低压侧漏感与LC滤波器组 成LCL滤波。为便于分析…

C语言小例程

题目&#xff1a;两个乒乓球队进行比赛&#xff0c;各出三人。甲队为a,b,c三人&#xff0c;乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比&#xff0c;c说他不和x,z比&#xff0c;请编程序找出三队赛手的名单。 #include <stdio.h> #in…

Windows11系统自动获取电脑IPV6地址,并且开机自动发送到指定邮箱

废话&#xff1a;最近放假回家&#xff0c;在家里突然想玩游戏了&#xff0c;Steamdeck性能终归有限。部分游戏始终玩的不爽&#xff0c;想到之前了解到的SunshnieMoonlight串流的方案&#xff0c;远程调用家里的电脑打游戏&#xff0c;简直不要太爽。 一顿折腾之后配置好了所有…

算法05 模拟算法之二维数组相关内容详解【C++实现】

大家好&#xff0c;我是bigbigli&#xff0c;前面一节我们一节讲过一维数组的模拟了&#xff0c;如果还没看的话&#xff0c;可以&#x1f449;点击此处。模拟算法还有很多内容需要讲&#xff0c;比如图像、日期相关的模拟算法&#xff0c;后续将继续更新&#xff0c;今天先来讲…

C语言| 数组的顺序查找

顺序查找 查找数组a中第一次出现数字m的下标&#xff0c;并输出该下标&#xff1b; 如果没有则输出sorry。 1 定义变量 数组a&#xff0c;n表示数组的个数&#xff0c; m要查找的数字 2 用sizeof()函数&#xff0c;求出数组元素的个数 3 从键盘中任意输出一个数字m&#xff0c;…

大疆炸机后MOV修复方法(DJI Inspire 3)

dji大疆可以说是无人机中的华为&#xff0c;产品线之广性能之高让高傲的美国人侧面&#xff0c;质量和性价比才是王道。另外产品线的细分也是制胜法宝&#xff0c;无论是手持、农用机、特殊无人机还是影视级产品DJI都有涉及&#xff0c;给人的感觉就是在无人机细分方面它已经无…

信号基本分析方法——频域分析

二、频域分析 随机信号的时域分析只能提供有限的时域故障特征信息&#xff0c;故障发生时往往会引起信号频率结构的变化&#xff0c;而故障频率可以计算和预知&#xff0c;通过检测频率的幅值变换规律&#xff0c;就可以监控故障的发展过程。 频谱分析的理论基础是傅里叶变换…

支持 MKV、MP4、AVI、MPG 等格式视频转码器

一、简介 1、一款开源的视频转码器&#xff0c;适用于 Linux、Mac 和 Windows。它是一个免费的工具&#xff0c;由志愿者们开发&#xff0c;可以将几乎所有格式的视频转换为现代、广泛支持的编码格式。你可以在官网上下载该应用或源代码。该软件支持 MKV、MP4、AVI、MPG 等格式…