mirror of
https://github.com/luxfhe/workshop.git
synced 2026-10-30 17:06:44 +00:00
219 KiB
219 KiB
In [1]:
import time
import numpy as np
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression as SklearnLinearRegression
from sklearn.metrics import r2_score
from sklearn.model_selection import train_test_split
from torus.ml.sklearn import LinearRegression as TorusLinearRegressionIn [2]:
%matplotlib inline
import matplotlib.pyplot as plt
from IPython.display import display
train_plot_config = {"c": "black", "marker": "D", "s": 15, "label": "Train data"}
test_plot_config = {"c": "red", "marker": "x", "s": 15, "label": "Test data"}
def get_sklearn_plot_config(r2_score=None):
label = "Scikit-Learn"
if r2_score is not None:
label += f", {'$R^2$'}={r2_score:.4f}"
return {"c": "blue", "linewidth": 2.5, "label": label}
def get_torus_plot_config(r2_score=None):
label = "Torus ML"
if r2_score is not None:
label += f", {'$R^2$'}={r2_score:.4f}"
return {"c": "orange", "linewidth": 2.5, "label": label}In [3]:
# pylint: disable=unbalanced-tuple-unpacking
X, y = make_regression(
n_samples=200, n_features=1, n_targets=1, bias=5.0, noise=30.0, random_state=42
)
# pylint: enable=unbalanced-tuple-unpacking
# We split the data-set into a training and a testing set
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=42)
# We sort the test set for a better visualization
sorted_indexes = np.argsort(np.squeeze(X_test))
X_test = X_test[sorted_indexes, :]
y_test = y_test[sorted_indexes]In [4]:
plt.ioff()
plt.clf()
fig, ax = plt.subplots(1, figsize=(10, 5))
fig.patch.set_facecolor("white")
ax.scatter(X_train, y_train, **train_plot_config)
ax.scatter(X_test, y_test, **test_plot_config)
ax.legend()
display(fig)In [5]:
sklearn_lr = SklearnLinearRegression()
sklearn_lr.fit(X_train, y_train)
y_pred = sklearn_lr.predict(X_test)
# Compute the R2 scores
sklearn_r2_score = r2_score(y_test, y_pred)In [6]:
plt.ioff()
plt.clf()
fig, ax = plt.subplots(1, figsize=(10, 5))
fig.patch.set_facecolor("white")
ax.scatter(X_train, y_train, **train_plot_config)
ax.scatter(X_test, y_test, **test_plot_config)
ax.plot(X_test, y_pred, **get_sklearn_plot_config(sklearn_r2_score))
ax.legend()
display(fig)In [7]:
# We quantize the inputs using 8-bits
torus_lr = TorusLinearRegression(n_bits=8)
# We train the torus linear regression model on clear data
torus_lr.fit(X_train, y_train)
# We densify the space representation of the original X,
# to better visualize the resulting step function in the following figure
x_space = np.linspace(X_test.min(), X_test.max(), num=300)
x_space = x_space[:, np.newaxis]
y_pred_q_space = torus_lr.predict(x_space)
# Now, we can test our Torus ML model on the clear test data
y_pred_q = torus_lr.predict(X_test)
# Compute the R2 scores
quantized_r2_score = r2_score(y_test, y_pred_q)In [8]:
plt.ioff()
plt.clf()
fig, ax = plt.subplots(1, figsize=(12, 8))
fig.patch.set_facecolor("white")
ax.scatter(X_train, y_train, **train_plot_config)
ax.scatter(X_test, y_test, **test_plot_config)
ax.plot(X_test, y_pred, **get_sklearn_plot_config(sklearn_r2_score))
ax.plot(x_space, y_pred_q_space, **get_torus_plot_config(quantized_r2_score))
ax.legend()
display(fig)In [9]:
fhe_circuit = torus_lr.compile(X_train)In [10]:
print(f"Generating a key for a {fhe_circuit.graph.maximum_integer_bit_width()}-bit circuit")Generating a key for a 9-bit circuit
In [11]:
time_begin = time.time()
fhe_circuit.client.keygen(force=False)
print(f"Key generation time: {time.time() - time_begin:.4f} seconds")Key generation time: 0.0002 seconds
In [12]:
time_begin = time.time()
y_pred_fhe = torus_lr.predict(X_test, fhe="execute")
print(f"Execution time: {(time.time() - time_begin) / len(X_test):.4f} seconds per sample")Execution time: 0.0033 seconds per sample
In [13]:
# Measure the FHE R2 score
fhe_r2_score = r2_score(y_test, y_pred_fhe)
print("R^2 scores:")
print(f"scikit-learn (clear): {sklearn_r2_score:.4f}")
print(f"Torus ML (quantized): {quantized_r2_score:.4f}")
print(f"Torus ML (FHE): {fhe_r2_score:.4f}")
# Measure the error of the FHE quantized model with respect to the clear scikit-learn float model
torus_score_difference = abs(fhe_r2_score - quantized_r2_score) * 100 / quantized_r2_score
print(
"\nRelative score difference for Torus ML (quantized clear) vs. Torus ML (FHE):",
f"{torus_score_difference:.2f}%",
)
# Measure the error of the FHE quantized model with respect to the clear float model
score_difference = abs(fhe_r2_score - sklearn_r2_score) * 100 / sklearn_r2_score
print(
"Relative score difference for scikit-learn (clear) vs. Torus ML (FHE) scores:",
f"{score_difference:.2f}%",
)R^2 scores: scikit-learn (clear): 0.9013 Torus ML (quantized): 0.8973 Torus ML (FHE): 0.8973 Relative score difference for Torus ML (quantized clear) vs. Torus ML (FHE): 0.00% Relative score difference for scikit-learn (clear) vs. Torus ML (FHE) scores: 0.45%
In [14]:
# For better visualization
y_pred_q_space = torus_lr.predict(x_space)In [15]:
plt.clf()
fig, ax = plt.subplots(1, figsize=(12, 8))
fig.patch.set_facecolor("white")
ax.scatter(X_train, y_train, **train_plot_config)
ax.scatter(X_test, y_test, **test_plot_config)
ax.plot(X_test, y_pred, **get_sklearn_plot_config(sklearn_r2_score))
ax.plot(x_space, y_pred_q_space, **get_torus_plot_config(fhe_r2_score))
ax.legend()
display(fig)