Skip to content

Commit 3d17b4b

Browse files
committed
--wip--
1 parent e73bef7 commit 3d17b4b

4 files changed

Lines changed: 114 additions & 63 deletions

File tree

tools/machine-learning/fall_detection/dataset/dataset.py

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from polars._typing import IntoExpr
77

88
from .pseudo_labels import PseudoLabeller
9+
from .pseudo_labels import Label
910

1011

1112
class FallenDataset:
@@ -23,7 +24,7 @@ def __init__(
2324
group_keys: list[str],
2425
features: Iterable[IntoExpr] | IntoExpr,
2526
) -> None:
26-
self.dataframe = dataframe.drop_nulls()[:10000]
27+
self.dataframe = dataframe[:100000].drop_nulls()
2728

2829
self.labeller = PseudoLabeller()
2930
self.features = features
@@ -65,20 +66,35 @@ def to_windowed(
6566
[
6667
self.dataframe.select(
6768
generate_lags(feature, samples_per_window, "group"),
68-
)[
69-
samples_per_window : -label_shift
70-
or None : samples_between_windows
71-
]
69+
)[samples_per_window - 1 : -label_shift or None :]
7270
for feature in self.features
7371
],
7472
how="horizontal",
7573
)
74+
print(windowed_features)
75+
print(windowed_features.null_count())
7676

7777
shifted_labels = self.dataframe.select(
7878
pl.col("labels").shift(-label_shift).over("group")
79-
)[samples_per_window : -label_shift or None : samples_between_windows]
80-
81-
windowed_dataframe = windowed_features.hstack(shifted_labels)
79+
)[samples_per_window - 1 : -label_shift or None :]
80+
81+
predecessors_of_shifted_labels = self.dataframe.select(
82+
pl.col("labels")
83+
.shift(-(label_shift - 1))
84+
.over("group")
85+
.alias("label_predecessor")
86+
)[
87+
samples_per_window - 1 : -label_shift
88+
or None : samples_between_windows
89+
]
90+
91+
windowed_dataframe_with_predecessors = windowed_features.hstack(
92+
shifted_labels
93+
).hstack(predecessors_of_shifted_labels)
94+
95+
windowed_dataframe = windowed_dataframe_with_predecessors.filter(
96+
pl.col("label_predecessor") == Label.Stable
97+
).drop("label_predecessor")
8298

