<filename>models/Z_CNN_part_seg_msg.py
import torch.nn as nn
import torch
import torch.nn.functional as F
from models.pointnet2_utils import PointNetSetAbstractionMsg,PointNetSetAbstraction,PointNetFeaturePropagation
from Z_CNN import TransformerBlock,PointNet,z_order,CNN

class get_model(nn.Module):
    def __init__(self, num_classes, normal_channel=False):
        super(get_model, self).__init__()
        super(get_model, self).__init__()
        if normal_channel:  # normalchannel用于判断是否需要加入法向量，需要的话就在输入通道数上+3
            additional_channel = 3
        else:
            additional_channel = 0
        if normal_channel:
            channel = 6
        else:
            channel = 3
        self.cnn = CNN(channel=channel)
        self.normal_channel = normal_channel
        self.sa1 = PointNetSetAbstractionMsg(512, [0.1, 0.2, 0.4], [32, 64, 128], 3 + additional_channel,
                                             [[32, 32, 64], [64, 64, 128], [64, 96, 128]])
        self.sa2 = PointNetSetAbstractionMsg(128, [0.4, 0.8], [64, 128], 128 + 128 + 64,
                                             [[128, 128, 256], [128, 196, 256]])
        self.sa3 = PointNetSetAbstraction(npoint=None, radius=None, nsample=None, in_channel=512 + 3,
                                          mlp=[256, 512, 1024], group_all=True)
        # 以下就是分割部分所特有的进行上采样部分
        # 以下就是分割部分所特有的进行上采样部分
        self.fp1 = PointNetFeaturePropagation(in_channel=150 + additional_channel, mlp=[128, 128])
        #self.fp3 = PointNetFeaturePropagation(in_channel=1536, mlp=[256, 256])#下采样中的跳联得到1536,1024+256+256。
        #self.fp2 = PointNetFeaturePropagation(in_channel=576, mlp=[256, 128])
        #fp3使用150+add是因为它加入了sa1中提取出的特征，我们要保留这一步的话只用改变torch.cat中的内容
        self.xx1=nn.ConvTranspose1d(1024,256,128)#由于插值的原因，++本身会使用到上述在特征提取时得到的数字来进行插值，但反卷积目前并不需要，故直接使用最终结果1024
        self.xx2 = nn.ConvTranspose1d(256,128,385)#目前的问题是，在知晓了，输入通道数为1024的情况下，如何产生输出维度，使得最终图像的长度变成++原本应该有的长度
        #反卷积之后大小的计算方法为Lout=(Lin−1)×stride−2×padding+dilation×(kernelsize−1)+outputpadding+1
        #其中，lin是输入张量的第三个维度大小，lout是输出图片的第三个维度大小。函数中的输入输出通道则为第二个维度大小
        #在反卷积完成之后需要将得到的特征与transformer中的特征合并，怎么弄？
        #有多少个卷积核去卷，就会有多少个通道
        self.xx3=nn.Conv1d(128,128,1)#如果反卷积无法使第二个维度回到128，则使用一次卷积操作
        self.xx4 = nn.BatchNorm1d(128)
        self.conv1 = nn.Conv1d(128, 128, 1)
        self.bn1 = nn.BatchNorm1d(128)#归一化函数
        self.drop1 = nn.Dropout(0.5)
        self.conv2 = nn.Conv1d(128, num_classes, 1)

    def forward(self, xyz, cls_label):
        # Set Abstraction layers
        B,C,N = xyz.shape
        if self.normal_channel:
            l0_points = xyz
            l0_xyz = xyz[:,:3,:]
        else:
            l0_points = xyz
            l0_xyz = xyz
        l1_xyz, l1_points = self.sa1(l0_xyz, l0_points)
        l2_xyz, l2_points = self.sa2(l1_xyz, l1_points)
        l3_xyz, l3_points = self.sa3(l2_xyz, l2_points)
        # Feature Propagation layers
        #l2_points = self.fp3(l2_xyz, l3_xyz, l2_points, l3_points)
        #l1_points = self.fp2(l1_xyz, l2_xyz, l1_points, l2_points)
        #x1_points=l3_points.permute(0,2,1)
        x, xyz0, feature = z_order(xyz)
        x = self.cnn(x)  # torch.Size[64, 128, 1],,[16,128,1]
        print(x.size())
        x2_points=self.xx1(l3_points)#相当于l2points
        x1_points=self.xx2(x2_points)#相当于l1points
        #x1_points=torch.cat([x1_points,xn_points],1)xn_points是transformer中得到的逐点特征，如果在第三维上两张量的长度不同，则先通过
        #卷积操作，将其长度变为相同，然后连接起来，再进行卷积，变到128上，最后放入插值中
        #可以把只含xyz的数据也进行反卷积，用来替代l0-xyz，x2-points用来替代l1-points，但x2-points要先把transformer得到的特征cat上

        cls_label_one_hot = cls_label.view(B,16,1).repeat(1,1,N)#view函数用于重构向量维度
        #l0_points = self.fp1(l0_xyz, l1_xyz, torch.cat([cls_label_one_hot, l0_xyz, l0_points], 1), l1_points)
        l0_points = self.fp1(l0_xyz, l1_xyz, torch.cat([cls_label_one_hot,l0_xyz,l0_points],1), x1_points)

        # FC layers
        feat = F.relu(self.bn1(self.conv1(l0_points)))
        x = self.drop1(feat)
        x = self.conv2(x)
        x = F.log_softmax(x, dim=1)
        x = x.permute(0, 2, 1)
        return x, l3_points


