关于息肉检测和识别项目的总结

前言

整体的思路:首先息肉数据集分为三类:
1.正常细胞 
2. 增生性息肉 
3.  肿瘤

要想完成这个任务,首先重中之重是分割任务,分割结果的好坏, 当分割结果达到一定的准确度后,开始对分割后的结果进行下游分类任务处理。最后在进行两个网络的分类结果的综合处理,从而达到想要的目的和结果。

分割网络的实现

分割网络我们常见的是UNet、Unet++、以及各种Unet的魔改版,这是因为Unet强大的泛化性,以及它能在分割的大部分领域表现出良好的性能所决定的,本次项目的实现并未选择Unet进行实现,而是选择了ESFPNet进行任务分割。这里是关于这个网络的代码,有兴趣的同学可以搜索查看 。

关于ESFP网络结构的介绍

ESFP网络架构图

from Encoder import mit
from Decoder import mlp
from mmcv.cnn import ConvModule

class ESFPNetStructure(nn.Module):

    def __init__(self, embedding_dim = 160):
        super(ESFPNetStructure, self).__init__()
        
        # Backbone
        if model_type == 'B0':
            self.backbone = mit.mit_b0()
        if model_type == 'B1':
            self.backbone = mit.mit_b1()
        if model_type == 'B2':
            self.backbone = mit.mit_b2()
        if model_type == 'B3':
            self.backbone = mit.mit_b3()
        if model_type == 'B4':
            self.backbone = mit.mit_b4()
        if model_type == 'B5':
            self.backbone = mit.mit_b5()
        
        self._init_weights()  # load pretrain
        
        # LP Header
        self.LP_1 = mlp.LP(input_dim = self.backbone.embed_dims[0], embed_dim = self.backbone.embed_dims[0])
        self.LP_2 = mlp.LP(input_dim = self.backbone.embed_dims[1], embed_dim = self.backbone.embed_dims[1])
        self.LP_3 = mlp.LP(input_dim = self.backbone.embed_dims[2], embed_dim = self.backbone.embed_dims[2])
        self.LP_4 = mlp.LP(input_dim = self.backbone.embed_dims[3], embed_dim = self.backbone.embed_dims[3])
        
        # Linear Fuse
        self.linear_fuse34 = ConvModule(in_channels=(self.backbone.embed_dims[2] + self.backbone.embed_dims[3]), out_channels=self.backbone.embed_dims[2], kernel_size=1,norm_cfg=dict(type='BN', requires_grad=True))
        self.linear_fuse23 = ConvModule(in_channels=(self.backbone.embed_dims[1] + self.backbone.embed_dims[2]), out_channels=self.backbone.embed_dims[1], kernel_size=1,norm_cfg=dict(type='BN', requires_grad=True))
        self.linear_fuse12 = ConvModule(in_channels=(self.backbone.embed_dims[0] + self.backbone.embed_dims[1]), out_channels=self.backbone.embed_dims[0], kernel_size=1,norm_cfg=dict(type='BN', requires_grad=True))
        
        # Fused LP Header
        self.LP_12 = mlp.LP(input_dim = self.backbone.embed_dims[0], embed_dim = self.backbone.embed_dims[0])
        self.LP_23 = mlp.LP(input_dim = self.backbone.embed_dims[1], embed_dim = self.backbone.embed_dims[1])
        self.LP_34 = mlp.LP(input_dim = self.backbone.embed_dims[2], embed_dim = self.backbone.embed_dims[2])
        
        # Final Linear Prediction
        self.linear_pred = nn.Conv2d((self.backbone.embed_dims[0] + self.backbone.embed_dims[1] + self.backbone.embed_dims[2] + self.backbone.embed_dims[3]), 1, kernel_size=1)
        
    def _init_weights(self):
        
        if model_type == 'B0':
            pretrained_dict = torch.load('./Pretrained/mit_b0.pth')
        if model_type == 'B1':
            pretrained_dict = torch.load('./Pretrained/mit_b1.pth')
        if model_type == 'B2':
            pretrained_dict = torch.load('./Pretrained/mit_b2.pth')
        if model_type == 'B3':
            pretrained_dict = torch.load('./Pretrained/mit_b3.pth')
        if model_type == 'B4':
            pretrained_dict = torch.load('./Pretrained/mit_b4.pth')
        if model_type == 'B5':
            pretrained_dict = torch.load('./Pretrained/mit_b5.pth')
            
            
        model_dict = self.backbone.state_dict()
        pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict}
        model_dict.update(pretrained_dict)
        self.backbone.load_state_dict(model_dict)
        print("successfully loaded!!!!")
        
        
    def forward(self, x):
