【阅读笔记】联邦学习实战第5章——用FATE从零实现横向逻辑回归v1.8.0

目录

前言

1.Dock镜像部署FATE

1.1 安装Centos和虚拟机

1.2 安装Docker 和 Docker-compose

1.3 FATE安装

2.FATE编程范式

3.用FATE实现横向逻辑回归

3.1数据集获取

3.2 数据输入

数据转化配置文件

3.3 模型训练与评估

总结

参考链接


前言

FATE不过多介绍,本文主要是对《联邦学习实战》第五章的一个复现,由于书里面的FATE应该是v1.5.0之前的版本,现在FATE最新版已经是v1.8.0,一些路径,以及组件化配置的方式发生了改变,而且文中的方法是利用train_data去训练模型,同时也用train_data去评估模型,我们也在这里加了用test_data去评估模型的模块。

下面给出了跟FATE有关的三个网站,十分重要:

FATE官方网站

github

FATE文档

1.Dock镜像部署FATE

FATE支持Linux和Mac系统,支持单机部署、集群部署和KubeFATE部署三种方式,具体的部署安装请查看FATE的官方文档,对于Windows10系统,需要用虚拟机部署FATE,这里提供利用Docker镜像配置FATE单机部署的方法。

1.1 安装Centos和虚拟机

首先要安装Centos 7 的虚拟机,需要虚拟机的软件VMware,和Centos7的镜像文件。其中VM和Centos7都可以从网上下载。这里面推荐大家看这篇文章VMware16 的安装。

1.2 安装Docker 和 Docker-compose

这里直接提供两篇文章参考,没什么难度,按照提示操作即可,注意别开科学上网。

CentOS7 搭建Docker环境

centos7 部署docker-compose

1.3 FATE安装

官方文档:FATE单机部署指南

# 部署环境变量
export version=1.8.0

# 拉取镜像
wget https://webank-ai-1251170195.cos.ap-guangzhou.myqcloud.com/fate/${version}/release/standalone_fate_docker_image_${version}_release.tar.gz
docker load -i standalone_fate_docker_image_${version}_release.tar.gz
docker images | grep federatedai/standalone_fate

# 启动镜像
docker run -d --name standalone_fate -p 8080:8080 federatedai/standalone_fate:${version};
docker ps -a | grep standalone_fate

# 进入容器
docker exec -it $(docker ps -aqf "name=standalone_fate") bash

官方文档里有教如何测试是否安装成功的:

Toy测试:

flow test toy -gid 10000 -hid 10000

如果成功,会出现如下语句:

success to calculate secure_sum, it is 2000.0

单元测试

fate_test unittest federatedml --yes

如果成功,屏幕显示类似下方的语句:

there are 0 failed test

注意:可能由于版本变化,或者其他原因,我的v1.8.0的单元测试是会报错的,但不影响后续FATE的使用。

2.FATE编程范式

这个算是使用FATE的重点,我们主要介绍下组件化配置。

FATE构建联邦学习模型有两种不同编程范式

  • 组件化配置:模型训练拆分为不同的任务,每个任务以组建的形式通过有向无环图相连,联邦学习所需的配置参数在配置文件中定义。该模式中,用户只需自定义和提交配置文件,就可以直接执行联邦训练。

  • 脚本编程:FATE提供API接口,用户通过脚本编程的方式实现联邦模型,类似直接使用Python编程。

组件化配置文件:

  • dsl配置文件:FATE内置的一套自定义领域特定语言,在dsl中,常见的机器学习任务划分为不同的模块,如数据读写、模型训练、模型评估可以通过一个有向无环图连接。

  • conf配置文件:设置dsl中组件模块的参数。

这里详细介绍下DSL配置文件:

DSL配置文件主要由组件名,模块,输入,输出,是否需要部署等构成:

  • component_name:一个组件的名称,后缀以下划线加数字方式,例如dataio_0,通常数字都以0开始

  • module:FATE支持的算法模块中可选项,选择其中一个(Dataio,Intersect,Federated sampling,Feature scale,Hetero Feature Binning,Onehout encoder,Hetero feature selection,union,Hetero-lr,local baseline,Hetero-LinR,Hetero-Poisson,Homo-LR,Homo-NN,Hetero Secure Boosting,Evaluation,Hetero Pearson,Hetero-NN)

  • input:有两种类型的输入:一种是data(数据),一种是model(模型)。 data又分为三类:1. 普通数据。用于dataio,feature_engineering和evaluation的;2. 训练数据 。主要使用于一些逻辑回归模型中(如homo_lr,hetero_lr,secure_boost) ;3. 测试评估数据。如果训练数据指定了,将会被作为测试集,如果训练数据没有制定,将会被作为预测或转换任务

  • output:同样和输入一样有两种类型的输出:一种是data(数据),一种model(模型)

3.用FATE实现横向逻辑回归

由于FATE版本发生改变,所以与FATE操作的相关代码,配置文件都发生了改变,下面会介绍与书中不一样的地方。

3.1数据集获取

数据选取sklearn库中内置乳腺癌肿瘤数据集,这里面附下代码

