Code: Select all
def calculate_sensitivity(image: np.ndarray) -> float:
if image.ndim > 1:
d = image.flatten()
else:
d = image
d_f = np.mean(d)
deviations_of_d = np.abs(d - d_f)
furthest_of_d = np.max(deviations_of_d)
argmax_furthest_of_d = np.where(deviations_of_d == furthest_of_d)[0][0]
dprime = np.delete(d, argmax_furthest_of_d)
dprime_f = np.mean(dprime)
return abs(d_f - dprime_f)
def apply_noise(image: np.ndarray, epsilon: float) -> np.ndarray:
image = image.flatten()
sensibility = calculate_sensitivity(image)
b = sensibility / epsilon
noise = np.random.laplace(0, b, image.shape)
output = image + noise
clip_output = np.clip(output, 0, 1) # -1, 1 for facenet
return clip_output.reshape((160, 160, 3))
Bilder mit Rauschen bei unterschiedlichen Epsilon-Werten
Ich denke, es funktioniert, bin mir aber nicht ganz sicher, ob es der richtige Ansatz ist. Ich wende Rauschen auf ein Bild mit mehr als einem Kanal an und verwende die Funktion flatten(), um die Empfindlichkeit des Bildes einfacher zu berechnen. Später verwende ich die Funktion reshape(), um das Bild wieder in seine ursprüngliche Form zu bringen. Ist das richtig? Oder sollte ich das Rauschen auf jeden Kanal einzeln anwenden?
Selbst wenn ich das Rauschen auf jeden Kanal einzeln anwenden würde, müsste ich das Bild dann nicht reduzieren? Zum Beispiel ein Bild mit (C, H, W) = (3, 160, 160). Wenn ich das Rauschen auf jeden Kanal anwende, müsste ich immer noch die Höhe und Breite reduzieren. Das Problem wäre also dasselbe.
Meine Referenz zum Thema Datenschutz ist dieses Video und dieser Artikel. In dem Artikel verwenden sie Gaußsches Rauschen, aber ich habe den Laplace-Operator wegen seiner Einfachheit gewählt.

Mit diesem Code möchte ich eine Pipeline ähnlich der im Artikel beschriebenen implementieren, bei der ich eine differenziell private Blockfunktion zwischen zwei Faltungsblöcken einfüge, um sie zu erstellen den Datensafe. Die verrauschten Bilder oben wurden einfach durch die Summe des Rauschens zum Tensor des Bildes erzeugt, wie in der Zeile „Ausgabe = Bild + Rauschen“.
Das Problem ist: Ich habe das Rauschen zum abgeflachten Tensor hinzugefügt und ihn dann in seine ursprüngliche Form umgeformt. Aber bleibt bei dieser Umgestaltung der ursprüngliche Raum erhalten? Wie garantiere ich zum Beispiel, dass in der Eingabe [[1, 2],[3, 4]] abgeflacht wird -> [1, 2, 3, 4] die Ausgabe umgeformt wird -> [[1,2],[3,4]] und die Ausgabe nicht umgeformt wird [[4,3][2,1]].
Es stellt sich auch die Frage, ob mein Code tatsächlich den DP-Algorithmus implementiert
Mobile version