[Code]R2U-Net中的眼部血管分割

DenseUnet.py 

import torch
import torch.nn as nn
import torch.nn.functional as F# 定义一个名为Single_level_densenet的类,继承自nn.Module,它构建了一个单层级的DenseNet结构
class Single_level_densenet(nn.Module):def __init__(self, filters, num_conv=4):super(Single_level_densenet, self).__init__()# 记录卷积层的数量self.num_conv = num_conv# 用于存储卷积层的ModuleList,方便管理多个卷积层self.conv_list = nn.ModuleList()# 用于存储批归一化层的ModuleList,方便管理多个批归一化层self.bn_list = nn.ModuleList()# 循环创建指定数量的卷积层和批归一化层,并添加到对应的ModuleList中for i in range(self.num_conv):# 创建二维卷积层,输入输出通道数都为filters,卷积核大小为3,填充为1self.conv_list.append(nn.Conv2d(filters, filters, 3, padding=1))# 创建批归一化层,处理的通道数为filtersself.bn_list.append(nn.BatchNorm2d(filters))def forward(self, x):# 用于存储每层输出的列表,先把输入x添加进去作为初始值outs = []outs.append(x)# 遍历每一个卷积层进行前向传播计算for i in range(self.num_conv):# 对当前层的输入(初始为x或者前面层累加后的结果)进行卷积操作temp_out = self.conv_list[i](outs[i])# 从第二层卷积开始(索引大于0),将前面层的输出进行累加if i > 0:for j in range(i):temp_out += outs[j]# 对累加后的结果进行批归一化和ReLU激活操作,然后添加到outs列表中outs.append(F.relu(self.bn_list[i](temp_out)))# 获取最后一层的输出作为最终输出out_final = outs[-1]# 删除outs列表,释放内存(可选操作,Python的垃圾回收机制通常也会处理)del outsreturn out_final# 定义一个名为Down_sample的类,继承自nn.Module,用于下采样操作(这里使用最大池化实现)
class Down_sample(nn.Module):def __init__(self, kernel_size=2, stride=2):super(Down_sample, self).__init__()# 创建最大池化层用于下采样,指定池化核大小和步长self.down_sample_layer = nn.MaxPool2d(kernel_size, stride)def forward(self, x):# 对输入进行下采样操作,得到下采样后的结果y = self.down_sample_layer(x)return y, x# 定义一个名为Upsample_n_Concat的类,继承自nn.Module,用于上采样并拼接操作
class Upsample_n_Concat(nn.Module):def __init__(self, filters):super(Upsample_n_Concat, self).__init__()# 创建转置卷积层用于上采样,将通道数保持为filters,设置卷积核大小、填充和步长等参数self.upsample_layer = nn.ConvTranspose2d(filters, filters, 4, padding=1, stride=2)# 创建卷积层,用于对上采样后拼接的结果进行卷积处理,输入通道数为拼接后的2倍filters,输出通道数为filtersself.conv = nn.Conv2d(2 * filters, filters, 3, padding=1)# 创建批归一化层,处理的通道数为filtersself.bn = nn.BatchNorm2d(filters)def forward(self, x, y):# 对输入x进行上采样操作x = self.upsample_layer(x)# 在通道维度上拼接上采样后的x和另一个输入yx = torch.cat([x, y], dim=1)# 对拼接后的结果进行卷积、批归一化和ReLU激活操作x = F.relu(self.bn(self.conv(x)))return x# 定义一个名为Dense_Unet的类,继承自nn.Module,构建了整个Dense-Unet网络结构
class Dense_Unet(nn.Module):def __init__(self, in_chan=1, out_chan=2, filters=128, num_conv=4):super(Dense_Unet, self).__init__()# 最开始的卷积层,将输入通道数转换为filters,卷积核大小为1self.conv1 = nn.Conv2d(in_chan, filters, 1)# 第一个单层级的DenseNet结构self.d1 = Single_level_densenet(filters, num_conv)# 第一个下采样模块self.down1 = Down_sample()# 第二个单层级的DenseNet结构self.d2 = Single_level_densenet(filters, num_conv)# 第二个下采样模块self.down2 = Down_sample()# 第三个单层级的DenseNet结构self.d3 = Single_level_densenet(filters, num_conv)# 第三个下采样模块self.down3 = Down_sample()# 第四个单层级的DenseNet结构self.d4 = Single_level_densenet(filters, num_conv)# 第四个下采样模块self.down4 = Down_sample()# 网络底部的单层级的DenseNet结构self.bottom = Single_level_densenet(filters, num_conv)# 用于从底层向上采样并拼接的模块(对应第四个上采样拼接层)self.up4 = Upsample_n_Concat(filters)# 第四个上采样拼接后的单层级的DenseNet结构self.u4 = Single_level_densenet(filters, num_conv)# 用于从下往上第三个上采样并拼接的模块self.up3 = Upsample_n_Concat(filters)# 第三个上采样拼接后的单层级的DenseNet结构self.u3 = Single_level_densenet(filters, num_conv)# 用于从下往上第二个上采样并拼接的模块self.up2 = Upsample_n_Concat(filters)# 第二个上采样拼接后的单层级的DenseNet结构self.u2 = Single_level_densenet(filters, num_conv)# 用于从下往上第一个上采样并拼接的模块self.up1 = Upsample_n_Concat(filters)# 第一个上采样拼接后的单层级的DenseNet结构self.u1 = Single_level_densenet(filters, num_conv)# 最后的输出卷积层,将通道数转换为out_chan,卷积核大小为1self.outconv = nn.Conv2d(filters, out_chan, 1)def forward(self, x):# 先对输入进行初始的卷积操作x = self.conv1(x)# 经过第一个单层级DenseNet结构和下采样操作,得到下采样后的结果x以及对应的特征图y1x, y1 = self.down1(self.d1(x))# 经过第二个单层级DenseNet结构和下采样操作,得到下采样后的结果x以及对应的特征图y2x, y2 = self.down1(self.d2(x))# 经过第三个单层级DenseNet结构和下采样操作,得到下采样后的结果x以及对应的特征图y3x, y3 = self.down1(self.d3(x))# 经过第四个单层级DenseNet结构和下采样操作,得到下采样后的结果x以及对应的特征图y4x, y4 = self.down1(self.d4(x))# 通过网络底部的单层级DenseNet结构进行处理x = self.bottom(x)# 从底层开始进行上采样、拼接以及单层级DenseNet结构处理,依次向上进行类似操作x = self.u4(self.up4(x, y4))x = self.u3(self.up3(x, y3))x = self.u2(self.up2(x, y2))x = self.u1(self.up1(x, y1))# 经过最后的输出卷积层得到最终输出x1 = self.outconv(x)# 对最终输出进行softmax操作,在维度1(通常是通道维度,如果输出是分类任务的概率形式)上进行归一化,将其转换为概率分布形式x1 = F.softmax(x1, dim=1)return x1if __name__ == '__main__':# 创建一个Dense_Unet实例,输入通道数为3,输出通道数为21,中间特征通道数filters为128,并将模型移动到GPU上(如果可用)net = Dense_Unet(3, 21, 128).cuda()print(net)# 创建一个随机的输入张量,大小为[4, 3, 224, 224],表示批量大小为4,通道数为3,图像高宽为224,并将其移动到GPU上(如果可用)in1 = torch.randn(4, 3, 224, 224).cuda()# 将输入in1传入网络进行前向传播,得到输出out = net(in1)print(out.size())

