SPDZ基础使用手册(深度学习视角)

基本类型

深度学习中最常使用的便是秘密定点数sfix,有关定点数的高级运算协议请参阅Paper: Secure Computation With Fixed-Point Numbers.

容器类型

SPDZ的深度学习框架主要基于TensorFlow实现,其中使用的容器是张量Tensor,在库中的定义如下:

def Tensor(cls, shape):
    """
    Type-dependent tensor of any dimension::

        a = sfix.Tensor([10, 10])
    """
    if len(shape) == 1:
        return Array(shape[0], cls)
    else:
        return MultiArray(shape, cls)

可以看出使用Tensor在大多数情况就是在使用MultiArray,类比Python基础类型的多维列表。

这里举一个例子:

a = sint.Tensor([3, 10, 10])    #创建张量,类型为sint,内容是3个10×10的矩阵
a[0].input_from(0)    #第一个矩阵从第0方读取数据
a[1].input_from(1)    #第二个矩阵从第1方读取数据
a[2][:] = a[0][:] * a[1][:]    #第三个矩阵由前两个矩阵元素对应相乘实现;[:] 表示选择这个矩阵的所有元素。

MultiArray的其它用法

assign(other, base=0)

        Assign container to content. Not implemented for floating-point.

                Parameters other – container of matching size and type

assign_all(value)

        Assign the same value to all entries.

                Parameters value – convertible to relevant basic type

assign_part_vector(vector, base=0)

        Assign vector from range of the first dimension, including all entries in further dimensions.

                Parameters

                        • vector – updated entries

                        • base – index in first dimension (regint/cint/int)

assign_vector(vector, base=0)

               Assign vector to content. Not implemented for floating-point.

                Parameters

                                • vector – vector of matching size convertible to relevant basic type

                                • base – compile-time (int)

direct_mul(other, reduce=True, indices=None, res_type=None)

        Matrix multiplication in the virtual machine. Unlike dot(), this only works for sint and sfix, and it returns a vector instead of a data structure.

                Parameters

                        • self Matrix / 2-dimensional MultiArray

                        • other Matrix / 2-dimensional MultiArray

                        • indices – 4-tuple of regint vectors for index selection (default is complete multiplication)

                Returns Matrix as vector of relevant type (row-major)

PS: 不常用,因为泛用性很差,只能针对二维数组;也是库里自带函数的通病,以至于很多tf的很多高级函数在库中都是不存在的。

dot(other, res_params=None, n_threads=None)

        Matrix-matrix and matrix-vector multiplication.

                Parameters

                • self – two-dimensional

                • other – Matrix or Array of matching size and type

                • n_threads – number of threads (default: all in same thread)

        Return type Matrix or Array of appropriate size and type

input_from(player, budget=None, raw=False, **kwargs)

        Fill with inputs from player if supported by type.

                Parameters player – public (regint/cint/int)

randomize(*args, n_threads=None)

        Randomize according to data type. If it is sfix, the following will sample an individual         uniformly random entry of the multi-array M roughly in the range [𝑎, 𝑏]:

M.randomize(a, b)

reveal()

        Reveal to MultiArray of same shape.

reveal_list()

        Reveal as list.

sort(key_indices=None, n_bits=None)

        Sort sub-arrays (different first index) in place. This uses radix sort.

                Parameters

                        • key_indices – indices to sorting keys, for example (1, 2) to sort three-dimensional array a by keys a[*][1][2]. Default is (0, ..., 0) of correct length.

                        • n_bits – number of bits in keys (default: global bit length)

…………

重要模块 - Compiler.library 

Compiler.library.do_while(loop_fn, g=None)

        Do-while loop. The loop is stopped if the return value is zero. It must be public. The following executes exactly once:

@do_while
def _():
    ...
    return regint(0)

Compiler.library.for_range(start, stop=None, step=None)

        Decorator to execute loop bodies consecutively. Arguments work as in Python range(), but         they can be any public integer. Information has to be passed out via container types such as         Array or using update(). Note that changing Python data structures such as lists within the         loop is not possible, but the compiler cannot warn about this.

                Parameters start/stop/step – regint/cint/int

PS: 勘误-默认参数应为stop,同Python中的 for i in range(stop)。

例:The following should output 10:

n = 10
a = sint.Array(n)
x = sint(0)
@for_range(n)
def _(i):
    a[i] = i
    x.update(x + 1)
print_ln('%s', x.reveal())

其它函数详情请参阅SPDZ手册。

…………

重要模块 - Compiler.mpc_math 

