Skip to content

Commit 08e8d7a

Browse files
Move dataset to public
1 parent bd16c5b commit 08e8d7a

265 files changed

Lines changed: 113 additions & 67 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎intro_to_ml.py‎

Lines changed: 113 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,38 @@
44
app = marimo.App(width="medium")
55

66
with app.setup(hide_code=True):
7+
import marimo as mo
8+
9+
10+
@app.cell(hide_code=True)
11+
async def _():
12+
import sys
13+
14+
# Seaborn isn't installed by default in Pyodide, so we install it here (only if the notebook runs on WebAssembly):
15+
if "pyodide" in sys.modules:
16+
import micropip
17+
await micropip.install("seaborn")
18+
import seaborn as sns
19+
else:
20+
import seaborn as sns
21+
return (sns,)
22+
23+
24+
@app.cell(hide_code=True)
25+
def _():
726
import base64
827
from pathlib import Path
928
from io import BytesIO
1029
import time
1130
from pickle import dump
1231

13-
import marimo as mo
14-
1532
import numpy as np
1633
import pandas as pd
1734
from PIL import Image
1835

1936
import matplotlib.pyplot as plt
2037
from matplotlib.colors import ListedColormap
2138

22-
import seaborn as sns
2339
import altair as alt
2440

2541
from skimage.io import imread
@@ -28,6 +44,23 @@
2844

2945
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
3046

47+
return (
48+
BytesIO,
49+
ConfusionMatrixDisplay,
50+
Image,
51+
ListedColormap,
52+
Path,
53+
alt,
54+
base64,
55+
confusion_matrix,
56+
dump,
57+
imread,
58+
np,
59+
pd,
60+
plt,
61+
rescale_intensity,
62+
)
63+
3164

3265
@app.cell(hide_code=True)
3366
def _():
@@ -119,7 +152,7 @@ def _():
119152

120153
@app.cell
121154
def _():
122-
dataset_path = mo.notebook_location() / "./dataset"
155+
dataset_path = mo.notebook_location() / "public" / "dataset"
123156

124157
path_exists = "✅ yes" if dataset_path.exists() else "❌ no"
125158

@@ -149,7 +182,7 @@ def _():
149182

150183

151184
@app.cell
152-
def _(dataset_path, img2url, load_dataset_btn):
185+
def _(Path, dataset_path, img2url, imread, load_dataset_btn, pd):
153186
mo.stop(not load_dataset_btn.value, mo.md("Click the button to load the dataset."))
154187

155188
def read_image(image_path) -> str:
@@ -189,7 +222,7 @@ def _():
189222

190223

191224
@app.cell
192-
def _(df):
225+
def _(df, imread, np):
193226
images = np.array([imread(f) for f in df['image_path']])
194227

195228
mo.md(f"✅ Read all the images into a Numpy array of shape **{images.shape}** corresponding to (N, X, Y).")
@@ -213,7 +246,7 @@ def _(class_labels):
213246

214247

215248
@app.cell
216-
def _(class_dropdown, df, images):
249+
def _(class_dropdown, df, images, np, plt):
217250
def show_images_selection(images_selection, ncols=7):
218251
nrows = int(np.ceil(len(images_selection) / ncols))
219252
fig, axes = plt.subplots(nrows=nrows, ncols=ncols, figsize=(12, 6))
@@ -251,7 +284,7 @@ def _():
251284

252285

253286
@app.cell
254-
def _(df, measurements_btn, url2img):
287+
def _(df, measurements_btn, np, url2img):
255288
mo.stop(not measurements_btn.value, mo.md("Click the button to compute the measurements."))
256289

257290
def compute_mean_intensity(base64_image: str):
@@ -337,15 +370,15 @@ def _():
337370

338371

339372
@app.cell
340-
def _(images):
373+
def _(images, np, rescale_intensity):
341374
images_normed = np.array([rescale_intensity(img, out_range=(0, 1)) for img in images])
342375

343376
mo.md(f"➡️ Shape of images (normalized): **{images_normed.shape}**")
344377
return (images_normed,)
345378

346379

347380
@app.cell
348-
def _(images, images_normed):
381+
def _(images, images_normed, np, plot_image_before_after_normalization):
349382
random_idx = np.random.randint(len(images))
350383

351384
img_before = images[random_idx]
@@ -364,7 +397,7 @@ def _():
364397

365398

366399
@app.cell
367-
def _(images_normed):
400+
def _(images_normed, np):
368401
pixel_features = np.reshape(images_normed, (len(images_normed), -1))
369402

370403
mo.md(f"➡️ Shape of pixel value features: **{pixel_features.shape}**")
@@ -388,7 +421,7 @@ def _():
388421