#         这段代码是一个模型的前向传递过程。该模型首先通过backbone网络,
#         对输入的x进行特征提取,得到4个不同分辨率的特征图。
#         然后将这些特征图送入LP Header网络进行处理,融合不同层次的特征。
#         接着通过上采样(interpolation)将处理后的特征图进行恢复到原始输入图像尺寸大小,
#         并最终送入线性预测器(linear_pred)获得输出结果。
        ##################  Go through backbone ###################
        
        B = x.shape[0]
        
        #stage 1
        out_1, H, W = self.backbone.patch_embed1(x)
        for i, blk in enumerate(self.backbone.block1):
            out_1 = blk(out_1, H, W)
        out_1 = self.backbone.norm1(out_1)
        #将输入特征图out_1从形状(Batch_Size, N, W, H)变形为(Batch_Size, H, W, N)
        #其中-1表示自动计算N的值。接着使用permute函数将特征维度N和高宽维度H、W交换位置
        #变成(Batch_Size, N, H, W)的形状
        out_1 = out_1.reshape(B, H, W, -1).permute(0, 3, 1, 2).contiguous()  #(Batch_Size, self.backbone.embed_dims[0], 88, 88)
        
        # stage 2
        out_2, H, W = self.backbone.patch_embed2(out_1)
        for i, blk in enumerate(self.backbone.block2):
            out_2 = blk(out_2, H, W)
        out_2 = self.backbone.norm2(out_2)
        out_2 = out_2.reshape(B, H, W, -1).permute(0, 3, 1, 2).contiguous()  #(Batch_Size, self.backbone.embed_dims[1], 44, 44)
        
        # stage 3
        out_3, H, W = self.backbone.patch_embed3(out_2)
        for i, blk in enumerate(self.backbone.block3):
            out_3 = blk(out_3, H, W)
        out_3 = self.backbone.norm3(out_3)
        out_3 = out_3.reshape(B, H, W, -1).permute(0, 3, 1, 2).contiguous()  #(Batch_Size, self.backbone.embed_dims[2], 22, 22)
        
        # stage 4
        out_4, H, W = self.backbone.patch_embed4(out_3)
        for i, blk in enumerate(self.backbone.block4):
            out_4 = blk(out_4, H, W)
        out_4 = self.backbone.norm4(out_4)
        out_4 = out_4.reshape(B, H, W, -1).permute(0, 3, 1, 2).contiguous()  #(Batch_Size, self.backbone.embed_dims[3], 11, 11)
        
        # go through LP Header
        lp_1 = self.LP_1(out_1)
        lp_2 = self.LP_2(out_2)  
        lp_3 = self.LP_3(out_3)  
        lp_4 = self.LP_4(out_4)
        
        # linear fuse and go pass LP Header     上采样并拼接
        lp_34 = self.LP_34(self.linear_fuse34(torch.cat([lp_3, F.interpolate(lp_4,scale_factor=2,mode='bilinear', align_corners=False)], dim=1)))
        lp_23 = self.LP_23(self.linear_fuse23(torch.cat([lp_2, F.interpolate(lp_34,scale_factor=2,mode='bilinear', align_corners=False)], dim=1)))
        lp_12 = self.LP_12(self.linear_fuse12(torch.cat([lp_1, F.interpolate(lp_23,scale_factor=2,mode='bilinear', align_corners=False)], dim=1)))
        
        # get the final output
        lp4_resized = F.interpolate(lp_4,scale_factor=8,mode='bilinear', align_corners=False)
        lp3_resized = F.interpolate(lp_34,scale_factor=4,mode='bilinear', align_corners=False)
        lp2_resized = F.interpolate(lp_23,scale_factor=2,mode='bilinear', align_corners=False)
        lp1_resized = lp_12
        
        out = self.linear_pred(torch.cat([lp1_resized, lp2_resized, lp3_resized, lp4_resized], dim=1))
        out_resized = F.interpolate(out,scale_factor=4,mode='bilinear', align_corners=True)
        
        return out_resized

上述图片和代码是关于ESFP核心网络的编写,下面就来详细介绍一下这个网络。