这块其实没啥好说的,库中都已经给了各种数学运算,直接调用就好,原理可以参阅源代码或相关论文。

重要模块 - Compiler.ml 

这块是使用SPDZ框架实现深度学习的关键,手册中直接举了几个机器学习的例子和现成的深度学习的例子,紧接着便是具体类的基和参数介绍。我们以一个深度学习的具体代码为例进行介绍。

# this trains a dense neural network on MNIST
# see https://github.com/csiro-mlai/mnist-mpc for data preparation
# 该代码在根目录的Programs/Source中

program.options_from_args()    #表示程序可以从外界(终端)获取输入

#SPDZ在0.3.7版本后有了torch导入数据的功能
if 'torch' in program.args:
    import torchvision
    data = []
    for train in True, False:
        ds = torchvision.datasets.MNIST(root='/tmp', train=train, download=True)
	# normalize to [0,1] before input
        samples = sfix.input_tensor_via(0, ds.data / 255., binary=True)
        labels = sint.input_tensor_via(0, ds.targets, binary=True, one_hot=True)
        data += [(labels, samples)]

    (training_labels, training_samples), (test_labels, test_samples) = data

#这里是正常读取处理好的数据集的方法
else:
    training_samples = sfix.Tensor([60000, 28, 28])    #为样本与标签设置存储结构
    training_labels = sint.Tensor([60000, 10])

    test_samples = sfix.Tensor([10000, 28, 28])
    test_labels = sint.Tensor([10000, 10])

    training_labels.input_from(0)    #读入数据,在根目录的Player-Data/Input-P0-0
    training_samples.input_from(0)

    test_labels.input_from(0)
    test_samples.input_from(0)    #注意导入的顺序

from Compiler import ml
tf = ml

#构建网络层,这里的层都是库中写好的,用法同tf
layers = [
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(128),
    tf.keras.layers.Activation('relu'),
    tf.keras.layers.Dense(10,  activation='softmax')
]

model = tf.keras.models.Sequential(layers)    #构建模型

optim = tf.keras.optimizers.SGD(momentum=0.9, learning_rate=0.01)    #选择优化器,设置参数

model.compile(optimizer=optim)    #编译

#Train model.
opt = model.fit(
    training_samples,
    training_labels,
    epochs=1,
    batch_size=128,
    validation_data=(test_samples, test_labels)
)

#Use model for prediction
guesses = model.predict(test_samples)

这是一段训练预测一体的代码,单独训练与预测也是可以的,只需要修改最后的代码。

目前使用这种模式的代码只可实现库中训练、库中保存秘密模型、使用库中训练好的模型预测,非常的不灵活;库中还提供了另一种模式的代码:

# this trains network D from SecureNN
# see https://github.com/csiro-mlai/mnist-mpc for data preparation
# 该代码在根目录的Programs/Source中

import ml
import math
import re
import util    #这里引用的应是Compiler中的包

program.options_from_args()
sfix.set_precision_from_args(program, True)
MultiArray.disable_index_checks()

#设置特征和标签数量
if 'profile' in program.args:
    print('Compiling for profiling')
    N = 1000
    n_test = 100
elif 'debug' in program.args:
    N = 100
    n_test = 100
elif 'debug1000' in program.args:
    N = 1000
    n_test = 1000
elif 'debug5000' in program.args:
    N = 5000
    n_test = 5000
else:
    N = 60000
    n_test = 10000

#deep-mpc库中有预处理数据集的方法,默认就是N = 60000,n_test = 10000
n_examples = N
n_features = 28 ** 2

try:    #设置轮数
    n_epochs = int(program.args[1])
except:
    n_epochs = 100

try:    #设置batch大小
    batch_size = int(program.args[2])
except:
    batch_size = N

assert batch_size <= N
ml.Layer.back_batch_size = batch_size

try:    #设置线程数
    ml.set_n_threads(int(program.args[3]))
except:
    pass

if program.options.ring:
    assert sfix.f * 4 == int(program.options.ring)

if 'stride1' in program.args:    #设置步长
    stride = (1, 1)
else:
    stride = (2, 2)

if 'valid' in program.args:    #设置padding方式
    padding = 'VALID'
    inner_dim = (28 - 4) // stride[0]
else:
    padding = 'SAME'
    inner_dim = 28 // stride[0]

layers = [    #层
    ml.FixConv2d([N, 28, 28, 1], (5, 5, 5, 1), (5,),
                 [N, inner_dim, inner_dim, 5], stride, padding),
    ml.Relu([N, inner_dim, inner_dim, 5]),
]