这段 Python 代码使用 PyTorch 框架构建了一个类似 U-Net 结构的神经网络模型,叫做Dense_Unet。整体网络结构融合了 DenseNet 的密集连接思想和 U-Net 的编码器 - 解码器架构特点,用于图像相关的任务(比如图像分割等),以下是更详细的说明:

 
  • 编码器部分
    • 先是通过一个简单的conv1卷积层将输入图像的通道数进行调整,然后经过多个Single_level_densenet模块和Down_sample模块的组合,不断地对图像特征进行提取并下采样,使得特征图尺寸逐步变小的同时,特征通道数保持为filters,提取到不同层次的抽象特征,这部分类似 U-Net 中的编码器,用于捕捉图像中的高级语义信息。
  • 解码器部分
    • 从网络底部开始,通过多个Upsample_n_Concat模块进行上采样操作,同时将对应下采样过程中保存的特征图进行拼接(实现了类似跳跃连接的功能,有助于融合不同层次的特征信息),然后再经过Single_level_densenet模块进一步处理这些拼接后的特征,逐步恢复特征图尺寸到接近输入图像的大小,这部分对应 U-Net 中的解码器,用于将高级语义特征还原为和输入图像空间分辨率相近的特征表示。
  • 输出部分
    • 最后通过outconv卷积层将特征通道数转换为指定的输出通道数out_chan,并且使用softmax函数将输出转换为概率分布形式(如果是分类任务等应用场景的话),得到最终的网络输出结果,输出结果的尺寸取决于输入图像尺寸以及网络的结构参数设置等。

