qqubb commited on
Commit
1a32e82
1 Parent(s): c1dc645

Upload 18 files

Browse files
.gitattributes CHANGED
@@ -30,3 +30,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
30
  *.zst filter=lfs diff=lfs merge=lfs -text
31
  *tfevents* filter=lfs diff=lfs merge=lfs -text
32
  deployment_logit/client_dir/3427324229_encrypted_output filter=lfs diff=lfs merge=lfs -text
 
 
30
  *.zst filter=lfs diff=lfs merge=lfs -text
31
  *tfevents* filter=lfs diff=lfs merge=lfs -text
32
  deployment_logit/client_dir/3427324229_encrypted_output filter=lfs diff=lfs merge=lfs -text
33
+ deployment_logit/server_dir/3427324229_encrypted_output filter=lfs diff=lfs merge=lfs -text
.gitignore CHANGED
@@ -1,3 +1,4 @@
 
1
  .fhe_keys/
2
  client_dir/
3
  server_dir/
 
1
+ .fhe/
2
  .fhe_keys/
3
  client_dir/
4
  server_dir/
README.md CHANGED
@@ -1,13 +1,7 @@
1
- ---
2
- title: Titanic Survival Prediction using Fully Homomorphic Encryption (FHE)
3
- sdk: gradio
4
- colorFrom: blue
5
- ---
6
-
7
- Titanic Survival Prediction using Fully Homomorphic Encryption (FHE)
8
 
9
  Titanic survival code adapted from:
10
  https://huggingface.co/spaces/gradio/titanic_survival_main
11
 
12
  FHE Cloud Deployment code adapted from:
13
- https://github.com/zama-ai/concrete-ml/blob/release/1.1.x/use_case_examples/deployment/README.md
 
1
+ Titanic Survival Prediction using Fully Homomorphic Encryption (FHE) and Cloud Deployment of Encrypted ML
 
 
 
 
 
 
2
 
3
  Titanic survival code adapted from:
4
  https://huggingface.co/spaces/gradio/titanic_survival_main
5
 
6
  FHE Cloud Deployment code adapted from:
7
+ https://github.com/zama-ai/concrete-ml/blob/release/1.1.x/use_case_examples/deployment/README.md
app.py CHANGED
@@ -166,9 +166,9 @@ def concrete_predict_survival(input_dict):
166
  pred = concrete_clf.predict_proba(df)[0]
167
  return {"Perishes": float(pred[0]), "Survives": float(pred[1])}
168
 
169
- # print("\nclear_test ", clear_predict_survival({'Pclass': [1], 'Sex': [0], 'Age': [25], 'Fare': [20.0], 'Embarked': [2], 'Company': [1]}))
170
 
171
- # print("encrypted_test", concrete_predict_survival({'Pclass': [1], 'Sex': [0], 'Age': [25], 'Fare': [20.0], 'Embarked': [2], 'Company': [1]}),"\n")
172
 
173
 
174
  def key_gen_fn() -> Dict:
@@ -362,7 +362,7 @@ def run_fhe_fn(user_id: str) -> Dict:
362
  fhe_execution_time_box: gr.update(visible=False),
363
  }
364
  else:
365
- time.sleep(1)
366
  print(f"response.ok: {response.ok}, {response.json()} - Computed")
367
 
368
  return {
@@ -661,4 +661,4 @@ with gr.Blocks() as demo:
661
 
662
  # ------------------------- End -------------------------
663
 
664
- demo.launch(share=True)
 
166
  pred = concrete_clf.predict_proba(df)[0]
167
  return {"Perishes": float(pred[0]), "Survives": float(pred[1])}
168
 
169
+ print("\nclear_test ", clear_predict_survival({'Pclass': [1], 'Sex': [0], 'Age': [25], 'Fare': [20.0], 'Embarked': [2], 'Company': [1]}))
170
 
171
+ print("encrypted_test", concrete_predict_survival({'Pclass': [1], 'Sex': [0], 'Age': [25], 'Fare': [20.0], 'Embarked': [2], 'Company': [1]}),"\n")
172
 
173
 
174
  def key_gen_fn() -> Dict:
 
362
  fhe_execution_time_box: gr.update(visible=False),
363
  }
