Roman commited on
Commit
1974e22
•
1 Parent(s): 2a040cc

chore: include reshape in FHE execution

Browse files
app.py CHANGED
@@ -187,7 +187,7 @@ def encrypt(user_id, input_image, filter_name):
187
  client = get_client(user_id, filter_name)
188
 
189
  # Pre-process, encrypt and serialize the image
190
- encrypted_image = client.pre_process_encrypt_serialize(input_image)
191
 
192
  # Compute the input's size in Megabytes
193
  encrypted_input_size = len(encrypted_image) / 1000000
 
187
  client = get_client(user_id, filter_name)
188
 
189
  # Pre-process, encrypt and serialize the image
190
+ encrypted_image = client.encrypt_serialize(input_image)
191
 
192
  # Compute the input's size in Megabytes
193
  encrypted_input_size = len(encrypted_image) / 1000000
client_server_interface.py CHANGED
@@ -118,20 +118,17 @@ class FHEClient:
118
  """
119
  return self.client.evaluation_keys.serialize()
120
 
121
- def pre_process_encrypt_serialize(self, input_image):
122
- """Pre-process, encrypt and serialize the input image in the clear.
123
 
124
  Args:
125
- input_image (numpy.ndarray): The image to pre-process, encrypt and serialize.
126
 
127
  Returns:
128
  bytes: The pre-processed, encrypted and serialized image.
129
  """
130
- # Pre-process the image
131
- preprocessed_image = self.filter.pre_processing(input_image)
132
-
133
  # Encrypt the image
134
- encrypted_image = self.client.encrypt(preprocessed_image)
135
 
136
  # Serialize the encrypted image to be sent to the server
137
  serialized_encrypted_image = self.client.specs.serialize_public_args(encrypted_image)
 
118
  """
119
  return self.client.evaluation_keys.serialize()
120
 
121
+ def encrypt_serialize(self, input_image):
122
+ """Encrypt and serialize the input image in the clear.
123
 
124
  Args:
125
+ input_image (numpy.ndarray): The image to encrypt and serialize.
126
 
127
  Returns:
128
  bytes: The pre-processed, encrypted and serialized image.
129
  """
 
 
 
130
  # Encrypt the image
131
+ encrypted_image = self.client.encrypt(input_image)
132
 
133
  # Serialize the encrypted image to be sent to the server
134
  serialized_encrypted_image = self.client.specs.serialize_public_args(encrypted_image)
filters.py CHANGED
@@ -52,7 +52,7 @@ class TorchRotate(nn.Module):
52
  Returns:
53
  torch.Tensor: The rotated image.
54
  """
55
- return x.transpose(2, 3)
56
 
57
 
58
  class TorchConv(nn.Module):
@@ -102,15 +102,26 @@ class TorchConv(nn.Module):
102
  kernel_shape[0],
103
  kernel_shape[1],
104
  )
 
 
105
  else:
106
  raise ValueError(
107
  "Wrong kernel shape, only 1D or 2D kernels are accepted. Got kernel of shape "
108
  f"{kernel_shape}"
109
  )
110
 
 
 
 
 
 
 
111
  # Apply the convolution
112
  x = nn.functional.conv2d(x, kernel, stride=stride, groups=self.groups)
113
 
 
 
 
114
  # Subtract a given threshold if given
115
  if self.threshold is not None:
116
  x -= self.threshold
@@ -212,8 +223,11 @@ class Filter:
212
  # This version's compiler only handles tuples of 1-batch array as inputset, meaning we need
213
  # to define the inputset as a Tuple[np.ndarray[shape=(1, 3, H, W)]]
214
  np.random.seed(42)
 
 
 
215
  inputset = tuple(
216
- np.random.randint(0, 256, size=((1, 3) + INPUT_SHAPE), dtype=np.int64) for _ in range(100)
217
  )
218
 
219
  # Convert the Torch module to a Numpy module
@@ -239,22 +253,6 @@ class Filter:
239
 
240
  return self.fhe_circuit
241
 
242
- def pre_processing(self, input_image):
243
- """Apply pre-processing to the encrypted input images.
244
-
245
- Args:
246
- input_image (np.ndarray): The image to pre-process.
247
-
248
- Returns:
249
- input_image (np.ndarray): The pre-processed image.
250
- """
251
- # Reshape the inputs found in inputset. This is done because Torch and Numpy don't follow
252
- # the same shape conventions.
253
- # Additionally, make sure the input images are made of integers only
254
- input_image = np.expand_dims(input_image.transpose(2, 0, 1), axis=0).astype(np.int64)
255
-
256
- return input_image
257
-
258
  def post_processing(self, output_image):
259
  """Apply post-processing to the encrypted output images.