LadderNet.py 

这段代码整体构建了一个名为 LadderNet 的神经网络架构,其具有类似梯子(Ladder)的结构特点,主要用于图像相关的任务(比如图像分类等),以下是更详细的功能说明:

 
  • 特征提取与初步整合
    • 通过 Initial_LadderBlock 模块对输入数据进行初始的特征提取以及不同层次特征的初步融合,它内部通过一系列卷积、下采样、上采样等操作将输入的特征进行变换,得到包含不同层次融合信息的特征列表,这是网络对输入数据特征感知和初步处理的阶段。
import torch
import torch.nn.functional as F
import torch.nn as nn# 定义一个 dropout 的概率值,这里设置为 0.25,用于在网络中进行随机失活操作,防止过拟合
drop = 0.25# 定义一个名为conv3x3的函数,用于创建一个3x3的二维卷积层
def conv3x3(in_planes, out_planes, stride=1):"""3x3 convolution with padding"""# 创建二维卷积层,输入通道数为in_planes,输出通道数为out_planes,卷积核大小为3,步长为stride,填充为1,并且使用偏置(bias=True)return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,padding=1, bias=True)# 定义一个名为BasicBlock的类,继承自nn.Module,它是构建网络的基本模块(类似ResNet中的基本残差块概念)
class BasicBlock(nn.Module):# 定义一个类属性expansion,用于表示该模块输出通道相对于输入通道数的扩展倍数,这里为1,表示输出通道数和输入通道数倍数关系为1:1expansion = 1def __init__(self, inplanes, planes, stride=1, downsample=None):super(BasicBlock, self).__init__()# 如果输入通道数和输出通道数不一致,创建一个额外的卷积层conv0用于调整通道数if inplanes!= planes:self.conv0 = conv3x3(inplanes, planes)# 记录输入通道数self.inplanes = inplanes# 记录输出通道数self.planes = planes# 创建第一个卷积层,输入输出通道数都为planes(如果输入输出通道数相同的情况),步长为strideself.conv1 = conv3x3(planes, planes, stride)# 原本这里应该是批归一化层,用于归一化数据,当前被注释掉了,可能是根据实际需求暂不使用或者后续添加#self.bn1 = nn.BatchNorm2d(planes)# 创建ReLU激活函数,inplace=True表示直接在输入的张量上进行修改,节省内存空间self.relu = nn.ReLU(inplace=True)# 原本这里应该还有第二个卷积层,用于进一步特征提取,当前被注释掉了,同样可能是根据实际情况的调整#self.conv2 = conv3x3(planes, planes)# 原本对应的第二个卷积层后的批归一化层,也被注释掉了#self.bn2 = nn.BatchNorm2d(planes)# 用于下采样的模块(比如在残差连接中,如果输入和输出尺寸或通道数不一致时进行调整的模块),可以传入外部定义的下采样操作,初始化为传入的参数downsampleself.downsample = downsample# 记录当前模块使用的步长self.stride = stride# 创建一个二维的Dropout层,按照给定的概率drop对特征图进行随机失活操作,防止过拟合self.drop = nn.Dropout2d(p=drop)def forward(self, x):# 如果输入通道数和输出通道数不一致,先通过conv0卷积层调整通道数,并经过ReLU激活函数if self.inplanes!= self.planes:x = self.conv0(x)x = F.relu(x)# 经过第一个卷积层操作out = self.conv1(x)# 原本这里应该进行批归一化操作,被注释掉了#out = self.bn1(out)# 经过ReLU激活函数激活out = self.relu(out)# 进行随机失活操作,按照设定的概率drop对特征图部分元素置零out = self.drop(out)# 这里应该是重复使用了conv1卷积层,可能是代码有误或者特殊的设计需求,正常可能是另一个不同的卷积层进行特征提取(对比原ResNet基本块的结构)out1 = self.conv1(out)# 原本这里应该还有ReLU激活,被注释掉了,可能不符合当前的设计逻辑#out1 = self.relu(out1)# 将经过卷积等操作后的结果out1和最初的输入x进行相加,实现残差连接的效果(虽然当前结构和标准残差块有差异)out2 = out1 + x# 最后经过ReLU激活函数得到该模块的最终输出return F.relu(out2)
import torch.nn as nn# 定义一个名为Bottleneck的类,继承自nn.Module,它通常用于构建深度神经网络中的瓶颈结构(例如在ResNet中常被使用),这种结构有助于减少计算量的同时保留重要的特征信息。
class Bottleneck(nn.Module):# 定义一个类属性expansion,它表示经过这个瓶颈模块后输出通道数相对于输入通道数的扩展倍数,这里设置为4,意味着输出通道数是输入通道数的4倍。expansion = 4def __init__(self, inplanes, planes, stride=1, downsample=None):super(Bottleneck, self).__init__()# 第一个卷积层,将输入通道数inplanes转换为planes,使用1x1的卷积核,这种1x1卷积可以在不改变特征图尺寸的情况下调整通道数,同时设置bias=False,因为后面跟着批归一化层,批归一化层会对数据进行归一化并处理偏置相关的操作,所以这里不需要额外的偏置。self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)# 第一个批归一化层,用于对经过conv1卷积层后的输出进行归一化操作,它有助于加快网络收敛速度,提高训练稳定性,处理的通道数为planes。self.bn1 = nn.BatchNorm2d(planes)# 第二个卷积层,使用3x3的卷积核,输入输出通道数都为planes,步长为stride,padding=1保证了在卷积操作时特征图的尺寸在宽和高方向上不会缩小(当stride为1时),同样设置bias=False。self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride,padding=1, bias=False)# 第二个批归一化层,对经过conv2卷积层后的输出进行归一化,通道数依然为planes。self.bn2 = nn.BatchNorm2d(planes)# 第三个卷积层,将通道数从planes扩展为planes * self.expansion(也就是变为原来的4倍),使用1x1的卷积核,同样不使用偏置。self.conv3 = nn.Conv2d(planes, planes * self.expansion, kernel_size=1, bias=False)# 第三个批归一化层,对经过conv3卷积层后的输出进行归一化,处理的通道数为planes * self.expansion。self.bn3 = nn.BatchNorm2d(planes * self.expansion)# 创建ReLU激活函数,inplace=True表示直接在输入的张量上进行修改,这样可以节省内存空间,激活函数用于给网络引入非线性因素,使网络能够学习到更复杂的映射关系。self.relu = nn.ReLU(inplace=True)# 用于下采样的模块(比如在残差连接中,如果输入和输出的尺寸或通道数不一致时进行相应调整的模块),可以传入外部定义的下采样操作,初始化为传入的参数downsample。self.downsample = downsample# 记录当前模块使用的步长,它会影响特征图的尺寸变化以及卷积操作的效果等。self.stride = stridedef forward(self, x):# 将输入x保存为residual,用于后续的残差连接,残差连接的目的是让网络能够更容易地学习到恒等映射,有助于解决深层网络训练时的梯度消失等问题。residual = x# 经过第一个卷积层conv1,对输入x进行通道数的调整。out = self.conv1(x)# 对经过conv1卷积后的输出进行批归一化操作,使其数据分布更符合网络训练的要求。out = self.bn1(out)# 经过ReLU激活函数进行激活,引入非线性因素。out = self.relu(out)# 经过第二个卷积层conv2,进一步提取特征,根据设定的步长stride等参数,可能会改变特征图的尺寸(如果stride不为1)。out = self.conv2(out)# 对经过conv2卷积后的输出进行批归一化操作。out = self.bn2(out)# 再次经过ReLU激活函数进行激活。out = self.relu(out)# 经过第三个卷积层conv3,将通道数按照expansion倍数进行扩展,得到最终的特征表示(在这个瓶颈模块内)。out = self.conv3(out)# 对经过conv3卷积后的输出进行批归一化操作。out = self.bn3(out)# 如果定义了下采样模块(即self.downsample不为None),说明输入和输出在尺寸或通道数上不一致,需要对原始输入x进行下采样操作,使其能和当前模块输出的out在维度上匹配,以便进行后续的残差连接。if self.downsample is not None:residual = self.downsample(x)# 将经过一系列卷积、归一化等操作后的out和经过下采样(如果有)后的residual进行相加,实现残差连接,让网络能够学习到在这个模块上需要补充或调整的特征信息。out += residual# 最后再经过ReLU激活函数进行激活,得到这个瓶颈模块的最终输出,传递给下一层网络。out = self.relu(out)return out
import torch.nn as nn
import torch.nn.functional as F# 定义名为Initial_LadderBlock的类,继承自nn.Module,这个类构建了一个类似梯子结构(Ladder)的神经网络模块,
# 可能用于图像相关任务中特征的提取、下采样、上采样以及不同层次特征的融合等操作。
class Initial_LadderBlock(nn.Module):def __init__(self, planes, layers, kernel=3, block=BasicBlock, inplanes=3):super().__init__()# 记录每个阶段特征图的通道数,后续用于确定网络中各卷积层、模块等的输入输出通道数设置,# 例如决定每层特征的维度大小,是网络结构构建中的重要参数。self.planes = planes# 记录网络模块所包含的层数,通过循环该层数次数来构建对应数量的层结构(如不同层的卷积、模块等),# 控制网络的深度和复杂度。self.layers = layers# 记录卷积核的大小,默认值为3,它决定了卷积操作时感受野的大小以及对特征图局部信息的提取范围,# 不同的卷积核大小会影响网络学习到的特征模式。self.kernel = kernel# 根据给定的卷积核大小计算在进行卷积操作时需要的填充(padding)大小,# 对于kernel为奇数的情况,这样能保证在默认步长为1时卷积操作后特征图尺寸不变,# 确保特征图在卷积过程中的空间维度变化符合预期。self.padding = int((kernel - 1) / 2)# 创建一个初始的卷积层(inconv),用于对输入数据进行初次的特征提取和通道数调整,# 将输入通道数(由inplanes指定,默认为3,可根据实际输入数据的通道数修改)转换为planes指定的通道数,# 卷积核大小为3,步长为1,填充为1,并且使用偏置(bias=True),这是网络的第一层操作。self.inconv = nn.Conv2d(in_channels=inplanes, out_channels=planes,kernel_size=3, stride=1, padding=1, bias=True)# 创建一个ModuleList用于存储下采样分支(down branch)中的模块列表,每个模块会按顺序对特征进行处理,# 模块的具体类型由传入的block参数指定(默认为BasicBlock),通过循环创建多个这样的模块来构建下采样分支的多层结构。self.down_module_list = nn.ModuleList()for i in range(0, layers):# 在每次循环中,根据当前层数i,按照特定的通道数扩展规则(每次将planes乘以2的i次方)创建相应的block类型模块,# 并添加到down_module_list中,用于下采样分支中不同层次的特征提取和变换,每个模块处理对应层次的特征信息。self.down_module_list.append(block(planes * (2 ** i), planes * (2 ** i)))# 创建一个ModuleList用于存储下采样分支中用于执行下采样操作的卷积层列表,这里采用带步长的卷积操作来替代传统的池化操作实现下采样,# 这样在减少特征图尺寸的同时还能改变通道数,是下采样过程中的关键操作部分。self.down_conv_list = nn.ModuleList()for i in range(0, layers):# 在每次循环中,根据当前层数i,创建对应的卷积层,其输入通道数为planes * 2 ** i,输出通道数为planes * 2 ** (i + 1),# 步长为2(实现下采样,使特征图尺寸减半),卷积核大小为kernel,填充为前面计算好的self.padding,# 通过这些参数设置实现下采样以及通道数翻倍的效果,逐步改变特征的维度和分辨率。self.down_conv_list.append(nn.Conv2d(planes * 2 ** i, planes * 2 ** (i + 1), stride=2, kernel_size=kernel, padding=self.padding))# 创建底部的模块,用于处理经过多次下采样后到达网络最深层的特征,模块类型同样由传入的block参数指定,# 其通道数按照层数扩展到planes * (2 ** layers),负责对最深层次的特征进行进一步的特征提取和变换。self.bottom = block(planes * (2 ** layers), planes * (2 ** layers))# 创建一个ModuleList用于存储上采样分支(up branch)中的转置卷积层列表,转置卷积层用于在网络的上采样阶段逐步恢复特征图的尺寸,# 使其回到与输入图像相近的大小,同时调整通道数以匹配后续操作的要求。self.up_conv_list = nn.ModuleList()# 创建一个ModuleList用于存储上采样分支中对应的模块列表(模块类型同样由block参数指定),# 这些模块用于对上采样后的特征进行处理、融合以及进一步的特征调整等操作,以完善特征表示。self.up_dense_list = nn.ModuleList()for i in range(0, layers):# 在每次循环中,根据当前层数i,创建转置卷积层,其输入通道数为planes * 2 ** (layers - i)(对应从底部往上每层的输入通道数,随着层数递减而变化),# 输出通道数为planes * 2 ** max(0, layers - i - 1)(同样根据层数合理调整输出通道数,确保特征维度的正确变化),# 设置合适的卷积核大小、步长、填充和输出填充等参数来实现上采样操作,使特征图尺寸逐步增大。self.up_conv_list.append(nn.ConvTranspose2d(in_channels=planes * 2 ** (layers - i), out_channels=planes * 2 ** max(0, layers - i - 1), kernel_size=3,stride=2, padding=1, output_padding=1, bias=True))# 创建对应的block类型的模块,其处理的通道数为planes * 2 ** max(0, layers - i - 1),用于对上采样后得到的特征进一步处理,# 将该模块添加到up_dense_list中,以便在上采样分支的每层中按顺序对特征进行操作。self.up_dense_list.append(block(planes * 2 ** max(0, layers - i - 1), planes * 2 ** max(0, layers - i - 1)))def forward(self, x):# 首先将输入x传入初始卷积层inconv进行特征提取和通道数调整,将输入数据的特征维度转换为planes指定的通道数,# 得到最初的特征表示,然后经过ReLU激活函数引入非线性因素,使网络能够学习到更复杂的特征关系。out = self.inconv(x)out = F.relu(out)# 创建一个空列表down_out,用于存储下采样分支每层的输出特征,方便后续在上采样分支中进行特征融合时使用,# 保存不同层次下采样后的特征信息,实现跨层的特征传递和融合。down_out = []# 下采样分支(down branch)的处理循环,按照预先设定的层数self.layers进行迭代操作,依次处理每一层的特征。for i in range(0, self.layers):# 将当前特征out传入下采样分支对应的模块(从down_module_list中按顺序取出的模块)进行特征提取和处理,# 该模块会对特征进行特定的变换,例如根据其内部定义的卷积、激活等操作提取更抽象的特征。out = self.down_module_list[i](out)# 将经过模块处理后的当前层特征添加到down_out列表中保存起来,以便后续在上采样时使用这些不同层次的特征。down_out.append(out)# 再将经过模块处理后的特征传入对应的下采样卷积层(从down_conv_list中按顺序取出的卷积层)进行下采样操作,# 通过步长为2的卷积减少特征图的尺寸,同时根据卷积层的参数设置增加通道数,实现特征的下采样和维度变换。out = self.down_conv_list[i](out)# 经过下采样卷积层后,通过ReLU激活函数引入非线性因素,使下采样后的特征具有更强的表达能力,# 得到下一层下采样分支的输入特征,继续下一轮的下采样操作。out = F.relu(out)# 底部(bottom branch)的处理,将经过多次下采样后的特征传入底部模块self.bottom进行处理,# 该模块对最深层的特征进行进一步的特征提取和变换,得到最深层次的特征表示,并将其保存为bottom变量,# 方便后续在上采样分支中作为初始特征进行上采样和融合操作。out = self.bottom(out)bottom = out# 创建一个空列表up_out,用于存储上采样分支每层的输出特征,初始时将底部特征bottom添加进去,# 作为上采样分支的起始特征,后续会在此基础上逐步恢复特征图尺寸并融合其他层次的特征。up_out = []up_out.append(bottom)# 上采样分支(up branch)的处理循环,按照预先设定的层数self.layers进行迭代操作,依次处理每一层的特征,逐步恢复特征图尺寸并融合特征。for j in range(0, self.layers):# 对上采样分支当前层的特征out进行上采样操作,使用对应的转置卷积层(从up_conv_list中按顺序取出的转置卷积层),# 然后将上采样结果和下采样分支对应层的特征(从down_out列表中按对应顺序取出)进行相加融合,实现特征的跳跃连接效果,# 类似

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java中的“封装“详解

