Spaces:
Build error
Build error
added alternative#
Browse files- app.py +54 -4
- funcs/som.py +40 -0
app.py
CHANGED
@@ -4,9 +4,12 @@ import csv
|
|
4 |
import json
|
5 |
import torch
|
6 |
import numpy as np
|
|
|
7 |
import gradio as gr
|
8 |
|
9 |
from phate import PHATEAE
|
|
|
|
|
10 |
from funcs.som import ClusterSOM
|
11 |
from funcs.tools import numpy_to_native
|
12 |
|
@@ -14,6 +17,7 @@ from funcs.processor import process_data
|
|
14 |
from funcs.plot_func import plot_sensor_data_from_json
|
15 |
from funcs.dataloader import BaseDataset2, read_json_files
|
16 |
|
|
|
17 |
DEVICE = torch.device("cpu")
|
18 |
reducer10d = PHATEAE(epochs=30, n_components=10, lr=.0001, batch_size=128, t='auto', knn=8, relax=True, metric='euclidean')
|
19 |
reducer10d.load('models/r10d_6.pth')
|
@@ -133,6 +137,43 @@ def process_som_data(data, prediction):
|
|
133 |
|
134 |
return processed_data
|
135 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
def get_som_mp4_v2(csv_file_box, slice_size_slider, sample_rate, window_size_slider, reducer=reducer10d, cluster=cluster_som):
|
137 |
processed_file_box, json_file_box, slices_per_leg, plot_box_leg, plot_box_overlay, slice_slider, plot_slice_leg, get_all_slice, slice_json_box = process_data(csv_file_box, slice_size_slider, sample_rate, window_size_slider)
|
138 |
|
@@ -161,8 +202,17 @@ def get_som_mp4_v2(csv_file_box, slice_size_slider, sample_rate, window_size_sli
|
|
161 |
prediction = cluster_som.predict(embedding10d)
|
162 |
processed_data = process_som_data(data,prediction)
|
163 |
|
|
|
|
|
|
|
|
|
|
|
|
|
164 |
# Write the processed data to a CSV file
|
165 |
-
header = ['Gait', 'TS', 'State', 'Condition',
|
|
|
|
|
|
|
166 |
with open('animation_table.csv', 'w', newline='') as csvfile:
|
167 |
csv_writer = csv.writer(csvfile)
|
168 |
csv_writer.writerow(header)
|
@@ -174,7 +224,7 @@ def get_som_mp4_v2(csv_file_box, slice_size_slider, sample_rate, window_size_sli
|
|
174 |
som_video = cluster.plot_activation(embedding10d)
|
175 |
som_video.write_videofile('som_sequence.mp4')
|
176 |
|
177 |
-
return processed_file_box, json_file_box, slices_per_leg, plot_box_leg, plot_box_overlay, slice_slider, plot_slice_leg, get_all_slice, slice_json_box, 'som_sequence.mp4', 'animation.mp4'
|
178 |
return processed_file_box, json_file_box, slices_per_leg, plot_box_leg, plot_box_overlay, slice_slider, plot_slice_leg, get_all_slice, slice_json_box, 'som_sequence.mp4', None
|
179 |
|
180 |
# ml inference
|
@@ -232,7 +282,7 @@ with gr.Blocks(title='Cabasus') as cabasus_sensor:
|
|
232 |
|
233 |
with gr.Row():
|
234 |
real_video = gr.Video(label='real video')
|
235 |
-
trend_graph = gr.
|
236 |
|
237 |
plot_box_leg = gr.Plot(label="Filtered Signal Plot")
|
238 |
slice_slider = gr.Slider(minimum=1, maximum=300, label='Slice select', step=1)
|
@@ -282,7 +332,7 @@ with gr.Blocks(title='Cabasus') as cabasus_sensor:
|
|
282 |
#redoing the whole calculation with the file loading
|
283 |
csv_file_box.change(get_som_mp4_v2, inputs=[csv_file_box, slice_size_slider, sample_rate, window_size_slider],
|
284 |
outputs=[processed_file_box, json_file_box, slices_per_leg, plot_box_leg, plot_box_overlay, slice_slider, plot_slice_leg, get_all_slice, slice_json_box,
|
285 |
-
activation_video, animation])
|
286 |
|
287 |
button_label_Add.click(attach_label_to_json, inputs=[slice_json_box, label_name], outputs=[slice_json_label_box])
|
288 |
|
|
|
4 |
import json
|
5 |
import torch
|
6 |
import numpy as np
|
7 |
+
import pandas as pd
|
8 |
import gradio as gr
|
9 |
|
10 |
from phate import PHATEAE
|
11 |
+
from pytvlwcharts import *
|
12 |
+
from pandas import Timestamp
|
13 |
from funcs.som import ClusterSOM
|
14 |
from funcs.tools import numpy_to_native
|
15 |
|
|
|
17 |
from funcs.plot_func import plot_sensor_data_from_json
|
18 |
from funcs.dataloader import BaseDataset2, read_json_files
|
19 |
|
20 |
+
|
21 |
DEVICE = torch.device("cpu")
|
22 |
reducer10d = PHATEAE(epochs=30, n_components=10, lr=.0001, batch_size=128, t='auto', knn=8, relax=True, metric='euclidean')
|
23 |
reducer10d.load('models/r10d_6.pth')
|
|
|
137 |
|
138 |
return processed_data
|
139 |
|
140 |
+
def scores_to_dataframe(scores, start_time='2022-07-01 09:15:00+05:30', start_score=100, none_replacement=-0):
|
141 |
+
# Create a timestamp for every score in the list
|
142 |
+
timestamps = [pd.Timestamp(start_time) + pd.Timedelta(seconds=i) for i in range(len(scores))]
|
143 |
+
|
144 |
+
# Convert timestamps to unix timestamps
|
145 |
+
unix_timestamps = [int(ts.value // 10**9) for ts in timestamps]
|
146 |
+
|
147 |
+
# Initialize open prices list
|
148 |
+
open_prices = [start_score]
|
149 |
+
|
150 |
+
# Calculate open and close prices
|
151 |
+
for i in range(1, len(scores)):
|
152 |
+
if scores[i-1] is not None:
|
153 |
+
open_prices.append(open_prices[i-1] + scores[i-1])
|
154 |
+
else:
|
155 |
+
open_prices.append(open_prices[i-1])
|
156 |
+
|
157 |
+
close_prices = [open + (score if score is not None else none_replacement) for open, score in zip(open_prices, scores)]
|
158 |
+
|
159 |
+
# Create high and low prices
|
160 |
+
high_prices = [max(open, close) for open, close in zip(open_prices, close_prices)]
|
161 |
+
low_prices = [min(open, close) for open, close in zip(open_prices, close_prices)]
|
162 |
+
|
163 |
+
# Create a dataframe
|
164 |
+
df = pd.DataFrame({
|
165 |
+
'time': unix_timestamps,
|
166 |
+
'open': open_prices,
|
167 |
+
'high': high_prices,
|
168 |
+
'low': low_prices,
|
169 |
+
'close': close_prices
|
170 |
+
})
|
171 |
+
|
172 |
+
# Start index from 1
|
173 |
+
df.index += 1
|
174 |
+
|
175 |
+
return df
|
176 |
+
|
177 |
def get_som_mp4_v2(csv_file_box, slice_size_slider, sample_rate, window_size_slider, reducer=reducer10d, cluster=cluster_som):
|
178 |
processed_file_box, json_file_box, slices_per_leg, plot_box_leg, plot_box_overlay, slice_slider, plot_slice_leg, get_all_slice, slice_json_box = process_data(csv_file_box, slice_size_slider, sample_rate, window_size_slider)
|
179 |
|
|
|
202 |
prediction = cluster_som.predict(embedding10d)
|
203 |
processed_data = process_som_data(data,prediction)
|
204 |
|
205 |
+
scores = cluster_som.score(embedding10d, threshold_radius=8.5)
|
206 |
+
scores_df = scores_to_dataframe(scores)
|
207 |
+
DailyChart = Chart(data=scores_df, width = 1360, height = 500,
|
208 |
+
time_scale=TimeScaleOptions(seconds_visible=True,
|
209 |
+
time_visible=True)).mark_candlestick()
|
210 |
+
|
211 |
# Write the processed data to a CSV file
|
212 |
+
header = ['Gait', 'TS', 'State', 'Condition',
|
213 |
+
'Shape1', 'Shape2', 'Shape3', 'Shape4',
|
214 |
+
'Color1', 'Color2', 'Color3', 'Color4',
|
215 |
+
'Danger1', 'Danger2', 'Danger3', 'Danger4']
|
216 |
with open('animation_table.csv', 'w', newline='') as csvfile:
|
217 |
csv_writer = csv.writer(csvfile)
|
218 |
csv_writer.writerow(header)
|
|
|
224 |
som_video = cluster.plot_activation(embedding10d)
|
225 |
som_video.write_videofile('som_sequence.mp4')
|
226 |
|
227 |
+
return processed_file_box, json_file_box, slices_per_leg, plot_box_leg, plot_box_overlay, slice_slider, plot_slice_leg, get_all_slice, slice_json_box, 'som_sequence.mp4', 'animation.mp4', DailyChart
|
228 |
return processed_file_box, json_file_box, slices_per_leg, plot_box_leg, plot_box_overlay, slice_slider, plot_slice_leg, get_all_slice, slice_json_box, 'som_sequence.mp4', None
|
229 |
|
230 |
# ml inference
|
|
|
282 |
|
283 |
with gr.Row():
|
284 |
real_video = gr.Video(label='real video')
|
285 |
+
trend_graph = gr.Plot(label='trend graph')
|
286 |
|
287 |
plot_box_leg = gr.Plot(label="Filtered Signal Plot")
|
288 |
slice_slider = gr.Slider(minimum=1, maximum=300, label='Slice select', step=1)
|
|
|
332 |
#redoing the whole calculation with the file loading
|
333 |
csv_file_box.change(get_som_mp4_v2, inputs=[csv_file_box, slice_size_slider, sample_rate, window_size_slider],
|
334 |
outputs=[processed_file_box, json_file_box, slices_per_leg, plot_box_leg, plot_box_overlay, slice_slider, plot_slice_leg, get_all_slice, slice_json_box,
|
335 |
+
activation_video, animation, trend_graph])
|
336 |
|
337 |
button_label_Add.click(attach_label_to_json, inputs=[slice_json_box, label_name], outputs=[slice_json_label_box])
|
338 |
|
funcs/som.py
CHANGED
@@ -65,6 +65,46 @@ class ClusterSOM:
|
|
65 |
results.append((-1, None)) # Noise
|
66 |
|
67 |
return results
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
|
69 |
# rearranging the subplots in the closest square format
|
70 |
def rearrange_subplots(self, num_subplots):
|
|
|
65 |
results.append((-1, None)) # Noise
|
66 |
|
67 |
return results
|
68 |
+
|
69 |
+
def score(self, data, midpoints=None, threshold_radius=4):
|
70 |
+
"""
|
71 |
+
Compute the score for each sample in the data based on the distance of the BMU node to the closest midpoint of the SOM grid.
|
72 |
+
|
73 |
+
:param data: The input data.
|
74 |
+
:param midpoints: A dictionary with keys as the indices of the SOMs and values as lists of midpoints on the grid for the corresponding SOMs.
|
75 |
+
:param threshold_radius: The threshold radius for score calculation.
|
76 |
+
"""
|
77 |
+
scores = []
|
78 |
+
|
79 |
+
for sample in data:
|
80 |
+
# Predict the cluster and BMU SOM coordinate for each sample in the data
|
81 |
+
result = self.predict([sample])[0]
|
82 |
+
|
83 |
+
# Check if it is not a noise
|
84 |
+
if result[0] != -1:
|
85 |
+
# The activated SOM's index and its corresponding BMU
|
86 |
+
activated_som_index, bmu = result[0], result[1]
|
87 |
+
|
88 |
+
# Get the corresponding SOM for the data point
|
89 |
+
som = self.som_models[activated_som_index]
|
90 |
+
|
91 |
+
# If specific midpoints are provided for SOMs, use them; else compute the midpoint of the SOM grid
|
92 |
+
if midpoints is not None and activated_som_index in midpoints:
|
93 |
+
specified_midpoints = midpoints[activated_som_index]
|
94 |
+
else:
|
95 |
+
specified_midpoints = [tuple((dim-1)/2 for dim in som.get_weights().shape[:2])]
|
96 |
+
|
97 |
+
# Compute the grid distances from the BMU to each midpoint and find the minimum distance
|
98 |
+
min_distance = min(np.sqrt((midpoint[0] - bmu[0])**2 + (midpoint[1] - bmu[1])**2) for midpoint in specified_midpoints)
|
99 |
+
|
100 |
+
# Compute the score as the minimum grid distance minus the threshold radius
|
101 |
+
score = min_distance - threshold_radius
|
102 |
+
|
103 |
+
scores.append(score)
|
104 |
+
else:
|
105 |
+
scores.append(None) # Noise
|
106 |
+
|
107 |
+
return scores
|
108 |
|
109 |
# rearranging the subplots in the closest square format
|
110 |
def rearrange_subplots(self, num_subplots):
|