Bootstrap

联邦学习框架Fate使用记录(三):Fate1.8-a集群服务使用记录

一、使用前的说明

横向和纵向操作步骤其实差不多,只是模块选择、调用预测有些区别,官方其实有纵向例子,我这次就主要用横向记录了,也会提及一些关于纵向的东西
可以参照前两篇单机版的配置一起看

二、数据准备

2.1 上传数据

上传数据(xxxx.csv文件)到jupyter notebook
在这里插入图片描述

2.2 编写数据上传配置

之前因为对Linux不太熟悉,用了比较笨的方法,直接编辑并上传json文件,其实可以用cat > 文件路径/文件名称 <<EOF 文件内容 EOF来直接生成,官方例子也是这样写的

cat > fateflow/examples/upload/xxxxxx.json <<EOF
  {
"file": "fateflow/examples/data/xxxx.csv",
  "head": 1,  
  "partition": 10,
  "work_mode": 1,  
  "table_name": "a",
  "namespace": "a"
}
EOF

“head”: 1, 识别表头
“work_mode”: 1, 1代表集群
“table_name”: “数据表名”,
“namespace”: “空间名称”

guest方和host方都需要按上述步骤操作

2.3 提交数据至fate

flow data upload -c fateflow/examples/upload/xxxxxx.json
同理,guest和host方都需要提交数据
到了这一步之后,用来预测之前,host方都不需要跟进操作了,后续开始guest的建模过程。

三、建模

这次采用带有测试数据的方式,guest和host方都需要上传一份训练数据和一份测试数据。

3.1 dsl构建

读取数据----处理转化数据----数据标准化----建模----评估

cat > fateflow/examples/lr/xxx_dsl.json <<EOF
{
    "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": {
                    "test_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",
                        "homo_lr_1.data"
                    ]
                }
            },
            "output": {
                "data": [
                    "data"
                ]
            }
        }
    }
}

EOF

3.2 模块参数设置

cat > fateflow/examples/lr/xxxx_conf.json <<EOF
{
    "dsl_version": 2,
    "initiator": {
        "role": "guest",
        "party_id": 10000
    },
    "role": {
        "guest": [
            10000
        ],
        "host": [
            9999
        ],
        "arbiter": [
            9999
        ]
    },
    "component_parameters": {
        "common": {
            "data_transform_0": {
                "missing_fill": true,
                "missing_fill_method": "mean",
                "outlier_replace": false,
                "with_label": true,
                "label_name": "label",
                "label_type": "int",
                "output_format": "dense"
            },

    
            "homo_lr_0": {
                "penalty": "L2",
                "tol": 1e-05,
                "alpha": 0.01,
                "optimizer": "sgd",
                "batch_size": -1,
                "learning_rate": 0.5,
                "init_param": {
                    "init_method": "zeros"
                },
                "max_iter": 2000,
                "early_stop": "diff",
                "encrypt_param": {
                    "method": null
                },
                "cv_param": {
                    "n_splits": 4,
                    "shuffle": true,
                    "random_seed": 33,
                    "need_cv": false
                },
                "decay": 1,
                "decay_sqrt": true
            },
            "callback_param": {
                    "callbacks": ["EarlyStopping"],
                    "validation_freqs": 1
                },
            "evaluation_0": {
                "eval_type": "binary"
            }
        },
        "role": {
            "host": {
                "0": {
                    "reader_0": {
                        "table": {
                            "name": "host方训练数据表名",
                            "namespace": "host方训练数据表空间"
                        }
                    },
                    "reader_1": {
                        "table": {
                            "name": "host方测试数据表名",
                            "namespace": "host方测试数据表空间"
                        }
                    },
                    "evaluation_0": {
                        "need_run": true
                    }
                }
            },
            "guest": {
                "0":
                {
                    "reader_0": {
                        "table": {
                            "name": "guest方训练数据表名",
                            "namespace": "guest方训练数据表空间"
                        }
                    },
                    "reader_1": {
                        "table": {
                            "name": "guest方测试数据表名",
                            "namespace": "guest方测试数据表空间"
                        }
                    }
                }
            }
        }
    }
}
EOF

3.3 提交任务

flow job submit -d fateflow/examples/lr/xxxx_dsl.json -c fateflow/examples/lr/xxxx_conf.json

3.4 查看fateboard

在这里插入图片描述

四、模型建立

4.1 模型推理

需要修改的是arbiter、guest、host对应的id和jobID

flow model deploy --model-id arbiter-9999#guest-10000#host-9999#model --model-version xxxxxxxxxxx (提交任务的jobID)

命令会返回一个模型版本号

4.2 加载模型配置