封装(Encapsulation)是面向对象编程(OOP)的四大基本特性之一。它通过将数据和操作数据的方法绑定在一起,并隐藏对象的内部实现细节,只提供有限的访问接口来实现。这种机制不仅提高了代码的安全性&#xff0…

深度学习常用方法(一)

1. Dropout 的原理 Dropout 是一种防止神经网络过拟合(学习得过于复杂,导致泛化能力差)的方法。 原理:在每次训练时,随机“丢弃”一部分神经元(即暂时让它们失效,设置为零)&#x…

C++趣味编程:基于树莓派Pico的模拟沙漏-倾斜开关与LED的互动实现

沙漏,作为一种古老的计时工具,利用重力让沙子通过狭小通道,形成了计时效果。在现代,我们可以通过电子元件模拟沙漏的工作原理。本项目利用树莓派Pico、倾斜开关和LED,实现了一个电子沙漏。以下是项目的详细技术解析与C++代码实现。 一、项目概述 1. 项目目标 通过倾斜开关…

【Oracle】个人收集整理的Oracle常用SQL及命令

【建表】 create table emp( id number(12), name nvarchar2(20), primary key(id) ); 【充值一】 insert into emp select rownum,dbms_random.string(*,dbms_random.value(6,20)) from dual connect by level<101; 【充值二】 begin for i in 1..100 loop inser…