backbone(部分引用于原论文)

  • 使用model_type来加载预训练模型,这里有5个参数可选。通过指定的预训练权重来初始化backbone网络。
  • Mix Transformer编码器(MiT)是一个模块,它利用了ViT网络的思想,并在四个阶段中使用四个重叠的路径合并模块和自注意力预测。
  • transformer使用的自注意力层缺乏局部归纳偏差(图像像素是局部相关的,其相关图是平移不变的概念),会导致数据饥饿问题。
  • 为了缓解受小数据集限制的应用面临的数据饥饿挑战,可以利用广泛使用的迁移学习的概念。MiT的编码器利用了这个想法,在大型ImageNet数据库上进行了预训练对于我们的ESPFNet架构,将这些预训练的MiT编码器集成为骨干,并用初始化的解码器再次训练它们。
  • 这是一种直接的方法,可以在小型特定任务数据集表现良好性能,同时也能够超过最先进的CNN模型的性能。

Efficient stage-wise feature pyramid(ESFP)

  • 高层(全局)特征比低层(局部)特征对整体分割性能的贡献更大。ESFP首先对每个阶段的输出进行线性预测(有效的是连接通道的数量),然后将这些预处理的特征从全局到局部线性融合。这些中间聚合特征被连接起来,并相互协作产生最终的分割。
  • 在训练之前,将输入调整为352 × 352像素,并将其归一化以进行分割。我们还使用随机翻转、旋转和亮度变化作为输入的数据增强操作。损失函数结合了加权交联(IoU)损失和加权二元交叉熵(BCE)损失:

实现细节

在这里插入图片描述
这一部分是关于MIt 编码器对图像进行编码的操作。

这一部分则是ESFP对网络进行解码的过程。

LP Header
 # LP Header
        self.LP_1 = mlp.LP(input_dim = self.backbone.embed_dims[0], embed_dim = self.backbone.embed_dims[0])
        self.LP_2 = mlp.LP(input_dim = self.backbone.embed_dims[1], embed_dim = self.backbone.embed_dims[1])
        self.LP_3 = mlp.LP(input_dim = self.backbone.embed_dims[2], embed_dim = self.backbone.embed_dims[2])
        self.LP_4 = mlp.LP(input_dim = self.backbone.embed_dims[3], embed_dim = self.backbone.embed_dims[3])
  • self.backbone.embed_dims[0] [1] [2] [3]、 获取到相应分辨率的特征图通道数,在这里输入和输出通道是相同的维度数。
  • LP Header用于对不同分辨率的特征图进行进一步的处理和提取,以获得更加有用的信息,为后续的特征融合和预测操作做准备。
Linear Fuse(线性融合)
        # Linear Fuse
        self.linear_fuse34 = ConvModule(in_channels=(self.backbone.embed_dims[2] + self.backbone.embed_dims[3]), out_channels=self.backbone.embed_dims[2], kernel_size=1,norm_cfg=dict(type='BN', requires_grad=True))
        self.linear_fuse23 = ConvModule(in_channels=(self.backbone.embed_dims[1] + self.backbone.embed_dims[2]), out_channels=self.backbone.embed_dims[1], kernel_size=1,norm_cfg=dict(type='BN', requires_grad=True))
        self.linear_fuse12 = ConvModule(in_channels=(self.backbone.embed_dims[0] + self.backbone.embed_dims[1]), out_channels=self.backbone.embed_dims[0], kernel_size=1,norm_cfg=dict(type='BN', requires_grad=True))
        
  • 通过上述的网络结构图可以看出,我们需要3个线性融合层。
  • 通过ConvModule来定义Linear Fuse层,其中in_channels表示Linear Fuse的输入通道数,由两个特征图的通道数相加得到。out_channels表示Linear Fuse的输出通道数,与对应层次的特征图通道数相同。
  • 通过这些Linear Fuse层的操作,可以将不同分辨率的特征图进行融合,从而提高特征的表达能力和多尺度信息的利用效果
Fused LP Header(融合的LP Header)
# Fused LP Header
        self.LP_12 = mlp.LP(input_dim = self.backbone.embed_dims[0], embed_dim = self.backbone.embed_dims[0])
        self.LP_23 = mlp.LP(input_dim = self.backbone.embed_dims[1], embed_dim = self.backbone.embed_dims[1])
        self.LP_34 = mlp.LP(input_dim = self.backbone.embed_dims[2], embed_dim = self.backbone.embed_dims[2])
  • 将融合后的特征图的通道数变换为与backbone的对应层次的特征图通道数相同的维度。
  • 用于对线性融合后的特征图进行进一步的特征提取和转换,以获得更加有用的信息,并为最终的预测操作做准备
