Mark Duppenthaler commited on
Commit
54be5f9
·
1 Parent(s): cf4e7fe

Add dataset selector

Browse files
backend/app.py CHANGED
@@ -1,4 +1,5 @@
1
  from backend.chart import mk_variations
 
2
  from backend.examples import audio_examples_tab, image_examples_tab, video_examples_tab
3
  from flask import Flask, Response, send_from_directory
4
  from flask_cors import CORS
@@ -35,19 +36,20 @@ def index():
35
  return send_from_directory(app.static_folder, "index.html")
36
 
37
 
38
- @app.route("/data/<path:filename>")
39
- def data_files(filename):
40
  """
41
  Serves csv files from the data directory.
42
  """
43
  data_dir = os.path.join(os.path.dirname(__file__), "data")
44
- file_path = os.path.join(data_dir, filename)
 
45
  if os.path.isfile(file_path):
46
  df = pd.read_csv(file_path)
47
- logger.info(f"Processing file: {filename}")
48
- if filename.endswith("benchmark.csv"):
49
- return get_leaderboard(df)
50
- elif filename.endswith("attacks_variations.csv"):
51
  return get_chart(df)
52
 
53
  return "File not found", 404
@@ -118,43 +120,14 @@ def proxy(url):
118
  return {"error": str(e)}, 500
119
 
120
 
121
- def get_leaderboard(df):
122
  # Determine file type and handle accordingly
123
-
124
- # Modify the dataframe - you'll need to define first_cols and attack_scores
125
- first_cols = [
126
- "snr",
127
- "sisnr",
128
- "stoi",
129
- "pesq",
130
- ] # Define appropriate values based on your needs
131
- attack_scores = [
132
- "bit_acc",
133
- "log10_p_value",
134
- "TPR",
135
- "FPR",
136
- ] # Define appropriate values based on your needs
137
- categories = {
138
- "speed": "Time",
139
- "updownresample": "Time",
140
- "echo": "Time",
141
- "random_noise": "Amplitude",
142
- "lowpass_filter": "Amplitude",
143
- "highpass_filter": "Amplitude",
144
- "bandpass_filter": "Amplitude",
145
- "smooth": "Amplitude",
146
- "boost_audio": "Amplitude",
147
- "duck_audio": "Amplitude",
148
- "shush": "Amplitude",
149
- "pink_noise": "Amplitude",
150
- "aac_compression": "Compression",
151
- "mp3_compression": "Compression",
152
- }
153
 
154
  # This part adds on all the columns
155
- df = get_old_format_dataframe(df, first_cols, attack_scores)
156
 
157
- groups, default_selection = get_leaderboard_filters(df, categories)
158
 
159
  # Replace NaN values with None for JSON serialization
160
  df = df.fillna(value="NaN")
 
1
  from backend.chart import mk_variations
2
+ from backend.config import get_dataset_config
3
  from backend.examples import audio_examples_tab, image_examples_tab, video_examples_tab
4
  from flask import Flask, Response, send_from_directory
5
  from flask_cors import CORS
 
36
  return send_from_directory(app.static_folder, "index.html")
37
 
38
 
39
+ @app.route("/data/<path:dataset_name>")
40
+ def data_files(dataset_name):
41
  """
42
  Serves csv files from the data directory.
43
  """
44
  data_dir = os.path.join(os.path.dirname(__file__), "data")
45
+ file_path = os.path.join(data_dir, dataset_name) + ".csv"
46
+ logger.info(f"Looking for dataset file: {file_path}")
47
  if os.path.isfile(file_path):
48
  df = pd.read_csv(file_path)
49
+ logger.info(f"Processing dataset: {dataset_name}")
50
+ if dataset_name.endswith("benchmark"):
51
+ return get_leaderboard(dataset_name, df)
52
+ elif dataset_name.endswith("attacks_variations"):
53
  return get_chart(df)
54
 
55
  return "File not found", 404
 