RAG (Retrieval Augmented Generation) 检索增强和生成

1 RAG技术简介 1.1 RAG技术概述 RAG&#xff08;Retrieval Augmented Generation&#xff09; 是一种结合了检索&#xff08;Retrieval&#xff09;和生成&#xff08;Generation&#xff09;的技术&#xff0c;旨在通过利用外部知识库来增强大型语言模型&#xff08;LLMs&am…

Android 编译和使用libheif

项目中需要使用libheif,libde265,libyuv。一下是相应的cmakelist.txt。这里直接使用了静态库。 里面涉及到c包的链接&#xff0c;需要stdc。 ${PROJECT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}/liblibde265.a这个路径由于操作过程中copy出现问题&#xff0c;多了一层路径&…

【无标题】多模态对齐

第一章 绪论 1.1 研究背景和意义 在现实生活中,人类往往是以事件为单位来认识和理解世界的,一个事件包 含了时间、地点、参与者等多个静态因素。将这些事件信息从非结构化数据中提 取出来,已逐渐成为信息抽取领域的关键任务之一。事件通常并非孤立存在,而 是彼此关联,它…

DIY-Tomcat part 3 实现对动态资源的请求

实现ServletRequest package connector;import javax.servlet.RequestDispatcher; import javax.servlet.ServletInputStream; import javax.servlet.ServletRequest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i…

