TF Encrypted是TensorFlow中一个用于加密机器学习的框架,它看起来和感觉上都很像TensorFlow,利用了Keras API 的易用性,同时通过安全多方计算和同态加密实现了对加密数据的训练和预测。TF Encrypted的目标是使保护隐私的机器学习变得可用,而不需要密码学、分布式系统或高性能计算方面的专业知识。
同时,现在TF Encrypted已经完全支持tensorflow2,使代码更加清晰明了。
tf-encrypted最直接的安装方式:
pip install tf-encrypted
但是这个方式已经不能用了,会出现报错,比如:
'NoneType' object has no attribute 'secure_seed'
取而代之的方式是直接git clone这个仓库,流程如下:
安装python版本为3.8的conda环境
conda create -n tfe python=3.8
激活环境
conda activate tfe
下载tf-encrypted仓库
git clone https://github.com/tf-encrypted/tf-encrypted.git
进入tf-encrypted仓库
cd tf-encrypted
安装所需依赖包
pip install -e .
需要注意:tensorflow版本必须>=2.9.1,否则可能出现如下报错:
ImportError: cannot import name 'glob_stateful_parallelism' from 'tensorflow.python.ops.while_v2'
编译tf-encrypted仓库
make build
执行后会先下载一个压缩包,如果执行太慢,可以尝试手动执行下载:
curl -ol https://github.com/jedisct1/libsodium/archive/1.0.17.tar.gz
编译到最后可能出现如下问题:
原因就是系统中g++的版本过低,需要升级,以至少支持g++14版本。
加载tf-encrypted库
由于此时我们没有在Python环境中安装tf-encrypted,因此需要手动载入这个库:
sys.path.append('/home/zwx/tf-encrypted')
import tf_encrypted as tfe
官网提供的矩阵乘法示例
import tensorflow as tf
import sys
sys.path.append('/home/zwx/tf-encrypted')
import tf_encrypted as tfe
@tfe.local_computation('input-provider')
def provide_input():
# normal TensorFlow operations can be run locally
# as part of defining a private input, in this
# case on the machine of the input provider
return tf.ones(shape=(2, 5))
# provide inputs
w = tfe.define_private_variable(tf.ones(shape=(5, 3)))
print('w:', w)
print('w_plaintext:', w.reveal(), '\n', w.reveal().to_native())
x = provide_input()
print('x:', x)
print('x_plaintext:', x.reveal(), '\n', x.reveal().to_native())
# eager execution
y = tfe.matmul(x, w)
res = y.reveal().to_native()
# build graph and run graph
@tfe.function
def matmul_func(x, w):
y = tfe.matmul(x, w)
print('y_ciphertext:', y)
return y.reveal().to_native()
res = matmul_func(x, w)
print('res:\n', res)
代码重点:
官网提供的简单神经网络示例
import tensorflow as tf
import sys
sys.path.append('/home/zwx/tf-encrypted')
import tf_encrypted as tfe
@tfe.local_computation('prediction-client')
def provide_input():
# normal TensorFlow operations can be run locally
# as part of defining a private input, in this
# case on the machine of the input provider
return tf.ones(shape=(5, 10))
x = provide_input()
model = tfe.keras.Sequential([
tfe.keras.layers.Dense(512, batch_input_shape=x.shape),
tfe.keras.layers.Activation('relu'),
tfe.keras.layers.Dense(10),
])
# get prediction input from client
logits = model(x)
result = logits.reveal()
print('result:', result, '\n', result.to_native())
在/examples/benchmark/inference文件中给出了隐私推理的示例。
首先进入tf-encrypted的根目录下(因为跑推理的脚本里需要tf_encrypted.player
):
cd /tf-encrypted
然后执行命令跑基于协议的模型推理:
./examples/benchmark/inference/run-remote.sh resnet50 --protocol ABY3 --config ./examples/benchmark/inference/config.json
注意路径要正确,不然是跑不通的!
参数选择:
model_name: resnet50, densenet121, vgg19
protocol: ABY3, Pond, SecureNN
precision: 64-bit by default (可以改成high使用128-bit)
config: IP的配置(感觉暂时不用管)
执行命令,可以得到这6个文件:
不过,可能会遇到如下的报错:
attr {
key: "explicit_paddings"
value {
list {
}
}
}
raise ValueError(
ValueError: Could not infer attribute explicit_paddings type from empty iterator
不用着急,这个问题是框架在转tf模型时出现的onnx库错误,通过查阅tensorflow-onnx官方文档,知道了这个问题的原因是onnx版本过高的问题。
解决方案:将onnx版本降级到1.14.1即可:pip install onnx==1.14.1
再次执行推理命令,可以在log_master.txt中看到如下的输出日志信息:
从这个日志文件中能得到什么信息?