#填充层
if 'maxpool' in program.args:
    layers += [ml.MaxPool((N, inner_dim, inner_dim, 5))]
    inner_dim //= 2

n_inner = inner_dim ** 2 * 5

dropout = 'dropout' in program.args

if '1dense' in program.args:
    if dropout:
        layers += [ml.Dropout(N, n_inner)]
    layers += [ml.Dense(N, n_inner, 10),]
elif '2dense' in program.args:
    if dropout:
        layers += [ml.Dropout(N, n_inner)]
    layers += [
        ml.Dense(N, n_inner, 100),
        ml.Relu([N, 100]),
        ml.Dense(N, 100, 10),
    ]
    if dropout or 'dropout1' in program.args:
        layers.insert(-1, ml.Dropout(N, 100))
else:
    raise Exception('need to specify number of dense layers')

layers += [ml.MultiOutput(N, 10)]

Y = sint.Matrix(n_test, 10)    #存储测试集标签
X = sfix.Matrix(n_test, n_features)    #存储测试集特征

if not ('no_acc' in program.args and 'no_loss' in program.args):
    layers[-1].Y.input_from(0)    #读取训练集标签
    layers[0].X.input_from(0)    #读取训练集特征
    Y.input_from(0)    #读取测试集标签
    X.input_from(0)    #读取测试集特征

optim = ml.Optimizer.from_args(program, layers)    #外部读入优化器
optim.run_by_args(program, n_epochs, batch_size, X, Y)    #训练

FixConv2d参数:(input_shape, weight_shape, (out_channels,), output_shape, stride, padding)
#weight_shape:过滤器大小,就是滑动的那个框

Relu参数:([N, d, d_out])

MaxPool参数:(input_shape, pool_size, strides, padding))

Dense参数:(N, d_in, d_out)

Dropout参数:(N, d1, d2=1, alpha=0.5)       
#d1: 总维度,这通常表示特定层输入或输出的特征数量或维度。
#d2: 另一个维度,默认值为1。在某些场景下,如当需要将数据处理为三维结构(例如,在处理时间序列数据或具有多个特征映射的卷积层输出时),这个参数变得有用。
#alpha: 概率(必须是2的幂),表示每个神经元被置零的概率。默认值是0.5,意味着在每次前向传播时,有50%的概率每个神经元的输出会被置为0。

MultiOutput参数:(N, d_out)        #这一般就是最后一层了,d_out是最终分类数目

优化器

class Compiler.ml.Optimizer(layers=[], report_loss=None)

        Bases: object

        Base class for graphs of layers.

        backward(**kwargs)

                Compute backward propagation.

        eval(**kwargs)

                Compute evaluation after training.

                        Parameters

                                • data – sample data (Compiler.types.Matrix with one row per sample)

                                • top – return top prediction instead of probability distribution

                        Returns sfix/sint Array (depening on top)

class Compiler.ml.SGD(layers, n_epochs=1, debug=False, report_loss=None)

        Bases: Compiler.ml.Optimizer

        Stochastic gradient descent.

                Parameters

                        • layers – layers of linear graph

                        • n_epochs – number of epochs for training

                        • report_loss – disclose and print loss

        backward(**kwargs)

                Compute backward propagation.

        eval(**kwargs)

                Compute evaluation after training.

                Parameters

                        • data – sample data (Compiler.types.Matrix with one row per sample)

                        • top – return top prediction instead of probability distribution

                Returns sfix/sint Array (depening on top)

run/run_in_batches/run_by_args 皆是进行训练,通过run_by_args的参数可知,顺便它也能进行预测。(源码太长不再放这里了,仅简单介绍一下整个函数:)

run_by_args(self, program, n_runs, batch_size, test_X, test_Y,
                    acc_batch_size=None)

主要逻辑和功能 - run_by_args

  1. 参数解析: 方法首先解析program.args中的参数,如学习率(gamma), 折旧率(depreciation), 动量(momentum), 是否打印损失(print_losses)等。

  2. 动态配置: 根据提供的参数动态调整训练和评估配置,如是否使用动量(nomom), 是否记录每层的时间(time_layers), 是否在训练之前首先进行模型评估(acc_first), 以及是否对卷积操作进行特定的处理(full_cisc).

  3. 训练和评估: 根据n_runs参数指定的次数,执行训练循环。在每次循环中,根据配置执行前向传播(forward), 反向传播(backward), 和参数更新(update). 如果设置了测试集(test_Xtest_Y), 也会执行测试集上的评估,并计算准确率和损失。

  4. 特殊条件处理: 支持特殊的命令行参数来执行一些特定操作,如one_iter用于执行一次完整的前向和反向传播并打印权重,bench1bench10用于性能基准测试。

  5. 学习率调整: 如果检测到模型发散(crash)或准确率低于阈值,学习率(gamma)会减半以尝试恢复训练。此外,如果设置了折旧率(depreciation), 学习率将按该比率递减。

  6. 输出权重: 如果指定了model_output, 最后会输出模型的权重。