cat > fateflow/examples/model/homo_publish_load_model.json <<EOF 
{
  "initiator": {
    "party_id": "10000",
    "role": "guest"
  },
  "role": {
    "guest": [
      "10000"
    ],
    "host": [
      "9999"
    ],
    "arbiter": [
      "9999"
    ]
  },
  "job_parameters": {
    "model_id": "arbiter-9999#guest-10000#host-9999#model",
    "model_version": "xxxx"
  }
}
EOF

model_version填写4.1返回的模型版本号
提交任务,加载模型

flow model load -c fateflow/examples/model/homo_publish_load_model.json

4.1 建立模型

cat > fateflow/examples/model/bind_model_service.json <<EOF
{
    "service_id": "自命名服务ID",
    "initiator": {
        "party_id": "10000",
        "role": "guest"
    },
    "role": {
        "guest": ["10000"],
        "host": ["9999"],
        "arbiter": ["9999"]
    },
    "job_parameters": {
        "work_mode": 1,
        "model_id": "arbiter-9999#guest-10000#host-9999#model",
        "model_version": "模型版本号"
    }
}
EOF

提交任务,建立模型服务

flow model bind -c fateflow/examples/model/bind_model_service.json

五、模型使用

5.1 在线预测

在线预测没看到有横向的案例,好像是不支持横向在线预测,如果有使用成功的朋友也可以踢我一脚,强行使用不会报错,显示调用成功,但是返回值没有概率值。。。也就是不返回结果,纵向使用到是没有问题。

curl -X POST -H 'Content-Type: application/json' -i 'http://地址:8059/federation/v1/inference' --data '{   "head": {     "serviceId": "cngb_0922"   },   "body": {     "featureData": {         "x1": 1111,         "x2": 121,         "x3": 122,         "x4":10,         "x5": 10,         "x6":11,         "x7":11,        "x8":1221,          "x9": 20,          "x10":31  },     "sendToRemoteFeatureData": {         "uid": "1"     }   } }'

正常请况是可以返回类似如下结构的json(纵向,示例取自官方纵向示例)

{
  "flag":0,
  "data":
  	{
      "prob":0.30684422824464636,
      "guestInputDataHitRate:{}":0.0,
      "guestModelWeightHitRate:{}":0.0,
      "retcode":0
    },
  "retmsg":"success",
  "retcode":0
}

横向使用是没有概率值的,retmsg是success,retcode是0,但是data里面只能返回模型ID之类的东西。
在这里插入图片描述

5.2 本地预测

也有一些问题,先写流程,问题最后讲
上传预测数据和之前上传训练数据一样,没有区别

5.2.1 编写预测文件
cat > fateflow/examples/predict/predict_conf.json <<EOF
{
  "dsl_version": "2",
  "initiator": {
    "role": "guest",
    "party_id": 10000
  },
  "role": {
    "guest": [
      10000
    ],
    "host": [
      9999
    ],
    "arbiter": [
      9999
    ]
  },
  "job_parameters": {
    "common": {
      "job_type": "predict",
      "model_id": "arbiter-9999#guest-10000#host-9999#model",
      "model_version": "模型版本号"
    }
  },
  "component_parameters": {
    "common": {
    },
    "role": {
      "guest": {
        "0": {
          "reader_0": {
            "table": {
              "name": "预测数据表名",
              "namespace": "预测数据空间名称"
            }
          },
          "dataio_0": {
            "with_label": false,
            "label_name": "label",
            "label_type": "int",
            "output_format": "dense"
          }
        }
      },
      "host": {
        "0": {
          "reader_0": {
            "table": {
              "name": "xxx",
              "namespace": "xxx"
            }
          },
          "dataio_0": {
            "with_label": false,
            "output_format": "dense"
          }
        }
      }
    }
  }
}
EOF
5.2.2 提交任务,进行预测
flow job submit  -c  fateflow/examples/predict/predict_conf_test.json

5.3 问题

本地预测用起来也有一些问题,保存的模型使用时,还会按照训练的流水线去跑,以上述我构建的模型为例子如下图所示。

1.预测也会严格按照训练模块进行使用,比如真正使用的时候是没有标签的,但是依旧会走到模型评估这一步,我尝试采用构建一个新的单流水线,一起提交,不会报错,但是没用(摊手)
2.可以看出,参数文件我只是设置了reader_0的待预测数据,但是预测时还会额外加载一个reader_1,就是之前上传的测试数据(摊手)
在这里插入图片描述

5.4 总结

在这里插入图片描述

虽然有一些问题,但是也是可以使用的,在上图homo_lr_0中,也是会给出预测标签值和概率值的。

5.5 另外一种使用方法

对于lr来说,横向联邦学习会给出lr各个特征的权重和截距,也就是说,在数据标准化之后,我们可以根据提供的参数来重新构建一个线性回归模型,然后将输出带入sigmoid函数,经过实验,所输出的概率值是和模型预测一致的。

六、结尾

总的来说,fate对于纵向联邦的支持会更多一些,因为也是第一次使用,如果有哪些错误也希望大伙指出,互相学习。

;