做网站的客户需求,引擎seo如何优化,中国丹东,哪些做海报比较好的网站前言
整体的思路#xff1a;首先息肉数据集分为三类#xff1a;
1.正常细胞
2. 增生性息肉
3. 肿瘤要想完成这个任务#xff0c;首先重中之重是分割任务#xff0c;分割结果的好坏#xff0c; 当分割结果达到一定的准确度后#xff0c;开始对分割后的结果进行下游分类…前言
整体的思路首先息肉数据集分为三类
1.正常细胞
2. 增生性息肉
3. 肿瘤要想完成这个任务首先重中之重是分割任务分割结果的好坏 当分割结果达到一定的准确度后开始对分割后的结果进行下游分类任务处理。最后在进行两个网络的分类结果的综合处理从而达到想要的目的和结果。
分割网络的实现
分割网络我们常见的是UNet、Unet、以及各种Unet的魔改版这是因为Unet强大的泛化性以及它能在分割的大部分领域表现出良好的性能所决定的本次项目的实现并未选择Unet进行实现而是选择了ESFPNet进行任务分割。这里是关于这个网络的代码有兴趣的同学可以搜索查看 。
关于ESFP网络结构的介绍 from Encoder import mit
from Decoder import mlp
from mmcv.cnn import ConvModuleclass ESFPNetStructure(nn.Module):def __init__(self, embedding_dim 160):super(ESFPNetStructure, self).__init__()# Backboneif 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 Headerself.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 Fuseself.linear_fuse34 ConvModule(in_channels(self.backbone.embed_dims[2] self.backbone.embed_dims[3]), out_channelsself.backbone.embed_dims[2], kernel_size1,norm_cfgdict(typeBN, requires_gradTrue))self.linear_fuse23 ConvModule(in_channels(self.backbone.embed_dims[1] self.backbone.embed_dims[2]), out_channelsself.backbone.embed_dims[1], kernel_size1,norm_cfgdict(typeBN, requires_gradTrue))self.linear_fuse12 ConvModule(in_channels(self.backbone.embed_dims[0] self.backbone.embed_dims[1]), out_channelsself.backbone.embed_dims[0], kernel_size1,norm_cfgdict(typeBN, requires_gradTrue))# Fused LP Headerself.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 Predictionself.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_size1)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 1out_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 2out_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 3out_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 4out_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 Headerlp_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_factor2,modebilinear, align_cornersFalse)], dim1)))lp_23 self.LP_23(self.linear_fuse23(torch.cat([lp_2, F.interpolate(lp_34,scale_factor2,modebilinear, align_cornersFalse)], dim1)))lp_12 self.LP_12(self.linear_fuse12(torch.cat([lp_1, F.interpolate(lp_23,scale_factor2,modebilinear, align_cornersFalse)], dim1)))# get the final outputlp4_resized F.interpolate(lp_4,scale_factor8,modebilinear, align_cornersFalse)lp3_resized F.interpolate(lp_34,scale_factor4,modebilinear, align_cornersFalse)lp2_resized F.interpolate(lp_23,scale_factor2,modebilinear, align_cornersFalse)lp1_resized lp_12out self.linear_pred(torch.cat([lp1_resized, lp2_resized, lp3_resized, lp4_resized], dim1))out_resized F.interpolate(out,scale_factor4,modebilinear, align_cornersTrue)return out_resized上述图片和代码是关于ESFP核心网络的编写下面就来详细介绍一下这个网络。
backbone部分引用于原论文
使用model_type来加载预训练模型这里有5个参数可选。通过指定的预训练权重来初始化backbone网络。Mix Transformer编码器(MiT)是一个模块它利用了ViT网络的思想并在四个阶段中使用四个重叠的路径合并模块和自注意力预测。transformer使用的自注意力层缺乏局部归纳偏差(图像像素是局部相关的其相关图是平移不变的概念)会导致数据饥饿问题。为了缓解受小数据集限制的应用面临的数据饥饿挑战可以利用广泛使用的迁移学习的概念。MiT的编码器利用了这个想法在大型ImageNet数据库上进行了预训练对于我们的ESPFNet架构将这些预训练的MiT编码器集成为骨干并用初始化的解码器再次训练它们。这是一种直接的方法可以在小型特定任务数据集表现良好性能同时也能够超过最先进的CNN模型的性能。
Efficient stage-wise feature pyramidESFP
高层(全局)特征比低层(局部)特征对整体分割性能的贡献更大。ESFP首先对每个阶段的输出进行线性预测(有效的是连接通道的数量)然后将这些预处理的特征从全局到局部线性融合。这些中间聚合特征被连接起来并相互协作产生最终的分割。在训练之前将输入调整为352 × 352像素并将其归一化以进行分割。我们还使用随机翻转、旋转和亮度变化作为输入的数据增强操作。损失函数结合了加权交联(IoU)损失和加权二元交叉熵(BCE)损失:
实现细节 这一部分是关于MIt 编码器对图像进行编码的操作。 这一部分则是ESFP对网络进行解码的过程。
LP Header # LP Headerself.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 Fuseself.linear_fuse34 ConvModule(in_channels(self.backbone.embed_dims[2] self.backbone.embed_dims[3]), out_channelsself.backbone.embed_dims[2], kernel_size1,norm_cfgdict(typeBN, requires_gradTrue))self.linear_fuse23 ConvModule(in_channels(self.backbone.embed_dims[1] self.backbone.embed_dims[2]), out_channelsself.backbone.embed_dims[1], kernel_size1,norm_cfgdict(typeBN, requires_gradTrue))self.linear_fuse12 ConvModule(in_channels(self.backbone.embed_dims[0] self.backbone.embed_dims[1]), out_channelsself.backbone.embed_dims[0], kernel_size1,norm_cfgdict(typeBN, requires_gradTrue))
通过上述的网络结构图可以看出我们需要3个线性融合层。通过ConvModule来定义Linear Fuse层其中in_channels表示Linear Fuse的输入通道数由两个特征图的通道数相加得到。out_channels表示Linear Fuse的输出通道数与对应层次的特征图通道数相同。通过这些Linear Fuse层的操作可以将不同分辨率的特征图进行融合从而提高特征的表达能力和多尺度信息的利用效果
Fused LP Header融合的LP Header
# Fused LP Headerself.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 Predictionself.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_size1)
n.Conv2d用于定义一个二维卷积层其中的输入通道数为融合后的特征图的通道数总和。输入通道是各个分辨率维度的总和输出通道为1表示进行目标检测的预测结果。这个最终的线性预测层将融合后的特征图映射到一维的通道上以输出目标检测的预测结果。这样通过特征融合与转换后的特征图可以进行最终的目标检测操作并得到预测结果。
前向传播 B x.shape[0]#stage 1out_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 2out_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 3out_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 4out_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 Headerlp_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_factor2,modebilinear, align_cornersFalse)], dim1)))lp_23 self.LP_23(self.linear_fuse23(torch.cat([lp_2, F.interpolate(lp_34,scale_factor2,modebilinear, align_cornersFalse)], dim1)))lp_12 self.LP_12(self.linear_fuse12(torch.cat([lp_1, F.interpolate(lp_23,scale_factor2,modebilinear, align_cornersFalse)], dim1)))# get the final outputlp4_resized F.interpolate(lp_4,scale_factor8,modebilinear, align_cornersFalse)lp3_resized F.interpolate(lp_34,scale_factor4,modebilinear, align_cornersFalse)lp2_resized F.interpolate(lp_23,scale_factor2,modebilinear, align_cornersFalse)lp1_resized lp_12out self.linear_pred(torch.cat([lp1_resized, lp2_resized, lp3_resized, lp4_resized], dim1))out_resized F.interpolate(out,scale_factor4,modebilinear, align_cornersTrue)
前向传播的过程就是将结果中的完整过程串联起来进行完整的预测。输入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,HW)变形为(Batch_SizeN H, W)通过reshape进行N维度的计算-1表示自动计算N的值。接着使用permute函数将特征维度N和高宽维度H、W交换位置变成(Batch_Size, N, H, W)的形状
阶段2、3、4
与上述阶段一的操作大致相同也就是图中最上面一层backbone网络的操作。
LP Header # go through LP Headerlp_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_factor2,modebilinear, align_cornersFalse)], dim1)))lp_23 self.LP_23(self.linear_fuse23(torch.cat([lp_2, F.interpolate(lp_34,scale_factor2,modebilinear, align_cornersFalse)], dim1)))lp_12 self.LP_12(self.linear_fuse12(torch.cat([lp_1, F.interpolate(lp_23,scale_factor2,modebilinear, align_cornersFalse)], dim1)))使用torch.cat函数将lp_3与经过上采样后的lp_4拼接起来然后通过self.linear_fuse34和LP_34模块进行线性融合得到lp_34。类似地通过拼接和线性融合操作得到lp_23和lp_12。
最终上采样 # get the final outputlp4_resized F.interpolate(lp_4,scale_factor8,modebilinear, align_cornersFalse)lp3_resized F.interpolate(lp_34,scale_factor4,modebilinear, align_cornersFalse)lp2_resized F.interpolate(lp_23,scale_factor2,modebilinear, align_cornersFalse)lp1_resized lp_12对lp_4进行上采样操作得到lp4_resized上采样因子为8对lp_34进行上采样操作得到lp3_resized上采样因子为4对lp_23进行上采样操作得到lp2_resized上采样因子为2lp_12不进行上采样。
最终输出 out self.linear_pred(torch.cat([lp1_resized, lp2_resized, lp3_resized, lp4_resized], dim1))out_resized F.interpolate(out,scale_factor4,modebilinear, align_cornersTrue)
使用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_size3, padding1),nn.ReLU(),nn.Conv2d(128, 256, kernel_size3, padding1),nn.ReLU(),nn.MaxPool2d(kernel_size2, stride2),nn.Conv2d(256, 512, kernel_size3, padding1),nn.ReLU(),nn.Conv2d(512, 512, kernel_size3, padding1),nn.ReLU(),nn.MaxPool2d(kernel_size2, stride2))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(dim1))首先对其进行4次卷积和3次最大池化进行下采样和特征提取。随后定义一个全连接层让通道数最终降到我们所需要的分类数最后再做一次Softmax。
前向传播过程
前向传播过程则是将我们之前做好的分割结果和原图进行通道维度cat连接后再进行一最大池化操作然后进行分类操作。我们对不同种类的数据做了one-hot类别编码。
以上就是大致总统思路后续代码会上传到github