Final Linear Prediction(最终线性预测)
# Final Linear Prediction
        self.linear_pred = nn.Conv2d((self.backbone.embed_dims[0] + self.backbone.embed_dims[1] + self.backbone.embed_dims[2] + self.backbone.embed_dims[3]), 1, kernel_size=1)
        
  • n.Conv2d用于定义一个二维卷积层,其中的输入通道数为融合后的特征图的通道数总和。
  • 输入通道是各个分辨率维度的总和,输出通道为1,表示进行目标检测的预测结果。
  • 这个最终的线性预测层将融合后的特征图映射到一维的通道上,以输出目标检测的预测结果。这样,通过特征融合与转换后的特征图,可以进行最终的目标检测操作并得到预测结果。

前向传播

       B = x.shape[0]
        
       #stage 1
       out_1, H, W = self.backbone.patch_embed1(x)
       for i, blk in enumerate(self.backbone.block1):
           out_1 = blk(out_1, H, W)
       out_1 = self.backbone.norm1(out_1)
       #将输入特征图out_1从形状(Batch_Size, N, W, H)变形为(Batch_Size, H, W, N)
       #其中-1表示自动计算N的值。接着使用permute函数将特征维度N和高宽维度H、W交换位置
       #变成(Batch_Size, N, H, W)的形状
       out_1 = out_1.reshape(B, H, W, -1).permute(0, 3, 1, 2).contiguous()  #(Batch_Size, self.backbone.embed_dims[0], 88, 88)
       
       # stage 2
       out_2, H, W = self.backbone.patch_embed2(out_1)
       for i, blk in enumerate(self.backbone.block2):
           out_2 = blk(out_2, H, W)
       out_2 = self.backbone.norm2(out_2)
       out_2 = out_2.reshape(B, H, W, -1).permute(0, 3, 1, 2).contiguous()  #(Batch_Size, self.backbone.embed_dims[1], 44, 44)
       
       # stage 3
       out_3, H, W = self.backbone.patch_embed3(out_2)
       for i, blk in enumerate(self.backbone.block3):
           out_3 = blk(out_3, H, W)
       out_3 = self.backbone.norm3(out_3)
       out_3 = out_3.reshape(B, H, W, -1).permute(0, 3, 1, 2).contiguous()  #(Batch_Size, self.backbone.embed_dims[2], 22, 22)
       
       # stage 4
       out_4, H, W = self.backbone.patch_embed4(out_3)
       for i, blk in enumerate(self.backbone.block4):
           out_4 = blk(out_4, H, W)
       out_4 = self.backbone.norm4(out_4)
       out_4 = out_4.reshape(B, H, W, -1).permute(0, 3, 1, 2).contiguous()  #(Batch_Size, self.backbone.embed_dims[3], 11, 11)
       
       # go through LP Header
       lp_1 = self.LP_1(out_1)
       lp_2 = self.LP_2(out_2)  
       lp_3 = self.LP_3(out_3)  
       lp_4 = self.LP_4(out_4)
       
       # linear fuse and go pass LP Header     上采样并拼接
       lp_34 = self.LP_34(self.linear_fuse34(torch.cat([lp_3, F.interpolate(lp_4,scale_factor=2,mode='bilinear', align_corners=False)], dim=1)))
       lp_23 = self.LP_23(self.linear_fuse23(torch.cat([lp_2, F.interpolate(lp_34,scale_factor=2,mode='bilinear', align_corners=False)], dim=1)))
       lp_12 = self.LP_12(self.linear_fuse12(torch.cat([lp_1, F.interpolate(lp_23,scale_factor=2,mode='bilinear', align_corners=False)], dim=1)))
       
       # get the final output
       lp4_resized = F.interpolate(lp_4,scale_factor=8,mode='bilinear', align_corners=False)
       lp3_resized = F.interpolate(lp_34,scale_factor=4,mode='bilinear', align_corners=False)
       lp2_resized = F.interpolate(lp_23,scale_factor=2,mode='bilinear', align_corners=False)
       lp1_resized = lp_12
       
       out = self.linear_pred(torch.cat([lp1_resized, lp2_resized, lp3_resized, lp4_resized], dim=1))
       out_resized = F.interpolate(out,scale_factor=4,mode='bilinear', align_corners=True)
        