389422

390423
@app.cell
391-
def _(df, pixel_features, valid_fract_slider):
424+
def _(df, pd, pixel_features, valid_fract_slider):
392425
from sklearn.model_selection import train_test_split
393426

394427
X = pixel_features
@@ -527,39 +560,42 @@ def _():
527560
return
528561

529562

530-
@app.function
531-
def fit_and_evaluate_classifier(model, x_train, y_train, x_val, y_val):
532-
"""Fit a Scikit-Learn classifier on the training set and report evaluation metrics on the validation set."""
533-
# Fit on the training set
534-
model.fit(X=x_train, y=y_train)
563+
@app.cell
564+
def _(ConfusionMatrixDisplay, confusion_matrix):
565+
def fit_and_evaluate_classifier(model, x_train, y_train, x_val, y_val):
566+
"""Fit a Scikit-Learn classifier on the training set and report evaluation metrics on the validation set."""
567+
# Fit on the training set
568+
model.fit(X=x_train, y=y_train)
569+
570+
# Score on the training set
571+
acc_train = model.score(X=x_train, y=y_train)
535572

536-
# Score on the training set
537-
acc_train = model.score(X=x_train, y=y_train)
573+
# Score on the validation set
574+
acc_val = model.score(X=x_val, y=y_val)
538575

539-
# Score on the validation set
540-
acc_val = model.score(X=x_val, y=y_val)
576+
# Predict on the training set
577+
y_pred_train = model.predict(x_train)
541578

542-
# Predict on the training set
543-
y_pred_train = model.predict(x_train)
579+
# Predict on the validation set
580+
y_pred_val = model.predict(x_val)
544581

545-
# Predict on the validation set
546-
y_pred_val = model.predict(x_val)
582+
# Confusion matrices
583+
cm_train = confusion_matrix(y_train, y_pred_train, labels=model.classes_)
584+
disp_train = ConfusionMatrixDisplay(confusion_matrix=cm_train, display_labels=model.classes_)
547585

548-
# Confusion matrices
549-
cm_train = confusion_matrix(y_train, y_pred_train, labels=model.classes_)
550-
disp_train = ConfusionMatrixDisplay(confusion_matrix=cm_train, display_labels=model.classes_)
586+
cm_val = confusion_matrix(y_val, y_pred_val, labels=model.classes_)
587+
disp_val = ConfusionMatrixDisplay(confusion_matrix=cm_val, display_labels=model.classes_)
551588

552-
cm_val = confusion_matrix(y_val, y_pred_val, labels=model.classes_)
553-
disp_val = ConfusionMatrixDisplay(confusion_matrix=cm_val, display_labels=model.classes_)
589+
return {
590+
"accuracy_training": acc_train,
591+
"accuracy_validation": acc_val,
592+
"confusion_matrix_training": disp_train,
593+
"confusion_matrix_validation": disp_val,
594+
"n_train": len(x_train),
595+
"n_validation": len(x_val),
596+
}
554597

555-
return {
556-
"accuracy_training": acc_train,
557-
"accuracy_validation": acc_val,
558-
"confusion_matrix_training": disp_train,
559-
"confusion_matrix_validation": disp_val,
560-
"n_train": len(x_train),
561-
"n_validation": len(x_val),
562-
}
598+
return (fit_and_evaluate_classifier,)
563599

564600

565601
@app.cell(hide_code=True)
@@ -582,6 +618,7 @@ def _():
582618