注意:这种模式的代码编译时要加额外的参数,具体的参数请参阅csiro-mlai/deep-mpc (github.com)中的common.sh第69行。这里给一个具体的例子:

#原运行命令
./run-local.sh emul D prob 2 2 64    
 
#实际编译命令(实际上原命令包括编译与运行)
python3 ./compile.py -R 64 -K '' -CD mnist_full_D 2 128 2 trunc_pr f64 k127 2dense | grep -v WARNING   

(未完待续)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/498375.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

高等数学基础篇(数二)之微分方程常考题型

常考题型&#xff1a; 一、方程求解 二、综合题 三、应用题 目录 一、方程求解 二、综合题 三、应用题 一、方程求解 二、综合题 三、应用题

springcloud微服务项目,通过gateway+nacos实现灰度发布(系统不停机升级)

一、背景 灰度发布的目的是保证系统的高可用&#xff0c;不停机&#xff0c;提升用户体验。在微服务系统中&#xff0c;原有系统不下线&#xff0c;新版系统与原有系统同时在线&#xff0c;通过访问权重在线实时配置&#xff0c;可以让少量用户先应用新版本功能&#xff0c;如…

excel 提取数字字符混合文本中的数字(快捷键ctrl+e)

首先&#xff0c;已知A列数据&#xff0c;在B1单元格输入A列中的数据&#xff0c;如3*4*6 第二部&#xff1a;全选对应的B列&#xff0c;然后&#xff1a; ctrld 批量复制 CTRLE 智能复制 由此可见&#xff0c;智能提取汉字与数字混合中的数字方法 。若想分别提取3个数字&am…

量化交易入门(二十六)RSI指标实现,能盈利吗?

RSI的理论学完了&#xff0c;我们接着用苹果股票的历史数据来回测一下&#xff0c;看看这个指标靠不靠谱。 示例代码 import backtrader as bt import yfinance as yf# 定义RSI策略 class RSIStrategy(bt.Strategy):params ((rsi_period, 14),(rsi_upper, 70),(rsi_lower, 30…

新手体验OceanBase社区版V4.2:离线部署单节点集群

本文源自OceanBase用户的分享 先简单总结如下&#xff1a; 1.本文适合初学者体验OceanBase社区版 v4.2.2 2.仅需准备一台配置为2C/8G的Linux虚拟机 3.通过离线方式安装&#xff0c;以便更直观地了解安装过程 一、Linux系统准备 在宿主机(即你的windows PC电脑)上安装vbox软…

李宏毅【生成式AI导论 2024】第5讲 让语言模型彼此合作,把一个人活成一个团队

GPD4,它也有非常强大的能力。但是GPT4如果跟其他的语言模型合作,他们其实可以发挥1加1大于二的力量。 为什么要让模型合作? 那怎么让模型彼此合作呢?有很多不同的方式。一个可能性是假设你现在手边就有一堆语言模型,他们可能有不同的能力使用,他们可能有不同的成本局来…

如何将几个长度相同的列表并列组合在一起(附:zip函数使用出错原因:巨坑~)

Python中列表对象使用很方便&#xff0c;用Python编程时&#xff0c;经常会遇到将多个长度相同的列表是针对某一组特定对象的&#xff0c;如何能方便的把这些列表组合起来一起使用呢&#xff1f;ZIP()函数可以方便的解决这个问题。 一、将几个长度相同的列表并列组合 例如&am…

2014年认证杯SPSSPRO杯数学建模B题(第二阶段)位图的处理算法全过程文档及程序

2014年认证杯SPSSPRO杯数学建模 B题 位图的处理算法 原题再现&#xff1a; 图形&#xff08;或图像&#xff09;在计算机里主要有两种存储和表示方法。矢量图是使用点、直线或多边形等基于数学方程的几何对象来描述图形&#xff0c;位图则使用像素来描述图像。一般来说&#…

3D产品可视化SaaS

