| import torch |
| import torch.nn as nn |
| import torch_geometric.nn as nng |
| from onescience.modules.embedding import timestep_embedding, unified_pos_embedding |
| from onescience.modules.mlp.MLP import StandardMLP |
|
|
| class Model(nn.Module): |
| """ |
| PointNet 模型。 |
| |
| 用于处理点云数据,通过 MLP 提取局部特征,并使用全局最大池化提取全局特征。 |
| """ |
| def __init__(self, args, device): |
| super(Model, self).__init__() |
| self.__name__ = "PointNet" |
|
|
| |
| self.in_block = StandardMLP( |
| input_dim=args.n_hidden, |
| output_dim=args.n_hidden * 2, |
| hidden_dims=[args.n_hidden * 2], |
| activation=args.act, |
| use_bias=True |
| ) |
|
|
| |
| self.max_block = StandardMLP( |
| input_dim=args.n_hidden * 2, |
| output_dim=args.n_hidden * 32, |
| hidden_dims=[args.n_hidden * 8], |
| activation=args.act, |
| use_bias=True |
| ) |
|
|
| |
| self.out_block = StandardMLP( |
| input_dim=args.n_hidden * (2 + 32), |
| output_dim=args.n_hidden * 4, |
| hidden_dims=[args.n_hidden * 16], |
| activation=args.act, |
| use_bias=True |
| ) |
|
|
| |
| self.encoder = StandardMLP( |
| input_dim=args.fun_dim + args.space_dim, |
| output_dim=args.n_hidden, |
| hidden_dims=[args.n_hidden * 2], |
| activation=args.act, |
| use_bias=True |
| ) |
|
|
| |
| self.decoder = StandardMLP( |
| input_dim=args.n_hidden, |
| output_dim=args.out_dim, |
| hidden_dims=[args.n_hidden * 2], |
| activation=args.act, |
| use_bias=True |
| ) |
|
|
| self.fcfinal = nn.Linear(args.n_hidden * 4, args.n_hidden) |
|
|
| def forward(self, x, fx, T=None, geo=None): |
| if geo is None: |
| raise ValueError("Please provide edge index for Graph Neural Networks") |
| |
| |
| if x.dim() == 3: |
| x = x.squeeze(0) |
| if fx is not None and fx.dim() == 3: |
| fx = fx.squeeze(0) |
|
|
| assert ( |
| x.size(0) > 0 |
| ), "Input cannot be empty" |
|
|
| |
| batch = torch.zeros(x.shape[0], dtype=torch.long, device=x.device) |
|
|
| |
| z = torch.cat((x, fx), dim=-1).float() |
| z = self.encoder(z) |
| z = self.in_block(z) |
|
|
| |
| global_coef = self.max_block(z) |
| global_coef = nng.global_max_pool(global_coef, batch=batch) |
|
|
| |
| nb_points = torch.tensor([batch.shape[0]], device=z.device) |
| global_coef = global_coef.repeat_interleave(nb_points, dim=0) |
|
|
| |
| z = torch.cat([z, global_coef], dim=1) |
| z = self.out_block(z) |
| z = self.fcfinal(z) |
| z = self.decoder(z) |
|
|
| return z.unsqueeze(0) |
|
|