from sklearn.datasets import load_breast_cancer
import pandas as pd
# 导入并查看数据
breast_dataset = load_breast_cancer()
breast = pd.DataFrame(breast_dataset.data, columns=breast_dataset.feature_names)
breast.head()
# z-score标准化
breast = (breast-breast.mean()) / (breast.std())
# 获取列名
col_names = breast.columns.values.tolist()
# 更换列名
columns = {}
for idx, n in enumerate(col_names):
    columns[n] = "x%d"%idx
breast = breast.rename(columns=columns)
# 插入每行序列和y
breast['y'] = breast_dataset.target
idx = range(breast.shape[0])
breast.insert(0, 'idx', idx)
# 打乱数据并生成csv
breast = breast.sample(frac=1)
train = breast.iloc[:469]
eval =  breast.iloc[469:]
breast_1_train = breast.iloc[:200]
breast_2_train = breast.iloc[200:]
breast_1_train.to_csv('breast_1_train.csv', index=False, header=True)
breast_2_train.to_csv('breast_2_train.csv', index=False, header=True)
eval.to_csv('breast_eval.csv', index=False, header=True)

3.2 数据输入

由于FATE所有运算都基于DTable格式进行,所以要把数据上传到虚拟机相关路径($fate_dir/examples/data/)下,且把文件转换为DTable。

# 基目录
fate_dir=/data/projects/fate/

# 使用rz上传
$ rz -be

这里面是使用rz上传的,不会的可以百度一下,直接下载相关包也可以,我是通过xshell远程连接的,可以百度下xshell的连接方法

yum install lrzsz 

数据转化配置文件

  • examples/dsl/v2/upload

需要更改配置文件中的file,table_name,namespace,然后分别上传四个数据文件,A公司训练集、测试集,B公司训练集、测试集

{
    "file": "/data/projects/fate/examples/data/breast_eval.csv",  // 数据文件路径,相对于当前所在路径
    "head": 1,  // 指定数据文件是否包含表头,1: 是,0: 否
    "partition": 8, // 指定用于存储数据的分区数
    "work_mode": 0,  // 指定工作模式,0: 单机版,1: 集群版
    "table_name": "homo_breast_2_eval", // 需要转换为DTable格式的表名(相当于后续需要使用的表)
    "namespace": "homo_guest_breast_eval"  // DTable格式的表名对应的命名空间
}

配置文件如下:

  • 上传训练数据到公司A
{
    "file": "/fate/example/data/breast_1_train.csv",
    "head": 1,
    "partition": 8,
    "work_mode": 0,
    "table_name": "homo_breast_1_train",
    "namespace": "homo_host_breast_train"
}
  • 上传训练数据到公司B
{
    "file": "/fate/example/data/breast_2_train.csv",
    "head": 1,
    "partition": 8,
    "work_mode": 0,
    "table_name": "homo_breast_2_train",
    "namespace": "homo_guest_breast_train"
}
  • 上传测试数据到公司A
{
    "file": "/fate/example/data/breast_eval.csv",
    "head": 1,
    "partition": 8,
    "work_mode": 0,
    "table_name": "homo_breast_1_eval",
    "namespace": "homo_host_breast_eval"
}

  • 上传测试数据到公司B
{
    "file": "/fate/example/data/breast_eval.csv",
    "head": 1,
    "partition": 8,
    "work_mode": 0,
    "table_name": "homo_breast_2_eval",
    "namespace": "homo_guest_breast_eval"
}

四个文件分开进行上传,然后在当前路径下输入下方调用代码(v1.8.0版本方法):

flow data upload -c upload_conf.json

出现如下界面即说明成功:

【阅读笔记】联邦学习实战第5章——用FATE从零实现横向逻辑回归v1.8.0_第1张图片

在虚拟机中输入“board_url”的网址,就可以看到FATE-board可视化相关内容:

【阅读笔记】联邦学习实战第5章——用FATE从零实现横向逻辑回归v1.8.0_第2张图片

 可以看到数据上传完成。

3.3 模型训练与评估

书中的版本与v1.8.0完全发生了改变,我们需要重新配置dsl和conf文件,且书中是使用训练集建模,训练集评估,与建模流程不符,我们改变书中流程,使用训练集建模,训练集与测试集分开进行评估。

  • examples/dsl/v2/homo_logistic_regression

homo_lr_train_eval_dsl.json