8399
n_minority = (
84100
windowed_dataframe.get_column("labels")
@@ -87,13 +103,15 @@ def to_windowed(
87103
.select(pl.col("count"))
88104
.item()
89105
)
90-
91-
balanced_df = windowed_dataframe.group_by(
92-
"labels", maintain_order=True
93-
).map_groups(lambda group: group.sample(n=n_minority, seed=1))
94-
balanced_df = windowed_dataframe.sample(
95-
fraction=1, shuffle=True, seed=1
96-
)
106+
print(n_minority)
107+
108+
balanced_df = windowed_dataframe
109+
# balanced_df = windowed_dataframe.group_by(
110+
# "labels", maintain_order=True
111+
# ).map_groups(lambda group: group.sample(n=n_minority, seed=1))
112+
# balanced_df = windowed_dataframe.sample(
113+
# fraction=1, shuffle=True, seed=1
114+
# )
97115

98116
self.input_data = balanced_df.drop("labels")
99117
self.labels = balanced_df.select(pl.col("labels"))

tools/machine-learning/fall_detection/dataset/pseudo_labels.py

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,12 @@
77

88
@dataclass
99
class PseudoLabelParameters:
10-
falling_threshold: float = 0.6
11-
fallen_threshold: float = 1.3
10+
unstable_threshold: float = 0.6
1211

1312

1413
class Label(int, Enum):
15-
Upright = 0
16-
Falling = 1
17-
Fallen = 2
14+
Stable = 0
15+
SoonToBeUnstable = 1
1816

1917

2018
class PseudoLabeller:
@@ -25,21 +23,18 @@ def __init__(self, parameters: PseudoLabelParameters | None = None):
2523

2624
def generate_labels(self, data: pl.DataFrame) -> pl.Series:
2725
has_ground_contact = pl.col("Control.main_outputs.has_ground_contact")
28-
pitch = pl.col("Control.main_outputs.robot_orientation.pitch")
29-
# print(data.select(primary_state))
26+
pitch = pl.col(
27+
"Control.main_outputs.sensor_data.inertial_measurement_unit.roll_pitch.y"
28+
)
3029
return (
3130
data.select(
3231
pl.when(has_ground_contact)
3332
.then(
34-
pl.when(pitch.abs() > self.parameters.falling_threshold)
35-
.then(pl.lit(Label.Falling))
36-
.otherwise(pl.lit(Label.Upright))
37-
)
38-
.otherwise(
39-
pl.when(pitch.abs() > self.parameters.fallen_threshold)
40-
.then(pl.lit(Label.Fallen))
41-
.otherwise(pl.lit(Label.Falling))
33+
pl.when(pitch.abs() > self.parameters.unstable_threshold)
34+
.then(pl.lit(Label.SoonToBeUnstable))
35+
.otherwise(pl.lit(Label.Stable))
4236
)
37+
.otherwise(pl.lit(Label.SoonToBeUnstable))
4338
)
4439
.to_series()
4540
.alias("labels")

tools/machine-learning/fall_detection/scripts/inspect-data.py

Lines changed: 68 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import polars as pl
44
from data_loading import load
55
from dataset import FallenDataset
6+
import copy
67

78

89
def main():
@@ -11,35 +12,79 @@ def main():
1112
df = load("data.parquet")
1213
dataset = FallenDataset(
1314
df,
14-
group_keys=["robot_identifier", "match_identifier"],
15+
group_keys=[
16+
pl.col("robot_identifier"),
17+
pl.col("match_identifier"),
18+
],
1519
features=[
16-
pl.col("Control.main_outputs.robot_orientation.pitch"),
17-
pl.col("Control.main_outputs.robot_orientation.roll"),
18-
pl.col("Control.main_outputs.robot_orientation.yaw"),
20+
pl.col(
21+
"Control.main_outputs.sensor_data.inertial_measurement_unit.linear_acceleration.x"
22+
),
23+
pl.col(
24+
"Control.main_outputs.sensor_data.inertial_measurement_unit.linear_acceleration.y"
25+
),
26+
pl.col(
27+
"Control.main_outputs.sensor_data.inertial_measurement_unit.linear_acceleration.z"
28+
),
29+
pl.col(
30+
"Control.main_outputs.sensor_data.inertial_measurement_unit.roll_pitch.x"
31+
),
32+
pl.col(
33+
"Control.main_outputs.sensor_data.inertial_measurement_unit.roll_pitch.y"
34+
),
1935
pl.col("Control.main_outputs.has_ground_contact"),
2036
],
2137
)
22-
dataset.to_windowed(window_stride=1 / 83)
23-
24-
df = (
25-
dataset.input_data.hstack(dataset.labels)
26-
.with_row_index()
27-
.hstack(
28-
dataset.input_data.select(
29-
pl.col(
30-
"Control.main_outputs.robot_orientation.pitch"
31-
).list.last()
32-
).rename({"Control.main_outputs.robot_orientation.pitch": "pitch"})
33-
)
38+
dataset_copy = copy.deepcopy(dataset)
39+
dataset.to_windowed(window_stride=1 / 83, window_size=2 / 83, label_shift=0)
40+
# df = (
41+
# dataset.input_data.hstack(dataset.labels)
42+
# .with_row_index()
43+
# .hstack(
44+
# dataset.input_data.select(
45+
# pl.col(
46+
# "Control.main_outputs.sensor_data.inertial_measurement_unit.roll_pitch.y"
47+
# ) # .list.last()
48+
# ).rename(
49+
# {
50+
# "Control.main_outputs.sensor_data.inertial_measurement_unit.roll_pitch.y": "pitch"
51+
# }
52+
# )
53+
# )
54+
# )
55+
# print(dataset.input_data[0:10])
56+
# print(dataset.input_data.columns)
57+
print(dataset.get_input_tensor().shape)
58+
print(dataset.get_labels_tensor().shape)
59+
dataset_copy.to_windowed(
60+
window_stride=1 / 83, window_size=2 / 83, label_shift=20
3461
)
35-
print(df)
62+
print(dataset_copy.get_input_tensor().shape)
63+
print(dataset_copy.get_labels_tensor().shape)
64+
# print(dataset_copy.input_data[0:10])
3665

37-
px.scatter(
38-
df,
39-
x="index",
40-
y="pitch",
41-
color="labels",
42-
).show()
66+
# df_copy = (
67+
# dataset_copy.input_data.hstack(dataset_copy.labels)
68+
# .with_row_index()
69+
# .hstack(
70+
# dataset_copy.input_data.select(
71+
# pl.col(
72+
# "Control.main_outputs.sensor_data.inertial_measurement_unit.roll_pitch.y"
73+
# ) # .list.last()
74+
# ).rename(
75+
# {
76+
# "Control.main_outputs.sensor_data.inertial_measurement_unit.roll_pitch.y": "pitch"
77+
# }
78+
# )
79+
# )
80+
# )
81+
82+
# px.scatter(
83+
# df,
84+
# x="index",
85+
# y="pitch",
86+
# color="labels",
87+
# ).show()
4388

4489

4590
if __name__ == "__main__":

tools/machine-learning/fall_detection/scripts/train.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,11 @@ def build_linear_model(
132132
model = Sequential(
133133
[
134134
# ADD YOUR LAYERS HERE
135-
InputLayer(shape=(num_features, input_length, 1)),
135+
InputLayer(shape=(input_length, num_features, 1)),
136136
Conv2D(
137137
filters=wandb.config["number_of_filters"][0],
138138
kernel_size=[num_features, wandb.config["kernel_widths"][0]],
139-
strides=[num_features, 1],
139+
strides=[1, num_features],
140140
padding="valid",
141141
activation="relu",
142142
),
@@ -189,7 +189,7 @@ def build_sequential_model(
189189
model = Sequential(
190190
[
191191
# ADD YOUR LAYERS HERE
192-
InputLayer(shape=(num_features, input_length)),
192+
InputLayer(shape=(input_length, num_features)),
193193
LSTM(
194194
wandb.config["lstm_sizes"][0],
195195
dropout=0.4,
@@ -291,13 +291,6 @@ def train(model_type: ModelType, data_path: str) -> None:
291291
evaluate_model(model, x_test, y_test)
292292

293293
converter = tf.lite.TFLiteConverter.from_keras_model(model)
294-
converter._experimental_lower_tensor_list_ops = False
295-
converter.optimizations = [tf.lite.Optimize.DEFAULT]
296-
converter.target_spec.supported_ops = [
297-
tf.lite.OpsSet.TFLITE_BUILTINS, # enable TensorFlow Lite ops.
298-
tf.lite.OpsSet.SELECT_TF_OPS, # enable TensorFlow ops.
299-
]
300-
converter.allow_custom_ops = True
301294
model_tflite = converter.convert()
302295
with open("../../../etc/neural_networks/fall_detection.tflite", "wb") as f:
303296
f.write(model_tflite)

0 commit comments

Comments
 (0)