class get_loss(nn.Module):
    def __init__(self):
        super(get_loss, self).__init__()

    def forward(self, pred, target, trans_feat):
        total_loss = F.nll_loss(pred, target)

        return total_loss
<filename>models/Z_CNN_part_seg_msg.py
import torch.nn as nn
import torch
import torch.nn.functional as F
from models.pointnet2_utils import PointNetSetAbstractionMsg,PointNetSetAbstraction,PointNetFeaturePropagation
from Z_CNN import TransformerBlock,PointNet,z_order,CNN

class get_model(nn.Module):
    def __init__(self, num_classes, normal_channel=False):
        super(get_model, self).__init__()
        super(get_model, self).__init__()
        if normal_channel:  # normalchannel用于判断是否需要加入法向量，需要的话就在输入通道数上+3
            additional_channel = 3
        else:
            additional_channel = 0
        if normal_channel:
            channel = 6
        else:
            channel = 3
        self.cnn = CNN(channel=channel)
        self.normal_channel = normal_channel
        self.sa1 = PointNetSetAbstractionMsg(512, [0.1, 0.2, 0.4], [32, 64, 128], 3 + additional_channel,
                                             [[32, 32, 64], [64, 64, 128], [64, 96, 128]])
        self.sa2 = PointNetSetAbstractionMsg(128, [0.4, 0.8], [64, 128], 128 + 128 + 64,
                                             [[128, 128, 256], [128, 196, 256]])
        self.sa3 = PointNetSetAbstraction(npoint=None, radius=None, nsample=None, in_channel=512 + 3,
                                          mlp=[256, 512, 1024], group_all=True)
        # 以下就是分割部分所特有的进行上采样部分
        # 以下就是分割部分所特有的进行上采样部分
        self.fp1 = PointNetFeaturePropagation(in_channel=150 + additional_channel, mlp=[128, 128])
        #self.fp3 = PointNetFeaturePropagation(in_channel=1536, mlp=[256, 256])#下采样中的跳联得到1536,1024+256+256。
        #self.fp2 = PointNetFeaturePropagation(in_channel=576, mlp=[256, 128])
        #fp3使用150+add是因为它加入了sa1中提取出的特征，我们要保留这一步的话只用改变torch.cat中的内容
        self.xx1=nn.ConvTranspose1d(1024,256,128)#由于插值的原因，++本身会使用到上述在特征提取时得到的数字来进行插值，但反卷积目前并不需要，故直接使用最终结果1024
        self.xx2 = nn.ConvTranspose1d(256,128,385)#目前的问题是，在知晓了，输入通道数为1024的情况下，如何产生输出维度，使得最终图像的长度变成++原本应该有的长度
        #反卷积之后大小的计算方法为Lout=(Lin−1)×stride−2×padding+dilation×(kernelsize−1)+outputpadding+1
        #其中，lin是输入张量的第三个维度大小，lout是输出图片的第三个维度大小。函数中的输入输出通道则为第二个维度大小
        #在反卷积完成之后需要将得到的特征与transformer中的特征合并，怎么弄？
        #有多少个卷积核去卷，就会有多少个通道
        self.xx3=nn.Conv1d(128,128,1)#如果反卷积无法使第二个维度回到128，则使用一次卷积操作
        self.xx4 = nn.BatchNorm1d(128)
        self.conv1 = nn.Conv1d(128, 128, 1)
        self.bn1 = nn.BatchNorm1d(128)#归一化函数
        self.drop1 = nn.Dropout(0.5)
        self.conv2 = nn.Conv1d(128, num_classes, 1)

    def forward(self, xyz, cls_label):
        # Set Abstraction layers
        B,C,N = xyz.shape
        if self.normal_channel:
            l0_points = xyz
            l0_xyz = xyz[:,:3,:]
        else:
            l0_points = xyz
            l0_xyz = xyz
        l1_xyz, l1_points = self.sa1(l0_xyz, l0_points)
        l2_xyz, l2_points = self.sa2(l1_xyz, l1_points)
        l3_xyz, l3_points = self.sa3(l2_xyz, l2_points)
        # Feature Propagation layers
        #l2_points = self.fp3(l2_xyz, l3_xyz, l2_points, l3_points)
        #l1_points = self.fp2(l1_xyz, l2_xyz, l1_points, l2_points)
        #x1_points=l3_points.permute(0,2,1)
        x, xyz0, feature = z_order(xyz)
        x = self.cnn(x)  # torch.Size[64, 128, 1],,[16,128,1]
        print(x.size())
        x2_points=self.xx1(l3_points)#相当于l2points
        x1_points=self.xx2(x2_points)#相当于l1points
        #x1_points=torch.cat([x1_points,xn_points],1)xn_points是transformer中得到的逐点特征，如果在第三维上两张量的长度不同，则先通过
        #卷积操作，将其长度变为相同，然后连接起来，再进行卷积，变到128上，最后放入插值中
        #可以把只含xyz的数据也进行反卷积，用来替代l0-xyz，x2-points用来替代l1-points，但x2-points要先把transformer得到的特征cat上

        cls_label_one_hot = cls_label.view(B,16,1).repeat(1,1,N)#view函数用于重构向量维度
        #l0_points = self.fp1(l0_xyz, l1_xyz, torch.cat([cls_label_one_hot, l0_xyz, l0_points], 1), l1_points)
        l0_points = self.fp1(l0_xyz, l1_xyz, torch.cat([cls_label_one_hot,l0_xyz,l0_points],1), x1_points)

        # FC layers
        feat = F.relu(self.bn1(self.conv1(l0_points)))
        x = self.drop1(feat)
        x = self.conv2(x)
        x = F.log_softmax(x, dim=1)
        x = x.permute(0, 2, 1)
        return x, l3_points