120
  return {"error": str(e)}, 500
121
 
122
 
123
+ def get_leaderboard(dataset_name, df):
124
  # Determine file type and handle accordingly
125
+ config = get_dataset_config(dataset_name)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
  # This part adds on all the columns
128
+ df = get_old_format_dataframe(df, config["first_cols"], config["attack_scores"])
129
 
130
+ groups, default_selection = get_leaderboard_filters(df, config["categories"])
131
 
132
  # Replace NaN values with None for JSON serialization
133
  df = df.fillna(value="NaN")
backend/config.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def get_dataset_config(dataset_name):
2
+ if dataset_name == "voxpopuli_1k_audio_benchmark":
3
+ return {
4
+ "first_cols": [
5
+ "snr",
6
+ "sisnr",
7
+ "stoi",
8
+ "pesq",
9
+ ],
10
+ "attack_scores": [
11
+ "bit_acc",
12
+ "log10_p_value",
13
+ "TPR",
14
+ "FPR",
15
+ ],
16
+ "categories": {
17
+ "speed": "Time",
18
+ "updownresample": "Time",
19
+ "echo": "Time",
20
+ "random_noise": "Amplitude",
21
+ "lowpass_filter": "Amplitude",
22
+ "highpass_filter": "Amplitude",
23
+ "bandpass_filter": "Amplitude",
24
+ "smooth": "Amplitude",
25
+ "boost_audio": "Amplitude",
26
+ "duck_audio": "Amplitude",
27
+ "shush": "Amplitude",
28
+ "pink_noise": "Amplitude",
29
+ "aac_compression": "Compression",
30
+ "mp3_compression": "Compression",
31
+ },
32
+ }
33
+ elif dataset_name == "ravdess_1k_audio_benchmark":
34
+ return {
35
+ "first_cols": ["snr", "sisnr", "stoi", "pesq"],
36
+ "attack_scores": ["bit_acc", "log10_p_value", "TPR", "FPR"],
37
+ "categories": {
38
+ "speed": "Time",
39
+ "updownresample": "Time",
40
+ "echo": "Time",
41
+ "random_noise": "Amplitude",
42
+ "lowpass_filter": "Amplitude",
43
+ "highpass_filter": "Amplitude",
44
+ "bandpass_filter": "Amplitude",
45
+ "smooth": "Amplitude",
46
+ "boost_audio": "Amplitude",
47
+ "duck_audio": "Amplitude",
48
+ "shush": "Amplitude",
49
+ "pink_noise": "Amplitude",
50
+ "aac_compression": "Compression",
51
+ "mp3_compression": "Compression",
52
+ },
53
+ }
54
+ elif dataset_name == "val2014_1k_image_benchmark":
55
+ return {
56
+ "first_cols": ["psnr", "ssim", "lpips", "decoder_time"],
57
+ "attack_scores": ["bit_acc", "log10_p_value", "TPR", "FPR"],
58
+ "categories": {
59
+ "proportion": "Geometric",
60
+ "collage": "Inpainting",
61
+ "center_crop": "Geometric",
62
+ "rotate": "Geometric",
63
+ "jpeg": "Compression",
64
+ "brightness": "Visual",
65
+ "contrast": "Visual",
66
+ "saturation": "Visual",
67
+ "sharpness": "Visual",
68
+ "resize": "Geometric",
69
+ "overlay_text": "Inpainting",
70
+ "hflip": "Geometric",
71
+ "perspective": "Geometric",
72
+ "median_filter": "Visual",
73
+ "hue": "Visual",
74
+ "gaussian_blur": "Visual",
75
+ "comb": "Mixed",
76
+ "avg": "Averages",
77
+ "none": "Baseline",
78
+ },
79
+ }
80
+ elif dataset_name == "sav_val_full_video_benchmark":
81
+ return {
82
+ "first_cols": ["psnr", "ssim", "msssim", "lpips", "vmaf", "decoder_time"],
83
+ "attack_scores": ["bit_acc", "log10_p_value", "TPR", "FPR"],
84
+ "categories": {
85
+ "HorizontalFlip": "Geometric",
86
+ "Rotate": "Geometric",
87
+ "Resize": "Geometric",
88
+ "Crop": "Geometric",
89
+ "Perspective": "Geometric",
90
+ "Brightness": "Visual",
91
+ "Contrast": "Visual",
92
+ "Saturation": "Visual",
93
+ "Grayscale": "Visual",
94
+ "Hue": "Visual",
95
+ "JPEG": "Compression",
96
+ "GaussianBlur": "Visual",
97
+ "MedianFilter": "Visual",
98
+ "H264": "Compression",
99
+ "H264rgb": "Compression",
100
+ "H265": "Compression",
101
+ "VP9": "Compression",
102
+ "H264_Crop_Brightness0": "Mixed",
103
+ "H264_Crop_Brightness1": "Mixed",
104
+ "H264_Crop_Brightness2": "Mixed",
105
+ "H264_Crop_Brightness3": "Mixed",
106
+ },
107
+ }
108
+ else:
109
+ raise ValueError(f"Unknown dataset: {dataset_name}")
frontend/src/App.tsx CHANGED
@@ -1,14 +1,11 @@
1
  import { useState } from 'react'