黑马程序员Java笔记整理(day05)

1.面向对象编程 2.用法 3.对象是什么 4.对象在计算机中是啥 5.无参与有参构造器 小结: 6.this的作用 7.小结 8.封装 9.小结 10.实体类 11.小结 12.static 13.小结 14.static修饰方法 15.static应用前景 16.几个注意事项 17.java中可以直接用类的名字创建数组&#xff0c;如: M…

Perforce SAST专家详解:自动驾驶汽车的安全与技术挑战,Klocwork、Helix QAC等静态代码分析成必备合规性工具

自动驾驶汽车安全吗&#xff1f;现代汽车的软件包含1亿多行代码&#xff0c;支持许多不同的功能&#xff0c;如巡航控制、速度辅助和泊车摄像头。而且&#xff0c;这些嵌入式系统中的代码只会越来越复杂。 随着未来汽车的互联程度越来越高&#xff0c;这一趋势还将继续。汽车越…

《Python基础》之数据加密模块hashlib的用法

目录 一、简介 二、用法 步骤一、导入hashlib库 步骤二、创建哈希对象 步骤三、往哈希对象中传值 1、可以在创建对象的时候传值 2、使用updata传值 步骤四、获取经过哈希对象加密后的值 三、注意事项 1、编码问题 2、安全性 3、多次传值 四、总结 一、简介 hashli…