class get_loss(nn.Module):
    def __init__(self):
        super(get_loss, self).__init__()

    def forward(self, pred, target, trans_feat):
        total_loss = F.nll_loss(pred, target)

        return total_loss
# normalchannel用于判断是否需要加入法向量，需要的话就在输入通道数上+3 # 以下就是分割部分所特有的进行上采样部分 # 以下就是分割部分所特有的进行上采样部分 #self.fp3 = PointNetFeaturePropagation(in_channel=1536, mlp=[256, 256])#下采样中的跳联得到1536,1024+256+256。 #self.fp2 = PointNetFeaturePropagation(in_channel=576, mlp=[256, 128]) #fp3使用150+add是因为它加入了sa1中提取出的特征，我们要保留这一步的话只用改变torch.cat中的内容 #由于插值的原因，++本身会使用到上述在特征提取时得到的数字来进行插值，但反卷积目前并不需要，故直接使用最终结果1024 #目前的问题是，在知晓了，输入通道数为1024的情况下，如何产生输出维度，使得最终图像的长度变成++原本应该有的长度 #反卷积之后大小的计算方法为Lout=(Lin−1)×stride−2×padding+dilation×(kernelsize−1)+outputpadding+1 #其中，lin是输入张量的第三个维度大小，lout是输出图片的第三个维度大小。函数中的输入输出通道则为第二个维度大小 #在反卷积完成之后需要将得到的特征与transformer中的特征合并，怎么弄？ #有多少个卷积核去卷，就会有多少个通道 #如果反卷积无法使第二个维度回到128，则使用一次卷积操作 #归一化函数 # Set Abstraction layers # Feature Propagation layers #l2_points = self.fp3(l2_xyz, l3_xyz, l2_points, l3_points) #l1_points = self.fp2(l1_xyz, l2_xyz, l1_points, l2_points) #x1_points=l3_points.permute(0,2,1) # torch.Size[64, 128, 1],,[16,128,1] #相当于l2points #相当于l1points #x1_points=torch.cat([x1_points,xn_points],1)xn_points是transformer中得到的逐点特征，如果在第三维上两张量的长度不同，则先通过 #卷积操作，将其长度变为相同，然后连接起来，再进行卷积，变到128上，最后放入插值中 #可以把只含xyz的数据也进行反卷积，用来替代l0-xyz，x2-points用来替代l1-points，但x2-points要先把transformer得到的特征cat上 #view函数用于重构向量维度 #l0_points = self.fp1(l0_xyz, l1_xyz, torch.cat([cls_label_one_hot, l0_xyz, l0_points], 1), l1_points) # FC layers