-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
intern-william@nodeflux-67
committed
Jun 26, 2022
1 parent
b7c12fe
commit 0e1151f
Showing
11 changed files
with
261 additions
and
75 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
env/* | ||
*__pycache__* | ||
*__pycache__* | ||
*.ipynb_checkpoints* | ||
*.pickle* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
FROM python:3.9.13-slim | ||
|
||
ENV DEBIAN_FRONTEND=noninteractive | ||
|
||
RUN apt-get update -qq && \ | ||
apt-get install -y git vim libgtk2.0-dev zip unzip && \ | ||
rm -rf /var/cache/apk/* | ||
|
||
COPY requirements.txt / | ||
RUN pip --no-cache-dir install -r /requirements.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import dash | ||
import config | ||
|
||
app = dash.Dash(__name__, use_pages=True) | ||
app.layout = dash.html.Div([ | ||
dash.page_container | ||
]) | ||
|
||
if __name__ == '__main__': | ||
app.run_server(host=config.host, port=config.port['dash']) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import fiftyone as fo | ||
from flask import Flask, render_template, request, redirect, url_for | ||
import config, utils | ||
|
||
app = Flask(__name__) | ||
dataset = fo.Dataset() | ||
session = None | ||
|
||
@app.route('/fiftyone/<name>', methods=['GET']) | ||
def preview_fiftyone(name): | ||
return redirect(f'{config.url}:{config.port["fiftyone"]}/datasets/{name}') | ||
|
||
@app.route('/embedding/<name>', methods=['GET']) | ||
def preview_embedding(name): | ||
return redirect(f'{config.url}:{config.port["dash"]}/embedding/{name}') | ||
|
||
@app.route('/compute', methods=['POST']) | ||
def compute(): | ||
data = request.get_json() | ||
name = data['name'] | ||
|
||
dataset = fo.load_dataset(name) | ||
df = utils.create_dataframe(dataset) | ||
save_path = f'{name}.pickle' | ||
df.to_pickle(save_path) | ||
|
||
print(f'Saved computation to {save_path}') | ||
return '', 204 | ||
|
||
@app.route('/fiftyone/update', methods=['POST']) | ||
def fiftyone_load(): | ||
data = request.get_json() | ||
name = data['name'] | ||
ids = data['ids'] | ||
|
||
global dataset, session | ||
dataset = fo.load_dataset(name) | ||
stage = fo.Select('') | ||
stage.sample_ids.clear() | ||
for id in ids: stage.sample_ids.append(id) | ||
view = dataset.add_stage(stage) | ||
session.view = view | ||
|
||
print(f'Updated view of dataset {name} to {len(ids)} samples.') | ||
return '', 204 | ||
|
||
if __name__ == '__main__': | ||
session = fo.launch_app(dataset, address=config.address, port=config.port['fiftyone'], remote=True) | ||
app.run(host=config.host, port=config.port['flask']) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
port = { | ||
'flask' : 6000, | ||
'fiftyone' : 6002, | ||
'dash' : 6001, | ||
} | ||
|
||
host = address = ip = '0.0.0.0' | ||
|
||
url = 'http://192.168.103.67' |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,99 @@ | ||
import fiftyone as fo | ||
import fiftyone.brain as fob | ||
import dash | ||
import pandas as pd | ||
import math | ||
|
||
def compute_embeddings(dataset): | ||
return fob.compute_visualization( | ||
dataset, | ||
num_dims=2, | ||
brain_key="image_embeddings", | ||
verbose=True, | ||
seed=51, | ||
patches_field="ground_truth" | ||
).points | ||
|
||
def create_dataframe(dataset): | ||
embeddings = compute_embeddings(dataset) | ||
|
||
df = pd.DataFrame(columns=['index', 'uniqueness', 'label','sqrt_area','embeddings_x', 'embeddings_y']) | ||
|
||
index = 0 | ||
for sample in dataset: | ||
for detection in sample.ground_truth.detections: | ||
print(detection) | ||
df.loc[index] = [index, sample.uniqueness, detection.label, math.sqrt(detection.area), embeddings[index,0], embeddings[index, 1]] | ||
index += 1 | ||
|
||
return df | ||
import plotly.express as px | ||
import plotly.graph_objects as go | ||
import requests | ||
import os | ||
import config | ||
|
||
def create_figure(df, min_uniqueness, max_uniqueness, min_sqrt_area, max_sqrt_area): | ||
mask = (df['uniqueness'] >= min_uniqueness) & (df['uniqueness'] <= max_uniqueness) & (df['sqrt_area'] >= min_sqrt_area) & (df['sqrt_area'] <= max_sqrt_area) | ||
fig = px.scatter(df[mask], x='embeddings_x', y='embeddings_y', color='label', size='sqrt_area', custom_data=['id'], hover_data=['uniqueness']) | ||
figure = go.FigureWidget(fig) | ||
figure.update_layout( | ||
autosize=True, | ||
width=1080, | ||
height=566, | ||
) | ||
return figure | ||
|
||
df = None | ||
|
||
def main(name): | ||
if name not in fo.list_datasets(): | ||
message = f'Dataset {name} is not in list.' | ||
else: | ||
dataset = fo.load_dataset(name) | ||
df = create_dataframe(dataset) | ||
df.to_pickle(name) | ||
message = 'Saved embedding to {name}.' | ||
|
||
print(message) | ||
return message | ||
|
||
import dash | ||
|
||
file_path = f'{name}.pickle' | ||
if not os.path.exists(file_path): requests.post(url=f'{config.url}:{config.port["flask"]}/compute', json={'name':name}) | ||
|
||
global df | ||
df = pd.read_pickle(file_path) | ||
uniqueness_range = (0, 1) | ||
sqrt_area_range = (0, df['sqrt_area'].max()) | ||
|
||
figure = create_figure(df, uniqueness_range[0], uniqueness_range[1], sqrt_area_range[0], sqrt_area_range[1]) | ||
|
||
return dash.html.Div(children=[ | ||
dash.html.H3('Embedding Visualization'), | ||
dash.dcc.Graph( | ||
id='graph', | ||
figure=figure | ||
), | ||
dash.html.P(f'{name}', id='name'), | ||
dash.html.P(id='num_sample'), | ||
dash.html.P('Filter by uniqueness:'), | ||
dash.dcc.RangeSlider( | ||
id='uniqueness-slider', | ||
min=0, max=1, step=0.001, | ||
marks={0: '0', 1: '1'}, | ||
value=[0, 1] | ||
), | ||
dash.html.P('Filter by sqrt area:'), | ||
dash.dcc.RangeSlider( | ||
id='sqrt-area-slider', | ||
min=0, max=df['sqrt_area'].max(), step=df['sqrt_area'].max()/1000, | ||
marks={0: '0', df['sqrt_area'].max(): f'{df["sqrt_area"].max()}'}, | ||
value=[0, df['sqrt_area'].max()] | ||
), | ||
]) | ||
|
||
@dash.callback( | ||
dash.Output(component_id='graph', component_property='figure'), | ||
dash.Input(component_id='uniqueness-slider', component_property='value'), | ||
dash.Input(component_id='sqrt-area-slider', component_property='value'), | ||
) | ||
def update_figure(uniqueness_slider_range, sqrt_area_slider_range): | ||
global_uniqueness_range = uniqueness_slider_range | ||
global_sqrt_area_range = sqrt_area_slider_range | ||
figure = create_figure(df, global_uniqueness_range[0], global_uniqueness_range[1], global_sqrt_area_range[0], global_sqrt_area_range[1]) | ||
print(f'Updated uniquesness range to {global_uniqueness_range}') | ||
print(f'Updated sqrt area range to {global_sqrt_area_range}') | ||
return figure | ||
|
||
@dash.callback( | ||
dash.Output(component_id='num_sample', component_property='children'), | ||
dash.Input(component_id='name', component_property='children'), | ||
dash.Input(component_id='graph', component_property='selectedData') | ||
) | ||
def update(name, input_value): | ||
print(name, input_value) | ||
if input_value is not None: | ||
ids = set() | ||
points = input_value['points'] | ||
for point in points: | ||
id = point['customdata'][0] | ||
ids.add(id) | ||
ids = list(ids) | ||
requests.post( | ||
url = f'{config.url}:{config.port["flask"]}/fiftyone/update', | ||
json = { | ||
'name' : name, | ||
'ids' : ids | ||
} | ||
) | ||
return f'Callback: {input_value}' | ||
|
||
dash.register_page(__name__, path_template="/embedding/<name>") | ||
|
||
def layout(name=None): | ||
print(f'Computing embedding for {name}') | ||
print(f'Dash embedding {name}') | ||
if name is not None: | ||
return main(name) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
Flask==2.1.2 | ||
dash==2.5.1 | ||
plotly==5.9.0 | ||
fiftyone==0.16.5 | ||
torch==1.11.0 | ||
torchvision==0.12.0 | ||
umap-learn==0.5.3 | ||
ipywidgetsipywidgets==7.7.1 | ||
pandas==1.4.3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import requests | ||
import config | ||
|
||
def get(url): | ||
return requests.get(url) | ||
|
||
def post(url, data): | ||
requests.post(url=url, json=data) | ||
|
||
def preview_fiftyone(name): | ||
get( | ||
url = f'{config.url}:{config.port["flask"]}/fiftyone/{name}' | ||
) | ||
|
||
def preview_embedding(name): | ||
get( | ||
url = f'{config.url}:{config.port["flask"]}/embedding/{name}' | ||
) | ||
|
||
def compute(name): | ||
post( | ||
url = f'{config.url}:{config.port["flask"]}/compute', | ||
data = { | ||
'name' : name | ||
} | ||
) | ||
|
||
def fiftyone_load(name, ids): | ||
post( | ||
url = f'{config.url}:{config.port["flask"]}/fiftyone/load', | ||
data = { | ||
'name' : name, | ||
'ids' : ids | ||
} | ||
) | ||
|
||
if __name__ == '__main__': | ||
compute('quickstart') | ||
preview_embedding('quickstart') | ||
preview_fiftyone('quickstart') | ||
# fiftyone_load('quickstart', ['']) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,45 @@ | ||
import fiftyone as fo | ||
import fiftyone.brain as fob | ||
import pandas as pd | ||
import math | ||
|
||
def create_quickstart(): | ||
import fiftyone.zoo as foz | ||
return foz.load_zoo_dataset("quickstart") | ||
def compute_embeddings(dataset): | ||
return fob.compute_visualization( | ||
dataset, | ||
num_dims=2, | ||
brain_key="image_embeddings", | ||
verbose=True, | ||
seed=51, | ||
patches_field="ground_truth" | ||
).points | ||
|
||
def create(name): | ||
return fo.Dataset(name) | ||
def create_dataframe(dataset): | ||
embeddings = compute_embeddings(dataset) | ||
|
||
df = pd.DataFrame(columns=['id', 'uniqueness', 'label', 'area', 'sqrt_area','embeddings_x', 'embeddings_y']) | ||
|
||
index = 0 | ||
|
||
def load(name): | ||
return fo.load_dataset(name) | ||
for sample in dataset: | ||
|
||
def delete(name): | ||
dataset = load(name) | ||
dataset.delete() | ||
id = sample.id | ||
|
||
def ls(): | ||
print(fo.list_datasets()) | ||
try: uniqueness = sample.uniqueness | ||
except: uniqueness = 0 | ||
|
||
for detection in sample.ground_truth.detections: | ||
|
||
try: label = detection.label | ||
except: label = '' | ||
|
||
try: area = detection.area | ||
except: area = 1 | ||
|
||
embeddings_x = embeddings[index, 0] | ||
embeddings_y = embeddings[index, 1] | ||
|
||
df.loc[index] = [id, uniqueness, label, area, math.sqrt(area), embeddings_x, embeddings_y] | ||
|
||
index += 1 | ||
|
||
return df |