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

点云生成:点云上使用WGAN-GP的一次尝试
项目说明
①说明
尝试了下在点云上使用了WGAN-GP。
1、判别器借鉴了PointNet结构。
2、生成器是随手乱搭的哈哈。
3、能跑通,效果有待改进。
②数据集
ModelNet总共有662中目标分类,127915个CAD,以及十类标记过方向朝向的数据。其中包含了三个子集:
1、ModelNet10:十个标记朝向的子集数据;
2、ModelNet40:40个类别的三维模型;
3、Aligned40:40类标记的三维模型。
这里使用了ModelNet40,并且归一化了,文件中的数据的意义:
1、横轴有六个数字,分别代表:x, y, z, r, g, b;
2、纵轴为点,每份数据一共有10000个点,项目中每份数据抽取其中1024个点进行训练。
In [ ]
!unzip data/data50045/modelnet40_normal_resampled.zip!mv modelnet40_normal_resampled dataset
项目主体
①导入需要的库
In [ ]
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
②数据处理
1、类别
In [ ]
category = { 'airplane': 0,}
2、生成训练和测试样本的list
In [ ]
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()
3、数据读取
In [ ]
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 pointDataGenerator
③定义网络
1、定义网络
1.1、提取特征网络
In [ ]
class 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 x
1.2、生成点云网络
In [ ]
class 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 x
1.3、D网络
In [ ]
class 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 x
1.4、G网络
In [ ]
class 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 x
2、模型结构可视化
In [ ]
Discriminator = 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,850Trainable params: 38,154Non-trainable params: 1,696---------------------------------------------------------------------------Input size (MB): 0.02Forward/backward pass size (MB): 19.45Params size (MB): 0.15Estimated Total Size (MB): 19.63---------------------------------------------------------------------------
{'total_params': 39850, 'trainable_params': 38154}
In [ ]
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,681Trainable params: 311,873Non-trainable params: 1,808-----------------------------------------------------------------------------Input size (MB): 0.00Forward/backward pass size (MB): 115.48Params size (MB): 1.20Estimated Total Size (MB): 116.68-----------------------------------------------------------------------------
{'total_params': 313681, 'trainable_params': 311873}
In [ ]
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 gp
⑤训练
1、Generator生成图片可视化
In [ ]
def 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')
2、训练
In [13]
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在点云上的一些尝试的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/42958.html
微信扫一扫
支付宝扫一扫