2
- import API from './API'
3
- import DataChart from './components/DataChart'
4
- import LeaderboardTable from './components/LeaderboardTable'
5
  import Examples from './components/Examples'
 
6
 
7
  function App() {
8
- const file = 'voxpopuli_1k_audio'
9
  const [activeTab, setActiveTab] = useState<
10
- 'dataChart' | 'leaderboard' | 'imageExamples' | 'audioExamples' | 'videoExamples'
11
- >('dataChart')
12
 
13
  return (
14
  <div className="min-h-screen w-11/12 mx-auto">
@@ -17,20 +14,8 @@ function App() {
17
  <h2 className="card-title">🥇 Omni Seal Bench Watermarking Leaderboard</h2>
18
  </div>
19
  </div>
20
- <div className="tabs tabs-border">
21
- <input
22
- type="radio"
23
- name="my_tabs_6"
24
- className="tab"
25
- aria-label="Data Chart"
26
- checked={activeTab === 'dataChart'}
27
- onChange={() => setActiveTab('dataChart')}
28
- defaultChecked
29
- />
30
- <div className="tab-content bg-base-100 border-base-300 p-6">
31
- <DataChart file={file} />
32
- </div>
33
 
 
34
  <input
35
  type="radio"
36
  name="my_tabs_6"
@@ -40,7 +25,7 @@ function App() {
40
  onChange={() => setActiveTab('leaderboard')}
41
  />
42
  <div className="tab-content bg-base-100 border-base-300 p-6">
43
- <LeaderboardTable file={file} />
44
  </div>
45
 
46
  <input
 
1
  import { useState } from 'react'
 
 
 
2
  import Examples from './components/Examples'
3
+ import LeaderBoardPage from './components/LeaderBoardPage'
4
 
5
  function App() {
 
6
  const [activeTab, setActiveTab] = useState<
7
+ 'leaderboard' | 'imageExamples' | 'audioExamples' | 'videoExamples'
8
+ >('leaderboard')
9
 
10
  return (
11
  <div className="min-h-screen w-11/12 mx-auto">
 
14
  <h2 className="card-title">🥇 Omni Seal Bench Watermarking Leaderboard</h2>
15
  </div>
16
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
+ <div className="tabs tabs-border">
19
  <input
20
  type="radio"
21
  name="my_tabs_6"
 
25
  onChange={() => setActiveTab('leaderboard')}
26
  />
27
  <div className="tab-content bg-base-100 border-base-300 p-6">
28
+ <LeaderBoardPage />
29
  </div>
30
 
31
  <input
frontend/src/components/DataChart.tsx CHANGED
@@ -12,7 +12,7 @@ import {
12
  import API from '../API'
13
 
14
  interface DataChartProps {
15
- file: string
16
  }
17
 
18
  interface Row {
@@ -76,7 +76,7 @@ const AttackSelector = ({
76
  )
77
  }
78
 
79
- const DataChart = ({ file }: DataChartProps) => {
80
  const [chartData, setChartData] = useState<Row[]>([])
81
  const [loading, setLoading] = useState(true)
82
  const [error, setError] = useState<string | null>(null)
@@ -86,7 +86,7 @@ const DataChart = ({ file }: DataChartProps) => {
86
  const [selectedAttack, setSelectedAttack] = useState<string | null>(null)
87
 
88
  useEffect(() => {
89
- API.fetchStaticFile(`data/${file}_attacks_variations.csv`)
90
  .then((response) => {
91
  const data = JSON.parse(response)
92
  const rows: Row[] = data['all_attacks_df'].map((row: any) => {
 
12
  import API from '../API'
13
 
14
  interface DataChartProps {
15
+ dataset: string
16
  }
17
 
18
  interface Row {
 
76
  )
77
  }
78
 
79
+ const DataChart = ({ dataset }: DataChartProps) => {
80
  const [chartData, setChartData] = useState<Row[]>([])
81
  const [loading, setLoading] = useState(true)
82
  const [error, setError] = useState<string | null>(null)
 
86
  const [selectedAttack, setSelectedAttack] = useState<string | null>(null)
87
 
88
  useEffect(() => {
89
+ API.fetchStaticFile(`data/${dataset}_attacks_variations`)
90
  .then((response) => {
91
  const data = JSON.parse(response)
92
  const rows: Row[] = data['all_attacks_df'].map((row: any) => {
frontend/src/components/DatasetSelector.tsx ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react'
2
+
3
+ interface DatasetSelectorProps {
4
+ datasets: string[]
5
+ selectedDataset: string
6
+ onDatasetChange: (dataset: string) => void
7
+ }
8
+
9
+ const DatasetSelector: React.FC<DatasetSelectorProps> = ({
10
+ datasets,
11
+ selectedDataset,
12
+ onDatasetChange,
13
+ }) => {
14
+ return (
15
+ <div className="mb-4">
16
+ <fieldset className="fieldset w-full p-4 rounded border">
17
+ <legend className="fieldset-legend font-semibold">Dataset</legend>
18
+ <div className="flex flex-wrap gap-2">
19
+ {datasets.map((dataset) => (
20
+ <label key={dataset} className="flex items-center gap-2 cursor-pointer">
21
+ <input
22
+ type="radio"
23
+ name="dataset"
24
+ className="radio radio-sm"
25
+ checked={selectedDataset === dataset}
26
+ onChange={() => onDatasetChange(dataset)}
27
+ />
28
+ <span className="text-sm">{dataset}</span>
29
+ </label>
30
+ ))}
31
+ </div>
32
+ </fieldset>
33
+ </div>
34
+ )
35
+ }
36
+
37
+ export default DatasetSelector
frontend/src/components/LeaderBoardPage.tsx ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState } from 'react'
2
+ import DatasetSelector from './DatasetSelector'
3
+ import LeaderboardTable from './LeaderboardTable'
4
+ import DataChart from './DataChart'
5
+
6
+ const LeaderBoardPage: React.FC = () => {
7
+ const datasets = [
8
+ 'voxpopuli_1k_audio',
9
+ 'ravdess_1k_audio',
10
+ 'val2014_1k_image',
11
+ 'sav_val_full_video',
12
+ ]
13
+ const [selectedDataset, setSelectedDataset] = useState('voxpopuli_1k_audio')
14
+
15
+ return (
16
+ <div className="space-y-6">
17
+ <DatasetSelector
18
+ datasets={datasets}
19
+ selectedDataset={selectedDataset}
20
+ onDatasetChange={setSelectedDataset}
21
+ />
22
+
23
+ <div className="space-y-8">
24
+ <LeaderboardTable dataset={selectedDataset} />
25
+ <div className="mt-8 pt-4 border-t border-gray-200">
26
+ <h3 className="text-lg font-semibold mb-4">Performance Chart</h3>
27
+ <DataChart dataset={selectedDataset} />
28
+ </div>
29
+ </div>
30
+ </div>
31
+ )
32
+ }
33
+
34
+ export default LeaderBoardPage
frontend/src/components/LeaderboardTable.tsx CHANGED
@@ -4,7 +4,7 @@ import LeaderboardFilter from './LeaderboardFilter'
4
  import ModelFilter from './ModelFilter'
5
 
6
  interface LeaderboardTableProps {
7
- file: string
8
  }
9
 
10
  interface Row {
@@ -21,7 +21,7 @@ interface GroupStats {
21
  stdDev: { [key: string]: number }
22
  }
23
 
24
- const LeaderboardTable: React.FC<LeaderboardTableProps> = ({ file }) => {
25
  const [tableRows, setTableRows] = useState<Row[]>([])
26
  const [tableHeader, setTableHeader] = useState<string[]>([])
27
  const [loading, setLoading] = useState(true)
@@ -39,7 +39,7 @@ const LeaderboardTable: React.FC<LeaderboardTableProps> = ({ file }) => {
39
  const [overallMetrics, setOverallMetrics] = useState<string[]>([])
40
 
41
  useEffect(() => {
42
- API.fetchStaticFile(`data/${file}_benchmark.csv`)
43
  .then((response) => {
44
  const data = JSON.parse(response)
45
  const rows: Row[] = data['rows']
@@ -128,7 +128,7 @@ const LeaderboardTable: React.FC<LeaderboardTableProps> = ({ file }) => {
128
  setError('Failed to fetch JSON: ' + err.message)
129
  setLoading(false)
130
  })
131
- }, [file])
132
 
133
  const toggleGroup = (group: string) => {
134
  setOpenGroups((prev) => ({ ...prev, [group]: !prev[group] }))
@@ -228,7 +228,6 @@ const LeaderboardTable: React.FC<LeaderboardTableProps> = ({ file }) => {
228
 
229
  return (
230
  <div className="rounded shadow overflow-auto">
231
- <h3 className="font-bold mb-2">{file}</h3>
232
  {loading && <div>Loading...</div>}
233
  {error && <div className="text-red-500">{error}</div>}
234
 
 
4
  import ModelFilter from './ModelFilter'
5
 
6
  interface LeaderboardTableProps {
7
+ dataset: string
8
  }
9
 
10
  interface Row {
 
21
  stdDev: { [key: string]: number }
22
  }
23
 
24
+ const LeaderboardTable: React.FC<LeaderboardTableProps> = ({ dataset }) => {
25
  const [tableRows, setTableRows] = useState<Row[]>([])
26
  const [tableHeader, setTableHeader] = useState<string[]>([])
27
  const [loading, setLoading] = useState(true)
 
39
  const [overallMetrics, setOverallMetrics] = useState<string[]>([])
40
 
41
  useEffect(() => {
42
+ API.fetchStaticFile(`data/${dataset}_benchmark`)
43
  .then((response) => {
44
  const data = JSON.parse(response)
45
  const rows: Row[] = data['rows']
 
128
  setError('Failed to fetch JSON: ' + err.message)
129
  setLoading(false)
130
  })
131
+ }, [dataset])
132
 
133
  const toggleGroup = (group: string) => {
134
  setOpenGroups((prev) => ({ ...prev, [group]: !prev[group] }))
 
228
 
229
  return (
230
  <div className="rounded shadow overflow-auto">
 
231
  {loading && <div>Loading...</div>}
232
  {error && <div className="text-red-500">{error}</div>}
233