Robotics
Transformers
ONNX
Safetensors
PyTorch
ballnet
metaball
multimodal
han-xudong commited on
Commit
0d0ab69
·
verified ·
1 Parent(s): f526b9f

Upload folder using huggingface_hub

Browse files
Files changed (5) hide show
  1. README.md +88 -85
  2. config.json +0 -0
  3. model.onnx +2 -2
  4. model.safetensors +3 -0
  5. modeling.py +97 -26
README.md CHANGED
@@ -1,85 +1,88 @@
1
- ---
2
- license: bsd-3-clause
3
- pipeline_tag: robotics
4
- tags:
5
- - ballnet
6
- - metaball
7
- - multimodal
8
- - onnx
9
- - pytorch
10
- library_name: transformers
11
- datasets:
12
- - han-xudong/ballnet-100k
13
- ---
14
-
15
- <p align="center">
16
- <img src="https://cdn-uploads.huggingface.co/production/uploads/670336f25ce58dd0c33e32e3/EC3s3yVe3mLlq6t6QxQGL.jpeg"
17
- style="width:100%; max-width:1000px; height:auto;">
18
- </p>
19
-
20
- # BallNet
21
-
22
- ## Model Description
23
-
24
- BallNet is an MLP model designed for the Metaball. It can predict both 6D force and 3D shape (mesh nodes) from the 6D motion of the ball.
25
-
26
- Try it out on the [Spaces demo](https://huggingface.co/spaces/han-xudong/ballnet-demo).
27
-
28
- - Developer: Xudong Han, Tianyu Wu, Fang Wan, and Chaoyang Song.
29
- - Model type: MLP
30
- - License: BSD-3-Clause
31
- - Github: [https://github.com/han-xudong/metaball](https://github.com/han-xudong/metaball)
32
-
33
- ## Intended Use
34
-
35
- This model is intended for researchers and developers working in robotics and tactile sensing. It can be used to enhance the capabilities of robotic systems by providing accurate predictions of force and shape based on tactile data.
36
-
37
- To load the model:
38
-
39
- ```python
40
- from transformers import AutoModel
41
-
42
- model = AutoModel.from_pretrained("han-xudong/ballnet", trust_remote_code=True)
43
- x = torch.zeros((1, 6)) # Example input: batch size of 1, 6D motion
44
- output = model(x)
45
- ```
46
-
47
- Or to load the ONNX version:
48
-
49
- ```python
50
- # Example code to load onnx
51
- import onnxruntime as ort
52
- import numpy as np
53
- from huggingface_hub import hf_hub_download
54
-
55
- onnx_model_path = hf_hub_download("han-xudong/ballnet", filename="model.onnx")
56
- ort_session = ort.InferenceSession(onnx_model_path)
57
-
58
- # Example input
59
- x = np.zeros((1, 6), dtype=np.float32) # Batch size of 1, 6D motion
60
- output = ort_session.run(None, {"motion": x})
61
- ```
62
-
63
- ## Training Data
64
-
65
- The model was trained on the [BallNet-100K](https://huggingface.co/datasets/han-xudong/ballnet-100k) dataset, which includes a variety of motion, force, and shape data collected by finite element simulations.
66
-
67
- ## Citation
68
-
69
- If you use this model in your research, please cite the following papers:
70
-
71
- ```bibtex
72
- @article{liu2024proprioceptive,
73
- title={Proprioceptive learning with soft polyhedral networks},
74
- author={Liu, Xiaobo and Han, Xudong and Hong, Wei and Wan, Fang and Song, Chaoyang},
75
- journal={The International Journal of Robotics Research},
76
- volume = {43},
77
- number = {12},
78
- pages = {1916-1935},
79
- year = {2024},
80
- publisher={SAGE Publications Sage UK: London, England},
81
- doi = {10.1177/02783649241238765}
82
- }
83
- ```
84
-
85
- [](https://arxiv.org/abs/2308.08538)
 
 
 
 
1
+ ---
2
+ license: bsd-3-clause
3
+ pipeline_tag: robotics
4
+ tags:
5
+ - ballnet
6
+ - metaball
7
+ - multimodal
8
+ - onnx
9
+ - pytorch
10
+ library_name: transformers
11
+ datasets:
12
+ - han-xudong/ballnet-100k
13
+ ---
14
+
15
+ # Model Card for BallNet
16
+
17
+ ## Table of Contents
18
+
19
+ - [Model Card for BallNet](#model-card-for-ballnet)
20
+ - [Table of Contents](#table-of-contents)
21
+ - [Model Description](#model-description)
22
+ - [Intended Use](#intended-use)
23
+ - [Training Data](#training-data)
24
+ - [Citation](#citation)
25
+
26
+ ## Model Description
27
+
28
+ BallNet is an MLP model designed for the Metaball. It can predict both 6D force and 3D shape (mesh nodes) from the 6D motion of the ball.
29
+
30
+ Try it out on the [Spaces demo](https://huggingface.co/spaces/han-xudong/ballnet-demo).
31
+
32
+ - Developer: Xudong Han, Tianyu Wu, Fang Wan, and Chaoyang Song.
33
+ - Model type: MLP
34
+ - License: BSD-3-Clause
35
+
36
+ ## Intended Use
37
+
38
+ This model is intended for researchers and developers working in robotics and tactile sensing. It can be used to enhance the capabilities of robotic systems by providing accurate predictions of force and shape based on tactile data.
39
+
40
+ To load the model:
41
+
42
+ ```python
43
+ from transformers import AutoModel
44
+
45
+ model = AutoModel.from_pretrained("han-xudong/ballnet", trust_remote_code=True)
46
+ x = torch.zeros((1, 6)) # Example input: batch size of 1, 6D motion
47
+ output = model(x)
48
+ ```
49
+
50
+ Or to load the ONNX version:
51
+
52
+ ```python
53
+ # Example code to load onnx
54
+ import onnxruntime as ort
55
+ import numpy as np
56
+ from huggingface_hub import hf_hub_download
57
+
58
+ onnx_model_path = hf_hub_download("han-xudong/ballnet", filename="model.onnx")
59
+ ort_session = ort.InferenceSession(onnx_model_path)
60
+
61
+ # Example input
62
+ x = np.zeros((1, 6), dtype=np.float32) # Batch size of 1, 6D motion
63
+ output = ort_session.run(None, {"motion": x})
64
+ ```
65
+
66
+ ## Training Data
67
+
68
+ The model was trained on the [BallNet-100K](https://huggingface.co/datasets/han-xudong/ballnet-100k) dataset, which includes a variety of motion, force, and shape data collected by finite element simulations.
69
+
70
+ ## Citation
71
+
72
+ If you use this model in your research, please cite the following papers:
73
+
74
+ ```bibtex
75
+ @article{liu2024proprioceptive,
76
+ title={Proprioceptive learning with soft polyhedral networks},
77
+ author={Liu, Xiaobo and Han, Xudong and Hong, Wei and Wan, Fang and Song, Chaoyang},
78
+ journal={The International Journal of Robotics Research},
79
+ volume = {43},
80
+ number = {12},
81
+ pages = {1916-1935},
82
+ year = {2024},
83
+ publisher={SAGE Publications Sage UK: London, England},
84
+ doi = {10.1177/02783649241238765}
85
+ }
86
+ ```
87
+
88
+ [](https://arxiv.org/abs/2308.08538)
config.json CHANGED
The diff for this file is too large to render. See raw diff
 
model.onnx CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:1138bf9e90c36e6e7e68e397dc8d109c444d96e95f3e8c45d65e5c3b756528c1
3
- size 15815554
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b543f9d911a78fdc5648eca294aa7e04e7edfeb441e43f4dfc3855a02e943f36
3
+ size 17347939
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:960574e99b9df54c0588506eb481c7e15ea0c4ff91813276edcac8a2864bec30
3
+ size 17346660
modeling.py CHANGED
@@ -7,48 +7,119 @@ class BallNetConfig(PretrainedConfig):
7
 
8
  def __init__(
9
  self,
10
- x_dim=[6],
11
- y_dim=[6, 1800],
12
- h1_dim=[100, 1000],
13
- h2_dim=[100, 1000],
 
14
  **kwargs,
15
  ):
16
  super().__init__(**kwargs)
 
17
  self.x_dim = x_dim
18
  self.y_dim = y_dim
19
- self.h1_dim = h1_dim
20
- self.h2_dim = h2_dim
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
 
23
- class BallNet(PreTrainedModel):
24
  config_class = BallNetConfig
 
 
25
 
26
- def __init__(self, config):
27
  super().__init__(config)
 
28
  self.x_dim = config.x_dim
29
  self.y_dim = config.y_dim
30
- self.h1_dim = config.h1_dim
31
- self.h2_dim = config.h2_dim
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
- self.model = nn.ModuleDict()
34
- # Define the model architecture
35
  for i in range(len(self.y_dim)):
36
- self.model[f"estimator_{i}"] = nn.Sequential(
37
- nn.Linear(self.x_dim[0], self.h1_dim[i]),
38
- nn.ReLU(),
39
- nn.Linear(self.h1_dim[i], self.h2_dim[i]),
40
- nn.ReLU(),
41
- nn.Linear(self.h2_dim[i], self.y_dim[i]),
42
- )
43
-
44
- # initialize weights
 
 
45
  self.post_init()
46
 
47
- def forward(self, x):
 
 
 
 
 
48
  outputs = []
49
  for i in range(len(self.y_dim)):
50
- # Get the estimator for the i-th output
51
- estimator = self.model[f"estimator_{i}"]
52
- y = estimator(x)
53
  outputs.append(y)
54
- return outputs
 
 
 
 
7
 
8
  def __init__(
9
  self,
10
+ x_dim: List[int],
11
+ y_dim: List[int],
12
+ hidden_dim: List[List[int]],
13
+ mean: List[float],
14
+ std: List[float],
15
  **kwargs,
16
  ):
17
  super().__init__(**kwargs)
18
+
19
  self.x_dim = x_dim
20
  self.y_dim = y_dim
21
+ self.hidden_dim = hidden_dim
22
+ self.mean = mean
23
+ self.std = std
24
+
25
+
26
+ class Normalizer(nn.Module):
27
+ def __init__(self, mean: Tensor, std: Tensor, eps: float = 1e-8):
28
+ super().__init__()
29
+ self.register_buffer("mean", mean)
30
+ self.register_buffer("std", std)
31
+ self.eps = eps
32
+
33
+ def normalize(self, x: Tensor) -> Tensor:
34
+ return (x - self.mean) / (self.std + self.eps)
35
+
36
+ def denormalize(self, x: Tensor) -> Tensor:
37
+ return x * (self.std + self.eps) + self.mean
38
 
39
 
40
+ class BallNetModel(PreTrainedModel):
41
  config_class = BallNetConfig
42
+ base_model_prefix = "ballnet"
43
+ supports_gradient_checkpointing = False
44
 
45
+ def __init__(self, config: BallNetConfig):
46
  super().__init__(config)
47
+
48
  self.x_dim = config.x_dim
49
  self.y_dim = config.y_dim
50
+ self.hidden_dim = config.hidden_dim
51
+
52
+ # ---------- split mean / std ----------
53
+ x_mean, x_std = [], []
54
+ y_mean, y_std = [], []
55
+
56
+ data_dim = self.x_dim + self.y_dim
57
+ data_start = 0
58
+
59
+ for i, dim in enumerate(data_dim):
60
+ data_end = data_start + dim
61
+ if i < len(self.x_dim):
62
+ x_mean.append(config.mean[data_start:data_end])
63
+ x_std.append(config.std[data_start:data_end])
64
+ else:
65
+ y_mean.append(config.mean[data_start:data_end])
66
+ y_std.append(config.std[data_start:data_end])
67
+ data_start = data_end
68
+
69
+ # ---------- normalizers ----------
70
+ self.x_normalizers = nn.ModuleList(
71
+ [
72
+ Normalizer(
73
+ mean=torch.tensor(x_mean[i], dtype=torch.float32),
74
+ std=torch.clamp(
75
+ torch.tensor(x_std[i], dtype=torch.float32), min=1e-8
76
+ ),
77
+ )
78
+ for i in range(len(self.x_dim))
79
+ ]
80
+ )
81
+
82
+ self.y_normalizers = nn.ModuleList(
83
+ [
84
+ Normalizer(
85
+ mean=torch.tensor(y_mean[i], dtype=torch.float32),
86
+ std=torch.clamp(
87
+ torch.tensor(y_std[i], dtype=torch.float32), min=1e-8
88
+ ),
89
+ )
90
+ for i in range(len(self.y_dim))
91
+ ]
92
+ )
93
+
94
+ # ---------- estimators ----------
95
+ self.estimators = nn.ModuleList()
96
 
 
 
97
  for i in range(len(self.y_dim)):
98
+ layers = []
99
+ in_dim = self.x_dim[0]
100
+
101
+ for out_dim in self.hidden_dim[i]:
102
+ layers.append(nn.Linear(in_dim, out_dim))
103
+ layers.append(nn.ReLU())
104
+ in_dim = out_dim
105
+
106
+ layers.append(nn.Linear(in_dim, self.y_dim[i]))
107
+ self.estimators.append(nn.Sequential(*layers))
108
+
109
  self.post_init()
110
 
111
+ def forward(self, x: Tensor, **kwargs):
112
+ """
113
+ x: (B, 6)
114
+ """
115
+ x = self.x_normalizers[0].normalize(x)
116
+
117
  outputs = []
118
  for i in range(len(self.y_dim)):
119
+ y = self.estimators[i](x)
120
+ y = self.y_normalizers[i].denormalize(y)
 
121
  outputs.append(y)
122
+
123
+ return {
124
+ "outputs": outputs
125
+ }