本文尝试在点云上应用WGAN-GP,判别器借鉴PointNet结构,生成器为自定义搭建。使用ModelNet40数据集,取1024个点训练。定义了FeatureNet、UFeatureNet等网络,通过Adam优化器训练,每2轮可视化生成结果,20轮保存模型,目前可运行但效果待提升。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

ModelNet总共有662中目标分类,127915个CAD,以及十类标记过方向朝向的数据。其中包含了三个子集:
1、ModelNet10:十个标记朝向的子集数据;
2、ModelNet40:40个类别的三维模型;
3、Aligned40:40类标记的三维模型。
这里使用了ModelNet40,并且归一化了,文件中的数据的意义:
1、横轴有六个数字,分别代表:x, y, z, r, g, b;
2、纵轴为点,每份数据一共有10000个点,项目中每份数据抽取其中1024个点进行训练。
!unzip data/data50045/modelnet40_normal_resampled.zip!mv modelnet40_normal_resampled dataset
import osimport numpy as npimport randomfrom mpl_toolkits import mplot3dimport matplotlib.pyplot as pltimport paddleimport paddle.nn.functional as Ffrom paddle.nn import Conv2D, Conv2DTranspose, MaxPool2D, Linear, BatchNorm, Dropout, ReLU, Tanh, LeakyReLU, Sequential
category = { 'airplane': 0,
}def getDatalist(file_path='./dataset/modelnet40_shape_names.txt'):
f = open(file_path, 'r')
f_train = open('./dataset/train.txt', 'w')
f_test = open('./dataset/test.txt', 'w') for category in f: if category.split('\n')[0] == 'airplane':
dict_path = os.path.join('./dataset/', category.split('\n')[0])
data_dict = os.listdir(dict_path)
count = 0
for data_path in data_dict: if count % 61 != 0:
f_train.write(os.path.join(dict_path, data_path) + ' ' + category) else:
f_test.write(os.path.join(dict_path, data_path) + ' ' + category)
count += 1
f_train.close()
f_test.close()
f.close()if __name__ == '__main__':
getDatalist()def pointDataLoader(file_path='./dataset/train.txt', mode='train'):
BATCHSIZE = 8
MAX_POINT = 250
datas = []
labels = []
f = open(file_path) for data_list in f:
point_data = []
data_path = data_list.split(' ')[0]
data_file = open(data_path)
point_num = 0
for points in data_file: if point_num == MAX_POINT: break
point_data.append([ float(points.split(',')[0]), float(points.split(',')[1]), float(points.split(',')[2])
])
point_num += 1
datas.append(point_data)
labels.append(category[data_list.split(' ')[1].split('\n')[0]])
f.close()
datas = np.array(datas)
labels = np.array(labels)
index_list = list(range(len(datas))) def pointDataGenerator():
if mode == 'train':
random.shuffle(index_list)
datas_list = []
labels_list = [] for i in index_list:
data = np.reshape(datas[i], [1, 250, 3]).astype('float32')
label = np.reshape(labels[i], [1]).astype('int64')
datas_list.append(data)
labels_list.append(label) if len(datas_list) == BATCHSIZE: yield np.array(datas_list), np.array(labels_list)
datas_list = []
labels_list = [] if len(datas_list) > 0: yield np.array(datas_list), np.array(labels_list) return pointDataGeneratorclass FeatureNet(paddle.nn.Layer):
def __init__(self, name_scope='FeatureNet_', num_point=256):
super(FeatureNet, self).__init__()
self.input_transform_net = Sequential(
Conv2D(1, 64, (1, 3)),
BatchNorm(64),
ReLU(),
Conv2D(64, 256, (1, 1)),
BatchNorm(256),
ReLU(),
MaxPool2D((num_point, 1))
)
self.input_fc = Sequential(
Linear(256, 64),
ReLU(),
Linear(64, 9,
weight_attr=paddle.framework.ParamAttr(initializer=paddle.nn.initializer.Assign(paddle.zeros((64, 9)))),
bias_attr=paddle.framework.ParamAttr(initializer=paddle.nn.initializer.Assign(paddle.reshape(paddle.eye(3), [-1])))
)
)
self.mlp_1 = Sequential(
Conv2D(1, 64, (1, 3)),
BatchNorm(64),
ReLU(),
Conv2D(64, 16,(1, 1)),
BatchNorm(16),
ReLU(),
)
self.feature_transform_net = Sequential(
Conv2D(16, 16, (1, 1)),
BatchNorm(16),
ReLU(),
MaxPool2D((num_point, 1))
)
self.feature_fc = Sequential(
Linear(16, 8),
ReLU(),
Linear(8, 16*16)
)
self.mlp_2 = Sequential(
Conv2D(16, 8, (1, 1)),
BatchNorm(8),
ReLU()
)
def forward(self, inputs):
"""
input: [batchsize, 1, 250, 3]
output: [batchsize, 250, 1]
"""
batchsize = inputs.shape[0]
t_net = self.input_transform_net(inputs)
t_net = paddle.squeeze(t_net)
t_net = self.input_fc(t_net)
t_net = paddle.reshape(t_net, [batchsize, 3, 3])
x = paddle.squeeze(inputs)
x = paddle.matmul(x, t_net)
x = paddle.unsqueeze(x, axis=1)
x = self.mlp_1(x)
t_net = self.feature_transform_net(x)
t_net = paddle.squeeze(t_net)
t_net = self.feature_fc(t_net)
t_net = paddle.reshape(t_net, [batchsize, 16, 16])
x = paddle.squeeze(x)
x = paddle.transpose(x, (0, 2, 1))
x = paddle.matmul(x, t_net)
x = paddle.transpose(x, (0, 2, 1))
x = paddle.unsqueeze(x, axis=-1)
x = self.mlp_2(x)
x = paddle.max(x, axis=2) return xclass UFeatureNet(paddle.nn.Layer):
def __init__(self, name_scope='UFeatureNet_', num_point=1024):
super(UFeatureNet, self).__init__()
self.stage_1 = Sequential(
Conv2DTranspose(1, 4, (1, 3)),
BatchNorm(4),
LeakyReLU(),
Conv2D(4, 16, (1, 1)),
BatchNorm(16),
LeakyReLU()
)
self.stage_2 = Sequential(
Conv2DTranspose(16, 32, (4, 4), (2, 1)),
BatchNorm(32),
LeakyReLU(),
Conv2D(32, 128, (1, 1)),
BatchNorm(128),
LeakyReLU()
)
self.stage_3 = Sequential(
Conv2DTranspose(128, 128, (4, 4), (2, 1)),
BatchNorm(128),
LeakyReLU(),
Conv2D(128, 64, (1, 3)),
BatchNorm(64),
LeakyReLU()
)
self.stage_4 = Sequential(
Conv2DTranspose(64, 32, (4, 1), (1, 1)),
BatchNorm(32),
LeakyReLU(),
Conv2D(32, 32, (1, 3)),
BatchNorm(32),
LeakyReLU()
)
self.stage_5 = Sequential(
Conv2DTranspose(32, 16, (2, 1), (1, 1)),
BatchNorm(16),
LeakyReLU(),
Conv2D(16, 1, (1, 3)),
Tanh()
) def forward(self, inputs):
"""
input: [batchsize, 1, 60, 1]
output: [batchsize, 1, 250, 3]
"""
x = self.stage_1(inputs)
x = self.stage_2(x)
x = self.stage_3(x)
x = self.stage_4(x)
x = self.stage_5(x) return xclass D(paddle.nn.Layer):
def __init__(self, name_scope='D_'):
super(D, self).__init__()
self.feature_net = FeatureNet()
self.fc = Sequential(
Linear(8, 8),
ReLU(),
Dropout(p=0.7),
Linear(8, 1)
) def forward(self, inputs):
"""
input: [batchsize, 1, 250, 3]
output: [batchsize, 1]
"""
x = self.feature_net(inputs)
x = paddle.squeeze(x)
x = self.fc(x) return xclass G(paddle.nn.Layer):
def __init__(self, name_scope='G_'):
super(G, self).__init__()
self.u_feature_net = UFeatureNet() def forward(self, inputs):
"""
input: [batchsize, 1, 60, 1]
output: [batchsize, 1, 250, 3]
"""
x = self.u_feature_net(inputs) return xDiscriminator = D() paddle.summary(Discriminator, (8, 1, 250, 3))
---------------------------------------------------------------------------
Layer (type) Input Shape Output Shape Param #
===========================================================================
Conv2D-1 [[8, 1, 250, 3]] [8, 64, 250, 1] 256
BatchNorm-1 [[8, 64, 250, 1]] [8, 64, 250, 1] 256
ReLU-1 [[8, 64, 250, 1]] [8, 64, 250, 1] 0
Conv2D-2 [[8, 64, 250, 1]] [8, 256, 250, 1] 16,640
BatchNorm-2 [[8, 256, 250, 1]] [8, 256, 250, 1] 1,024
ReLU-2 [[8, 256, 250, 1]] [8, 256, 250, 1] 0
MaxPool2D-1 [[8, 256, 250, 1]] [8, 256, 1, 1] 0
Linear-1 [[8, 256]] [8, 64] 16,448
ReLU-3 [[8, 64]] [8, 64] 0
Linear-2 [[8, 64]] [8, 9] 585
Conv2D-3 [[8, 1, 250, 3]] [8, 64, 250, 1] 256
BatchNorm-3 [[8, 64, 250, 1]] [8, 64, 250, 1] 256
ReLU-4 [[8, 64, 250, 1]] [8, 64, 250, 1] 0
Conv2D-4 [[8, 64, 250, 1]] [8, 16, 250, 1] 1,040
BatchNorm-4 [[8, 16, 250, 1]] [8, 16, 250, 1] 64
ReLU-5 [[8, 16, 250, 1]] [8, 16, 250, 1] 0
Conv2D-5 [[8, 16, 250, 1]] [8, 16, 250, 1] 272
BatchNorm-5 [[8, 16, 250, 1]] [8, 16, 250, 1] 64
ReLU-6 [[8, 16, 250, 1]] [8, 16, 250, 1] 0
MaxPool2D-2 [[8, 16, 250, 1]] [8, 16, 1, 1] 0
Linear-3 [[8, 16]] [8, 8] 136
ReLU-7 [[8, 8]] [8, 8] 0
Linear-4 [[8, 8]] [8, 256] 2,304
Conv2D-6 [[8, 16, 250, 1]] [8, 8, 250, 1] 136
BatchNorm-6 [[8, 8, 250, 1]] [8, 8, 250, 1] 32
ReLU-8 [[8, 8, 250, 1]] [8, 8, 250, 1] 0
FeatureNet-1 [[8, 1, 250, 3]] [8, 8, 1] 0
Linear-5 [[8, 8]] [8, 8] 72
ReLU-9 [[8, 8]] [8, 8] 0
Dropout-1 [[8, 8]] [8, 8] 0
Linear-6 [[8, 8]] [8, 1] 9
===========================================================================
Total params: 39,850
Trainable params: 38,154
Non-trainable params: 1,696
---------------------------------------------------------------------------
Input size (MB): 0.02
Forward/backward pass size (MB): 19.45
Params size (MB): 0.15
Estimated Total Size (MB): 19.63
---------------------------------------------------------------------------{'total_params': 39850, 'trainable_params': 38154}Generator = G() paddle.summary(Generator, (8, 1, 60, 1))
-----------------------------------------------------------------------------
Layer (type) Input Shape Output Shape Param #
=============================================================================
Conv2DTranspose-1 [[8, 1, 60, 1]] [8, 4, 60, 3] 16
BatchNorm-7 [[8, 4, 60, 3]] [8, 4, 60, 3] 16
LeakyReLU-1 [[8, 4, 60, 3]] [8, 4, 60, 3] 0
Conv2D-7 [[8, 4, 60, 3]] [8, 16, 60, 3] 80
BatchNorm-8 [[8, 16, 60, 3]] [8, 16, 60, 3] 64
LeakyReLU-2 [[8, 16, 60, 3]] [8, 16, 60, 3] 0
Conv2DTranspose-2 [[8, 16, 60, 3]] [8, 32, 122, 6] 8,224
BatchNorm-9 [[8, 32, 122, 6]] [8, 32, 122, 6] 128
LeakyReLU-3 [[8, 32, 122, 6]] [8, 32, 122, 6] 0
Conv2D-8 [[8, 32, 122, 6]] [8, 128, 122, 6] 4,224
BatchNorm-10 [[8, 128, 122, 6]] [8, 128, 122, 6] 512
LeakyReLU-4 [[8, 128, 122, 6]] [8, 128, 122, 6] 0
Conv2DTranspose-3 [[8, 128, 122, 6]] [8, 128, 246, 9] 262,272
BatchNorm-11 [[8, 128, 246, 9]] [8, 128, 246, 9] 512
LeakyReLU-5 [[8, 128, 246, 9]] [8, 128, 246, 9] 0
Conv2D-9 [[8, 128, 246, 9]] [8, 64, 246, 7] 24,640
BatchNorm-12 [[8, 64, 246, 7]] [8, 64, 246, 7] 256
LeakyReLU-6 [[8, 64, 246, 7]] [8, 64, 246, 7] 0
Conv2DTranspose-4 [[8, 64, 246, 7]] [8, 32, 249, 7] 8,224
BatchNorm-13 [[8, 32, 249, 7]] [8, 32, 249, 7] 128
LeakyReLU-7 [[8, 32, 249, 7]] [8, 32, 249, 7] 0
Conv2D-10 [[8, 32, 249, 7]] [8, 32, 249, 5] 3,104
BatchNorm-14 [[8, 32, 249, 5]] [8, 32, 249, 5] 128
LeakyReLU-8 [[8, 32, 249, 5]] [8, 32, 249, 5] 0
Conv2DTranspose-5 [[8, 32, 249, 5]] [8, 16, 250, 5] 1,040
BatchNorm-15 [[8, 16, 250, 5]] [8, 16, 250, 5] 64
LeakyReLU-9 [[8, 16, 250, 5]] [8, 16, 250, 5] 0
Conv2D-11 [[8, 16, 250, 5]] [8, 1, 250, 3] 49
Tanh-1 [[8, 1, 250, 3]] [8, 1, 250, 3] 0
UFeatureNet-1 [[8, 1, 60, 1]] [8, 1, 250, 3] 0
=============================================================================
Total params: 313,681
Trainable params: 311,873
Non-trainable params: 1,808
-----------------------------------------------------------------------------
Input size (MB): 0.00
Forward/backward pass size (MB): 115.48
Params size (MB): 1.20
Estimated Total Size (MB): 116.68
-----------------------------------------------------------------------------{'total_params': 313681, 'trainable_params': 311873}def gradient_penalty(discriminator, real, fake, batchsize):
t = paddle.uniform((batchsize,1,1,1))
t = paddle.expand_as(t, real)
inter = t * real + (1-t) * fake
inter.stop_gradient = False
inter_ = discriminator(inter)
grads = paddle.grad(inter_, [inter])[0]
grads = paddle.reshape(grads, [batchsize, grads.shape[1], grads.shape[2], grads.shape[3]])
epsilon = 1e-12
norm = paddle.sqrt(
paddle.mean(paddle.square(grads), axis=1) + epsilon
)
gp = paddle.mean((norm - 1)**2) * 10
return gpdef draw(data):
zdata = []
xdata = []
ydata = [] for i in data[0][0]:
xdata.append(i[0])
ydata.append(i[1])
zdata.append(i[2])
xdata = np.array(xdata)
ydata = np.array(ydata)
zdata = np.array(zdata)
ax = plt.axes(projection='3d')
ax.scatter3D(xdata, ydata, zdata, c='r')
plt.savefig('fake.png')def train():
train_loader = pointDataLoader(file_path='./dataset/train.txt', mode='train')
Discriminator = D()
Generator = G()
Discriminator.train()
Generator.train()
optim1 = paddle.optimizer.Adam(parameters=Discriminator.parameters(), weight_decay=0.001, learning_rate=1e-5)
optim2 = paddle.optimizer.Adam(parameters=Generator.parameters(), weight_decay=0.001, learning_rate=1e-5)
epoch_num = 2000
train_g = 2
for epoch in range(epoch_num): for batch_id, data in enumerate(train_loader()):
real = paddle.to_tensor(data[0])
noise = paddle.uniform((real.shape[0], 1, 60, 1))
fake = Generator(noise)
fake_loss = paddle.mean(Discriminator(fake))
real_loss = -1*paddle.mean(Discriminator(real))
gp = gradient_penalty(Discriminator, real, fake, real.shape[0])
d_loss = fake_loss + real_loss + gp
d_loss.backward()
optim1.step()
optim1.clear_grad() for _ in range(train_g):
noise = paddle.uniform((real.shape[0], 1, 60, 1))
fake = Generator(noise)
g_loss = -1*paddle.mean(Discriminator(fake))
g_loss.backward()
optim2.step()
optim2.clear_grad() if batch_id % 32 == 0:
print("epoch: {}, batch_id: {}, d_loss is: {}, g_loss is: {}".format(epoch, batch_id, d_loss.numpy(), g_loss.numpy()))
if epoch % 2 == 0:
noise = paddle.uniform((real.shape[0], 1, 60, 1))
fake = Generator(noise)
draw(fake.numpy()) if epoch % 20 == 0:
paddle.save(Discriminator.state_dict(), './model/D.pdparams')
paddle.save(optim1.state_dict(), './model/D.pdopt')
paddle.save(Generator.state_dict(), './model/G.pdparams')
paddle.save(optim2.state_dict(), './model/G.pdopt')if __name__ == '__main__':
train()以上就是点云生成:基于Paddle2.0实现WGAN-GP在点云上的一些尝试的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号