260
 
@@ -271,10 +269,6 @@ class Filter:
271
  # Clip the image's values to proper RGB standards as filters don't handle such constraints
272
  output_image = output_image.clip(0, 255)
273
 
274
- # Reshape the inputs found in inputset. This is done because Torch and Numpy don't follow
275
- # the same shape conventions.
276
- output_image = output_image.transpose(0, 2, 3, 1).squeeze(0)
277
-
278
  # Gradio requires all images to follow a RGB format
279
  if self.repeat_out_channels:
280
  output_image = output_image.repeat(3, axis=2)
 
52
  Returns:
53
  torch.Tensor: The rotated image.
54
  """
55
+ return x.transpose(0, 1)
56
 
57
 
58
  class TorchConv(nn.Module):
 
102
  kernel_shape[0],
103
  kernel_shape[1],
104
  )
105
+
106
+
107
  else:
108
  raise ValueError(
109
  "Wrong kernel shape, only 1D or 2D kernels are accepted. Got kernel of shape "
110
  f"{kernel_shape}"
111
  )
112
 
113
+ # Reshape the image. This is done because Torch convolutions and Numpy arrays (for PIL
114
+ # display) don't follow the same shape conventions. More precisely, x is of shape
115
+ # (Width, Height, Channels) while the conv2d operator requires an input of shape
116
+ # (Batch, Channels, Height, Width)
117
+ x = x.transpose(2, 0).unsqueeze(axis=0)
118
+
119
  # Apply the convolution
120
  x = nn.functional.conv2d(x, kernel, stride=stride, groups=self.groups)
121
 
122
+ # Reshape the output back to the original shape (Width, Height, Channels)
123
+ x = x.transpose(1, 3).reshape((x.shape[2], x.shape[3], self.n_out_channels))
124
+
125
  # Subtract a given threshold if given
126
  if self.threshold is not None:
127
  x -= self.threshold
 
223
  # This version's compiler only handles tuples of 1-batch array as inputset, meaning we need
224
  # to define the inputset as a Tuple[np.ndarray[shape=(1, 3, H, W)]]
225
  np.random.seed(42)
226
+ # inputset = tuple(
227
+ # np.random.randint(0, 256, size=((1, 3) + INPUT_SHAPE), dtype=np.int64) for _ in range(100)
228
+ # )
229
  inputset = tuple(
230
+ np.random.randint(0, 256, size=(INPUT_SHAPE + (3, )), dtype=np.int64) for _ in range(100)
231
  )
232
 
233
  # Convert the Torch module to a Numpy module
 
253
 
254
  return self.fhe_circuit
255
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  def post_processing(self, output_image):
257
  """Apply post-processing to the encrypted output images.
258
 
 
269
  # Clip the image's values to proper RGB standards as filters don't handle such constraints
270
  output_image = output_image.clip(0, 255)
271
 
 
 
 
 
272
  # Gradio requires all images to follow a RGB format
273
  if self.repeat_out_channels:
274
  output_image = output_image.repeat(3, axis=2)
