代码阅读记录(6)—Point-NN cls

run_nn_cls.py

Constructing Point-Memory Bank

feature_memory, label_memory = [], []
    # with torch.no_grad():
    for points, labels in tqdm(train_loader):
        
        points = points.cuda().permute(0, 2, 1)
        # Pass through the Non-Parametric Encoder
        point_features = point_nn(points)
        feature_memory.append(point_features)

        labels = labels.cuda()
        label_memory.append(labels)

构建出一组特征(feature_memory)和对应的标签(label_memory),用于训练模型。

# Feature Memory
feature_memory = torch.cat(feature_memory, dim=0)
feature_memory /= feature_memory.norm(dim=-1, keepdim=True)
feature_memory = feature_memory.permute(1, 0)

# Label Memory
label_memory = torch.cat(label_memory, dim=0)
label_memory = F.one_hot(label_memory).squeeze().float()

 这段代码是用PyTorch实现的特征和标签的内存功能。

首先,它将存储在feature_memory列表中的特征拼接在一起,并对每个特征向量进行归一化处理。然后,它将特征内存转置,以便可以更轻松地使用它们进行计算。

然后,它将存储在label_memory列表中的标签向量拼接在一起,并使用F.one_hot函数将这些标签向

量转换为one-hot形式。最后,它将one-hot编码的标签内存张量压缩为二维形状。

Saving Test Point Cloud Feature

test_features, test_labels = [], []
# with torch.no_grad():
for points, labels in tqdm(test_loader):
        
    points = points.cuda().permute(0, 2, 1)
    # Pass through the Non-Parametric Encoder
    point_features = point_nn(points)
    test_features.append(point_features)

    labels = labels.cuda()
    test_labels.append(labels)

首先定义了两个空列表 test_featurestest_labels,用于存储测试集中每个数据点的特征和标签。然后对测试集进行了遍历,将点云数据传入模型中,经过非参数编码器处理后得到该数据点的特征向量 point_features,并将其添加到 test_features 列表中。最后将该数据点的标签也存入 test_labels 列表中。 

test_features = torch.cat(test_features)
test_features /= test_features.norm(dim=-1, keepdim=True)
test_labels = torch.cat(test_labels)

第一行 `test_features = torch.cat(test_features)` 将测试特征沿指定的维度连接起来

第二行 `test_features /= test_features.norm(dim=-1, keepdim=True)` 对测试特征进行 L2 归一化。这通常用于确保所有特征向量具有相同的比例,并帮助提高某些机器学习算法的性能

第三行 `test_labels = torch.cat(test_labels)` 将测试标签沿指定的维度连接起来

 Starting Point-NN

gamma_list = [i * 10000 / 5000 for i in range(5000)]
best_acc, best_gamma = 0, 0
for gamma in gamma_list:

    # Similarity Matching
    Sim = test_features @ feature_memory

    # Label Integrate
    logits = (-gamma * (1 - Sim)).exp() @ label_memory

    acc = cls_acc(logits, test_labels)

    if acc > best_acc:
        # print('New best, gamma: {:.2f}; Point-NN acc: {:.2f}'.format(gamma, acc))
        best_acc, best_gamma = acc, gamma

首先创建了一个包含5000个元素的gamma_list列表,然后定义了两个变量best_acc和best_gamma,并将它们的值都初始化为0。

在循环中,对于gamma_list中的每个元素gamma,代码进行了以下操作:

1. 进行相似度匹配,即将测试数据的特征向量(test_features)与训练数据的特征向量(feature_memory)进行点积运算,得到相似度矩阵Sim。

2. 将该相似度矩阵Sim乘以-gamma并取指数(exp),再与训练数据的标签(label_memory)进行点积运算,得到logits变量。

3. 使用cls_acc函数计算出logits的准确率acc。

4. 如果当前计算得到的准确率acc比之前记录的最佳准确率best_acc要好,则更新best_acc和best_gamma的值。

最终,这段代码会输出在所有gamma值中能够得到最好准确率的gamma值best_gamma和其对应的准确率best_acc。

point_nn.py 

# Non-Parametric Network
class Point_NN(nn.Module):
    def __init__(self, input_points=1024, num_stages=4, embed_dim=72, k_neighbors=90, beta=1000, alpha=100):
        super().__init__()
        # Non-Parametric Encoder
        self.EncNP = EncNP(input_points, num_stages, embed_dim, k_neighbors, alpha, beta)


    def forward(self, x):
        # xyz: point coordinates
        # x: point features
        xyz = x.permute(0, 2, 1)

        # Non-Parametric Encoder
        x = self.EncNP(xyz, x)
        return x

EncNP

# Non-Parametric Encoder
class EncNP(nn.Module):  
    def __init__(self, input_points, num_stages, embed_dim, k_neighbors, alpha, beta):
        super().__init__()
        self.input_points = input_points
        self.num_stages = num_stages
        self.embed_dim = embed_dim
        self.alpha, self.beta = alpha, beta

        # Raw-point Embedding
        self.raw_point_embed = PosE_Initial(3, self.embed_dim, self.alpha, self.beta)

        self.FPS_kNN_list = nn.ModuleList() # FPS, kNN
        self.LGA_list = nn.ModuleList() # Local Geometry Aggregation
        self.Pooling_list = nn.ModuleList() # Pooling
        
        out_dim = self.embed_dim
        group_num = self.input_points

        # Multi-stage Hierarchy
        for i in range(self.num_stages):
            out_dim = out_dim * 2
            group_num = group_num // 2
            self.FPS_kNN_list.append(FPS_kNN(group_num, k_neighbors))
            self.LGA_list.append(LGA(out_dim, self.alpha, self.beta))
            self.Pooling_list.append(Pooling(out_dim))


    def forward(self, xyz, x):

        # Raw-point Embedding
        x = self.raw_point_embed(x)

        # Multi-stage Hierarchy
        for i in range(self.num_stages):
            # FPS, kNN
            xyz, lc_x, knn_xyz, knn_x = self.FPS_kNN_list[i](xyz, x.permute(0, 2, 1))
            # Local Geometry Aggregation
            knn_x_w = self.LGA_list[i](xyz, lc_x, knn_xyz, knn_x)
            # Pooling
            x = self.Pooling_list[i](knn_x_w)

        # Global Pooling
        x = x.max(-1)[0] + x.mean(-1)
        return x

与seg部分的编码差不多,只是对于所有阶段的处理结果,最终进行全局池化(Global Pooling)操作,得到一个固定维度的向量表示,作为整个编码器的输出结果。这里的全局池化操作使用的是 max pooling 和 mean pooling 的结合。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值