583619
@app.cell
584620
def _(
621+
fit_and_evaluate_classifier,
585622
fit_baseline_btn,
586623
print_classification_results,
587624
x_train_projected,
@@ -629,6 +666,7 @@ def _():
629666

630667
@app.cell
631668
def _(
669+
fit_and_evaluate_classifier,
632670
fit_linear_model_btn,
633671
print_classification_results,
634672
x_train_projected,
@@ -725,6 +763,7 @@ def _():
725763

726764
@app.cell
727765
def _(
766+
fit_and_evaluate_classifier,
728767
fit_decision_tree_btn,
729768
max_depth_selector,
730769
print_classification_results,
@@ -865,6 +904,7 @@ def _():
865904
def _(
866905
LogisticRegression,
867906
PCA,
907+
fit_and_evaluate_classifier,
868908
n_components_slider,
869909
print_classification_results,
870910
x_train,
@@ -993,7 +1033,7 @@ def _():
9931033

9941034

9951035
@app.cell
996-
def _(pipe, save_btn):
1036+
def _(Path, dump, pipe, save_btn):
9971037
mo.stop(not save_btn.value, mo.md("Click the button to save the pipeline."))
9981038

9991039
pipeline_file = Path("./pipeline.pkl")
@@ -1054,7 +1094,7 @@ def _():
10541094

10551095

10561096
@app.cell
1057-
def _():
1097+
def _(BytesIO, Image, alt, base64, np):
10581098
def url2img(base64_image: str) -> np.ndarray:
10591099
header, encoded = base64_image.split(",", 1)
10601100
img = Image.open(BytesIO(base64.b64decode(encoded)))
@@ -1116,23 +1156,26 @@ def create_altair_chart(df, x_col, y_col, show_images, size=700):
11161156
return create_altair_chart, img2url, url2img
11171157

11181158

1119-
@app.function
1120-
def predict_on_regular_grid(model, extent, nx=200, ny=200):
1121-
"""Run a classifier on a regular grid in a given domain."""
1122-
xx, yy = np.meshgrid(
1123-
np.linspace(extent[0], extent[1], nx),
1124-
np.linspace(extent[2], extent[3], ny),
1125-
)
1126-
grid_yx = np.c_[xx.ravel(), yy.ravel()]
1127-
preds_grid = model.predict(grid_yx)
1128-
label2id = {cls: i for i, cls in enumerate(model.classes_)}
1129-
preds_grid_idx = np.array([label2id[c] for c in preds_grid]).reshape(ny, nx)
1159+
@app.cell
1160+
def _(np):
1161+
def predict_on_regular_grid(model, extent, nx=200, ny=200):
1162+
"""Run a classifier on a regular grid in a given domain."""
1163+
xx, yy = np.meshgrid(
1164+
np.linspace(extent[0], extent[1], nx),
1165+
np.linspace(extent[2], extent[3], ny),
1166+
)
1167+
grid_yx = np.c_[xx.ravel(), yy.ravel()]
1168+
preds_grid = model.predict(grid_yx)
1169+
label2id = {cls: i for i, cls in enumerate(model.classes_)}
1170+
preds_grid_idx = np.array([label2id[c] for c in preds_grid]).reshape(ny, nx)
1171+
1172+
return preds_grid_idx
11301173

1131-
return preds_grid_idx
1174+
return (predict_on_regular_grid,)
11321175

11331176

11341177
@app.cell
1135-
def _():
1178+
def _(ListedColormap, pd, plt, predict_on_regular_grid, sns):
11361179
def plot_classification_results(model, X, y, results, extent, split="validation", palette_name="pastel"):
11371180
# Prediction on a regular grid
11381181
preds_grid_idx = predict_on_regular_grid(model, extent)
@@ -1208,23 +1251,26 @@ def print_classification_results(results: dict):
12081251
return plot_classification_results, print_classification_results
12091252

12101253

1211-
@app.function
1212-
def plot_image_before_after_normalization(img_before, img_after):
1213-
"""TODO: add docsting"""
1214-
fig, axes = plt.subplots(ncols=2)
1215-
im0 = axes[0].imshow(img_before, cmap="gray", vmin=0, vmax=255)
1216-
axes[0].set_title("Original image")
1217-
axes[0].set_axis_off()
1218-
fig.colorbar(im0, ax=axes[0], fraction=0.046, pad=0.04)
1219-
im1 = axes[1].imshow(img_after, cmap="gray", vmin=0, vmax=1)
1220-
axes[1].set_title("Intensity rescaled")
1221-
axes[1].set_axis_off()
1222-
fig.colorbar(im1, ax=axes[1], fraction=0.046, pad=0.04)
1223-
return fig
1254+
@app.cell
1255+
def _(plt):
1256+
def plot_image_before_after_normalization(img_before, img_after):
1257+
"""TODO: add docsting"""
1258+
fig, axes = plt.subplots(ncols=2)
1259+
im0 = axes[0].imshow(img_before, cmap="gray", vmin=0, vmax=255)
1260+
axes[0].set_title("Original image")
1261+
axes[0].set_axis_off()
1262+
fig.colorbar(im0, ax=axes[0], fraction=0.046, pad=0.04)
1263+
im1 = axes[1].imshow(img_after, cmap="gray", vmin=0, vmax=1)
1264+
axes[1].set_title("Intensity rescaled")
1265+
axes[1].set_axis_off()
1266+
fig.colorbar(im1, ax=axes[1], fraction=0.046, pad=0.04)
1267+
return fig
1268+
1269+
return (plot_image_before_after_normalization,)
12241270

12251271

12261272
@app.cell
1227-
def _(fit_model_with_pca):
1273+
def _(fit_model_with_pca, np, plt):
12281274
def plot_accuracy_vs_pca_components(model, x_train, x_val, y_train, y_val, max_components=20):
12291275
"""Does this show up in live docs?"""
12301276
train_accs = []

0 commit comments

Comments
 (0)