filters/black and white/deployment/client.zip CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:d715c22a7efedd7e592bc04e4e7f722e2a72de12fadcd526bc2dde6465053d51
3
- size 388
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d29a4e9e982ee241d8add504f07bcf97f4d8a0e9ac829beadca47a776071b529
3
+ size 385
filters/black and white/deployment/server.zip CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:4477689ba8760c3ee2239f25b783cb4629df831fbee9a6fde063b047219a4507
3
- size 4364
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a5c5140caae2aa8da37b2cde5f5fa4d91ad4eab377e026e64f8d85824c615eb7
3
+ size 5740
filters/blur/deployment/client.zip CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:07437fc6167a00e2fc72427254829c466600f5baacaa75abab6d023f07ebd657
3
  size 391
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4ae0e376e218678bda97cc74d9ec982f3bc2d6481de0f1d7ce9fe1aa86bb949f
3
  size 391
filters/blur/deployment/server.zip CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:94ecbd3c5a43abd6864538f92aec8634b1e29191c5f8f5925effc25ae1906213
3
- size 7263
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9743554d7f410d98e8cb2a42419805ee2474f7a7a72d53a0af6878d5ac57ae83
3
+ size 8716
filters/identity/deployment/client.zip CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:0245406eed38f2a0c5f0afdacd5aab3746b5c7f3542f77a1ac2962355d732dbb
3
- size 378
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1e6069504c9bdbee4a7512503f0e0f14540dda5e81f07b8c06945e2fd130e816
3
+ size 376
filters/identity/deployment/server.zip CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:78d4b454bd5fe0d624bacfc9119e18c8c334f9e2db6c83e5f3a212d76a9ea99a
3
- size 2559
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0977f6308e0545c9f46a4a1558e7ac9d8b9768d4a975e6a7b300c87c7aa31eb5
3
+ size 2537
filters/inverted/deployment/client.zip CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:0245406eed38f2a0c5f0afdacd5aab3746b5c7f3542f77a1ac2962355d732dbb
3
- size 378
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1e6069504c9bdbee4a7512503f0e0f14540dda5e81f07b8c06945e2fd130e816
3
+ size 376
filters/inverted/deployment/server.zip CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:d673c0980ec6987ff88b96c8c642082377de4158153a0828430717284575b629
3
- size 4179
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0c896a6ba50a4bdc05f6c2d7681d5bb2bb73455badad095eb89afff81371d851
3
+ size 4152
filters/ridge detection/deployment/client.zip CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:2d27edd60ab1d7186a6053209211922e256e86d9ae223f7056d8932890d3c50e
3
- size 397
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:284b77b3d44bde414f4d5024ed82d3661bb458d5161d4295d95fc093e1d43255
3
+ size 395
filters/ridge detection/deployment/server.zip CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:c3839b27ece3a2bd7caf37a5285674a88abf026c6f8bff550c47a84b4846f0ac
3
- size 5043
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7ff23c15ac778614572e8133436479cad9386ae0ad4a73198ed265e9faee4677
3
+ size 6440
filters/rotate/deployment/client.zip CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:0245406eed38f2a0c5f0afdacd5aab3746b5c7f3542f77a1ac2962355d732dbb
3
- size 378
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1e6069504c9bdbee4a7512503f0e0f14540dda5e81f07b8c06945e2fd130e816
3
+ size 376
filters/rotate/deployment/server.zip CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:3abdc1b55d1c63783b2d081ff67ca47c20b02ae1fd462a6398f7a80318c8529d
3
- size 4431
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a4ff1894d64c954ef5030cc7f09edd1e33502b4a90879c7e1f98e3b00041a458
3
+ size 4387
filters/sharpen/deployment/client.zip CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:21c933a828da907162224c3d13fb1b546316fa0be838ee6ee94659a27302ae67
3
  size 396
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3b724ed4b2985d5bafe983054848abc35479add2fa265f8337336604908a1e62
3
  size 396
filters/sharpen/deployment/server.zip CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:a137527248ec826be5b971f645e80be95c614f82c47225d73fc11d803df93d26
3
- size 7311
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c19c95cdcea6a43e45a06370f67bd770f55e41757d0c85ca6815b56d704c2a92
3
+ size 8735