PointNet.pytorch程序注释点云分类
程序员文章站
2022-06-26 17:05:34
PointNet.pytorch程序注释(一)点云分类论文及程序地址运行环境训练train测试test论文及程序地址论文原文PointNet: Deep Learning on Point Sets for 3D Classification and Segmentation源程序链接: https://github.com/fxia22/pointnet.pytorc.自己标注的程序链接: https://github.com/jiangdi1998/PointNet.pytorch.运行...
论文及程序地址
论文原文
PointNet: Deep Learning on Point Sets for 3D Classification and Segmentation
源程序
链接: https://github.com/fxia22/pointnet.pytorch.
自己标注的程序
链接: https://github.com/jiangdi1998/PointNet.pytorch.
运行环境
硬件:i7-6700HQ、GTX960M-2G
软件:Ubuntu18.04、Python3.6、Pytorch1.6.0、cuda10.2
训练集:ShapeNet
训练train
pointnet.pytorch/Utils/train_classification.py
由于显存只有2G,故将训练的batch_size = 8,同时在train_classification.py 71行和78行键入drop_last = True,pytorch这种动态图结构下,训练或者验证图片数不能整除batch_size是不会报错的。
运行程序命令
python3 train_classification.py --dataset '/home/jiangdi/Downloads/jiangdi1998-pointnet.pytorch-master/pointnet.pytorch/shapenetcore_partanno_segmentation_benchmark_v0' --nepoch='2' --batchSize='8' --dataset_type 'shapenet'
注释代码
from __future__ import print_function
import argparse
import os
import random
import torch
import torch.nn.parallel
import torch.optim as optim
import torch.utils.data
from pointnet.dataset import ShapeNetDataset, ModelNetDataset
from pointnet.model import PointNetCls, feature_transform_regularizer
import torch.nn.functional as F
from tqdm import tqdm
parser = argparse.ArgumentParser()
parser.add_argument(
'--batchSize', type=int, default=32, help='input batch size') #终端键入batchsize
parser.add_argument(
'--num_points', type=int, default=2500, help='input batch size') #默认的数据集每个点云是2500个点
parser.add_argument(
'--workers', type=int, help='number of data loading workers', default=4) #进程
parser.add_argument(
'--nepoch', type=int, default=250, help='number of epochs to train for') #epoch,训练多少个权重文件
parser.add_argument('--outf', type=str, default='cls', help='output folder')
parser.add_argument('--model', type=str, default='', help='model path') #预训练模型路径
parser.add_argument('--dataset', type=str, required=True, help="dataset path") #数据集路径
parser.add_argument('--dataset_type', type=str, default='shapenet', help="dataset type shapenet|modelnet40") #数据集类型shapenet或者modelnet40
parser.add_argument('--feature_transform', action='store_true', help="use feature transform")
opt = parser.parse_args()
print(opt)
blue = lambda x: '\033[94m' + x + '\033[0m' #test设置成蓝色字体
opt.manualSeed = random.randint(1, 10000) # fix seed #生成随机数
print("Random Seed: ", opt.manualSeed)
random.seed(opt.manualSeed)
torch.manual_seed(opt.manualSeed)
if opt.dataset_type == 'shapenet': #创建针对shapenet数据集的类对象
dataset = ShapeNetDataset( #训练集
root=opt.dataset,
classification=True, #打开分类的选项
npoints=opt.num_points)
test_dataset = ShapeNetDataset( #测试集
root=opt.dataset,
classification=True,
split='test', #标记为测试
npoints=opt.num_points,
data_augmentation=False)
elif opt.dataset_type == 'modelnet40':#创建针对modelnet数据集的类对象
dataset = ModelNetDataset(
root=opt.dataset,
npoints=opt.num_points,
split='trainval')
test_dataset = ModelNetDataset(
root=opt.dataset,
split='test',
npoints=opt.num_points,
data_augmentation=False)
else:
exit('wrong dataset type') #如果在终端没有键入正确的数据集格式,则警告
dataloader = torch.utils.data.DataLoader( #加载数据
dataset,
batch_size=opt.batchSize,
shuffle=True, #随机数
drop_last=True, #训练的数据数不能被batch_size整除,是不会报错的
num_workers=int(opt.workers))
testdataloader = torch.utils.data.DataLoader(
test_dataset,
batch_size=opt.batchSize,
shuffle=True,
drop_last=True,
num_workers=int(opt.workers))
print(len(dataset), len(test_dataset)) # 12137 2874
num_classes = len(dataset.classes)
print('classes', num_classes) #classes 16
try:
os.makedirs(opt.outf)
except OSError:
pass
classifier = PointNetCls(k=num_classes, feature_transform=opt.feature_transform) #调用model.py的PointNetCls定义分类函数
if opt.model != '':
classifier.load_state_dict(torch.load(opt.model)) #如果有预训练模型,将预训练模型加载
optimizer = optim.Adam(classifier.parameters(), lr=0.001, betas=(0.9, 0.999)) #优化函数,可以替换成SGD之类的
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=20, gamma=0.5)
classifier.cuda()
num_batch = len(dataset) / opt.batchSize #batch数目
for epoch in range(opt.nepoch): #在一个epoch下
scheduler.step()
for i, data in enumerate(dataloader, 0):
points, target = data #读取待训练对象点云与标签
target = target[:, 0]
points = points.transpose(2, 1) #放射变换
points, target = points.cuda(), target.cuda() #使用cuda加速
optimizer.zero_grad() #清除梯度
classifier = classifier.train() #训练
pred, trans, trans_feat = classifier(points) #计算预测值
loss = F.nll_loss(pred, target) #交叉熵函数
if opt.feature_transform:
loss += feature_transform_regularizer(trans_feat) * 0.001
loss.backward() #反向传播
optimizer.step() #优化
pred_choice = pred.data.max(1)[1] #
print(pred_choice) #tensor([ 0, 15, 4, 0], device='cuda:0')
correct = pred_choice.eq(target.data).cpu().sum()
print(correct) #tensor(1)
print('[%d: %d/%d] train loss: %f accuracy: %f' % (epoch, i, num_batch, loss.item(), correct.item() / float(opt.batchSize))) [0: 9/3034] train loss: 2.467071 accuracy: 0.250000
if i % 10 == 0: #每十次测试以下,过程同上
j, data = next(enumerate(testdataloader, 0))
points, target = data
target = target[:, 0]
points = points.transpose(2, 1)
points, target = points.cuda(), target.cuda()
classifier = classifier.eval()
pred, _, _ = classifier(points)
loss = F.nll_loss(pred, target)
pred_choice = pred.data.max(1)[1]
correct = pred_choice.eq(target.data).cpu().sum()
print('[%d: %d/%d] %s loss: %f accuracy: %f' % (epoch, i, num_batch, blue('test'), loss.item(), correct.item()/float(opt.batchSize))) #[0: 0/3034] test loss: 2.739059 accuracy: 0.000000
torch.save(classifier.state_dict(), '%s/cls_model_%d.pth' % (opt.outf, epoch)) #保存权重文件在cls/cls_model_1.pth
total_correct = 0
total_testset = 0
for i,data in tqdm(enumerate(testdataloader, 0)): #tqdm进度条
points, target = data
target = target[:, 0]
points = points.transpose(2, 1)
points, target = points.cuda(), target.cuda()
classifier = classifier.eval()
pred, _, _ = classifier(points)
pred_choice = pred.data.max(1)[1]
correct = pred_choice.eq(target.data).cpu().sum()
total_correct += correct.item()
total_testset += points.size()[0]
print("final accuracy {}".format(total_correct / float(total_testset))) #测试最终的正确率
运行过程
训练后的权重文件保存至
point.pytorch/utils/cls
训练权重结果
测试test
pointnet.pytorch/Utils/show_cls.py
1.将权重文件的路径写入到测试文件中,其中show_cls.py修改第16行的
default='/home/jiangdi/Downloads/jiangdi1998-pointnet.pytorch-master/pointnet.pytorch/utils/cls/cls_model_0.pth'
2.将第31行的修改batch_size 修改为batch_size= 8 ,第51行的float修改为float(8)
运行程序命令
python3 show_cls.py
注释代码
from __future__ import print_function
import argparse
import torch
import torch.nn.parallel
import torch.utils.data
from torch.autograd import Variable
from pointnet.dataset import ShapeNetDataset
from pointnet.model import PointNetCls
import torch.nn.functional as F
#showpoints(np.random.randn(2500,3), c1 = np.random.uniform(0,1,size = (2500)))
parser = argparse.ArgumentParser()
parser.add_argument('--model', type=str, default = '/home/jiangdi/Downloads/jiangdi1998-pointnet.pytorch-master/pointnet.pytorch/utils/cls/cls_model_0.pth', help='model path') #加载模型
parser.add_argument('--num_points', type=int, default=2500, help='input batch size') #默认的每个点云点数2500
opt = parser.parse_args()
print(opt)
test_dataset = ShapeNetDataset( #测试集为ShapeNetDataset
root='shapenetcore_partanno_segmentation_benchmark_v0',
split='test',
classification=True,
npoints=opt.num_points,
data_augmentation=False)
testdataloader = torch.utils.data.DataLoader( #加载测试集数据
test_dataset, batch_size=8, shuffle=True) #显存小,修改batch_size为8或者4
classifier = PointNetCls(k=len(test_dataset.classes))
classifier.cuda()
classifier.load_state_dict(torch.load(opt.model))
classifier.eval()
for i, data in enumerate(testdataloader, 0):
points, target = data
points, target = Variable(points), Variable(target[:, 0])
points = points.transpose(2, 1)
points, target = points.cuda(), target.cuda()
pred, _, _ = classifier(points)
loss = F.nll_loss(pred, target)
pred_choice = pred.data.max(1)[1]
print(pred_choice) #预测 tensor([ 4, 12, 15, 4, 15, 15, 12, 6], device='cuda:0')
print(target) #真值 tensor([ 4, 15, 15, 4, 15, 15, 15, 8], device='cuda:0')
correct = pred_choice.eq(target.data).cpu().sum() #计算正确率
print('i:%d loss: %f accuracy: %f' % (i, loss.data.item(), correct / float(8))) #显存小,修改batch_size为8或者4 ,i:0 loss: 0.426616 accuracy: 0.750000
运行结果
本文地址:https://blog.csdn.net/jd1998/article/details/112672836
上一篇: 腊八节日风俗有哪些