“我们正在走向衰退吗&#xff1f;” “我们已经陷入衰退了吗&#xff1f;” “我们正在步入衰退。” 过去几个月占据头条的问题和陈述引发了关于市场对每个行业影响的讨论和激烈辩论。 特别是对于科技行业来说&#xff0c;过去几周一直很动荡&#xff0c;围绕费用、增长和裁…

1.8 python 模块 time、random、string、hashlib、os、re、json

ython之模块 一、模块的介绍 &#xff08;1&#xff09;python模块&#xff0c;是一个python文件&#xff0c;以一个.py文件&#xff0c;包含了python对象定义和pyhton语句 &#xff08;2&#xff09;python对象定义和python语句 &#xff08;3&#xff09;模块让你能够有逻辑地…

Tomcat 单机多实例一键安装

文章目录 一、场景说明二、脚本职责三、参数说明四、操作示例五、注意事项 一、场景说明 本自动化脚本旨在为提高研发、测试、运维快速部署应用环境而编写。 脚本遵循拿来即用的原则快速完成 CentOS 系统各应用环境部署工作。 统一研发、测试、生产环境的部署模式、部署结构、…

Linux安装redis(基于CentOS系统,Ubuntu也可参考)

前言&#xff1a;本文内容为实操记录&#xff0c;仅供参考&#xff01; 一、下载并解压Redis 1、执行下面的命令下载redis&#xff1a;wget https://download.redis.io/releases/redis-6.2.6.tar.gz 2、解压redis&#xff1a;tar xzf redis-6.2.6.tar.gz 3、移动redis目录&a…

D. Friends and Subsequences 线段树上二分

有个细节&#xff0c;就是query的时候的顺序&#xff0c;不注意到直接T飞&#xff0c;分析知道如果它只在一边的话你直接一边 可以保证复杂度 #include<iostream> #include<cstring> #include<algorithm>const int N 2e510; using namespace std; using ll…

MySQL 数据库的日志管理、备份与恢复

一. 数据库备份 1.数据备份的重要性 备份的主要目的是灾难恢复。 在生产环境中&#xff0c;数据的安全性至关重要。 任何数据的丢失都可能产生严重的后果。 造成数据丢失的原因&#xff1a; 程序错误人为,操作错误,运算错误,磁盘故障灾难&#xff08;如火灾、地震&#xff0…

比较AI编程工具Copilot、Tabnine、Codeium和CodeWhisperer

主流的几个AI智能编程代码助手包括Github Copilot、Codeium、Tabnine、Replit Ghostwriter和Amazon CodeWhisperer。 你可能已经尝试过其中的一些&#xff0c;也可能还在不断寻找最适合自己或公司使用的编程助手。但是&#xff0c;这些产品都会使用精选代码示例来实现自我宣传…

Vue挂载全局方法

简介&#xff1a;有时候&#xff0c;频繁调用的函数&#xff0c;我们需要把它挂载在全局的vue原型上&#xff0c;方便调用&#xff0c;具体怎么操作&#xff0c;这里来记录一下。 一、这里以本地存储的方法为例 var localStorage window.localStorage; const db {/** * 更新…

如何在 Mac Pro 上恢复丢失的数据?

无论您多么努力&#xff0c;几乎不可能永远不会无意中删除 Mac 上的文件。当您得知删除后清空了垃圾箱时&#xff0c;您的处境可能看起来很黯淡。不要灰心。我们将教您如何使用本机操作系统功能或数据恢复工具恢复丢失的数据。奇客数据恢复Mac版可帮助恢复已从 Mac Pro 计算机上…

npm救赎之道:探索--save与--save--dev的神秘力量!

目录 1. --save和--save-dev是什么&#xff1f;2. 区别与应用场景--save--save-dev 3. 生产环境与开发环境4. 实际应用示例--save--save-dev 5. 总结 在现代软件开发中&#xff0c;npm&#xff08;Node Package Manager&#xff09;扮演着不可或缺的角色&#xff0c;为开发者提…

Java八股文(JVM)

Java八股文のJVM JVM JVM 什么是Java虚拟机&#xff08;JVM&#xff09;&#xff1f; Java虚拟机是一个运行Java字节码的虚拟机。 它负责将Java程序翻译成机器代码并执行。 JVM的主要组成部分是什么&#xff1f; JVM包括以下组件&#xff1a; ● 类加载器&#xff08;ClassLoa…

HTTP状态 405 - 方法不允许

方法有问题。 用Post发的请求&#xff0c;然后用Put接收的。 大家也可以看看是不是有这种问题 <body><h1>HTTP状态 405 - 方法不允许</h1><hr class"line" /><p><b>类型</b> 状态报告</p><p><b>消息…