前向传播的过程,就是将结果中的完整过程串联起来,进行完整的预测。输入x的形状为(Batch_Size, C, H, W),其中B表示批量大小,C表示通道数,H和W分别表示输入特征图的高度和宽度

阶段1
        out_1, H, W = self.backbone.patch_embed1(x)
        for i, blk in enumerate(self.backbone.block1):
            out_1 = blk(out_1, H, W)
        out_1 = self.backbone.norm1(out_1)
         out_1 = out_1.reshape(B, H, W, -1).permute(0, 3, 1, 2).contiguous()
  • 通过self.backbone.patch_embed1对输入特征图进行分块嵌入操作,得到输出特征图out_1和新的高度H和宽度W
  • 进行self.backbone.block1中的一系列残差块操作,对输出特征图out_1进行特征提取。
  • 对out_1进行归一化处理,得到归一化后的特征图out_1。
  • 将输入特征图out_1从形状(Batch_Size,H,W)变形为(Batch_Size,N, H, W),通过reshape进行N维度的计算,-1表示自动计算N的值。接着使用permute函数将特征维度N和高宽维度H、W交换位置,变成(Batch_Size, N, H, W)的形状
阶段2、3、4

与上述阶段一的操作大致相同,也就是图中最上面一层,backbone网络的操作。

LP Header
        # go through LP Header
        lp_1 = self.LP_1(out_1)
        lp_2 = self.LP_2(out_2)  
        lp_3 = self.LP_3(out_3)  
        lp_4 = self.LP_4(out_4)

将out_1、out_2、out_3、out_4分别输入到对应的LP模块中(LP_1、LP_2、LP_3、LP_4),得到相应的低层级特征表示lp_1、lp_2、lp_3、lp_4。

在这里插入图片描述
也就是黑色框中所做的事情。

线性融合与上采样:
 # linear fuse and go pass LP Header     上采样并拼接
        lp_34 = self.LP_34(self.linear_fuse34(torch.cat([lp_3, F.interpolate(lp_4,scale_factor=2,mode='bilinear', align_corners=False)], dim=1)))
        lp_23 = self.LP_23(self.linear_fuse23(torch.cat([lp_2, F.interpolate(lp_34,scale_factor=2,mode='bilinear', align_corners=False)], dim=1)))
        lp_12 = self.LP_12(self.linear_fuse12(torch.cat([lp_1, F.interpolate(lp_23,scale_factor=2,mode='bilinear', align_corners=False)], dim=1)))
  • 使用torch.cat函数将lp_3与经过上采样后的lp_4拼接起来,然后通过self.linear_fuse34和LP_34模块进行线性融合,得到lp_34。
  • 类似地,通过拼接和线性融合操作得到lp_23和lp_12。
最终上采样
       # get the final output
        lp4_resized = F.interpolate(lp_4,scale_factor=8,mode='bilinear', align_corners=False)
        lp3_resized = F.interpolate(lp_34,scale_factor=4,mode='bilinear', align_corners=False)
        lp2_resized = F.interpolate(lp_23,scale_factor=2,mode='bilinear', align_corners=False)
        lp1_resized = lp_12
  • 对lp_4进行上采样操作,得到lp4_resized,上采样因子为8;
  • 对lp_34进行上采样操作,得到lp3_resized,上采样因子为4;
  • 对lp_23进行上采样操作,得到lp2_resized,上采样因子为2;
  • lp_12不进行上采样。
最终输出
 out = self.linear_pred(torch.cat([lp1_resized, lp2_resized, lp3_resized, lp4_resized], dim=1))
 out_resized = F.interpolate(out,scale_factor=4,mode='bilinear', align_corners=True)
        
  • 使用torch.cat函数将lp1_resized、lp2_resized、lp3_resized和lp4_resized进行拼接,得到形状为(B, N, H, W)的特征图。
  • 将拼接后的特征图通过self.linear_pred和线性预测模块进行特征转换,得到最终的输出特征图out。
  • 对out进行上采样操作,得到out_resized,上采样因子为4。
  • 最后对结果进行 Sigmod和Threshold便可以得到分割后的Output。、

分类网络介绍

分割任务完成了,那分类任务则是在分割任务的基础上,再做下游的分类任务。分类网络结构如下