QT实战--qt各种按钮实现

本篇介绍qt一些按钮的实现&#xff0c;包括正常按钮&#xff1b;带有下拉箭头的按钮的各种实现&#xff1b;按钮和箭头两部分分别响应&#xff1b;图片和按钮大小一致&#xff1b;图片和按钮大小不一致的处理&#xff1b;文字和图片位置的按钮 效果图如下&#xff1a; 详细实现…

恶补英语初级第12天,《描述进行中的动作》

对话 Where’s Sally, Jack? She’s in the garden, Jane. What’s she doing? she’s sitting under the tree. Is Tim in the garden, too? Yes, he is. He’s climbing the tree. I beg your pardon? Who’s climbing the tree? Tim is. What about the dog? The dog’…

联表查询,外键

联表查询 使用多表可以减少冗余&#xff0c;便于增删改操作&#xff0c;查询操作复杂 表与表之间通过主键和外键关联 外键 如果一张表的某个列指向另一个表的主键列 &#xff0c;就称之为外键列 -- 添加外键 alter table t_emp add constraint 外键名 foreign key (depart)…

【OJ】前K个高频单词和单词识别和两个数组的交集

个人主页 &#xff1a; zxctscl 如有转载请先通知 题目 1. 692. 前K个高频单词1.1 分析1.2 代码 2. KY264 单词识别2.1 分析2.2 代码 3. 349. 两个数组的交集3.1 分析3.2 代码 1. 692. 前K个高频单词 1.1 分析 先试用map来统计每个单词出现的次数&#xff1a; map<string,i…