{
    "components": {
        "reader_0": {
            "module": "Reader",
            "output": {
                "data": [
                    "data"
                ]
            }
        },
        "reader_1": {
            "module": "Reader",
            "output": {
                "data": [
                    "data"
                ]
            }
        },
        "data_transform_0": {
            "module": "DataTransform",
            "input": {
                "data": {
                    "data": [
                        "reader_0.data"
                    ]
                }
            },
            "output": {
                "data": [
                    "data"
                ],
                "model": [
                    "model"
                ]
            }
        },
        "data_transform_1": {
            "module": "DataTransform",
            "input": {
                "data": {
                    "data": [
                        "reader_1.data"
                    ]
                },
                "model": [
                    "data_transform_0.model"
                ]
            },
            "output": {
                "data": [
                    "data"
                ],
                "model": [
                    "model"
                ]
            }
        },
        "scale_0": {
            "module": "FeatureScale",
            "input": {
                "data": {
                    "data": [
                        "data_transform_0.data"
                    ]
                }
            },
            "output": {
                "data": [
                    "data"
                ],
                "model": [
                    "model"
                ]
            }
        },
        "scale_1": {
            "module": "FeatureScale",
            "input": {
                "data": {
                    "data": [
                        "data_transform_1.data"
                    ]
                },
                "model": [
                    "scale_0.model"
                ]
            },
            "output": {
                "data": [
                    "data"
                ],
                "model": [
                    "model"
                ]
            }
        },
        "homo_lr_0": {
            "module": "HomoLR",
            "input": {
                "data": {
                    "train_data": [
                        "scale_0.data"
                    ],
                    "validate_data": [
                        "scale_1.data"
                    ]
                }
            },
            "output": {
                "data": [
                    "data"
                ],
                "model": [
                    "model"
                ]
            }
        },
        "homo_lr_1": {
            "module": "HomoLR",
            "input": {
                "data": {
                    "eval_data": [
                        "scale_1.data"
                    ]
                },
                "model": [
                    "homo_lr_0.model"
                ]
            },
            "output": {
                "data": [
                    "data"
                ],
                "model": [
                    "model"
                ]
            }
        },
        "evaluation_0": {
            "module": "Evaluation",
            "input": {
                "data": {
                    "data": [
                        "homo_lr_0.data"
                    ]
                }
            },
            "output": {
                "data": [
                    "data"
                ]
            }
        },
        "evaluation_1": {
            "module": "Evaluation",
            "input": {
                "data": {
                    "data": [
                        "homo_lr_1.data"
                    ]
                }
            },
            "output": {
                "data": [
                    "data"
                ]
            }
        }        
    }
}

homo_lr_train_eval_conf.json

{
    "dsl_version": 2,
    "initiator": {
        "role": "guest",
        "party_id": 9999
    },
    "role": {
        "guest": [
            9999
        ],
        "host": [
            10000
        ],
        "arbiter": [
            9999
        ]
    },
    "component_parameters": {
        "common": {
            "data_transform_0": {
                "with_label": true,
                "output_format": "dense"
            },
            "homo_lr_0": {
                "penalty": "L2",
                "tol": 1e-05,
                "alpha": 0.01,
                "optimizer": "rmsprop",
                "batch_size": 320,
                "learning_rate": 0.15,
                "init_param": {
                    "init_method": "zeros"
                },
                "encrypt_param": {
                    "method": null
                },
                "max_iter": 3,
                "early_stop": "diff",
                "cv_param": {
                    "n_splits": 4,
                    "shuffle": true,
                    "random_seed": 33,
                    "need_cv": false
                },
                "callback_param": {
                    "callbacks": ["EarlyStopping"],
                    "validation_freqs": 1
                }
            },
            "evaluation_0": {
                "eval_type": "binary"
            },
            "evaluation_1": {
                "eval_type": "binary"
            }
        },
        "role": {
            "host": {
                "0": {
                    "evaluation_0": {
                        "need_run": false
                    },
                    "reader_1": {
                        "table": {
                            "name": "homo_breast_1_eval",
                            "namespace": "homo_host_breast_eval"
                        }
                    },
                    "reader_0": {
                        "table": {
                            "name": "homo_breast_1_train",
                            "namespace": "homo_host_breast_train"
                        }
                    }
                }
            },
            "guest": {
                "0": {
                    "reader_1": {
                        "table": {
                            "name": "homo_breast_2_eval",
                            "namespace": "homo_guest_breast_eval"
                        }
                    },
                    "reader_0": {
                        "table": {
                            "name": "homo_breast_2_train",
                            "namespace": "homo_guest_breast_train"
                        }
                    }
                }
            }
        }
    }
}

在相关路径下,输入相关代码即可:

flow job submit -c ${runtime_config} -d ${dsl}

根据提示进入FATEBoard 可视化网页,即可查看运行过程以及结果

【阅读笔记】联邦学习实战第5章——用FATE从零实现横向逻辑回归v1.8.0_第3张图片

【阅读笔记】联邦学习实战第5章——用FATE从零实现横向逻辑回归v1.8.0_第4张图片

 到这里,我们复现单机版用FATE实现横向逻辑回归就完成了。

总结

由于我是根据联邦学习实战这本书入门,其中介绍了FATE平台,且给了一些例子,但是在例子的实际进行中,根据书上的步骤会不断报错,后来了解到是因为版本发生了大改,所以根据最新的版本,重新复现了一遍。

这是我第一次发布内容,对于本文有任何问题,可以一起讨论。后面也会不间断的更新一些跟联邦学习有关的文章。

参考链接

二、 FATE实战:实现横向逻辑回归任务的训练及预测_范星星的博客-CSDN博客_fate实战
【阅读笔记】联邦学习实战——用FATE从零实现横向逻辑回归_HERODING23的博客-CSDN博客_联邦学习fate

你可能感兴趣的