self.conv_layers = nn.Sequential(
                nn.Conv2d(4, 128, kernel_size=3, padding=1),
                nn.ReLU(),
                nn.Conv2d(128, 256, kernel_size=3, padding=1),
                nn.ReLU(),
                nn.MaxPool2d(kernel_size=2, stride=2),
                nn.Conv2d(256, 512, kernel_size=3, padding=1),
                nn.ReLU(),
                nn.Conv2d(512, 512, kernel_size=3, padding=1),
                nn.ReLU(),
                nn.MaxPool2d(kernel_size=2, stride=2)
            )

            self.fc_layers = nn.Sequential(
                nn.Flatten(),
                nn.Linear(16**2*512, 512),  # 调整大小以适应您的需求
                nn.ReLU(),
                nn.Dropout(0.3),
                nn.Linear(512, 256),  # 调整大小以适应您的需求
                nn.ReLU(),
                nn.Dropout(0.3),
                nn.Linear(256, 3),
                nn.LogSoftmax(dim=1)
            )

首先对其进行4次卷积和3次最大池化进行下采样和特征提取。随后定义一个全连接层让通道数最终降到我们所需要的分类数,最后再做一次Softmax。

前向传播过程

前向传播过程则是将我们之前做好的分割结果,和原图进行通道维度cat连接后,再进行一最大池化操作,然后进行分类操作。我们对不同种类的数据做了one-hot类别编码。

以上就是大致总统思路,后续代码会上传到github

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

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

相关文章

Node.js的基本概念node -v 和npm -v 这两个命令的作用

Node.js 是一个开源且跨平台的 JavaScript 运行时环境,它可以让你在服务器端运行 JavaScript 代码。Node.js 使用了 Chrome 的 V8 JavaScript 引擎来执行代码,非常高效。 在 Node.js 出现之前,JavaScript 通常只在浏览器中运行,用…

谈思生物医疗直播 | 霍德生物研发中心负责人王安欣博士“iPSC衍生神经细胞产品全悬浮自动化工艺及特殊质控方法开发”

iPSC通过人体来源的终端体细胞重编程而来,其衍生细胞产品的生产与质控面临着诸多挑战,但也解决了许多自体细胞治疗的不稳定性和高成本等产业化难点。例如自体细胞不仅供体之间的差异对产品质量可能造成影响,即使同一个供体,体细胞…

SSM培训报名管理系统开发mysql数据库web结构java编程计算机网页源码eclipse项目

一、源码特点 SSM 培训报名管理系统是一套完善的信息系统,结合SSM框架完成本系统,对理解JSP java编程开发语言有帮助系统采用SSM框架(MVC模式开发),系统具有完整的源代码和数据库,系统主 要采用B/S模式开…

http1,https,http2,http3总结

1.HTTP 当我们浏览网页时,地址栏中使用最多的多是https://开头的url,它与我们所学的http协议有什么区别? http协议又叫超文本传输协议,它是应用层中使用最多的协议, http与我们常说的socket有什么区别吗? …

TSINGSEE青犀省级高速公路视频上云联网方案:全面实现联网化、共享化、智能化

一、需求背景 随着高速铁路的建设及铁路管理的精细化,原有的模拟安防视频监控系统已经不能满足视频监控需求,越来越多站点在建设时已开始规划高清安防视频监控系统。高速公路视频监控资源非常丰富,需要对其进行综合管理与利用。通过构建监控…

Java版 招投标系统简介 招投标系统源码 java招投标系统 招投标系统功能设计

功能描述 1、门户管理:所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含:招标公告、非招标公告、系统通知、政策法规。 2、立项管理:企业用户可对需要采购的项目进行立项申请,并提交审批,查看所…

【计算机网络】分层模型和应用协议