分布式协同 - 分布式锁一二事儿

文章目录 导图Pre概述概述1. 分布式互斥和临界资源的协调2. 分布式锁的基本原理3. 分布式锁的实现方式a. 基于数据库实现的分布式锁b. 基于Redis实现的分布式锁c. 基于Zookeeper实现的分布式锁 4. 高并发场景下的分布式锁优化a. 分段锁&#xff08;Sharded Locks&#xff09;b.…

Vue-01

Vue框架 Vue官网&#xff1a; Vue.js 框架 数据模型和view的通信就是依靠viewmodel的关键。 目前主流版本仍然是vue2版本。 Vue快速入门 1.新建一个HTML文件&#xff0c;引入Vue.js文件。Vue.js文件是官方引入的一个文件&#xff0c;我们如果要使用Vue就必须引入这个文件。…

【微服务】Nacos

一、安装 1、官网地址&#xff1a;https://nacos.io/download/nacos-server/ 2、启动&#xff1a;找到bin目录下的startup.cmd双击启动&#xff0c;或者打开一个命令窗口输入&#xff1a; startup.cmd -m standalone双击启动后如下&#xff1a;可以访问控制台地址 访问后的…

【Docker项目实战】使用Docker部署Paint Board在线创意画板工具

【Docker项目实战】使用Docker部署Paint Board在线创意画板工具 一、 Paint Board介绍1.1 Paint Board简介1.2 主要功能1.3 主要使用场景二、本次实践规划2.1 本地环境规划2.2 本次实践介绍三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版…

在oracle下载jdk显示400 Bad Request Request Header Or Cookie Too Large

下载JDK17&#xff0c;官网地址&#xff1a;【https://www.oracle.com/cn/java/technologies/downloads/#jdk17-windows】 问题&#xff1a; 出现 400 Bad Request: Request Header Or Cookie Too Large 错误&#xff0c;通常是由于浏览器存储的 Cookies 或请求头过大所导致的…