364
  else:
365
+ time.sleep(10)
366
  print(f"response.ok: {response.ok}, {response.json()} - Computed")
367
 
368
  return {
 
661
 
662
  # ------------------------- End -------------------------
663
 
664
+ demo.launch()
deployment_logit/client.zip CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:e1f806d1aa6f67cafd07321486215d4e5822279fb9fe14a401e9a77f4d44093b
3
- size 6147
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:058a33d9d78957b853112809fc202cd1ee546c9beca2550ed95f140569833657
3
+ size 6437
deployment_logit/client_dir/3427324229_encrypted_output ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7daf64ac339601799c4db40703bd2c1b9d699288f06814ddb3a2f391eb20d934
3
+ size 3932690
deployment_logit/client_dir/447559753_encrypted_output ADDED
Binary file (984 kB). View file
 
deployment_logit/server.zip CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:1b6ab82039055e3b69889be441918546b1609010f69096c88ed5b1c12c18f7ac
3
- size 9629
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:54c45f9b27bd5493a2e58e3ad9fa8365490bd65abefbe0befb24b1f1a20c433c
3
+ size 14985
deployment_logit/server_dir/3427324229_encrypted_input ADDED
Binary file (393 kB). View file
 
deployment_logit/server_dir/3427324229_encrypted_output ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7daf64ac339601799c4db40703bd2c1b9d699288f06814ddb3a2f391eb20d934
3
+ size 3932690
deployment_logit/server_dir/447559753_encrypted_input ADDED
Binary file (61.8 kB). View file
 
deployment_logit/server_dir/447559753_encrypted_output ADDED
Binary file (984 kB). View file
 
deployment_logit/versions.json CHANGED
@@ -1 +1 @@
1
- {"concrete-ml": "1.4.0", "concrete-python": "2.5", "python": "3.10.12"}
 
1
+ {"concrete-python": "2.5.1", "concrete-ml": "1.4.1", "python": "3.10.12"}
requirements.txt CHANGED
@@ -1,7 +1,7 @@
1
  scikit-learn
2
  numpy
3
  pandas
4
- concrete-ml==1.4.0
5
- gradio==3.35.2
6
- uvicorn>=0.21.0
7
- fastapi>=0.93.0
 
1
  scikit-learn
2
  numpy
3
  pandas
4
+ concrete-ml
5
+ gradio
6
+ uvicorn
7
+ fastapi
server.py CHANGED
@@ -94,7 +94,7 @@ def get_output(user_id: str = Form()):
94
  with encrypted_output_path.open("rb") as f:
95
  encrypted_output = f.read()
96
 
97
- time.sleep(1)
98
 
99
  # Send the encrypted output
100
  return Response(encrypted_output)
 
94
  with encrypted_output_path.open("rb") as f:
95
  encrypted_output = f.read()
96
 
97
+ time.sleep(10)
98
 
99
  # Send the encrypted output
100
  return Response(encrypted_output)
train.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ import numpy
4
+ import pandas as pd
5
+ import torch
6
+
7
+ from sklearn.ensemble import RandomForestClassifier
8
+ from sklearn.model_selection import train_test_split
9
+
10
+ from sklearn.metrics import average_precision_score
11
+ from sklearn.model_selection import GridSearchCV, train_test_split
12
+
13
+ from concrete.ml.sklearn import RandomForestClassifier as ConcreteRandomForestClassifier
14
+
15
+ def train(dev_folder="./dev"):
16
+ # Download the data-sets
17
+ if not os.path.isfile("./files/titanic.csv"):
18
+ raise ValueError(
19
+ "no dataset"
20
+ )
21
+
22
+ current_dir = os.path.dirname(os.path.realpath(__file__))
23
+ data = pd.read_csv(os.path.join(current_dir, "files/titanic.csv"))
24
+
25
+ def encode_age(df):
26
+ df.Age = df.Age.fillna(-0.5)
27
+ bins = (-1, 0, 5, 12, 18, 25, 35, 60, 120)
28
+ categories = pd.cut(df.Age, bins, labels=False)
29
+ df.Age = categories
30
+ return df
31
+
32
+
33
+ def encode_fare(df):
34
+ df.Fare = df.Fare.fillna(-0.5)
35
+ bins = (-1, 0, 8, 15, 31, 1000)
36
+ categories = pd.cut(df.Fare, bins, labels=False)
37
+ df.Fare = categories
38
+ return df
39
+
40
+
41
+ def encode_df(df):
42
+ df = encode_age(df)
43
+ df = encode_fare(df)
44
+ sex_mapping = {"male": 0, "female": 1}
45
+ df = df.replace({"Sex": sex_mapping})
46
+ embark_mapping = {"S": 1, "C": 2, "Q": 3}
47
+ df = df.replace({"Embarked": embark_mapping})
48
+ df.Embarked = df.Embarked.fillna(0)
49
+ df["Company"] = 0
50
+ df.loc[(df["SibSp"] > 0), "Company"] = 1
51
+ df.loc[(df["Parch"] > 0), "Company"] = 2
52
+ df.loc[(df["SibSp"] > 0) & (df["Parch"] > 0), "Company"] = 3
53
+ df = df[
54
+ [
55
+ "PassengerId",
56
+ "Pclass",
57
+ "Sex",
58
+ "Age",
59
+ "Fare",
60
+ "Embarked",
61
+ "Company",
62
+ "Survived",
63
+ ]
64
+ ]
65
+ return df
66
+
67
+ train = encode_df(data)
68
+
69
+ X_all = train.drop(["Survived", "PassengerId"], axis=1)
70
+ y_all = train["Survived"]
71
+
72
+ num_test = 0.20
73
+ X_train, X_test, y_train, y_test = train_test_split(
74
+ X_all, y_all, test_size=num_test, random_state=23
75
+ )
76
+
77
+ # n_estimators = 50
78
+ # max_depth = 4
79
+ # n_bits = 6
80
+ # n_jobs_xgb = 1
81
+ # n_jobs_gridsearch = -1
82
+
83
+ # A gridsearch to find the best parameters
84
+ parameters = {
85
+ "n_bits": [6],
86
+ "max_depth": [4, 8],
87
+ "n_estimators": [30, 50],
88
+ "n_jobs": [-1],
89
+ }
90
+
91
+ concrete_clf = ConcreteRandomForestClassifier()
92
+ # concrete_clf.fit(X_train, y_train)
93
+ # concrete_predictions = concrete_clf.predict(X_test)
94
+
95
+ grid_search = GridSearchCV(concrete_clf, parameters, cv=3, n_jobs=-1, scoring="accuracy")
96
+ grid_search.fit(X_train, y_train)
97
+
98
+ # Check the accuracy of the best model
99
+ print(f"Best score: {grid_search.best_score_}")
100
+
101
+ # Check best hyper-parameters
102
+ print(f"Best parameters: {grid_search.best_params_}")
103
+
104
+ # Extract best model
105
+ best_model = grid_search.best_estimator_
106
+ assert isinstance(best_model, ConcreteRandomForestClassifier)
107
+
108
+ best_model.compile(X_train)
109
+
110
+ # Export the final model such that we can reuse it in a client/server environment
111
+
112
+ # Save the model to be pushed to a server later
113
+ from concrete.ml.deployment import FHEModelDev
114
+
115
+ fhe_api = FHEModelDev(dev_folder, best_model)
116
+ fhe_api.save()
117
+
118
+
119
+ if __name__ == "__main__":
120
+ train()