网络分层模型和应用协议 1. 分层模型 1.1 五层网络模型 网络要解决的问题是:两个程序之间如何交换数据。 四层?五层?七层? 2. 应用层协议 2.1 URL URL(uniform resource locator,统一资源定位符&#…

基于深度学习的人脸表情识别 计算机竞赛

文章目录 0 前言1 技术介绍1.1 技术概括1.2 目前表情识别实现技术 2 实现效果3 深度学习表情识别实现过程3.1 网络架构3.2 数据3.3 实现流程3.4 部分实现代码 4 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习的人脸表情识别 该项目较…

网络工程综合试题(二)

1. SR技术有哪些缺点? SR(Segment Routing)技术是一种新兴的网络编程技术,它具有很多优点,但也存在一些缺点,包括: 部署复杂性:SR技术需要对网络进行改造和升级,包括更新…

拉扎维模拟CMOS集成电路设计西交张鸿老师课程P6~9视频学习记录

目录 p6 p7 CG放大器 输入阻抗的计算方法; 输出阻抗的计算​编辑​编辑 p8p9 为什么需要差动放大器 噪声 什么是差分信号 基础差动放大器 利用叠加法求解增益; 共模响应 CMRR 带其他类似负载的差动对 ------------------------------------…

Postman测试金蝶云星空Webapi【协同开发云】

文章目录 Postman测试金蝶云星空Webapi【协同开发云】环境说明业务背景大致流程具体操作请求登录接口请求标准接口查看保存提交审核反审核撤销 请求自定义接口参数是字符串参数是实体类单个实体类实体类是集合 其他 Postman测试金蝶云星空Webapi【协同开发云】 环境说明 金蝶…

计算机视觉 激光雷达结合无监督学习进行物体检测的工作原理

一、简述 激光雷达是目前正在改变世界的传感器。它集成在自动驾驶汽车、自主无人机、机器人、卫星、火箭等中。该传感器使用激光束了解世界,并测量激光击中目标返回所需的时间,输出是点云信息,利用这些信息,我们可以从3D点云中查找障碍物。 从自动驾驶汽车的角度看激光雷达…

计算机网络第3章-TCP协议(2)

TCP拥塞控制 TCP拥塞控制的三种方式: 慢启动、拥塞避免、快速恢复 慢启动 当一条TCP连接开始时,cwnd的值是一个很小的MSS值,这使得初始发送速率大约为MSS/RTT。 在慢启动状态,cwnd的值以1个MSS开始并且每当传输的报文段首次被…

thinkphp链接mqtt服务器,然后在订阅下发布消息

cmd打开项目根目录&#xff0c;安装插件&#xff0c;执行下面的命令 composer require php-mqtt/client执行完成之后会在vendor 目录下有php-mqtt 文件 然后在你的 extend文件下 新建mqtt文件 在文件中新建 Mqtt.php 下面是代码 <?php /** S: * Name: 控制器: * Autho…

我用好说 AI 做二次元人设

你有没有想过自己做一部原创作品&#xff1f; 就像开发《星露谷物语》那样&#xff0c;自己把控作品的 角色、故事、载体、宣传 等方方面面&#xff0c;让 idea 不再只是灵光一闪。 以前是 “万事开头难”&#xff0c;可能第一步都举步维艰。但现在有了 AI 就不同了&#xff…

菜单管理中icon图标回显

<el-table-column prop"icon" label"图标" show-overflow-tooltip algin"center"><template v-slot"{ row }"><el-icon :class"row.icon"></el-icon></template></el-table-column>

Java面向对象(进阶)特征之二:继承性

文章目录 一、继承的概述&#xff08;1&#xff09;生活中的继承&#xff08;2&#xff09; Java中的继承1、角度一&#xff1a;从上而下2、角度二&#xff1a;从下而上 &#xff08;3&#xff09;继承的好处&#xff08;4&#xff09;总结 二、继承的语法与应用举例&#xff0…

SpringBoot通过注解形式实现系统操作日志

介绍 我们在日常开发工作中&#xff0c;肯定逃不开与日志接触&#xff0c;一些比较严谨的后台管理系统里面会涉及到一些比较重要的资料&#xff0c;有些公司为了知道有哪些人登录了系统&#xff0c;是谁在什么时候修改了用户信息或者资料&#xff0c;所以就有了操作日志这么个…

灯串上亚马逊加拿大合规标准CSA认证如何办理?

灯串 灯串和配件都是插头连接的便携式、临时性商品&#xff0c;最大额定输入电压为 120 伏。 本政策适用于季节性照明、装饰性灯具以及灯串。 亚马逊灯串政策 根据亚马逊的要求&#xff0c;所有季节性和装饰性灯串均应经过检测&#xff0c;并且遵守下列法规、标准和要求&…

LabVIEW应用开发——基本函数(一)

前面我们介绍了一些控件的介绍和属性的配置&#xff0c;想要完成一个软件只会拖控件肯定是不行的&#xff0c;没办法实现既有的功能。比如我们要实现从串口中读到数据&#xff0c;根据一定的协议解析&#xff0c;然后转换成各个参数的值的显示&#xff0c;包括时间、电压、电流…