Showing preview only (646K chars total). Download the full file or copy to clipboard to get everything.
Repository: anupamkliv/FedERA
Branch: main
Commit: 8db9bbcdc037
Files: 1415
Total size: 557.9 KB
Directory structure:
gitextract_o4_ojofq/
├── .bandit
├── .coveragerc
├── .github/
│ └── workflows/
│ ├── publish.yml
│ ├── pytest_coverage.yml
│ ├── ubuntu.yml
│ └── windows.yml
├── .gitignore
├── CONDUCT.md
├── Dockerfile
├── LICENSE
├── README.md
├── client_custom_dataset/
│ └── CUSTOM/
│ ├── test/
│ │ ├── Breast_1_131.npy
│ │ ├── Breast_1_178.npy
│ │ ├── Breast_1_38.npy
│ │ ├── Breast_1_46.npy
│ │ ├── Breast_1_56.npy
│ │ ├── Breast_1_57.npy
│ │ ├── Breast_1_58.npy
│ │ ├── Chestxray_0_10192.npy
│ │ ├── Chestxray_0_2599.npy
│ │ ├── Chestxray_0_27.npy
│ │ ├── Chestxray_10_2647.npy
│ │ ├── Chestxray_10_7361.npy
│ │ ├── Chestxray_11_6369.npy
│ │ ├── Chestxray_12_3194.npy
│ │ ├── Chestxray_12_6281.npy
│ │ ├── Chestxray_1_1545.npy
│ │ ├── Chestxray_2_10770.npy
│ │ ├── Chestxray_2_1294.npy
│ │ ├── Chestxray_2_2942.npy
│ │ ├── Chestxray_3_4808.npy
│ │ ├── Chestxray_3_563.npy
│ │ ├── Chestxray_3_8533.npy
│ │ ├── Chestxray_3_9185.npy
│ │ ├── Chestxray_3_9271.npy
│ │ ├── Chestxray_3_9492.npy
│ │ ├── Chestxray_5_10699.npy
│ │ ├── Chestxray_5_3477.npy
│ │ ├── Chestxray_5_756.npy
│ │ ├── Chestxray_5_7941.npy
│ │ ├── Chestxray_5_8493.npy
│ │ ├── Chestxray_6_7326.npy
│ │ ├── Chestxray_7_10995.npy
│ │ ├── Chestxray_7_8642.npy
│ │ ├── Chestxray_7_9211.npy
│ │ ├── Chestxray_8_2448.npy
│ │ ├── Chestxray_9_1970.npy
│ │ ├── Oct_0_10252.npy
│ │ ├── Oct_0_10370.npy
│ │ ├── Oct_0_1901.npy
│ │ ├── Oct_0_2534.npy
│ │ ├── Oct_0_4375.npy
│ │ ├── Oct_0_521.npy
│ │ ├── Oct_0_5368.npy
│ │ ├── Oct_0_7082.npy
│ │ ├── Oct_0_72818.npy
│ │ ├── Oct_0_7570.npy
│ │ ├── Oct_0_9852.npy
│ │ ├── Oct_1_757.npy
│ │ ├── Oct_2_26531.npy
│ │ ├── Oct_2_3752.npy
│ │ ├── Oct_2_8134.npy
│ │ ├── Oct_2_8207.npy
│ │ ├── Oct_2_9648.npy
│ │ ├── Oct_3_1567.npy
│ │ ├── Oct_3_1669.npy
│ │ ├── Oct_3_2292.npy
│ │ ├── Oct_3_2794.npy
│ │ ├── Oct_3_4851.npy
│ │ ├── Oct_3_4912.npy
│ │ ├── Oct_3_5127.npy
│ │ ├── Oct_3_5626.npy
│ │ ├── Oct_3_5777.npy
│ │ ├── Oct_3_6087.npy
│ │ ├── Oct_3_6417.npy
│ │ ├── Oct_3_9802.npy
│ │ ├── Tissue_0_10673.npy
│ │ ├── Tissue_0_12024.npy
│ │ ├── Tissue_0_12038.npy
│ │ ├── Tissue_0_14742.npy
│ │ ├── Tissue_0_1487.npy
│ │ ├── Tissue_0_17483.npy
│ │ ├── Tissue_0_18694.npy
│ │ ├── Tissue_0_20122.npy
│ │ ├── Tissue_0_2373.npy
│ │ ├── Tissue_0_3171.npy
│ │ ├── Tissue_0_411.npy
│ │ ├── Tissue_0_4904.npy
│ │ ├── Tissue_0_6028.npy
│ │ ├── Tissue_0_7434.npy
│ │ ├── Tissue_0_8139.npy
│ │ ├── Tissue_0_8962.npy
│ │ ├── Tissue_0_9511.npy
│ │ ├── Tissue_0_9949.npy
│ │ ├── Tissue_3_8272.npy
│ │ ├── Tissue_3_9593.npy
│ │ ├── Tissue_4_10949.npy
│ │ ├── Tissue_4_16558.npy
│ │ ├── Tissue_4_17314.npy
│ │ ├── Tissue_4_18139.npy
│ │ ├── Tissue_4_2355.npy
│ │ ├── Tissue_5_17494.npy
│ │ ├── Tissue_5_22443.npy
│ │ ├── Tissue_6_11839.npy
│ │ ├── Tissue_6_12194.npy
│ │ ├── Tissue_6_13317.npy
│ │ ├── Tissue_6_14084.npy
│ │ ├── Tissue_6_15019.npy
│ │ ├── Tissue_6_15092.npy
│ │ ├── Tissue_6_15204.npy
│ │ ├── Tissue_6_17363.npy
│ │ ├── Tissue_6_19355.npy
│ │ ├── Tissue_6_19528.npy
│ │ ├── Tissue_6_21927.npy
│ │ ├── Tissue_6_37014.npy
│ │ ├── Tissue_7_14747.npy
│ │ ├── Tissue_7_14849.npy
│ │ ├── Tissue_7_18085.npy
│ │ ├── Tissue_7_18646.npy
│ │ ├── Tissue_7_21396.npy
│ │ ├── Tissue_7_21427.npy
│ │ ├── Tissue_7_2508.npy
│ │ ├── Tissue_7_2884.npy
│ │ ├── Tissue_7_7116.npy
│ │ └── Tissue_7_7248.npy
│ └── train/
│ ├── Breast_0_0.npy
│ ├── Breast_0_11.npy
│ ├── Breast_0_115.npy
│ ├── Breast_0_14.npy
│ ├── Breast_0_20.npy
│ ├── Breast_0_24.npy
│ ├── Breast_0_28.npy
│ ├── Breast_0_3.npy
│ ├── Breast_0_30.npy
│ ├── Breast_0_33.npy
│ ├── Breast_0_45.npy
│ ├── Breast_0_47.npy
│ ├── Breast_0_64.npy
│ ├── Breast_0_66.npy
│ ├── Breast_0_71.npy
│ ├── Breast_0_73.npy
│ ├── Breast_0_74.npy
│ ├── Breast_0_85.npy
│ ├── Breast_1_1.npy
│ ├── Breast_1_10.npy
│ ├── Breast_1_12.npy
│ ├── Breast_1_13.npy
│ ├── Breast_1_15.npy
│ ├── Breast_1_16.npy
│ ├── Breast_1_17.npy
│ ├── Breast_1_2.npy
│ ├── Breast_1_21.npy
│ ├── Breast_1_22.npy
│ ├── Breast_1_227.npy
│ ├── Breast_1_23.npy
│ ├── Breast_1_249.npy
│ ├── Breast_1_25.npy
│ ├── Breast_1_27.npy
│ ├── Breast_1_29.npy
│ ├── Breast_1_32.npy
│ ├── Breast_1_34.npy
│ ├── Breast_1_35.npy
│ ├── Breast_1_37.npy
│ ├── Breast_1_40.npy
│ ├── Breast_1_408.npy
│ ├── Breast_1_41.npy
│ ├── Breast_1_42.npy
│ ├── Breast_1_43.npy
│ ├── Breast_1_433.npy
│ ├── Breast_1_48.npy
│ ├── Breast_1_5.npy
│ ├── Breast_1_50.npy
│ ├── Breast_1_51.npy
│ ├── Breast_1_52.npy
│ ├── Breast_1_53.npy
│ ├── Breast_1_54.npy
│ ├── Breast_1_55.npy
│ ├── Breast_1_6.npy
│ ├── Breast_1_60.npy
│ ├── Breast_1_61.npy
│ ├── Breast_1_62.npy
│ ├── Breast_1_64.npy
│ ├── Breast_1_65.npy
│ ├── Breast_1_68.npy
│ ├── Breast_1_69.npy
│ ├── Breast_1_7.npy
│ ├── Breast_1_70.npy
│ ├── Breast_1_72.npy
│ ├── Breast_1_75.npy
│ ├── Breast_1_76.npy
│ ├── Breast_1_77.npy
│ ├── Breast_1_8.npy
│ ├── Breast_1_9.npy
│ ├── Chestxray_0_10696.npy
│ ├── Chestxray_0_10927.npy
│ ├── Chestxray_0_11206.npy
│ ├── Chestxray_0_2549.npy
│ ├── Chestxray_0_44.npy
│ ├── Chestxray_0_4584.npy
│ ├── Chestxray_0_474.npy
│ ├── Chestxray_0_4858.npy
│ ├── Chestxray_0_5282.npy
│ ├── Chestxray_0_6167.npy
│ ├── Chestxray_0_6235.npy
│ ├── Chestxray_0_6401.npy
│ ├── Chestxray_0_6403.npy
│ ├── Chestxray_0_6438.npy
│ ├── Chestxray_0_6482.npy
│ ├── Chestxray_0_7202.npy
│ ├── Chestxray_0_752.npy
│ ├── Chestxray_0_7551.npy
│ ├── Chestxray_0_8453.npy
│ ├── Chestxray_10_4463.npy
│ ├── Chestxray_11_1275.npy
│ ├── Chestxray_11_2068.npy
│ ├── Chestxray_11_3915.npy
│ ├── Chestxray_11_4063.npy
│ ├── Chestxray_11_64880.npy
│ ├── Chestxray_11_7570.npy
│ ├── Chestxray_11_9678.npy
│ ├── Chestxray_12_10521.npy
│ ├── Chestxray_12_1472.npy
│ ├── Chestxray_12_151.npy
│ ├── Chestxray_12_194.npy
│ ├── Chestxray_12_3225.npy
│ ├── Chestxray_12_3458.npy
│ ├── Chestxray_12_4112.npy
│ ├── Chestxray_12_4694.npy
│ ├── Chestxray_12_5795.npy
│ ├── Chestxray_12_7320.npy
│ ├── Chestxray_12_9084.npy
│ ├── Chestxray_1_10242.npy
│ ├── Chestxray_1_4797.npy
│ ├── Chestxray_1_6404.npy
│ ├── Chestxray_1_7034.npy
│ ├── Chestxray_1_7388.npy
│ ├── Chestxray_1_8324.npy
│ ├── Chestxray_1_8326.npy
│ ├── Chestxray_1_8907.npy
│ ├── Chestxray_2_10082.npy
│ ├── Chestxray_2_10125.npy
│ ├── Chestxray_2_10149.npy
│ ├── Chestxray_2_10349.npy
│ ├── Chestxray_2_10524.npy
│ ├── Chestxray_2_10638.npy
│ ├── Chestxray_2_10750.npy
│ ├── Chestxray_2_11137.npy
│ ├── Chestxray_2_1160.npy
│ ├── Chestxray_2_1177.npy
│ ├── Chestxray_2_1408.npy
│ ├── Chestxray_2_1727.npy
│ ├── Chestxray_2_1832.npy
│ ├── Chestxray_2_2029.npy
│ ├── Chestxray_2_2134.npy
│ ├── Chestxray_2_2535.npy
│ ├── Chestxray_2_3045.npy
│ ├── Chestxray_2_3462.npy
│ ├── Chestxray_2_3820.npy
│ ├── Chestxray_2_4261.npy
│ ├── Chestxray_2_5098.npy
│ ├── Chestxray_2_5125.npy
│ ├── Chestxray_2_5669.npy
│ ├── Chestxray_2_5987.npy
│ ├── Chestxray_2_6509.npy
│ ├── Chestxray_2_6807.npy
│ ├── Chestxray_2_7015.npy
│ ├── Chestxray_2_7113.npy
│ ├── Chestxray_2_7131.npy
│ ├── Chestxray_2_7152.npy
│ ├── Chestxray_2_7430.npy
│ ├── Chestxray_2_7706.npy
│ ├── Chestxray_2_7865.npy
│ ├── Chestxray_2_8054.npy
│ ├── Chestxray_2_8099.npy
│ ├── Chestxray_2_8955.npy
│ ├── Chestxray_2_9745.npy
│ ├── Chestxray_2_9882.npy
│ ├── Chestxray_2_9918.npy
│ ├── Chestxray_2_9951.npy
│ ├── Chestxray_3_10171.npy
│ ├── Chestxray_3_10717.npy
│ ├── Chestxray_3_1072.npy
│ ├── Chestxray_3_10733.npy
│ ├── Chestxray_3_11004.npy
│ ├── Chestxray_3_11050.npy
│ ├── Chestxray_3_1627.npy
│ ├── Chestxray_3_1767.npy
│ ├── Chestxray_3_18163.npy
│ ├── Chestxray_3_2116.npy
│ ├── Chestxray_3_2130.npy
│ ├── Chestxray_3_220.npy
│ ├── Chestxray_3_2320.npy
│ ├── Chestxray_3_2340.npy
│ ├── Chestxray_3_2410.npy
│ ├── Chestxray_3_2639.npy
│ ├── Chestxray_3_2759.npy
│ ├── Chestxray_3_3346.npy
│ ├── Chestxray_3_3435.npy
│ ├── Chestxray_3_3561.npy
│ ├── Chestxray_3_3650.npy
│ ├── Chestxray_3_3761.npy
│ ├── Chestxray_3_3919.npy
│ ├── Chestxray_3_3952.npy
│ ├── Chestxray_3_421.npy
│ ├── Chestxray_3_4216.npy
│ ├── Chestxray_3_4402.npy
│ ├── Chestxray_3_443.npy
│ ├── Chestxray_3_4675.npy
│ ├── Chestxray_3_4703.npy
│ ├── Chestxray_3_4836.npy
│ ├── Chestxray_3_4895.npy
│ ├── Chestxray_3_4919.npy
│ ├── Chestxray_3_4949.npy
│ ├── Chestxray_3_512.npy
│ ├── Chestxray_3_5301.npy
│ ├── Chestxray_3_5605.npy
│ ├── Chestxray_3_6751.npy
│ ├── Chestxray_3_7412.npy
│ ├── Chestxray_3_7657.npy
│ ├── Chestxray_3_7667.npy
│ ├── Chestxray_3_7801.npy
│ ├── Chestxray_3_8160.npy
│ ├── Chestxray_3_8298.npy
│ ├── Chestxray_3_8713.npy
│ ├── Chestxray_3_8954.npy
│ ├── Chestxray_3_9047.npy
│ ├── Chestxray_3_9081.npy
│ ├── Chestxray_3_9523.npy
│ ├── Chestxray_3_9811.npy
│ ├── Chestxray_3_982.npy
│ ├── Chestxray_4_1067.npy
│ ├── Chestxray_4_1162.npy
│ ├── Chestxray_4_1173.npy
│ ├── Chestxray_4_2288.npy
│ ├── Chestxray_4_3105.npy
│ ├── Chestxray_4_4324.npy
│ ├── Chestxray_4_6177.npy
│ ├── Chestxray_4_7510.npy
│ ├── Chestxray_4_7946.npy
│ ├── Chestxray_4_8534.npy
│ ├── Chestxray_4_8754.npy
│ ├── Chestxray_4_9122.npy
│ ├── Chestxray_4_9534.npy
│ ├── Chestxray_4_9580.npy
│ ├── Chestxray_5_10800.npy
│ ├── Chestxray_5_1091.npy
│ ├── Chestxray_5_1776.npy
│ ├── Chestxray_5_3935.npy
│ ├── Chestxray_5_4079.npy
│ ├── Chestxray_5_554.npy
│ ├── Chestxray_5_5938.npy
│ ├── Chestxray_5_6184.npy
│ ├── Chestxray_5_6391.npy
│ ├── Chestxray_5_9471.npy
│ ├── Chestxray_5_9729.npy
│ ├── Chestxray_6_1513.npy
│ ├── Chestxray_6_3188.npy
│ ├── Chestxray_6_5225.npy
│ ├── Chestxray_6_5805.npy
│ ├── Chestxray_6_7399.npy
│ ├── Chestxray_6_8382.npy
│ ├── Chestxray_6_8988.npy
│ ├── Chestxray_6_9056.npy
│ ├── Chestxray_6_9185.npy
│ ├── Chestxray_7_10100.npy
│ ├── Chestxray_7_10571.npy
│ ├── Chestxray_7_1145.npy
│ ├── Chestxray_7_1717.npy
│ ├── Chestxray_7_3195.npy
│ ├── Chestxray_7_5008.npy
│ ├── Chestxray_7_503.npy
│ ├── Chestxray_7_61644.npy
│ ├── Chestxray_7_69.npy
│ ├── Chestxray_7_7171.npy
│ ├── Chestxray_7_7260.npy
│ ├── Chestxray_7_7293.npy
│ ├── Chestxray_7_7542.npy
│ ├── Chestxray_7_7828.npy
│ ├── Chestxray_7_823.npy
│ ├── Chestxray_7_9268.npy
│ ├── Chestxray_8_17335.npy
│ ├── Chestxray_8_187.npy
│ ├── Chestxray_8_2918.npy
│ ├── Chestxray_8_3663.npy
│ ├── Chestxray_8_4409.npy
│ ├── Chestxray_8_6667.npy
│ ├── Chestxray_8_6771.npy
│ ├── Chestxray_8_8104.npy
│ ├── Chestxray_8_9794.npy
│ ├── Chestxray_9_2208.npy
│ ├── Chestxray_9_236.npy
│ ├── Chestxray_9_2714.npy
│ ├── Chestxray_9_6875.npy
│ ├── Chestxray_9_7803.npy
│ ├── Oct_0_10255.npy
│ ├── Oct_0_1033.npy
│ ├── Oct_0_10376.npy
│ ├── Oct_0_10487.npy
│ ├── Oct_0_1060.npy
│ ├── Oct_0_1173.npy
│ ├── Oct_0_1250.npy
│ ├── Oct_0_1373.npy
│ ├── Oct_0_1380.npy
│ ├── Oct_0_1399.npy
│ ├── Oct_0_1517.npy
│ ├── Oct_0_1524.npy
│ ├── Oct_0_1662.npy
│ ├── Oct_0_1684.npy
│ ├── Oct_0_1746.npy
│ ├── Oct_0_1924.npy
│ ├── Oct_0_2014.npy
│ ├── Oct_0_2158.npy
│ ├── Oct_0_2279.npy
│ ├── Oct_0_2548.npy
│ ├── Oct_0_2596.npy
│ ├── Oct_0_2722.npy
│ ├── Oct_0_2935.npy
│ ├── Oct_0_2954.npy
│ ├── Oct_0_2972.npy
│ ├── Oct_0_3006.npy
│ ├── Oct_0_3027.npy
│ ├── Oct_0_3071.npy
│ ├── Oct_0_3482.npy
│ ├── Oct_0_3485.npy
│ ├── Oct_0_3571.npy
│ ├── Oct_0_3607.npy
│ ├── Oct_0_3642.npy
│ ├── Oct_0_3859.npy
│ ├── Oct_0_3988.npy
│ ├── Oct_0_4289.npy
│ ├── Oct_0_4290.npy
│ ├── Oct_0_4333.npy
│ ├── Oct_0_449.npy
│ ├── Oct_0_450.npy
│ ├── Oct_0_4634.npy
│ ├── Oct_0_5293.npy
│ ├── Oct_0_5502.npy
│ ├── Oct_0_5688.npy
│ ├── Oct_0_5722.npy
│ ├── Oct_0_5798.npy
│ ├── Oct_0_5857.npy
│ ├── Oct_0_596.npy
│ ├── Oct_0_6403.npy
│ ├── Oct_0_6663.npy
│ ├── Oct_0_6760.npy
│ ├── Oct_0_6922.npy
│ ├── Oct_0_7047.npy
│ ├── Oct_0_7081.npy
│ ├── Oct_0_7107.npy
│ ├── Oct_0_7151.npy
│ ├── Oct_0_7218.npy
│ ├── Oct_0_7233.npy
│ ├── Oct_0_7331.npy
│ ├── Oct_0_7354.npy
│ ├── Oct_0_7581.npy
│ ├── Oct_0_7616.npy
│ ├── Oct_0_772.npy
│ ├── Oct_0_7767.npy
│ ├── Oct_0_7831.npy
│ ├── Oct_0_7892.npy
│ ├── Oct_0_7906.npy
│ ├── Oct_0_7992.npy
│ ├── Oct_0_8074.npy
│ ├── Oct_0_8106.npy
│ ├── Oct_0_8302.npy
│ ├── Oct_0_8346.npy
│ ├── Oct_0_8348.npy
│ ├── Oct_0_8489.npy
│ ├── Oct_0_851.npy
│ ├── Oct_0_8843.npy
│ ├── Oct_0_8955.npy
│ ├── Oct_0_9002.npy
│ ├── Oct_0_9224.npy
│ ├── Oct_0_9362.npy
│ ├── Oct_0_9377.npy
│ ├── Oct_0_9453.npy
│ ├── Oct_0_9587.npy
│ ├── Oct_0_9755.npy
│ ├── Oct_1_1207.npy
│ ├── Oct_1_1753.npy
│ ├── Oct_1_1796.npy
│ ├── Oct_1_2078.npy
│ ├── Oct_1_2182.npy
│ ├── Oct_1_2987.npy
│ ├── Oct_1_3566.npy
│ ├── Oct_1_4093.npy
│ ├── Oct_1_4149.npy
│ ├── Oct_1_4366.npy
│ ├── Oct_1_4436.npy
│ ├── Oct_1_5388.npy
│ ├── Oct_1_54.npy
│ ├── Oct_1_5800.npy
│ ├── Oct_1_6105.npy
│ ├── Oct_1_6414.npy
│ ├── Oct_1_65387.npy
│ ├── Oct_1_7773.npy
│ ├── Oct_1_8424.npy
│ ├── Oct_1_8527.npy
│ ├── Oct_1_8876.npy
│ ├── Oct_1_8976.npy
│ ├── Oct_1_9014.npy
│ ├── Oct_1_902.npy
│ ├── Oct_1_9097.npy
│ ├── Oct_1_9702.npy
│ ├── Oct_2_10143.npy
│ ├── Oct_2_10483.npy
│ ├── Oct_2_1052.npy
│ ├── Oct_2_10661.npy
│ ├── Oct_2_2610.npy
│ ├── Oct_2_26446.npy
│ ├── Oct_2_27682.npy
│ ├── Oct_2_3036.npy
│ ├── Oct_2_3249.npy
│ ├── Oct_2_4057.npy
│ ├── Oct_2_4370.npy
│ ├── Oct_2_5788.npy
│ ├── Oct_2_5962.npy
│ ├── Oct_2_5985.npy
│ ├── Oct_2_6369.npy
│ ├── Oct_2_7924.npy
│ ├── Oct_2_8401.npy
│ ├── Oct_2_9099.npy
│ ├── Oct_2_9163.npy
│ ├── Oct_2_9652.npy
│ ├── Oct_2_9760.npy
│ ├── Oct_3_10010.npy
│ ├── Oct_3_10059.npy
│ ├── Oct_3_10063.npy
│ ├── Oct_3_10164.npy
│ ├── Oct_3_10261.npy
│ ├── Oct_3_10341.npy
│ ├── Oct_3_10348.npy
│ ├── Oct_3_10360.npy
│ ├── Oct_3_10441.npy
│ ├── Oct_3_10444.npy
│ ├── Oct_3_10811.npy
│ ├── Oct_3_1092.npy
│ ├── Oct_3_1269.npy
│ ├── Oct_3_1370.npy
│ ├── Oct_3_1588.npy
│ ├── Oct_3_1671.npy
│ ├── Oct_3_1799.npy
│ ├── Oct_3_1820.npy
│ ├── Oct_3_1869.npy
│ ├── Oct_3_2031.npy
│ ├── Oct_3_2211.npy
│ ├── Oct_3_2217.npy
│ ├── Oct_3_2259.npy
│ ├── Oct_3_2277.npy
│ ├── Oct_3_2300.npy
│ ├── Oct_3_2320.npy
│ ├── Oct_3_2345.npy
│ ├── Oct_3_2388.npy
│ ├── Oct_3_25.npy
│ ├── Oct_3_2500.npy
│ ├── Oct_3_2530.npy
│ ├── Oct_3_2624.npy
│ ├── Oct_3_271.npy
│ ├── Oct_3_2777.npy
│ ├── Oct_3_2915.npy
│ ├── Oct_3_2921.npy
│ ├── Oct_3_3087.npy
│ ├── Oct_3_314.npy
│ ├── Oct_3_3240.npy
│ ├── Oct_3_3282.npy
│ ├── Oct_3_3379.npy
│ ├── Oct_3_3447.npy
│ ├── Oct_3_3492.npy
│ ├── Oct_3_36.npy
│ ├── Oct_3_3660.npy
│ ├── Oct_3_3685.npy
│ ├── Oct_3_3771.npy
│ ├── Oct_3_3895.npy
│ ├── Oct_3_3983.npy
│ ├── Oct_3_4006.npy
│ ├── Oct_3_4101.npy
│ ├── Oct_3_4393.npy
│ ├── Oct_3_4416.npy
│ ├── Oct_3_4499.npy
│ ├── Oct_3_4657.npy
│ ├── Oct_3_4711.npy
│ ├── Oct_3_4786.npy
│ ├── Oct_3_480.npy
│ ├── Oct_3_4887.npy
│ ├── Oct_3_4993.npy
│ ├── Oct_3_4996.npy
│ ├── Oct_3_4997.npy
│ ├── Oct_3_5083.npy
│ ├── Oct_3_5087.npy
│ ├── Oct_3_5098.npy
│ ├── Oct_3_5157.npy
│ ├── Oct_3_5187.npy
│ ├── Oct_3_5425.npy
│ ├── Oct_3_5501.npy
│ ├── Oct_3_5650.npy
│ ├── Oct_3_5657.npy
│ ├── Oct_3_5765.npy
│ ├── Oct_3_5805.npy
│ ├── Oct_3_5859.npy
│ ├── Oct_3_5967.npy
│ ├── Oct_3_5992.npy
│ ├── Oct_3_6058.npy
│ ├── Oct_3_6112.npy
│ ├── Oct_3_619.npy
│ ├── Oct_3_6209.npy
│ ├── Oct_3_6240.npy
│ ├── Oct_3_6277.npy
│ ├── Oct_3_6411.npy
│ ├── Oct_3_6561.npy
│ ├── Oct_3_6614.npy
│ ├── Oct_3_6674.npy
│ ├── Oct_3_6794.npy
│ ├── Oct_3_6903.npy
│ ├── Oct_3_7007.npy
│ ├── Oct_3_7102.npy
│ ├── Oct_3_7352.npy
│ ├── Oct_3_7453.npy
│ ├── Oct_3_7833.npy
│ ├── Oct_3_8099.npy
│ ├── Oct_3_823.npy
│ ├── Oct_3_8352.npy
│ ├── Oct_3_8399.npy
│ ├── Oct_3_8446.npy
│ ├── Oct_3_852.npy
│ ├── Oct_3_8542.npy
│ ├── Oct_3_8627.npy
│ ├── Oct_3_8752.npy
│ ├── Oct_3_8781.npy
│ ├── Oct_3_8817.npy
│ ├── Oct_3_8890.npy
│ ├── Oct_3_8911.npy
│ ├── Oct_3_9019.npy
│ ├── Oct_3_9356.npy
│ ├── Oct_3_9482.npy
│ ├── Oct_3_9592.npy
│ ├── Oct_3_9744.npy
│ ├── Oct_3_9875.npy
│ ├── Oct_3_9938.npy
│ ├── Tissue_0_10065.npy
│ ├── Tissue_0_10235.npy
│ ├── Tissue_0_10275.npy
│ ├── Tissue_0_10363.npy
│ ├── Tissue_0_10501.npy
│ ├── Tissue_0_10715.npy
│ ├── Tissue_0_10876.npy
│ ├── Tissue_0_10970.npy
│ ├── Tissue_0_1104.npy
│ ├── Tissue_0_11215.npy
│ ├── Tissue_0_11293.npy
│ ├── Tissue_0_11304.npy
│ ├── Tissue_0_11407.npy
│ ├── Tissue_0_11543.npy
│ ├── Tissue_0_11564.npy
│ ├── Tissue_0_11609.npy
│ ├── Tissue_0_11794.npy
│ ├── Tissue_0_11911.npy
│ ├── Tissue_0_12370.npy
│ ├── Tissue_0_12488.npy
│ ├── Tissue_0_12745.npy
│ ├── Tissue_0_12909.npy
│ ├── Tissue_0_13156.npy
│ ├── Tissue_0_13261.npy
│ ├── Tissue_0_13568.npy
│ ├── Tissue_0_13699.npy
│ ├── Tissue_0_13863.npy
│ ├── Tissue_0_14042.npy
│ ├── Tissue_0_14286.npy
│ ├── Tissue_0_14369.npy
│ ├── Tissue_0_14385.npy
│ ├── Tissue_0_14542.npy
│ ├── Tissue_0_14599.npy
│ ├── Tissue_0_14672.npy
│ ├── Tissue_0_14761.npy
│ ├── Tissue_0_14805.npy
│ ├── Tissue_0_1507.npy
│ ├── Tissue_0_15264.npy
│ ├── Tissue_0_154.npy
│ ├── Tissue_0_15446.npy
│ ├── Tissue_0_15489.npy
│ ├── Tissue_0_15550.npy
│ ├── Tissue_0_15846.npy
│ ├── Tissue_0_15920.npy
│ ├── Tissue_0_15943.npy
│ ├── Tissue_0_16003.npy
│ ├── Tissue_0_16179.npy
│ ├── Tissue_0_16471.npy
│ ├── Tissue_0_16578.npy
│ ├── Tissue_0_16604.npy
│ ├── Tissue_0_16671.npy
│ ├── Tissue_0_16729.npy
│ ├── Tissue_0_16738.npy
│ ├── Tissue_0_16811.npy
│ ├── Tissue_0_16840.npy
│ ├── Tissue_0_17170.npy
│ ├── Tissue_0_17171.npy
│ ├── Tissue_0_17285.npy
│ ├── Tissue_0_17376.npy
│ ├── Tissue_0_17412.npy
│ ├── Tissue_0_17486.npy
│ ├── Tissue_0_17613.npy
│ ├── Tissue_0_17929.npy
│ ├── Tissue_0_18094.npy
│ ├── Tissue_0_18387.npy
│ ├── Tissue_0_18481.npy
│ ├── Tissue_0_18485.npy
│ ├── Tissue_0_18497.npy
│ ├── Tissue_0_18545.npy
│ ├── Tissue_0_18552.npy
│ ├── Tissue_0_18581.npy
│ ├── Tissue_0_18612.npy
│ ├── Tissue_0_18634.npy
│ ├── Tissue_0_18715.npy
│ ├── Tissue_0_18737.npy
│ ├── Tissue_0_18825.npy
│ ├── Tissue_0_18933.npy
│ ├── Tissue_0_19059.npy
│ ├── Tissue_0_19110.npy
│ ├── Tissue_0_19120.npy
│ ├── Tissue_0_19162.npy
│ ├── Tissue_0_19290.npy
│ ├── Tissue_0_19312.npy
│ ├── Tissue_0_19356.npy
│ ├── Tissue_0_19436.npy
│ ├── Tissue_0_19781.npy
│ ├── Tissue_0_19861.npy
│ ├── Tissue_0_19937.npy
│ ├── Tissue_0_20028.npy
│ ├── Tissue_0_20365.npy
│ ├── Tissue_0_20416.npy
│ ├── Tissue_0_20423.npy
│ ├── Tissue_0_20465.npy
│ ├── Tissue_0_20502.npy
│ ├── Tissue_0_20740.npy
│ ├── Tissue_0_20901.npy
│ ├── Tissue_0_2091.npy
│ ├── Tissue_0_21093.npy
│ ├── Tissue_0_21164.npy
│ ├── Tissue_0_21240.npy
│ ├── Tissue_0_21398.npy
│ ├── Tissue_0_21504.npy
│ ├── Tissue_0_21546.npy
│ ├── Tissue_0_21663.npy
│ ├── Tissue_0_2183.npy
│ ├── Tissue_0_22081.npy
│ ├── Tissue_0_22085.npy
│ ├── Tissue_0_22135.npy
│ ├── Tissue_0_22355.npy
│ ├── Tissue_0_22468.npy
│ ├── Tissue_0_22513.npy
│ ├── Tissue_0_22534.npy
│ ├── Tissue_0_22550.npy
│ ├── Tissue_0_22615.npy
│ ├── Tissue_0_2285.npy
│ ├── Tissue_0_22873.npy
│ ├── Tissue_0_22928.npy
│ ├── Tissue_0_23157.npy
│ ├── Tissue_0_23203.npy
│ ├── Tissue_0_23279.npy
│ ├── Tissue_0_23295.npy
│ ├── Tissue_0_23422.npy
│ ├── Tissue_0_23562.npy
│ ├── Tissue_0_2737.npy
│ ├── Tissue_0_2896.npy
│ ├── Tissue_0_2965.npy
│ ├── Tissue_0_3072.npy
│ ├── Tissue_0_3132.npy
│ ├── Tissue_0_3156.npy
│ ├── Tissue_0_3214.npy
│ ├── Tissue_0_3264.npy
│ ├── Tissue_0_3382.npy
│ ├── Tissue_0_3487.npy
│ ├── Tissue_0_3652.npy
│ ├── Tissue_0_3802.npy
│ ├── Tissue_0_3864.npy
│ ├── Tissue_0_3966.npy
│ ├── Tissue_0_4209.npy
│ ├── Tissue_0_4414.npy
│ ├── Tissue_0_4466.npy
│ ├── Tissue_0_4795.npy
│ ├── Tissue_0_488.npy
│ ├── Tissue_0_4947.npy
│ ├── Tissue_0_4996.npy
│ ├── Tissue_0_5025.npy
│ ├── Tissue_0_5105.npy
│ ├── Tissue_0_5182.npy
│ ├── Tissue_0_5184.npy
│ ├── Tissue_0_5350.npy
│ ├── Tissue_0_5512.npy
│ ├── Tissue_0_5714.npy
│ ├── Tissue_0_5863.npy
│ ├── Tissue_0_5916.npy
│ ├── Tissue_0_5970.npy
│ ├── Tissue_0_6260.npy
│ ├── Tissue_0_6261.npy
│ ├── Tissue_0_6278.npy
│ ├── Tissue_0_6368.npy
│ ├── Tissue_0_65.npy
│ ├── Tissue_0_653.npy
│ ├── Tissue_0_6793.npy
│ ├── Tissue_0_6952.npy
│ ├── Tissue_0_7195.npy
│ ├── Tissue_0_7443.npy
│ ├── Tissue_0_7602.npy
│ ├── Tissue_0_7610.npy
│ ├── Tissue_0_7645.npy
│ ├── Tissue_0_77.npy
│ ├── Tissue_0_7807.npy
│ ├── Tissue_0_8051.npy
│ ├── Tissue_0_8072.npy
│ ├── Tissue_0_8147.npy
│ ├── Tissue_0_8340.npy
│ ├── Tissue_0_836.npy
│ ├── Tissue_0_8607.npy
│ ├── Tissue_0_8697.npy
│ ├── Tissue_0_8699.npy
│ ├── Tissue_0_8796.npy
│ ├── Tissue_0_8870.npy
│ ├── Tissue_0_913.npy
│ ├── Tissue_0_961.npy
│ ├── Tissue_0_9629.npy
│ ├── Tissue_0_9702.npy
│ ├── Tissue_0_9822.npy
│ ├── Tissue_1_1213.npy
│ ├── Tissue_1_13054.npy
│ ├── Tissue_1_13876.npy
│ ├── Tissue_1_14595.npy
│ ├── Tissue_1_14914.npy
│ ├── Tissue_1_15318.npy
│ ├── Tissue_1_15828.npy
│ ├── Tissue_1_17215.npy
│ ├── Tissue_1_17772.npy
│ ├── Tissue_1_18026.npy
│ ├── Tissue_1_19496.npy
│ ├── Tissue_1_19798.npy
│ ├── Tissue_1_1987.npy
│ ├── Tissue_1_20308.npy
│ ├── Tissue_1_20756.npy
│ ├── Tissue_1_21050.npy
│ ├── Tissue_1_2323.npy
│ ├── Tissue_1_4574.npy
│ ├── Tissue_1_483.npy
│ ├── Tissue_1_6495.npy
│ ├── Tissue_1_7192.npy
│ ├── Tissue_1_7418.npy
│ ├── Tissue_1_8376.npy
│ ├── Tissue_1_8601.npy
│ ├── Tissue_1_8790.npy
│ ├── Tissue_1_9741.npy
│ ├── Tissue_2_12291.npy
│ ├── Tissue_2_12512.npy
│ ├── Tissue_2_13211.npy
│ ├── Tissue_2_14652.npy
│ ├── Tissue_2_1538.npy
│ ├── Tissue_2_15651.npy
│ ├── Tissue_2_17690.npy
│ ├── Tissue_2_20081.npy
│ ├── Tissue_2_20348.npy
│ ├── Tissue_2_20909.npy
│ ├── Tissue_2_22554.npy
│ ├── Tissue_2_32155.npy
│ ├── Tissue_2_4327.npy
│ ├── Tissue_2_5861.npy
│ ├── Tissue_2_6910.npy
│ ├── Tissue_2_9569.npy
│ ├── Tissue_2_9599.npy
│ ├── Tissue_2_9684.npy
│ ├── Tissue_3_10163.npy
│ ├── Tissue_3_11736.npy
│ ├── Tissue_3_12666.npy
│ ├── Tissue_3_12794.npy
│ ├── Tissue_3_13262.npy
│ ├── Tissue_3_13850.npy
│ ├── Tissue_3_1443.npy
│ ├── Tissue_3_15028.npy
│ ├── Tissue_3_15037.npy
│ ├── Tissue_3_1526.npy
│ ├── Tissue_3_15283.npy
│ ├── Tissue_3_15641.npy
│ ├── Tissue_3_1584.npy
│ ├── Tissue_3_16139.npy
│ ├── Tissue_3_16275.npy
│ ├── Tissue_3_16431.npy
│ ├── Tissue_3_1673.npy
│ ├── Tissue_3_17222.npy
│ ├── Tissue_3_17288.npy
│ ├── Tissue_3_17682.npy
│ ├── Tissue_3_17823.npy
│ ├── Tissue_3_18447.npy
│ ├── Tissue_3_18679.npy
│ ├── Tissue_3_18706.npy
│ ├── Tissue_3_1891.npy
│ ├── Tissue_3_19517.npy
│ ├── Tissue_3_19530.npy
│ ├── Tissue_3_19595.npy
│ ├── Tissue_3_19725.npy
│ ├── Tissue_3_21530.npy
│ ├── Tissue_3_21678.npy
│ ├── Tissue_3_21791.npy
│ ├── Tissue_3_22927.npy
│ ├── Tissue_3_23085.npy
│ ├── Tissue_3_23161.npy
│ ├── Tissue_3_3332.npy
│ ├── Tissue_3_42135.npy
│ ├── Tissue_3_480.npy
│ ├── Tissue_3_492.npy
│ ├── Tissue_3_5199.npy
│ ├── Tissue_3_5292.npy
│ ├── Tissue_3_5334.npy
│ ├── Tissue_3_5376.npy
│ ├── Tissue_3_5378.npy
│ ├── Tissue_3_6005.npy
│ ├── Tissue_3_6065.npy
│ ├── Tissue_3_6238.npy
│ ├── Tissue_3_6310.npy
│ ├── Tissue_3_6344.npy
│ ├── Tissue_3_6730.npy
│ ├── Tissue_3_6861.npy
│ ├── Tissue_3_7346.npy
│ ├── Tissue_3_7502.npy
│ ├── Tissue_3_7831.npy
│ ├── Tissue_3_8562.npy
│ ├── Tissue_3_9809.npy
│ ├── Tissue_4_10991.npy
│ ├── Tissue_4_11167.npy
│ ├── Tissue_4_11184.npy
│ ├── Tissue_4_11425.npy
│ ├── Tissue_4_11664.npy
│ ├── Tissue_4_11790.npy
│ ├── Tissue_4_1208.npy
│ ├── Tissue_4_12407.npy
│ ├── Tissue_4_13305.npy
│ ├── Tissue_4_14365.npy
│ ├── Tissue_4_14431.npy
│ ├── Tissue_4_14691.npy
│ ├── Tissue_4_1501.npy
│ ├── Tissue_4_15191.npy
│ ├── Tissue_4_15266.npy
│ ├── Tissue_4_15269.npy
│ ├── Tissue_4_15273.npy
│ ├── Tissue_4_15333.npy
│ ├── Tissue_4_15662.npy
│ ├── Tissue_4_1600.npy
│ ├── Tissue_4_16887.npy
│ ├── Tissue_4_17707.npy
│ ├── Tissue_4_17947.npy
│ ├── Tissue_4_18588.npy
│ ├── Tissue_4_19067.npy
│ ├── Tissue_4_19602.npy
│ ├── Tissue_4_20012.npy
│ ├── Tissue_4_21513.npy
│ ├── Tissue_4_22008.npy
│ ├── Tissue_4_22293.npy
│ ├── Tissue_4_22427.npy
│ ├── Tissue_4_3675.npy
│ ├── Tissue_4_3731.npy
│ ├── Tissue_4_4221.npy
│ ├── Tissue_4_4419.npy
│ ├── Tissue_4_44906.npy
│ ├── Tissue_4_4744.npy
│ ├── Tissue_4_6584.npy
│ ├── Tissue_4_6589.npy
│ ├── Tissue_4_6739.npy
│ ├── Tissue_4_6827.npy
│ ├── Tissue_4_6904.npy
│ ├── Tissue_4_7830.npy
│ ├── Tissue_4_7968.npy
│ ├── Tissue_4_8010.npy
│ ├── Tissue_4_8585.npy
│ ├── Tissue_5_1049.npy
│ ├── Tissue_5_10618.npy
│ ├── Tissue_5_12264.npy
│ ├── Tissue_5_12835.npy
│ ├── Tissue_5_12894.npy
│ ├── Tissue_5_14246.npy
│ ├── Tissue_5_14371.npy
│ ├── Tissue_5_14841.npy
│ ├── Tissue_5_1639.npy
│ ├── Tissue_5_17423.npy
│ ├── Tissue_5_19155.npy
│ ├── Tissue_5_19755.npy
│ ├── Tissue_5_20836.npy
│ ├── Tissue_5_21381.npy
│ ├── Tissue_5_23079.npy
│ ├── Tissue_5_23084.npy
│ ├── Tissue_5_23166.npy
│ ├── Tissue_5_4184.npy
│ ├── Tissue_5_4787.npy
│ ├── Tissue_5_5071.npy
│ ├── Tissue_5_677.npy
│ ├── Tissue_5_7029.npy
│ ├── Tissue_5_7723.npy
│ ├── Tissue_5_7938.npy
│ ├── Tissue_5_8424.npy
│ ├── Tissue_5_8628.npy
│ ├── Tissue_6_10222.npy
│ ├── Tissue_6_10237.npy
│ ├── Tissue_6_10372.npy
│ ├── Tissue_6_10478.npy
│ ├── Tissue_6_10497.npy
│ ├── Tissue_6_10944.npy
│ ├── Tissue_6_10972.npy
│ ├── Tissue_6_1101.npy
│ ├── Tissue_6_11356.npy
│ ├── Tissue_6_11461.npy
│ ├── Tissue_6_11686.npy
│ ├── Tissue_6_11775.npy
│ ├── Tissue_6_119.npy
│ ├── Tissue_6_12285.npy
│ ├── Tissue_6_12712.npy
│ ├── Tissue_6_12874.npy
│ ├── Tissue_6_1291.npy
│ ├── Tissue_6_1295.npy
│ ├── Tissue_6_13046.npy
│ ├── Tissue_6_13250.npy
│ ├── Tissue_6_13321.npy
│ ├── Tissue_6_1335.npy
│ ├── Tissue_6_13369.npy
│ ├── Tissue_6_13715.npy
│ ├── Tissue_6_14052.npy
│ ├── Tissue_6_14469.npy
│ ├── Tissue_6_1468.npy
│ ├── Tissue_6_15347.npy
│ ├── Tissue_6_15468.npy
│ ├── Tissue_6_15472.npy
│ ├── Tissue_6_15603.npy
│ ├── Tissue_6_15999.npy
│ ├── Tissue_6_16265.npy
│ ├── Tissue_6_16560.npy
│ ├── Tissue_6_16636.npy
│ ├── Tissue_6_16930.npy
│ ├── Tissue_6_16985.npy
│ ├── Tissue_6_17098.npy
│ ├── Tissue_6_1725.npy
│ ├── Tissue_6_17308.npy
│ ├── Tissue_6_17357.npy
│ ├── Tissue_6_17462.npy
│ ├── Tissue_6_17968.npy
│ ├── Tissue_6_17979.npy
│ ├── Tissue_6_18189.npy
│ ├── Tissue_6_1838.npy
│ ├── Tissue_6_18661.npy
│ ├── Tissue_6_18676.npy
│ ├── Tissue_6_18883.npy
│ ├── Tissue_6_18893.npy
│ ├── Tissue_6_19159.npy
│ ├── Tissue_6_19308.npy
│ ├── Tissue_6_19401.npy
│ ├── Tissue_6_19430.npy
│ ├── Tissue_6_1946.npy
│ ├── Tissue_6_19776.npy
│ ├── Tissue_6_19930.npy
│ ├── Tissue_6_19935.npy
│ ├── Tissue_6_20138.npy
│ ├── Tissue_6_20273.npy
│ ├── Tissue_6_20359.npy
│ ├── Tissue_6_20534.npy
│ ├── Tissue_6_20857.npy
│ ├── Tissue_6_20977.npy
│ ├── Tissue_6_21009.npy
│ ├── Tissue_6_21052.npy
│ ├── Tissue_6_21207.npy
│ ├── Tissue_6_21295.npy
│ ├── Tissue_6_21514.npy
│ ├── Tissue_6_21539.npy
│ ├── Tissue_6_21851.npy
│ ├── Tissue_6_21926.npy
│ ├── Tissue_6_21973.npy
│ ├── Tissue_6_2203.npy
│ ├── Tissue_6_22133.npy
│ ├── Tissue_6_22138.npy
│ ├── Tissue_6_22348.npy
│ ├── Tissue_6_22357.npy
│ ├── Tissue_6_22475.npy
│ ├── Tissue_6_22642.npy
│ ├── Tissue_6_22907.npy
│ ├── Tissue_6_2296.npy
│ ├── Tissue_6_22988.npy
│ ├── Tissue_6_23056.npy
│ ├── Tissue_6_23287.npy
│ ├── Tissue_6_23485.npy
│ ├── Tissue_6_2518.npy
│ ├── Tissue_6_2800.npy
│ ├── Tissue_6_2841.npy
│ ├── Tissue_6_2933.npy
│ ├── Tissue_6_2978.npy
│ ├── Tissue_6_3307.npy
│ ├── Tissue_6_3309.npy
│ ├── Tissue_6_3506.npy
│ ├── Tissue_6_3536.npy
│ ├── Tissue_6_4076.npy
│ ├── Tissue_6_4133.npy
│ ├── Tissue_6_4359.npy
│ ├── Tissue_6_4373.npy
│ ├── Tissue_6_4524.npy
│ ├── Tissue_6_4591.npy
│ ├── Tissue_6_4726.npy
│ ├── Tissue_6_4749.npy
│ ├── Tissue_6_4882.npy
│ ├── Tissue_6_4905.npy
│ ├── Tissue_6_5016.npy
│ ├── Tissue_6_5115.npy
│ ├── Tissue_6_5250.npy
│ ├── Tissue_6_5648.npy
│ ├── Tissue_6_5723.npy
│ ├── Tissue_6_5851.npy
│ ├── Tissue_6_5879.npy
│ ├── Tissue_6_6110.npy
│ ├── Tissue_6_6229.npy
│ ├── Tissue_6_6292.npy
│ ├── Tissue_6_6439.npy
│ ├── Tissue_6_6542.npy
│ ├── Tissue_6_6602.npy
│ ├── Tissue_6_6749.npy
│ ├── Tissue_6_6841.npy
│ ├── Tissue_6_7207.npy
│ ├── Tissue_6_7236.npy
│ ├── Tissue_6_7756.npy
│ ├── Tissue_6_8011.npy
│ ├── Tissue_6_8196.npy
│ ├── Tissue_6_8227.npy
│ ├── Tissue_6_8382.npy
│ ├── Tissue_6_8700.npy
│ ├── Tissue_6_8818.npy
│ ├── Tissue_6_8988.npy
│ ├── Tissue_6_9130.npy
│ ├── Tissue_6_9150.npy
│ ├── Tissue_6_922.npy
│ ├── Tissue_6_945.npy
│ ├── Tissue_6_9465.npy
│ ├── Tissue_6_9501.npy
│ ├── Tissue_6_9528.npy
│ ├── Tissue_6_9640.npy
│ ├── Tissue_6_9849.npy
│ ├── Tissue_7_1044.npy
│ ├── Tissue_7_10916.npy
│ ├── Tissue_7_10989.npy
│ ├── Tissue_7_111.npy
│ ├── Tissue_7_11487.npy
│ ├── Tissue_7_11578.npy
│ ├── Tissue_7_11828.npy
│ ├── Tissue_7_12436.npy
│ ├── Tissue_7_12736.npy
│ ├── Tissue_7_12790.npy
│ ├── Tissue_7_12842.npy
│ ├── Tissue_7_13524.npy
│ ├── Tissue_7_13934.npy
│ ├── Tissue_7_1432.npy
│ ├── Tissue_7_14811.npy
│ ├── Tissue_7_14913.npy
│ ├── Tissue_7_14926.npy
│ ├── Tissue_7_14952.npy
│ ├── Tissue_7_15198.npy
│ ├── Tissue_7_15521.npy
│ ├── Tissue_7_15876.npy
│ ├── Tissue_7_1603.npy
│ ├── Tissue_7_16273.npy
│ ├── Tissue_7_16532.npy
│ ├── Tissue_7_16716.npy
│ ├── Tissue_7_17507.npy
│ ├── Tissue_7_17704.npy
│ ├── Tissue_7_17779.npy
│ ├── Tissue_7_17938.npy
│ ├── Tissue_7_18050.npy
│ ├── Tissue_7_18300.npy
│ ├── Tissue_7_18464.npy
│ ├── Tissue_7_1861.npy
│ ├── Tissue_7_20002.npy
│ ├── Tissue_7_20065.npy
│ ├── Tissue_7_2033.npy
│ ├── Tissue_7_20552.npy
│ ├── Tissue_7_2076.npy
│ ├── Tissue_7_20864.npy
│ ├── Tissue_7_21117.npy
│ ├── Tissue_7_21211.npy
│ ├── Tissue_7_21259.npy
│ ├── Tissue_7_21986.npy
│ ├── Tissue_7_22009.npy
│ ├── Tissue_7_22260.npy
│ ├── Tissue_7_22369.npy
│ ├── Tissue_7_2242.npy
│ ├── Tissue_7_2259.npy
│ ├── Tissue_7_23231.npy
│ ├── Tissue_7_23478.npy
│ ├── Tissue_7_2718.npy
│ ├── Tissue_7_3229.npy
│ ├── Tissue_7_3920.npy
│ ├── Tissue_7_4142.npy
│ ├── Tissue_7_45543.npy
│ ├── Tissue_7_4694.npy
│ ├── Tissue_7_4763.npy
│ ├── Tissue_7_4809.npy
│ ├── Tissue_7_4851.npy
│ ├── Tissue_7_5052.npy
│ ├── Tissue_7_5664.npy
│ ├── Tissue_7_6052.npy
│ ├── Tissue_7_6219.npy
│ ├── Tissue_7_640.npy
│ ├── Tissue_7_6526.npy
│ ├── Tissue_7_6702.npy
│ ├── Tissue_7_7044.npy
│ ├── Tissue_7_7065.npy
│ ├── Tissue_7_7235.npy
│ ├── Tissue_7_7722.npy
│ ├── Tissue_7_7859.npy
│ ├── Tissue_7_7914.npy
│ ├── Tissue_7_7993.npy
│ ├── Tissue_7_8054.npy
│ ├── Tissue_7_8107.npy
│ ├── Tissue_7_8200.npy
│ ├── Tissue_7_904.npy
│ ├── Tissue_7_9210.npy
│ ├── Tissue_7_9691.npy
│ └── Tissue_7_9759.npy
├── codecov.yml
├── configs/
│ ├── test_algorithms.json
│ ├── test_datasets.json
│ ├── test_models.json
│ ├── test_modules.json
│ ├── test_results.json
│ └── test_scalability.json
├── docs/
│ ├── Makefile
│ ├── make.bat
│ ├── requirements.txt
│ └── source/
│ ├── _autoapi_temp/
│ │ └── python/
│ │ └── module.rst
│ ├── conf.py
│ ├── contribution.rst
│ ├── index.rst
│ ├── installation.rst
│ ├── overview.rst
│ ├── refer.bib
│ ├── reference.rst
│ └── tutorials/
│ ├── algorithm.rst
│ ├── code_carbon.rst
│ ├── data_distribution.rst
│ ├── dataset.rst
│ ├── encryption.rst
│ ├── models.rst
│ ├── running.rst
│ └── tutorial.rst
├── federa/
│ ├── __init__.py
│ ├── client/
│ │ ├── __init__.py
│ │ ├── src/
│ │ │ ├── ClientConnection_pb2.py
│ │ │ ├── ClientConnection_pb2_grpc.py
│ │ │ ├── __init__.py
│ │ │ ├── client.py
│ │ │ ├── client_lib.py
│ │ │ ├── data_utils.py
│ │ │ ├── get_data.py
│ │ │ ├── net.py
│ │ │ └── net_lib.py
│ │ └── start_client.py
│ ├── server/
│ │ ├── __init__.py
│ │ ├── src/
│ │ │ ├── ClientConnection_pb2.py
│ │ │ ├── ClientConnection_pb2_grpc.py
│ │ │ ├── __init__.py
│ │ │ ├── algorithms/
│ │ │ │ ├── fedadagrad.py
│ │ │ │ ├── fedadam.py
│ │ │ │ ├── fedavg.py
│ │ │ │ ├── fedavgm.py
│ │ │ │ ├── feddyn.py
│ │ │ │ ├── fedyogi.py
│ │ │ │ ├── mime.py
│ │ │ │ ├── mimelite.py
│ │ │ │ └── scaffold.py
│ │ │ ├── client_connection_servicer.py
│ │ │ ├── client_manager.py
│ │ │ ├── client_wrapper.py
│ │ │ ├── distribution.py
│ │ │ ├── server.py
│ │ │ ├── server_evaluate/
│ │ │ │ ├── __init__.py
│ │ │ │ └── eval_lib.py
│ │ │ ├── server_lib.py
│ │ │ └── verification.py
│ │ └── start_server.py
│ └── tests/
│ ├── __init__.py
│ ├── minitest.json
│ ├── minitest.py
│ └── misc.py
├── requirements.txt
├── server_custom_dataset/
│ └── CUSTOM/
│ └── test/
│ ├── Breast_1_131.npy
│ ├── Breast_1_178.npy
│ ├── Breast_1_38.npy
│ ├── Breast_1_46.npy
│ ├── Breast_1_56.npy
│ ├── Breast_1_57.npy
│ ├── Breast_1_58.npy
│ ├── Chestxray_0_10192.npy
│ ├── Chestxray_0_2599.npy
│ ├── Chestxray_0_27.npy
│ ├── Chestxray_10_2647.npy
│ ├── Chestxray_10_7361.npy
│ ├── Chestxray_11_6369.npy
│ ├── Chestxray_12_3194.npy
│ ├── Chestxray_12_6281.npy
│ ├── Chestxray_1_1545.npy
│ ├── Chestxray_2_10770.npy
│ ├── Chestxray_2_1294.npy
│ ├── Chestxray_2_2942.npy
│ ├── Chestxray_3_4808.npy
│ ├── Chestxray_3_563.npy
│ ├── Chestxray_3_8533.npy
│ ├── Chestxray_3_9185.npy
│ ├── Chestxray_3_9271.npy
│ ├── Chestxray_3_9492.npy
│ ├── Chestxray_5_10699.npy
│ ├── Chestxray_5_3477.npy
│ ├── Chestxray_5_756.npy
│ ├── Chestxray_5_7941.npy
│ ├── Chestxray_5_8493.npy
│ ├── Chestxray_6_7326.npy
│ ├── Chestxray_7_10995.npy
│ ├── Chestxray_7_8642.npy
│ ├── Chestxray_7_9211.npy
│ ├── Chestxray_8_2448.npy
│ ├── Chestxray_9_1970.npy
│ ├── Oct_0_10252.npy
│ ├── Oct_0_10370.npy
│ ├── Oct_0_1901.npy
│ ├── Oct_0_2534.npy
│ ├── Oct_0_4375.npy
│ ├── Oct_0_521.npy
│ ├── Oct_0_5368.npy
│ ├── Oct_0_7082.npy
│ ├── Oct_0_72818.npy
│ ├── Oct_0_7570.npy
│ ├── Oct_0_9852.npy
│ ├── Oct_1_757.npy
│ ├── Oct_2_26531.npy
│ ├── Oct_2_3752.npy
│ ├── Oct_2_8134.npy
│ ├── Oct_2_8207.npy
│ ├── Oct_2_9648.npy
│ ├── Oct_3_1567.npy
│ ├── Oct_3_1669.npy
│ ├── Oct_3_2292.npy
│ ├── Oct_3_2794.npy
│ ├── Oct_3_4851.npy
│ ├── Oct_3_4912.npy
│ ├── Oct_3_5127.npy
│ ├── Oct_3_5626.npy
│ ├── Oct_3_5777.npy
│ ├── Oct_3_6087.npy
│ ├── Oct_3_6417.npy
│ ├── Oct_3_9802.npy
│ ├── Tissue_0_10673.npy
│ ├── Tissue_0_12024.npy
│ ├── Tissue_0_12038.npy
│ ├── Tissue_0_14742.npy
│ ├── Tissue_0_1487.npy
│ ├── Tissue_0_17483.npy
│ ├── Tissue_0_18694.npy
│ ├── Tissue_0_20122.npy
│ ├── Tissue_0_2373.npy
│ ├── Tissue_0_3171.npy
│ ├── Tissue_0_411.npy
│ ├── Tissue_0_4904.npy
│ ├── Tissue_0_6028.npy
│ ├── Tissue_0_7434.npy
│ ├── Tissue_0_8139.npy
│ ├── Tissue_0_8962.npy
│ ├── Tissue_0_9511.npy
│ ├── Tissue_0_9949.npy
│ ├── Tissue_3_8272.npy
│ ├── Tissue_3_9593.npy
│ ├── Tissue_4_10949.npy
│ ├── Tissue_4_16558.npy
│ ├── Tissue_4_17314.npy
│ ├── Tissue_4_18139.npy
│ ├── Tissue_4_2355.npy
│ ├── Tissue_5_17494.npy
│ ├── Tissue_5_22443.npy
│ ├── Tissue_6_11839.npy
│ ├── Tissue_6_12194.npy
│ ├── Tissue_6_13317.npy
│ ├── Tissue_6_14084.npy
│ ├── Tissue_6_15019.npy
│ ├── Tissue_6_15092.npy
│ ├── Tissue_6_15204.npy
│ ├── Tissue_6_17363.npy
│ ├── Tissue_6_19355.npy
│ ├── Tissue_6_19528.npy
│ ├── Tissue_6_21927.npy
│ ├── Tissue_6_37014.npy
│ ├── Tissue_7_14747.npy
│ ├── Tissue_7_14849.npy
│ ├── Tissue_7_18085.npy
│ ├── Tissue_7_18646.npy
│ ├── Tissue_7_21396.npy
│ ├── Tissue_7_21427.npy
│ ├── Tissue_7_2508.npy
│ ├── Tissue_7_2884.npy
│ ├── Tissue_7_7116.npy
│ └── Tissue_7_7248.npy
├── ssl/
│ ├── README.md
│ ├── ca-config.json
│ ├── ca-csr.json
│ ├── client-csr.json
│ └── server-csr.json
├── test/
│ ├── __init__.py
│ ├── benchtest/
│ │ ├── __init__.py
│ │ ├── test_results.py
│ │ └── test_scalability.py
│ ├── misc.py
│ └── unittest/
│ ├── __init__.py
│ ├── test_algorithms.py
│ ├── test_datasets.py
│ ├── test_models.py
│ └── test_modules.py
└── tutorials/
├── Code_Carbon_Tutorial.ipynb
├── Federated_Algorithm_Tutorial.ipynb
├── Number_of_clients_Tutorial.ipynb
├── Verifcation_module_tutorial.ipynb
├── accuracy_plot.py
├── data_distribution.ipynb
└── media_plot.ipynb
================================================
FILE CONTENTS
================================================
================================================
FILE: .bandit
================================================
[bandit]
targets: federa
[bandit.test]
severity: MEDIUM,HIGH
================================================
FILE: .coveragerc
================================================
[run]
parallel = True
concurrency = multiprocessing, thread
[report]
omit =
federa/server/start_server.py
federa/client/start_client.py
federa/tests/*
================================================
FILE: .github/workflows/publish.yml
================================================
name: Build and Push Docker Image
on:
push:
branches:
- main
env:
DOCKER_HUB_USERNAME: anupamkliv
DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }}
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Login to Docker Hub
run: docker login --username $DOCKER_HUB_USERNAME --password $DOCKER_HUB_PASSWORD
- name: Build and tag Docker image
run: |
docker build -t anupamkliv/federa:latest .
docker tag anupamkliv/federa:latest anupamkliv/federa:${{ github.sha }}
- name: Copy README to Docker image
run: |
docker create --name temp_container anupamkliv/federa:latest
docker cp README.md temp_container:/README.md
docker commit temp_container anupamkliv/federa:latest
docker rm temp_container
- name: Push Docker image to Docker Hub
run: |
docker push anupamkliv/federa:latest
docker push anupamkliv/federa:${{ github.sha }}
================================================
FILE: .github/workflows/pytest_coverage.yml
================================================
# This workflow will install Python dependencies, run tests and lint with a single version of Python
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
name: Pytest and code coverage
on: [push]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.8
uses: actions/setup-python@v3
with:
python-version: "3.8"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest coverage
pip install -r requirements.txt
- name: Test with pytest and report code coverage
run: |
coverage run -m --source=federa -p test.unittest.test_algorithms
coverage run -m --source=federa -p test.unittest.test_datasets
coverage run -m --source=federa -p test.unittest.test_modules
coverage run -m --source=federa -p test.unittest.test_models
coverage combine
continue-on-error: true
- name: Upload coverage report
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
- name: Run Bandit
run: |
bandit -r --ini .bandit
- name: Coveralls GitHub Action
uses: coverallsapp/github-action@v2
================================================
FILE: .github/workflows/ubuntu.yml
================================================
name: Ubuntu (latest)
on: [push]
permissions:
contents: read
jobs:
interactive-kvasir: # from interactive-kvasir.yml
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.8
uses: actions/setup-python@v3
with:
python-version: "3.8"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Interactive API - pytorch_kvasir_unet
run: |
pip install torch==1.13.1
pip install torchvision==0.14.1
python -m test.unittest.test_algorithms
================================================
FILE: .github/workflows/windows.yml
================================================
name: Windows (latest)
on: [push]
permissions:
contents: read
jobs:
interactive-kvasir: # from interactive-kvasir.yml
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.8
uses: actions/setup-python@v3
with:
python-version: "3.8"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Interactive API - pytorch_kvasir_unet
run: |
pip install torch==1.13.1
pip install torchvision==0.14.1
python -m test.unittest.test_algorithms
cli: # from taskrunner.yml
needs: [interactive-kvasir]
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.8
uses: actions/setup-python@v3
with:
python-version: "3.8"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Test TaskRunner API
run: |
python -m test.unittest.test_algorithms
================================================
FILE: .gitignore
================================================
================================================
FILE: CONDUCT.md
================================================
# Contributor Code of Conduct
## Introduction
As contributors and maintainers of this Federated Learning framework, we are committed to creating a safe and welcoming environment for everyone. This code of conduct outlines our expectations for all those who participate in our community, as well as the consequences for unacceptable behavior.
## Code of Conduct
We expect all contributors and users of the Federated Learning framework to abide by the following standards:
- **Be respectful:** Treat others with respect and dignity, and avoid engaging in any behavior that could be considered abusive, threatening, or harassing.
- **Be inclusive:** Ensure that everyone feels welcome, regardless of their background or identity.
- **Be collaborative:** Encourage collaboration and teamwork, and work towards common goals.
- **Be open-minded:** Be open to new ideas and perspectives, and consider feedback and criticism in a constructive manner.
- **Be transparent:** Be transparent about the framework's development process, and communicate any changes or updates clearly and honestly.
- **Be accountable:** Hold yourself and others accountable for their actions and behaviors, and enforce the code of conduct fairly and consistently.
We believe in creating a safe and welcoming environment for all members of our community, and we will not tolerate any behavior that violates this code of conduct. If you witness or experience any violations of this code of conduct, please report them to [insert contact information here].
By participating in our community, you agree to abide by this code of conduct.
## Unacceptable Behavior
Examples of unacceptable behavior include:
- Harassment, intimidation, or discrimination in any form.
- Physical, verbal, or written abuse, threats, or insults.
- Offensive or derogatory comments.
- Disrespectful or disruptive behavior.
- Inappropriate use of nudity, sexual images, or offensive language.
- Deliberate intimidation or stalking.
- Unwelcome sexual attention or advances.
- Advocating for or encouraging any of the above behavior.
## Consequences of Unacceptable Behavior
If a contributor or user engages in behavior that violates our standards of conduct, we may take any action we deem appropriate, up to and including temporary or permanent expulsion from the community.
Reporting Guidelines
If you experience or witness behavior that violates our standards of conduct, please report it to us by contacting [insert contact information here]. All reports will be kept confidential, and we will work with you to determine an appropriate course of action.
Attribution
Thank you for your cooperation in maintaining a positive and inclusive community for everyone involved in the Federated Learning framework!
================================================
FILE: Dockerfile
================================================
# Dockerfile
# Determine the system architecture
ARG ARCHITECTURE
# Use the official Python base image
FROM python:3.10-slim
# Install system dependencies
RUN apt-get update && \
apt-get install -y \
git \
protobuf-compiler
# Install PyTorch
RUN pip install torch torchvision
# Set the working directory
WORKDIR /usr/src/federa
# Copy the repository code into the container
COPY . .
# Install Python dependencies
RUN pip install --upgrade pip && \
pip install -r requirements.txt
# Expose the port for communication with the server
EXPOSE 8214
# Set the entry point command
ENTRYPOINT []
# Default argument values for the server
#CMD ["python", "-m", "federa.server.start_server"]
# Specify the command arguments as environment variables
ENV SERVER_ARGS=""
ENV CLIENT_ARGS=""
# Start the server and client using the provided arguments
CMD bash -c "python -m federa.server.start_server ${SERVER_ARGS} & \
python -m federa.client.start_client ${CLIENT_ARGS}"
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [2023] [Indian Institute of Technology, Kharagpur, West Bengal, India]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
# Federated Learning Framework
[](https://pypi.org/project/federa/)
[](https://federa.readthedocs.io/en/latest/?badge=latest)
[](https://opensource.org/licenses/Apache-2.0)
[](https://github.com/anupamkliv/FedERA/actions/workflows/ubuntu.yml)
[](https://github.com/anupamkliv/FedERA/actions/workflows/windows.yml)
[](https://coveralls.io/github/anupamkliv/FedERA?branch=main)
[](https://codecov.io/github/Kasliwal17/FedERA)
[](https://hub.docker.com/r/anupamkliv/federa)
[](https://github.com/PyCQA/bandit)
[](https://github.com/pylint-dev/pylint)
[](https://bestpractices.coreinfrastructure.org/projects/7364)
[](https://pepy.tech/project/federa)
`FedERA` is a highly dynamic and customizable framework that can accommodate many use cases with flexibility by implementing several functionalities over different federated learning algorithms, and essentially creating a plug-and-play architecture to accommodate different use cases.
## Supported Devices
FedERA has been extensively tested on and works with the following devices:
* Intel CPUs
* Nvidia GPUs
* Nvidia Jetson
* Raspberry Pi
* Intel NUC
With `FedERA`, it is possible to operate the server and clients on **separate devices** or on a **single device** through various means, such as utilizing different terminals or implementing multiprocessing.
## Installation
- Install the latest version from source code:
```
$ git clone https://github.com/anupamkliv/FedERA.git
$ cd FedERA
$ pip install -r requirements.txt
```
- Install the stable version (old version) via pip:
```
# assign the version federa==1.0.0
$ pip install federa
```
- Using Docker
Create a docker image
```
docker build -t federa .
```
Run the docker image
```
docker run federa
```
## Documentation
Website documentation has been made availbale for `FedERA`. Please visit [FedERA Documentation](https://federa.readthedocs.io/en/latest/index.html) for more details.
1. [Overview](https://federa.readthedocs.io/en/latest/overview.html)
2. [Installation](https://federa.readthedocs.io/en/latest/installation.html)
3. [Tutorials](https://federa.readthedocs.io/en/latest/tutorials.html)
4. [Contribution](https://federa.readthedocs.io/en/latest/contribution.html)
5. [API Reference](https://federa.readthedocs.io/en/latest/api.html)
## Starting server
```
python -m federa.server.start_server \
--algorithm fedavg \
--clients 1 \
--rounds 10 \
--epochs 10 \
--batch_size 10 \
--lr 0.01 \
--dataset mnist \
```
## Starting client
```
python -m federa.client.start_client \
--ip localhost:8214 \
--device cpu \
```
## Arguments to the clients and server
### Server
| Argument | Description | Default |
| ---------- | ------------------------------------------------------------ | ------- |
| algorithm | specifies the aggregation algorithm | fedavg |
| clients | specifies number of clients selected per round | 1 |
| fraction | specifies fraction of clients selected | 1 |
| rounds | specifies total number of rounds | 1 |
| model_path | specifies initial server model path | initial_model.pt |
| epochs | specifies client epochs per round | 1 |
| accept_conn| determines if connections accepted after FL begins | 1 |
| verify | specifies if verification module runs before rounds | 0 |
| threshold | specifies minimum verification score | 0 |
| timeout | specifies client training time limit per round | None |
| resize_size| specifies dataset resize dimension | 32 |
| batch_size | specifies dataset batch size | 32 |
| net | specifies network architecture | LeNet |
| dataset | specifies dataset name | MNIST |
| niid | specifies data distribution among clients | 1 |
| carbon | specifies if carbon emissions tracked at client side | 0 |
| encryption | specifies whether to use ssl encryption or not | 0 |
| server_key | specifies path to server key certificate | server-key.pem|
| server_cert | specifies path to server certificate | server.pem|
### Client
| Argument | Description | Default |
| ---------- | ------------------------------------------------------------ | ------- |
| server_ip | specifies server IP address | localhost:8214 |
| device | specifies device | cpu |
| encryption | specifies whether to use ssl encryption or not | 0 |
| ca | specifies path to CA certificate | ca.pem|
| wait_time | specifies time to wait before reconnecting to server | 30 |
## Architecture
Files architecture of `FedERA`. These contents may be helpful for users to understand our repo.
```
FedERA
├── federa
│ ├── client
│ │ ├── src
│ | | ├── client_lib
│ | | ├── client
│ | | ├── ClientConnection_pb2_grpc
│ | | ├── ClientConnection_pb2
│ | | ├── data_utils
│ | | ├── distribution
│ | | ├── get_data
│ | | ├── net_lib
│ | | ├── net
│ │ └── start_client
│ ├── server
│ │ ├── src
│ │ | ├── algorithms
│ │ | ├── server_evaluate
│ │ | ├── client_connection_servicer
│ │ | ├── client_manager
│ │ | ├── client_wrapper
│ │ | ├── ClientConnection_pb2_grpc
│ │ | ├── ClientConnection_pb2
│ │ | ├── server_lib
│ │ | ├── server
│ │ | ├── verification
│ │ └── start_server
| └── test
| ├── minitest
| └── misc
│
└── test
├── misc
├── benchtest
| ├── test_results
| └── test_scalability
└──unittest
├── test_algorithms
├── test_datasets
├── test_models
└── test_modules
```
## The framework is be composed of 4 modules, each module building upon the last:
* **Module 1: Verification module** [docs](https://federa.readthedocs.io/en/latest/overview.html#verification-module)
* **Module 2: Timeout module** [docs](https://federa.readthedocs.io/en/latest/overview.html#timeout-module)
* **Module 3: Intermediate client connections module** [docs](https://federa.readthedocs.io/en/latest/overview.html#intermediate-client-connections-module)
* **Module 4: Carbon emission tracking module** [docs](https://federa.readthedocs.io/en/latest/overview.html#carbon-emissions-tracking-module)
## Running tests
Various unit tests and bench tests are available in the `test` directory. To run any tests, run the following command from the root directory:
```
python -m test.unittest.test_algorithms
python -m test.unittest.test_datasets
python -m test.unittest.test_models
python -m test.unittest.test_modules
```
## Federated Learning Algorithms
Following federated learning algorithms are implemented in this framework:
| Method | Paper | Publication |
| ------------------- | ------------------------------------------------------------ | ---------------------------------------------------- |
| FedAvg | [Communication-Efficient Learning of Deep Networks from Decentralized Data](http://proceedings.mlr.press/v54/mcmahan17a/mcmahan17a.pdf) | AISTATS'2017 |
| FedDyn | [Federated Learning Based on Dynamic Regularization](https://openreview.net/forum?id=B7v4QMR6Z9w) | ICLR' 2021 |
| Scaffold | [SCAFFOLD: Stochastic Controlled Averaging for Federated Learning]() | ICML'2020 |
| Personalized FedAvg | [Improving Federated Learning Personalization via Model Agnostic Meta Learning](https://arxiv.org/pdf/1909.12488.pdf) | Pre-print |
| FedAdagrad | [Adaptive Federated Optimization](https://arxiv.org/pdf/2003.00295.pdf) | ICML'2020 |
| FedAdam | [Adaptive Federated Optimization](https://arxiv.org/pdf/2003.00295.pdf) | ICML'2020 |
| FedYogi | [Adaptive Federated Optimization](https://arxiv.org/pdf/2003.00295.pdf) | ICML'2020 |
| Mime | [Mime: Mimicking Centralized Stochastic Algorithms in Federated Learning](https://arxiv.org/pdf/2008.03606.pdf) | ICML'2020 |
| Mimelite | [Mime: Mimicking Centralized Stochastic Algorithms in Federated Learning](https://arxiv.org/pdf/2008.03606.pdf) | ICML'2020 |
## Datasets & Data Partition
Sophisticated in the real world, FL needs to handle various kind of data distribution scenarios, including iid and non-iid scenarios. Though there already exists some datasets and partition schemes for published data benchmark, it still can be very messy and hard for researchers to partition datasets according to their specific research problems, and maintain partition results during simulation.
### Data Partition
We provide multiple Non-IID data partition schemes. Here we show the data partition visualization of several common used datasets as the examples.
#### Balanced IID partition
Each client has same number of samples, and same distribution for all class samples.
<div align="left">
<img src="media/data_distribution/class_stats_0.png" width="300" />
<img src="media/data_distribution/sample_stats_0.png" width="300" />
</div>
#### Non-IID partition 2
<div align="left">
<img src="media/data_distribution/class_stats_1.png" width="300" />
<img src="media/data_distribution/sample_stats_1.png" width="300" />
</div>
#### Non-IID partition 3
<div align="left">
<img src="media/data_distribution/class_stats_2.png" width="300" />
<img src="media/data_distribution/sample_stats_2.png" width="300" />
</div>
<!-- #### Non-IID partition 4
<div align="left">
<img src="media/class_stats_3.png" width="300" />
<img src="media/sample_stats_3.png" width="300" />
</div>
#### Non-IID partition 5
<div align="left">
<img src="media/class_stats_4.png" width="300" />
<img src="media/sample_stats_4.png" width="300" />
</div> -->
### Datasets Supported
| Dataset | Training samples | Test samples | Classes
| ---------------------- | ------------------------ | ------------------ | ------------------ |
| MNIST | 60,000 | 10,000 | 10 |
| FashionMnist | 60,000 | 10,000 | 10 |
| CIFAR-10 | 50,000 | 10,000 | 10 |
| CIFAR-100 | 50,000 | 10,000 | 100 |
### Custom Dataset Support
We also provide a simple way to add your own dataset to the framework. The models employed in this framework were trained using a limited subset of the publicly accessible benchmark dataset MedMNIST v2 [(link)](https://medmnist.com/). We specifically selected four different medical image classes from this dataset, which include breast ultrasound (US), chest X-ray, retinal optical coherence tomography (OCT), and tissue microscopy. Each image within the dataset possesses dimensions of 28x28 pixels.
For the framework's implementation, we utilized this custom dataset for both the side server and the client. Look into [docs](https://federa.readthedocs.io/en/latest/tutorials/dataset.html#adding-support-for-new-datasets) for more details.
## Models Supported
`FedERA` has support for the following Deep Learning models, which are loaded from `torchvision.models`:
* LeNet-5
* ResNet-18
* ResNet-50
* VGG-16
* AlexNet
### Custom Model Support
We also provide a simple way to add your own models to the framework. Look into [docs](https://federa.readthedocs.io/en/latest/tutorials/dataset.html#adding-support-for-new-datasets) for more details.
## Carbon emission tracking
In `FedERA` [CodeCarbon](https://github.com/mlco2/codecarbon) package is used to estimate the carbon emissions generated by clients during training. CodeCarbon is a Python package that provides an estimation of the carbon emissions associated with software code.
## Performance Evaluation under different Non-IID setting
<!--
The `accuracy.py` file has functions defined needed to plot all the graphs show in this section.
### Accuracy of various FL algorithms available in the framework with a few dataset
<br>
<div align="center">
<table style="margin: auto">
<thead>
<tr>
<th>Dataset</th>
<th colspan=3>MNIST</th>
<th colspan=3>CIFAR-10</th>
<th colspan=3>CIFAR-100</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center" >Algorithm </td>
<td style="text-align: center">K=1</td>
<td style="text-align: center">K=2</td>
<td style="text-align: center">K=3</td>
<td style="text-align: center">K=1</td>
<td style="text-align: center">K=2</td>
<td style="text-align: center">K=3</td>
<td style="text-align: center">K=1</td>
<td style="text-align: center">K=2</td>
<td style="text-align: center">K=3</td>
</tr>
<tr>
<td>FedAvg </td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>FedAvgM </td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>FedAdam </td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>FedAdagrad </td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>FedYogi </td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Mime </td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Mimelite </td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>FedDyn </td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Scaffold </td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Personalized-FedAvg </td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
-->
### Plotting the accuracy of some algorithms against different Non-IID distributions
<div align="left">
<img src="media/accuracy/Al_0.png" width="230" />
<img src="media/accuracy/Al_1.png" width="230" />
<img src="media/accuracy/Al_3.png" width="230" />
<!-- <img src="media/accuracy/Al_4.png" width="230" /> -->
</div>
### Plotting accuracy on Non-IID distribution with different algorithms
<div align="left">
<img src="media/accuracy/niid_1.png" width="220" />
<img src="media/accuracy/niid_2.png" width="220" />
<img src="media/accuracy/niid_3.png" width="220" />
<!-- <img src="media/accuracy/niid_4.png" width="220" /> -->
</div>
<br/>
### Comparing accuracy of different algorithm with different Non-IID distributions
<div align="center">
<img width="40%" alt="" src="media/accuracy/Accuracy.png" >
</div>
<!-- ## References
<a id="1">[1]</a> Schmidt, V., Goyal, K., Joshi, A., Feld, B., Conell, L., Laskaris, N., Blank, D., Wilson, J., Friedler, S., & Luccioni, S. (2021). CodeCarbon: Estimate and Track Carbon Emissions from Machine Learning Computing. https://doi.org/10.5281/zenodo.4658424
<a id="2">[2]</a> -->
## Contact
<!-- Project Investigator: [Prof. ](https://scholar.google.com/citations?user=gF0H9nEAAAAJ&hl=ennjujbj) (abc@edu).
For technical issues related to __**FedERA**__ development, please contact our development team through Github issues or email:
- [Name Sirname](https://scholar.google.com/citations___): _____@gmail.com -->
For technical issues related to __**FedERA**__ development, please contact our development team through Github issues or email:
**Principal Investigator**
<a href="https://www.linkedin.com/in/debdoot/">Dr Debdoot Sheet</a> </br>
Department of Electrical Engineering,</br>
Indian Institute of Technology Kharagpur</br>
email: debdoot@ee.iitkgp.ac.in
**Contributor**
<a href="https://in.linkedin.com/in/anupam-borthakur-b85000185/">Anupam Borthakur</a> </br>
Centre of Excellence in Artificial Intelligence, </br>
Indian Institute of Technology Kharagpur </br>
email: anupamborthakur@kgpian.iitkgp.ac.in </br>
Github username: anupam-kliv
<a href="https://www.linkedin.com/in/asimmanna17/">Asim Manna</a> </br>
Centre of Excellence in Artificial Intelligence, </br>
Indian Institute of Technology Kharagpur </br>
email: asimmanna17@kgpian.iitkgp.ac.in </br>
Github username: asimmanna17
<a href="https://www.linkedin.com/in/aditya-kasliwal-982525227"> Aditya Kasliwal</a></br>
Manipal Institute of Technology</br>
email: kasliwaladitya17@gmail.com </br>
Github username: Kasliwal17
<a href="https://www.linkedin.com/in/dipayan-dewan-aabb8a79/">Dipayan Dewan</a> </br>
Centre of Excellence in Artificial Intelligence, </br>
Indian Institute of Technology Kharagpur </br>
email: diipayan93@kgpian.iitkgp.ac.in </br>
Github username: dipayandewan94
================================================
FILE: codecov.yml
================================================
codecov:
require_ci_to_pass: yes
================================================
FILE: configs/test_algorithms.json
================================================
{
"fedavg":{
"server": {
"algorithm":"fedavg",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":3,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": 20,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client": {
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"fedadagrad":{
"server":{
"algorithm":"fedadagrad",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":3,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": 20,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "CIFAR10",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"fedadam":{
"server":{
"algorithm":"fedadam",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":3,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": 20,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "CIFAR100",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"fedavgm":{
"server":{
"algorithm":"fedavgm",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":3,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": 20,
"resize_size": 224,
"batch_size": 32,
"net": "AlexNet",
"dataset": "CIFAR100",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"feddyn":{
"server":{
"algorithm":"feddyn",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":3,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": 20,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"fedyogi":{
"server":{
"algorithm":"fedyogi",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":3,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": 20,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"mime":{
"server":{
"algorithm":"mime",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":2,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": 20,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"mimelite":{
"server":{
"algorithm":"mimelite",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":3,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": 20,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"scaffold":{
"server":{
"algorithm":"scaffold",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":3,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": 20,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
}
}
================================================
FILE: configs/test_datasets.json
================================================
{
"MNIST":{
"server": {
"algorithm":"fedavg",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client": {
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"FashionMNIST":{
"server": {
"algorithm":"fedavg",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "FashionMNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client": {
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"CIFAR10":{
"server":{
"algorithm":"fedavg",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "resnet18",
"dataset": "CIFAR10",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"CIFAR100":{
"server":{
"algorithm":"fedavg",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "resnet18",
"dataset": "CIFAR100",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"CUSTOM":{
"server":{
"algorithm":"fedavg",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "CUSTOM",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
}
}
================================================
FILE: configs/test_models.json
================================================
{
"LeNet":{
"server":{
"algorithm":"fedavg",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"resnet18":{
"server":{
"algorithm":"fedavg",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "resnet18",
"dataset": "CIFAR10",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"resnet50":{
"server":{
"algorithm":"fedavg",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "resnet50",
"dataset": "CIFAR10",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"vgg16":{
"server":{
"algorithm":"fedavg",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "vgg16",
"dataset": "CIFAR10",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"AlexNet":{
"server":{
"algorithm":"fedavg",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": 30,
"resize_size": 224,
"batch_size": 32,
"net": "AlexNet",
"dataset": "CIFAR10",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
}
}
================================================
FILE: configs/test_modules.json
================================================
{
"verification":{
"server":{
"algorithm":"fedavg",
"num_of_clients":2,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 1,
"verification_threshold": 0.1,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"timeout":{
"server":{
"algorithm":"fedavg",
"num_of_clients":2,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": 60,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"intermediate":{
"server":{
"algorithm":"fedavg",
"num_of_clients":1,
"fraction_of_clients":1,
"num_of_rounds":2,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":1 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
}
}
================================================
FILE: configs/test_results.json
================================================
{
"fedavg":{
"server": {
"algorithm":"fedavg",
"num_of_clients":2,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client": {
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"fedadagrad":{
"server":{
"algorithm":"fedadagrad",
"num_of_clients":2,
"fraction_of_clients":1,
"num_of_rounds":2,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"fedadam":{
"server":{
"algorithm":"fedadam",
"num_of_clients":2,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"fedavgm":{
"server":{
"algorithm":"fedavgm",
"num_of_clients":2,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"feddyn":{
"server":{
"algorithm":"feddyn",
"num_of_clients":2,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"fedyogi":{
"server":{
"algorithm":"fedyogi",
"num_of_clients":2,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"mime":{
"server":{
"algorithm":"mime",
"num_of_clients":2,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"mimelite":{
"server":{
"algorithm":"mimelite",
"num_of_clients":2,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"scaffold":{
"server":{
"algorithm":"scaffold",
"num_of_clients":2,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
}
}
================================================
FILE: configs/test_scalability.json
================================================
{
"2":{
"server":{
"algorithm":"fedavg",
"num_of_clients":2,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"4":{
"server":{
"algorithm":"fedavg",
"num_of_clients":4,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"6":{
"server":{
"algorithm":"fedavg",
"num_of_clients":6,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"8":{
"server":{
"algorithm":"fedavg",
"num_of_clients":8,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"10":{
"server":{
"algorithm":"fedavg",
"num_of_clients":10,
"fraction_of_clients":1,
"num_of_rounds":1,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"5_rounds":{
"server":{
"algorithm":"fedavg",
"num_of_clients":2,
"fraction_of_clients":1,
"num_of_rounds":5,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"10_rounds":{
"server":{
"algorithm":"fedavg",
"num_of_clients":2,
"fraction_of_clients":1,
"num_of_rounds":10,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
},
"20_rounds":{
"server":{
"algorithm":"fedavg",
"num_of_clients":2,
"fraction_of_clients":1,
"num_of_rounds":20,
"initial_model_path":"initial_model.pt",
"epochs":1,
"accept_conn_after_FL_begin":0 ,
"verify": 0,
"verification_threshold": 0,
"timeout": null,
"resize_size": 32,
"batch_size": 32,
"net": "LeNet",
"dataset": "MNIST",
"device": "cpu",
"niid": 2,
"carbon": 0,
"encryption": 0,
"server_key": null,
"server_cert": null
},
"client":{
"ip_address": "localhost:8214",
"device":"cpu",
"wait_time": 10,
"encryption": 0,
"ca": null
}
}
}
================================================
FILE: docs/Makefile
================================================
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
================================================
FILE: docs/make.bat
================================================
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd
================================================
FILE: docs/requirements.txt
================================================
sphinx
furo
sphinxcontrib-napoleon
sphinx-autoapi
sphinx-design
sphinxcontrib-bibtex
================================================
FILE: docs/source/_autoapi_temp/python/module.rst
================================================
{% if not obj.display %}
:orphan:
{% endif %}
{{ obj.short_name }}
{{ "=" * obj.short_name|length }}
.. py:module:: {{ obj.name }}
{% if obj.docstring %}
.. autoapi-nested-parse::
{{ obj.docstring|indent(3) }}
{% endif %}
{% block subpackages %}
{% set visible_subpackages = obj.subpackages|selectattr("display")|list %}
{% if visible_subpackages %}
.. toctree::
:titlesonly:
:maxdepth: 3
{% for subpackage in visible_subpackages %}
{{ subpackage.short_name }}/index.rst
{% endfor %}
{% endif %}
{% endblock %}
{% block submodules %}
{% set visible_submodules = obj.submodules|selectattr("display")|list %}
{% if visible_submodules %}
.. toctree::
:titlesonly:
:maxdepth: 1
{% for submodule in visible_submodules %}
{{ submodule.short_name }}/index.rst
{% endfor %}
{% endif %}
{% endblock %}
{% block content %}
{% if obj.all is not none %}
{% set visible_children = obj.children|selectattr("short_name", "in", obj.all)|list %}
{% elif obj.type is equalto("package") %}
{% set visible_children = obj.children|selectattr("display")|list %}
{% else %}
{% set visible_children = obj.children|selectattr("display")|rejectattr("imported")|list %}
{% endif %}
{% if visible_children %}
{{ obj.type|title }} Contents
{{ "-" * obj.type|length }}---------
{% set visible_classes = visible_children|selectattr("type", "equalto", "class")|list %}
{% set visible_functions = visible_children|selectattr("type", "equalto", "function")|list %}
{% set visible_attributes = visible_children|selectattr("type", "equalto", "data")|list %}
{% if "show-module-summary" in autoapi_options and (visible_classes or visible_functions) %}
{% block classes scoped %}
{% if visible_classes %}
.. autoapisummary::
{% for klass in visible_classes %}
{{ klass.id }}
{% endfor %}
{% endif %}
{% endblock %}
{% block functions scoped %}
{% if visible_functions %}
.. autoapisummary::
{% for function in visible_functions %}
{{ function.id }}
{% endfor %}
{% endif %}
{% endblock %}
{% block attributes scoped %}
{% if visible_attributes %}
.. autoapisummary::
{% for attribute in visible_attributes %}
{{ attribute.id }}
{% endfor %}
{% endif %}
{% endblock %}
{% endif %}
{% for obj_item in visible_children %}
{{ obj_item.render()|indent(0) }}
{% endfor %}
{% endif %}
{% endblock %}
================================================
FILE: docs/source/conf.py
================================================
# Configuration file for the Sphinx documentation builder.
# -- Project information
project = 'FedERA'
copyright = '2023, KLIV'
author = 'KLIV'
release = '0.1'
version = '0.1.0'
# -- General configuration
extensions = [
'autoapi.extension', # this one is really important
'sphinx.ext.viewcode',
'sphinx.ext.githubpages',
'sphinx.ext.mathjax',
'sphinx.ext.intersphinx',
'sphinx.ext.todo',
'sphinx.ext.autosectionlabel', # allows referring sections its title, affects `ref`
'sphinx_design',
'sphinxcontrib.bibtex',
]
# for 'sphinxcontrib.bibtex' extension
bibtex_bibfiles = ['refer.bib']
bibtex_default_style = 'unsrt'
autodoc_mock_imports = ["numpy", "torch", "torchvision", "pandas"]
autoclass_content = 'both'
templates_path = ['_templates']
# configuration for 'autoapi.extension'
autoapi_type = 'python'
autoapi_dirs = ['../../federa']
autoapi_template_dir = '_autoapi_temp'
add_module_names = False # makes Sphinx render package.module.Class as Class
# Add more mapping for 'sphinx.ext.intersphinx'
intersphinx_mapping = {'python': ('https://docs.python.org/3', None),
'PyTorch': ('http://pytorch.org/docs/master/', None),
'numpy': ('https://numpy.org/doc/stable/', None),
'pandas': ('https://pandas.pydata.org/pandas-docs/dev/', None)}
# autosectionlabel throws warnings if section names are duplicated.
# The following tells autosectionlabel to not throw a warning for
# duplicated section names that are in different documents.
autosectionlabel_prefix_document = True
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# Config for 'sphinx.ext.todo'
todo_include_todos = True
# multi-language docs
language = 'en'
locale_dirs = ['../locales/'] # path is example but recommended.
gettext_compact = False # optional.
gettext_uuid = True # optional.
# -- Options for HTML output
html_theme = 'sphinx_rtd_theme'
# -- Options for EPUB output
epub_show_urls = 'footnote'
================================================
FILE: docs/source/contribution.rst
================================================
.. _contribution:
**********************
Contribution to FedERA
**********************
Reporting bugs
--------------
To report bugs or request features, we utilize GitHub issues. If you come across a bug or have an idea for a feature, don't hesitate to open an issue.
If you encounter any problems while using this software package, please submit a ticket to the Bug Tracker. Additionally, you can post pull requests or feature requests.
Contributing to FedERA
----------------------
If you wish to contribute to the project by submitting code, you can do so by creating a Pull Request. By contributing code, you agree that your contributions will be licensed under `Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0.html>`_.
We encourage you to contribute to the enhancement of **FedERA** or the implementation of existing FL methods within **FedERA**. The recommended method for contributing to **FedERA** is to fork the main repository on GitHub, clone it, and develop on a branch. Follow these steps:
1. Click on "Fork" to fork the project repository.
2. Clone your forked repository from your GitHub account to your local machine:
.. code-block:: shell-session
$ git clone https://github.com/anupamkliv/FedERA.git
and then navigate to the FedLab directory using the command
.. code-block:: shell-session
$ cd FedERA
3. Create a new branch to save your changes using the command
.. code-block:: shell-session
$ git checkout -b my-feature
4. Develop the feature on your branch and use the command
.. code-block:: shell-session
$ git add modified_files
followed by
.. code-block:: shell-session
$ git commit
to save your changes.
Pull Request Checklist
----------------------
- Please follow the file structure below for new features or create new file if there are something new.
.. code-block:: shell-session
FedERA
├── federa
│ ├── client
│ │ ├── src
│ | | ├── client_lib
│ | | ├── client
│ | | ├── ClientConnection_pb2_grpc
│ | | ├── ClientConnection_pb2
│ | | ├── data_utils
│ | | ├── distribution
│ | | ├── get_data
│ | | ├── net_lib
│ | | ├── net
│ │ └── start_client
│ ├── server
│ │ ├── src
│ │ | ├── algorithms
│ │ | ├── server_evaluate
│ │ | ├── client_connection_servicer
│ │ | ├── client_manager
│ │ | ├── client_wrapper
│ │ | ├── ClientConnection_pb2_grpc
│ │ | ├── ClientConnection_pb2
│ │ | ├── server_lib
│ │ | ├── server
│ │ | ├── verification
│ │ └── start_server
| └── test
| ├── minitest
| └── misc
│
└── test
├── misc
├── benchtest
| ├── test_results
| └── test_scalability
└──unittest
├── test_algorithms
├── test_datasets
├── test_models
└── test_modules
================================================
FILE: docs/source/index.rst
================================================
FedERA
===================================
**FedERA** is a highly dynamic and customizable framework that can accommodate many use cases with flexibility by implementing several functionalities over different federated learning algorithms, and essentially creating a plug-and-play architecture to accommodate different use cases.
Check out the :doc:`overview` section for further information, including
how to :ref:`installation` the project.
.. note::
This project is under active development.
Contents
--------
.. toctree::
:maxdepth: 2
overview
installation
tutorials/tutorial
contribution
reference
.. Citation
.. ........
.. Please cite **FedERA** in your publications if it helps your research:
.. .. code:: latex
.. @article{
.. }
Contacts
........
Contact the **FedERA** development team through Github issues or email:
- Development Team: federa.team@gmail.com
================================================
FILE: docs/source/installation.rst
================================================
.. _installation:
Installation
============
Install the package
-------------------
Follow this procedure to prepare the environment and install **FedERA**:
1. Install a Python 3.8 (>=3.6, <=3.9) virtual environment using venv.
See the `Venv installation guide <https://docs.python.org/3/library/venv.html>`_ for details.
2. Create a new environment for the project.
A. Using Virtual Environment
.. code-block:: console
$ python3 -m venv env
B. Using conda
.. code-block:: console
$ conda create -n env python=3.9
3. Activate the virtual environment.
A. Virtual Environment
.. code-block:: console
$ source env/bin/activate
B. Conda Environment
.. code-block:: console
$ conda activate env
4. Install the **FedERA** package.
A. Install the **stable version** with pip:
.. code-block:: console
$ pip install feder==$version$
B. Install the **latest version** from GitHub:
1. Clone the **FedERA** repository:
.. code-block:: console
$ git clone https://github.com/anupamkliv/FedERA.git
$ cd FedERA
2. Install dependencies:
.. code-block:: console
$ pip install -r requirements.txt
FedERA with Docker
------------------
Follow this procedure to build a Docker image of **FedERA**:
.. note::
The purpose of the Docker edition of **FedERA** is to provide an isolated environment complete with the prerequisites to run. Once the execution is finished, the container can be eliminated, and the computation results will be accessible in a directory on the local host.
1. Install Docker on all nodes in the federation.
See the `Docker installation guide <https://docs.docker.com/engine/install/>`_ for details.
2. Check that Docker is running properly with the *Hello World* command:
.. code-block:: console
$ docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
...
...
3. Build the Docker image of **FedERA**:
.. code-block:: console
$ docker build -t federa .
4. Run the Docker image of **FedERA**:
.. code-block:: console
$ docker run federa
================================================
FILE: docs/source/overview.rst
================================================
.. _overview:
******************
Overview of FedERA
******************
Introduction
============
Federated Learning is a machine learning technique for training models on distributed data without sharing it. In traditional machine learning, large datasets must first be collected and then sent to one location where they can be combined before the model is trained on them. However, this process can cause privacy concerns as sensitive personal data may become publicly available. Federated learning attempts to address these concerns by keeping individual user's data local while still allowing for powerful powerful statistical analysis that can be used to create accurate models at scale.
**FedAvg** is one of the foundational blocks of federated learning. A single communication round of FedAvg includes:
* Waiting for a number of clients to connect to a server (Step 0)
* Sending the clients a global model (Step 1)
* Train the model with locally available data (Step 2)
* Send the trained models back to the server (Step 3)
The server then averages the weights of the models and calculates a new aggregated model. This process constitutes a single communication round and several such communication rounds occur to train a model.
.. image:: ../imgs/fedavg_steps.png
:align: center
.. :class: only-light
Overview
========
**FedERA** is a highly dynamic and customizable framework that can accommodate many use cases with flexibility by implementing several functionalities over vanilla FedAvg, and essentially creating a plug-and-play architecture to accommodate different use cases.
Federated Learning
------------------
.. image:: ../imgs/phase1.png
:align: center
|
|
Establishing Connection between Server and Clients
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. image:: ../imgs/connection.png
:align: center
|
|
Communication with clients
~~~~~~~~~~~~~~~~~~~~~~~~~~
.. image:: ../imgs/communication.png
:align: center
|
|
Fractional and random subsampling
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* The Client_Manager can be used to sample the already connected clients.
* A minimum number of clients can be provided, upon which the Client_Manager will wait for that many clients to connect before returning a reference to them.
* If a fraction is provided, the Client_Manager will return that fraction of available clients.
* The Client_Manager can sample the clients based on their connection order or a random order. A function can also be provided to determine the selection of clients.
Various modules in Feder
------------------------
Feder is composed of 4 modules, each module building upon the last.
1. **Verification module.** Before aggregating, the server will perform a special verification round to determine which models to accommodate during aggregation.
2. **Timeout module.** Instead of waiting indefinitely for a client to finish training, the server will be able to issue a timeout, upon the completion of which, even if it hasn’t completed all epochs, the client will stop training and return the results.
3. **Intermediate client connections module.** New clients will be able to join the server anytime and may even be included in a round that is already live.
4. **Carbon emissions tracking module.** The framework will be able to track the carbon emissions of the clients during the training process.
Verification module
----------------------------
* After the server receives the trained weights, it aggregates all of them to form the new model. However, the selection of models for aggregation can be modified.
* Before aggregation, the server passes the models to a Verification module, which then uses a predefined procedure to generate scores for models, and then returns only those models that have performed above a defined threshold.
* The Verification module can be easily customized.
Steps in the Verification module
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. image:: ../imgs/verification_steps.png
:align: center
|
|
Modified Federated Learning architecture
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. image:: ../imgs/verification_1.png
:align: center
.. image:: ../imgs/verification_2.png
:align: center
|
|
Timeout module
--------------
* Often in real world scenarios, clients cannot keep training indefinitely. Therefore, a timeout functionality has been implemented.
* The server can specify a timeout parameter as a Train order configuration. The client will then train till the timeout occurs, and then return the results.
Steps in the Timeout module
~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. image:: ../imgs/timeout.png
:align: center
|
Intermediate client connections module
--------------------------------------
* Now, even during the middle of a communication round, the server can accept new client connections, incorporate them into the Client_Manager and even include them in the ongoing communication round as well.
* The server can be easily configured to allow or reject new connections during different parts of Federated Learning.
* Safeguards to notify when a client has disconnected anytime have been implemented.
Carbon emissions tracking module
--------------------------------
In **FedERA** CodeCarbon package is used to estimate the carbon emissions generated by clients during training. CodeCarbon is a Python package that provides an estimation of the carbon emissions associated with software code.
Tested on
~~~~~~~~~
**FedERA** has been extensively tested on and works with the following devices:
* Intel CPUs
* Nvidia GPUs
* Nvidia Jetson
* Raspberry Pi
* Intel NUC
With **FedERA**, it is possible to operate the server and clients on separate devices or on a single device through various means, such as utilizing different terminals or implementing multiprocessing.
.. image:: ../imgs/tested.png
:align: center
================================================
FILE: docs/source/refer.bib
================================================
@article{codecarbon,
author={Victor Schmidt and Kamal Goyal and Aditya Joshi and Boris Feld and Liam Conell and Nikolas Laskaris and Doug Blank and Jonathan Wilson and Sorelle Friedler and Sasha Luccioni},
title={{CodeCarbon: Estimate and Track Carbon Emissions from Machine Learning Computing}},
year={2021},
howpublished={\url{https://github.com/mlco2/codecarbon}},
DOI={10.5281/zenodo.4658424},
publisher={Zenodo},
}
================================================
FILE: docs/source/reference.rst
================================================
Reference
=========
.. bibliography::
================================================
FILE: docs/source/tutorials/algorithm.rst
================================================
.. _algorithm:
*****************************
Federated Learning Algorithms
*****************************
The implementation of federated learning algorithms in Feder consists of two components: the training part on the client side and the aggregation part on the server side. The training functions are coded in the net_lib.py file at client/src directory, while the aggregation functions are located in various files within the algorithms folder at server/src directory.
The algorithms currently implemented in **FedERA** are:
* FedAvg
* FedDyn
* FedAdam
* FedAdagrad
* Scaffold
* FedAvgM
* Mime
* Mimelite
* FedYogi
Adding a new algorithm to **FedERA**
-----------------------------------
To add a new algorithm to **FedERA**, you need to implement the training function on the client side and the aggregation function on the server side. The training function should be implemented in the net_lib.py file at client/src directory. The aggregation function should be implemented in a new file in the algorithms folder at server/src directory.
Implementing the training function
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The training function should be implemented in the net_lib file, in a fashion similar to the following example of the mimelite algorithm:
.. code-block:: python
def train_mimelite(net, state, trainloader, epochs, deadline=None):
#In the case of MimeLite, control_variate is nothing but a state like in case of momentum method
x = deepcopy(net)
criterion = torch.nn.CrossEntropyLoss()
lr = 0.001
momentum = 0.9
net.train()
for _ in tqdm(range(epochs)):
for images, labels in trainloader:
images, labels = images.to(DEVICE), labels.to(DEVICE)
loss = criterion(net(images), labels)
#Compute (full-batch) gradient of loss with respect to net's parameters
grads = torch.autograd.grad(loss,net.parameters())
#Update net's parameters using gradients
with torch.no_grad():
for param,grad,s in zip(net.parameters(), grads, state):
param.data = param.data - lr * ((1-momentum) * grad.data + momentum * s.data)
if deadline:
current_time = time.time()
if current_time >= deadline:
print("deadline occurred.")
break
#Compute gradient wrt the received model (x) using the wholde dataset
data = DataLoader(trainloader.dataset, batch_size = len(trainloader) * trainloader.batch_size, shuffle = True)
for images, labels in data:
images, labels = images.to(DEVICE), labels.to(DEVICE)
output = x(images)
loss = criterion(output, labels) #Calculate the loss with respect to y's output and labels
gradient_x = torch.autograd.grad(loss,x.parameters())
return net, gradient_x
After making the changes in the net_lib.py file, the client_lib.py file also needs to be updated so as to incorporate the newly defined algorithm. The client_lib.py file is located at client/src directory. The following code snippet shows the train function that needs to be updated in the client_lib.py file:
.. code-block:: python
def train(train_order_message):
data_bytes = train_order_message.modelParameters
data = torch.load( BytesIO(data_bytes), map_location="cpu" )
model_parameters, control_variate, control_variate2 = data['model_parameters'], data['control_variate'], data['control_variate2']
config_dict_bytes = train_order_message.configDict
config_dict = json.loads( config_dict_bytes.decode("utf-8") )
carbon_tracker = config_dict["carbon_tracker"]
model = get_net(config= config_dict)
model.load_state_dict(model_parameters)
model = model.to(device)
epochs = config_dict["epochs"]
if config_dict["timeout"]:
deadline = time.time() + config_dict["timeout"]
else:
deadline = None
#Run code carbon if the carbon-tracker flag is True
if (carbon_tracker==1):
tracker = OfflineEmissionsTracker(country_iso_code="IND", output_dir = save_dir_path)
tracker.start()
trainloader, testloader, _ = load_data(config_dict)
print("training started")
if (config_dict['algorithm'] == 'mimelite'):
model, control_variate = train_mimelite(model, control_variate, trainloader, epochs, deadline)
elif (config_dict['algorithm'] == 'scaffold'):
model, control_variate = train_scaffold(model, control_variate, trainloader, epochs, deadline)
elif (config_dict['algorithm'] == 'mime'):
model, control_variate = train_mime(model, control_variate, control_variate2, trainloader, epochs, deadline)
elif (config_dict['algorithm'] == 'fedavg'):
model = train_fedavg(model, trainloader, epochs, deadline)
elif (config_dict['algorithm'] == 'feddyn'):
model = train_feddyn(model, trainloader, epochs, deadline)
else:
model = train_model(model, trainloader, epochs, deadline)
print("training finished")
if (carbon_tracker==1):
emissions: float = tracker.stop()
print(f"Emissions: {emissions} kg")
myJSON = json.dumps(config_dict)
json_path = save_dir_path + "/config.json"
with open(json_path, "w") as jsonfile:
jsonfile.write(myJSON)
json_path = "config.json"
with open(json_path, "w") as jsonfile:
jsonfile.write(myJSON)
trained_model_parameters = model.state_dict()
#Create a dictionary where model_parameters and control_variate are stored which needs to be sent to the server
data_to_send = {}
data_to_send['model_parameters'] = trained_model_parameters
data_to_send['control_variate'] = control_variate #If there is no control_variate, this will become None
buffer = BytesIO()
torch.save(data_to_send, buffer)
buffer.seek(0)
data_to_send_bytes = buffer.read()
print("train eval")
train_loss, train_accuracy = test_model(model, testloader)
response_dict = {"train_loss": train_loss, "train_accuracy": train_accuracy}
response_dict_bytes = json.dumps(response_dict).encode("utf-8")
train_response_message = TrainResponse(
modelParameters = data_to_send_bytes,
responseDict = response_dict_bytes)
save_model_state(model)
return train_response_message
Implementing the aggregation function
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The aggregation function should be implemented within a class in a new file in the algorithms folder at server/src directory. The following code snippet shows the aggregation function for the mimelite algorithm as deffined in the mimelite.py file:
.. code-block:: python
class mimelite():
def __init__(self, config):
self.algorithm = "MimeLite"
self.lr = 1.0
self.momentum = 0.9
def aggregate(self,server_model_state_dict, optimizer_state, state_dicts, gradients_x):
keys = server_model_state_dict.keys() #List of keys in a state_dict
avg_y = OrderedDict() #This will be our new server_model_state_dict
for key in keys:
current_key_tensors = [state_dict[key] for state_dict in state_dicts]
current_key_sum = functools.reduce( lambda accumulator, tensor: accumulator + tensor, current_key_tensors )
current_key_average = current_key_sum / len(state_dicts)
avg_y[key] = current_key_average
#Average all the gradient_x in gradients_x
avg_grads = []
for i in range(len(gradients_x[0])):
#Average all the i'th element of gradient_x present in the gradients_x
current_tensors = [gradient_x[i] for gradient_x in gradients_x]
current_sum = functools.reduce(lambda accumulator, tensor: accumulator + tensor, current_tensors)
current_average = current_sum / len(gradients_x)
avg_grads.append(current_average)
for state, grad in zip(optimizer_state, avg_grads):
state.data = self.momentum * state.data + (1 - self.momentum) * grad.data
return avg_y, optimizer_state
================================================
FILE: docs/source/tutorials/code_carbon.rst
================================================
.. _code_carbon:
****************
Carbon Emissions
****************
CodeCarbon is a Python package that provides an estimation of the carbon emissions associated with software code. It can be integrated into software development workflows and offers real-time feedback on the environmental impact of the code being developed. CodeCarbon helps developers and organizations become more environmentally conscious by optimizing their code and making better choices regarding the hardware and infrastructure used to run it. It enables companies to achieve their sustainability goals and demonstrate their commitment to reducing their environmental impact.
To estimate the carbon emissions generated by clients during training, CodeCarbon has been utilized in the client_lib.py file, located in the client/src/ directory. By default, the client's location is set to India, but it can be modified to reflect the client's actual location. The following code snippet illustrates how CodeCarbon is used in the client_lib.py file:
.. code-block:: python
#Run code carbon if the carbon-tracker flag is True
if (carbon_tracker==1):
tracker = OfflineEmissionsTracker(country_iso_code="IND", output_dir = save_dir_path)
tracker.start()
trainloader, testloader, _ = load_data(config_dict)
print("training started")
if (config_dict['algorithm'] == 'mimelite'):
model, control_variate = train_mimelite(model, control_variate, trainloader, epochs, deadline)
elif (config_dict['algorithm'] == 'scaffold'):
model, control_variate = train_scaffold(model, control_variate, trainloader, epochs, deadline)
elif (config_dict['algorithm'] == 'mime'):
model, control_variate = train_mime(model, control_variate, control_variate2, trainloader, epochs, deadline)
elif (config_dict['algorithm'] == 'fedavg'):
model = train_fedavg(model, trainloader, epochs, deadline)
elif (config_dict['algorithm'] == 'feddyn'):
model = train_feddyn(model, trainloader, epochs, deadline)
else:
model = train_model(model, trainloader, epochs, deadline)
print("training finished")
if (carbon_tracker==1):
emissions: float = tracker.stop()
print(f"Emissions: {emissions} kg")
================================================
FILE: docs/source/tutorials/data_distribution.rst
================================================
.. _data_distribution:
*****************
Data Distribution
*****************
**FedERA** allows the option to train with either IID or non-IID data distribution. To specify the data distribution, you can use the "--iid" flag. When the flag is set to "1", the data distribution is IID. However, if you set it to a value between "2-5", the data distribution will be non-IID. Each argument value corresponds to a different non-IID distribution. The non-IID distributions are defined as follows:
.. code:: Python
def data_distribution(config, trainset):
labels = []
base_dir = os.getcwd()
storepath = os.path.join(base_dir, 'Distribution/', config['dataset']+'/')
seed = 10
random.seed(seed)
num_users = 5
#Calculate the number of samples present per class
for i in range(len(trainset)):
labels.append(trainset[i][1])
unique_labels = np.unique(np.array(labels))
label_index_list = {}
for key in unique_labels:
label_index_list[key] = []
for index, label in enumerate(labels):
label_index_list[label].append(index)
num_classes = len(unique_labels)
#Calculate the value of the probability distribution. For K=1, it will be iid distribution
K = config['niid']
if (K==1):
q_step = (1 - (1/num_classes))
else:
q_step = (1 - (1/num_classes))/(K-1)
#Shuffle the index position for all classes
for i in range(len(label_index_list)):
random.shuffle(label_index_list[i])
#Generate the different non-iid distribution. Data_presence_indicator will help to reduce the number of classes among the clients as the non-iid increases
for j in range(K):
dist = np.random.uniform(q_step, (1+j)*q_step, (num_classes, num_users))
if j != 0:
data_presence_indicator = np.random.choice([0, 1], (num_classes, num_users), p=[j*q_step, 1-(j*q_step)])
if len(np.where(np.sum(data_presence_indicator, axis=0) == 0)[0])>0:
for i in np.where(np.sum(data_presence_indicator, axis=0) == 0)[0]:
zero_array = data_presence_indicator[:,i]
zero_array[np.random.choice(len(zero_array),1)] =1
data_presence_indicator[:,i] = zero_array
dist = np.multiply(dist,data_presence_indicator)
psum = np.sum(dist, axis=1)
for i in range(dist.shape[0]):
dist[i] = dist[i]*len(label_index_list[i])/(psum[i]+0.00001)
dist = np.floor(dist).astype(int)
# If any client does not get any data then this logic helps to allocate the required samples among the clients
gainers = list(np.where(np.sum(dist, axis=0) != 0))[0]
if len(gainers) < num_users:
losers = list(np.where(np.sum(dist, axis=0) == 0))[0]
donors = np.random.choice(gainers, len(losers))
for index, donor in enumerate(donors):
avail_digits = np.where(dist[:,donor] != 0)[0]
for digit in avail_digits:
transfer_frac = np.random.uniform(0.1,0.9)
num_transfer = int(dist[digit, donor]*transfer_frac)
dist[digit, donor] = dist[digit, donor] - num_transfer
dist[digit, losers[index]] = num_transfer
#Logic to check if the summation of all the samples among the clients is equal to the total number of samples present for that class. If not it will adjust.
for num in range(num_classes):
while dist[num].sum() != len(label_index_list[num]):
index = random.randint(0,num_users-1)
if dist[num].sum() < len(label_index_list[num]):
dist[num][index]+=1
else:
dist[num][index]-=1
#Division of samples number among the clients
split = [[] for i in range(num_classes)]
for num in range(num_classes):
start = 0
for i in range(num_users):
split[num].append(label_index_list[num][start:start+dist[num][i]])
start = start+dist[num][i]
#Division of actual data points among the clients.
datapoints = [[] for i in range(num_users)]
class_histogram = [[] for i in range(num_users)]
class_stats= [[] for i in range(num_users)]
for i in range(num_users):
for num in range(num_classes):
datapoints[i] += split[num][i]
class_histogram[i].append(len(split[num][i]))
if(len(split[num][i])==0):
class_stats[i].append(0)
else:
class_stats[i].append(1)
#Store the dataset division in the folder
if not os.path.exists(storepath):
os.makedirs(storepath)
file_name = 'data_split_niid_'+ str(K)+'.pt'
torch.save({'datapoints': datapoints, 'histograms': class_histogram, 'class_statitics': class_stats}, storepath + file_name)
Visualizing the non-IID data distribution for MNIST dataset
-----------------------------------------------------------
Classwise distribution of samples among the clients for different non-IID distribution
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. figure:: ../../imgs/class_stats_0.png
:align: center
Classwise distribution of samples among the clients for non-IID distribution 1
|
.. figure:: ../../imgs/class_stats_1.png
:align: center
Classwise distribution of samples among the clients for non-IID distribution 2
|
.. figure:: ../../imgs/class_stats_2.png
:align: center
Classwise distribution of samples among the clients for non-IID distribution 3
|
.. figure:: ../../imgs/class_stats_3.png
:align: center
C lasswise distribution of samples among the clients for non-IID distribution 4
|
.. figure:: ../../imgs/class_stats_4.png
:align: center
Classwise distribution of samples among the clients for non-IID distribution 5
|
Samplewise distribution of samples among the clients for different non-IID distribution
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. figure:: ../../imgs/sample_stats_0.png
:align: center
Samplewise distribution of samples among the clients for non-IID distribution 1
|
.. figure:: ../../imgs/sample_stats_1.png
:align: center
Samplewise distribution of samples among the clients for non-IID distribution 2
|
.. figure:: ../../imgs/sample_stats_2.png
:align: center
Samplewise distribution of samples among the clients for non-IID distribution 3
|
.. figure:: ../../imgs/sample_stats_3.png
:align: center
Samplewise distribution of samples among the clients for non-IID distribution 4
|
.. figure:: ../../imgs/sample_stats_4.png
:align: center
Samplewise distribution of samples among the clients for non-IID distribution 5
================================================
FILE: docs/source/tutorials/dataset.rst
================================================
.. _dataset:
*********
Datasets
*********
The datasets used by **FedERA** are acquired by fetching them from torchvision.datasets. As of now, feder supports the following datasets:
* MNIST
* FashionMNIST
* CIFAR10
* CIFAR100
Adding support for new datasets
-------------------------------
There are two methods for incorporating support for new datasets in feder. One involves utilizing torchvision.datasets, while the other entails implementing support for a custom dataset.
Adding support for a dataset available in torchvision.datasets
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The torchvision.datasets package consists of popular datasets used in computer vision. The datasets are downloaded and cached automatically. The datasets are subclasses of torch.utils.data.Dataset i.e. they have the same API. This makes it easy to incorporate support for new datasets in feder. All that is required is to add a a few lines of code in the get_data function in the get_data.py file.
.. code-block:: python
def get_data(config):
# If the dataset is not custom, create a dataset folder
if config['dataset'] != 'CUSTOM':
dataset_path = "client_dataset"
if not os.path.exists(dataset_path):
os.makedirs(dataset_path)
# Get the train and test datasets for each supported dataset
if config['dataset'] == 'MNIST':
# Apply transformations to the images
apply_transform = transforms.Compose([transforms.Resize(config["resize_size"]), transforms.ToTensor()])
# Download and load the trainset
trainset = datasets.MNIST(root='client_dataset/MNIST', train=True, download=True, transform=apply_transform)
# Download and load the testset
testset = datasets.MNIST(root='client_dataset/MNIST', train=False, download=True, transform=apply_transform)
elif config['dataset'] == 'FashionMNIST':
apply_transform = transforms.Compose([transforms.Resize(config['resize_size']), transforms.ToTensor()])
trainset = datasets.FashionMNIST(root='client_dataset/FashionMNIST', train=True, download=True, transform=apply_transform)
testset = datasets.FashionMNIST(root='client_dataset/FashionMNIST', train=False, download=True, transform=apply_transform)
elif config['dataset'] == 'CIFAR10':
apply_transform = transforms.Compose([transforms.Resize(config['resize_size']), transforms.ToTensor()])
trainset = datasets.CIFAR10(root='client_dataset/CIFAR10', train=True, download=True, transform=apply_transform)
testset = datasets.CIFAR10(root='client_dataset/CIFAR10', train=False, download=True, transform=apply_transform)
elif config['dataset'] == 'CIFAR100':
apply_transform = transforms.Compose([transforms.Resize(config['resize_size']), transforms.ToTensor()])
trainset = datasets.CIFAR100(root='client_dataset/CIFAR100', train=True, download=True, transform=apply_transform)
testset = datasets.CIFAR100(root='client_dataset/CIFAR100', train=False, download=True, transform=apply_transform)
elif config['dataset'] == 'CUSTOM':
apply_transform = transforms.Compose([transforms.Resize(config['resize_size']), transforms.ToTensor()])
# Load the custom dataset
trainset = customDataset(root='client_custom_dataset/CUSTOM/train', transform=apply_transform)
testset = customDataset(root='client_custom_dataset/CUSTOM/test', transform=apply_transform)
else:
# Raise an error if an unsupported dataset is specified
raise ValueError("Unsupported dataset type: {}".format(config['dataset']))
# Return the train and test datasets
return trainset, testset
For example, to add support for the STL10 dataset, the following lines of code can be added to the get_data function:
.. code-block:: python
elif config['dataset'] == 'STL10':
apply_transform = transforms.Compose([transforms.Resize(config['resize_size']), transforms.ToTensor()])
trainset = datasets.STL10(root='client_dataset/STL10', split='train', download=True, transform=apply_transform)
testset = datasets.STL10(root='client_dataset/STL10', split='test', download=True, transform=apply_transform)
Adding support for a custom dataset
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In order to incorporate support for a custom dataset, the train and test sets for the dataset must be included in the train and test folders, respectively, within the client/client_custom_dataset/CUSTOM/ directory. The train and test data must be stored in .npy files. The custom_dataset class which loads the custom data has been defined in the get_data.py file and can be changed as per the requirements of the custom dataset. The custom_dataset class is a subclass of torch.utils.data.Dataset and has the same API as the datasets in torchvision.datasets. The following code snippet shows the custom_dataset class:
.. code-block:: python
class customDataset(data.Dataset):
def __init__(self, root, transform=None):
"""
Custom dataset class for loading image and label data from a folder of .npy files.
Args:
root (str): Path to the folder containing the .npy files.
transform (callable, optional): A function/transform that takes in an PIL image and returns a transformed version.
E.g, `transforms.RandomCrop`
"""
self.root = root
samples = sample_return(root)
self.samples = samples
self.transform = transform
def __getitem__(self, index):
"""
Retrieves a sample from the dataset at the given index.
Args:
index (int): Index of the sample to retrieve.
Returns:
img (PIL.Image): The image data.
label (int): The label for the image data.
"""
img, label= self.samples[index]
img = np.load(img)
img = Image.fromarray(img)
if self.transform is not None:
img = self.transform(img)
return img, label
def __len__(self):
return len(self.samples)
================================================
FILE: docs/source/tutorials/encryption.rst
================================================
.. _encryption:
**********
Encryption
**********
In the FedERA framework, encryption plays a crucial role in ensuring secure communication between the client and server during the Federated Learning process. This section provides guidance on generating and configuring the necessary certificates for TLS/SSL encryption.
TLS Basics
==========
To understand the encryption process, it's essential to grasp the fundamentals of TLS/SSL and chains of trust. TLS/SSL operates based on a transitive trust model, where trust in a certificate authority (CA) extends to the certificates it generates. Web browsers and operating systems have a "Trusted Roots" certificate store, automatically trusting certificates from public certificate authorities such as Let's Encrypt or GoDaddy.
In the case of FedERA, we establish our own CA and need to inform the client about the CA certificate for trust verification. Additionally, the server certificate must contain the exact server name the client connects to for validation.
Generate Certificates
=====================
For the purpose of this example, we will set up a basic PKI Infrastructure using CloudFlare's CFSSL toolset, specifically the `cfssl` and `cfssljson` tools. You can download these tools from `here <https://pkg.cfssl.org>`_ .
The `ssl` directory contains configuration files that can be modified, but for demonstration purposes, they can also be used as-is.
Generate CA Certificate and Config
----------------------------------
To generate the CA certificate and configuration, navigate to the `ssl` directory and run the following command:
.. code-block:: shell-session
$ cd FedERA/ssl
$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca
This command generates the `ca.pem` and `ca-key.pem` files. The `ca.pem` file is used by both the client and server for mutual verification.
Generate Server and Client Certificates
---------------------------------------
Server Certificate
~~~~~~~~~~~~~~~~~~
To generate the server certificate and key pair, run the following command in the `ssl` directory:
.. code-block:: shell-session
$ cd FedERA/ssl
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -hostname='127.0.0.1,localhost' server-csr.json | cfssljson -bare server
This command creates the server certificate and key pair to be used by the server during TLS/SSL encryption. Note that you can modify the `hostname` parameter to match the name or IP address of the server on your network.
Client Certificate
~~~~~~~~~~~~~~~~~~
To generate the client certificate and key pair, use the following command in the `ssl` directory:
.. code-block:: shell-session
$ cd FedERA/ssl
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json client-csr.json | cfssljson -bare client
When generating the client certificate and key pair, a warning message may appear regarding the absence of a "hosts" field. This warning is expected and acceptable since the client certificate is only used for client identification, not server identification.
TLS Server Identification and Encryption
========================================
In FedERA, the client trusts the certificate authority certificate, which subsequently enables trust in the server certificate. This is similar to how web browsers handle certificates, where pre-installed public certificate authority certificates establish trust.
For one-way trust verification (client verifies server identity but not vice versa), the server does not necessarily need to present the CA certificate as part of its certificate chain. The server only needs to present enough of the certificate chain for the client to trace it back to a trusted CA certificate.
In the FedERA framework, the gRPC server can be configured for SSL using the following code snippet:
----------------------------------------------------------------------------------------------------
On server side
~~~~~~~~~~~~~~
.. code-block:: python
if configurations['encryption']==1:
# Load the server's private key and certificate
keyfile = configurations['server_key']
certfile = configurations['server_cert']
private_key = bytes(open(keyfile).read(), 'utf-8')
certificate_chain = bytes(open(certfile).read(), 'utf-8')
# Create SSL/TLS credentials object
server_credentials = ssl_server_credentials([(private_key, certificate_chain)])
server.add_secure_port('localhost:8214', server_credentials)
On client side
~~~~~~~~~~~~~~
.. code-block:: python
if config["encryption"] == 1:
ca_cert = 'ca.pem'
root_certs = bytes(open(ca_cert).read(), 'utf-8')
credentials = grpc.ssl_channel_credentials(root_certs)
#create new gRPC channel to the server
channel = grpc.secure_channel(ip_address, options=[
('grpc.max_send_message_length', -1),
('grpc.max_receive_message_length', -1)
], credentials=credentials)
Acknowledgments
===============
This code and information were developed with the help of the repository `jottoekke/python-grpc-ssl <https://github.com/joekottke/python-grpc-ssl>`_, which provided valuable guidance in implementing the encryption functionality.
================================================
FILE: docs/source/tutorials/models.rst
================================================
.. _models:
*******
Models
*******
The models currently implemented in the framework are:
* LeNet-5
* ResNet-18
* ResNet-50
* VGG-16
* AlexNet
The `server_lib.py` file contains the implementation of Deep-Learning models for the server, while the `net.py` file contains the implementation of these models for the client. These models are either created by inheriting from torch.nn.module or are imported from torchvision.models.
Adding support for a new model
------------------------------
There are two ways to incorporate support for new models in **FedERA**. One involves creating a new class that inherits from torch.nn.module and the other involves importing a model from torchvision.models. The first method is more flexible and allows for more customization, while the second method is easier to implement and is recommended for beginners.
Adding support for a new model by inheriting from torch.nn.module
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To add support for a new model by inheriting from torch.nn.module, the following steps need to be followed:
1. Create a new class that inherits from torch.nn.module and defines the model that needs to be implemented, and add it to `server_lib.py` file and the `net.py` file. The code for LeNet is given below as an example:
.. code-block:: python
class LeNet(nn.Module):
def __init__(self, in_channels=1, num_classes=10):
super(LeNet, self).__init__()
self.conv1 = nn.Conv2d(in_channels, 6, kernel_size=5)
self.pool1 = nn.MaxPool2d(kernel_size=2,stride=2)
self.conv2 = nn.Conv2d(6, 16, kernel_size=5)
self.pool2 = nn.MaxPool2d(kernel_size=2,stride=2)
self.fc1 = nn.Linear(400, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, num_classes)
self.relu = nn.ReLU()
self.logSoftmax = nn.LogSoftmax(dim=1)
def forward(self, x):
x = self.conv1(x)
x = self.relu(x)
x = self.pool1(x)
x = self.conv2(x)
x = self.relu(x)
x = self.pool2(x)
x = x.view(-1, 400)
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
x = self.relu(x)
x = self.fc3(x)
x = self.logSoftmax(x)
return x
2. The models implemented in `client_lib.py` and `net.py` files are imported via the use of `get_net.py` function defined in both the files. This function takes in the name of the model as a string and returns the corresponding model. To add support for a new model, the name of the model needs to be added to the `get_net.py` function in both the files and appropriate changes need to be made. The code for the `get_net.py` function in `client_lib.py` is given below as an example:
.. code-block:: python
def get_net(config):
if config["net"] == 'LeNet':
if config['dataset'] in ['MNIST', 'FashionMNIST', 'CUSTOM']:
net = LeNet(in_channels=1, num_classes=10)
elif config['dataset'] == 'CIFAR10':
net = LeNet(in_channels=3, num_classes=10)
else:
net = LeNet(in_channels=3, num_classes=100)
if config["net"] == 'resnet18':
if config['dataset'] in ['MNIST', 'FashionMNIST']:
net = models.resnet18(num_classes=10)
elif config['dataset'] == 'CIFAR10':
net = models.resnet18(num_classes=10)
else:
net = models.resnet18(num_classes=100)
if config["net"] == 'resnet50':
if config['dataset'] in ['MNIST', 'FashionMNIST']:
net = models.resnet50(num_classes=10)
elif config['dataset'] == 'CIFAR10':
net = models.resnet50(num_classes=10)
else:
net = models.resnet50(num_classes=100)
if config["net"] == 'vgg16':
if config['dataset'] in ['MNIST', 'FashionMNIST']:
net = models.vgg16(num_classes=10)
elif config['dataset'] == 'CIFAR10':
net = models.vgg16(num_classes=10)
else:
net = models.vgg16(num_classes=100)
if config['net'] == 'AlexNet':
if config['dataset'] in ['MNIST', 'FashionMNIST']:
net = models.alexnet(num_classes=10)
elif config['dataset'] == 'CIFAR10':
net = models.alexnet(num_classes=10)
else:
net = models.alexnet(num_classes=100)
return net
Adding support for a new model by importing from torchvision.models
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To add support for a new model by importing from torchvision.models, import the model from torchvision.models in `server_lib.py` and `net.py` files and make changes in the `get_net` function appropriately. The code that needs to be added in `get_net` function to import ResNet38 model is given below as an example:
.. code-block:: python
if config["net"] == 'resnet38':
if config['dataset'] in ['MNIST', 'FashionMNIST']:
net = models.resnet38(num_classes=10)
elif config['dataset'] == 'CIFAR10':
net = models.resnet38(num_classes=10)
else:
net = models.resnet38(num_classes=100)
================================================
FILE: docs/source/tutorials/running.rst
================================================
.. _running:
*******************************
Running the Server and Clients
*******************************
Starting the Server
-------------------
The server is started by running the following command in the root directory of the framework:
.. code-block:: console
python -m federa.server.start_server
Arguments that can be passed to the server are:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. list-table:: Server Configuration Options
:widths: 25 45 20
:header-rows: 1
* - Argument
- Description
- Default
* - ``algorithm``
- specifies the aggregation algorithm
- ``fedavg``
* - ``clients``
- specifies number of clients selected per round
- ``1``
* - ``fraction``
- specifies fraction of clients selected
- ``1``
* - ``rounds``
- specifies total number of rounds
- ``1``
* - ``model_path``
- specifies initial server model path
- ``initial_model.pt``
* - ``epochs``
- specifies client epochs per round
- ``1``
* - ``accept_conn``
- determines if connections accepted after FL begins
- ``1``
* - ``verify``
- specifies if verification module runs before rounds
- ``0``
* - ``threshold``
- specifies minimum verification score
- ``0``
* - ``timeout``
- specifies client training time limit per round
- ``None``
* - ``resize_size``
- specifies dataset resize dimension
- ``32``
* - ``batch_size``
- specifies dataset batch size
- ``32``
* - ``net``
- specifies network architecture
- ``LeNet``
* - ``dataset``
- specifies dataset name
- ``MNIST``
* - ``niid``
- specifies data distribution among clients
- ``1``
* - ``carbon``
- specifies if carbon emissions tracked at client side
- ``0``
* - ``encryption``
- specifies whether to use SSL encryption or not
- ``0``
* - ``server_key``
- specifies path to server key certificate
- ``server-key.pem``
* - ``server_cert``
- specifies path to server certificate
- ``server.pem``
Starting the Clients
--------------------
The clients are started by running the following command in the root directory of the framework:
.. code-block:: console
python federa.client.start_client
Arguments that can be passed to the clients are:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. list-table:: Client Configuration Options
:widths: 25 45 20
:header-rows: 1
* - Argument
- Description
- Default
* - ``server_ip``
- specifies server IP address
- ``localhost:8214``
* - ``device``
- specifies device
- ``cpu``
* - ``encryption``
- specifies whether to use SSL encryption or not
- ``0``
* - ``ca``
- specifies path to CA certificate
- ``ca.pem``
* - ``wait_time``
- specifies time to wait before reconnecting to the server
- ``30``
================================================
FILE: docs/source/tutorials/tutorial.rst
================================================
.. _tutorial:
*********
Tutorials
*********
**FedERA** allows you to do federated learning in real time on various supported edge devices, including Intel CPUs, Nvidia GPUs, Nvidia Jetson, Raspberry Pi, Intel NUC. **FedERA** provides modular tools and standard algorithms to simplify federated learning implementation in real time using gRPC framework.
.. card:: Running Server and Client
:link: running
:link-type: ref
:class-card: sd-rounded-2 sd-border-1
Step-by-step guide on running server and clients on same and different devices.
.. card:: How to Customize Federated Learning Algorithm?
:link: algorithm
:link-type: ref
:class-card: sd-rounded-2 sd-border-1
Step-by-step guide on how to customize federated learning algorithm.
.. card:: How to add Custom Dataset?
:link: dataset
:link-type: ref
:class-card: sd-rounded-2 sd-border-1
Step-by-step guide on how to add a custom dataset.
.. card:: How to add Custom Model?
:link: models
:link-type: ref
:class-card: sd-rounded-2 sd-border-1
Step-by-step guide on how to add a custom model.
.. card:: How to add use different Data Distribution?
:link: data_distribution
:link-type: ref
:class-card: sd-rounded-2 sd-border-1
Step-by-step guide on how to use different data dstributions while training.
.. card:: How to get Carbon Footprint?
:link: code_carbon
:link-type: ref
:class-card: sd-rounded-2 sd-border-1
Step-by-step guide on how to get carbon footprint of the training process.
.. card:: How to use Encryption?
:link: encryption
:link-type: ref
:class-card: sd-rounded-2 sd-border-1
Step-by-step guide on how to use encryption in the training process.
.. toctree::
:maxdepth: 2
running
algorithm
dataset
models
data_distribution
code_carbon
encryption
..
Use :class:`NetworkManager` to customize communication
strategies, including synchronous and asynchronous communication.
================================================
FILE: federa/__init__.py
================================================
__version__='0.0.0'
================================================
FILE: federa/client/__init__.py
================================================
================================================
FILE: federa/client/src/ClientConnection_pb2.py
================================================
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: ClientConnection.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='ClientConnection.proto',
package='',
syntax='proto3',
serialized_options=None,
#create_key=_descriptor._internal_create_key,
serialized_pb=b'\n\x16\x43lientConnection.proto\"\xa3\x01\n\rServerMessage\x12\x1f\n\ntrainOrder\x18\x01 \x01(\x0b\x32\x0b.TrainOrder\x12\x1d\n\tevalOrder\x18\x02 \x01(\x0b\x32\n.EvalOrder\x12)\n\x0f\x64isconnectOrder\x18\x03 \x01(\x0b\x32\x10.DisconnectOrder\x12\'\n\x0esetParamsOrder\x18\x04 \x01(\x0b\x32\x0f.SetParamsOrder\"\x8a\x01\n\rClientMessage\x12%\n\rtrainResponse\x18\x01 \x01(\x0b\x32\x0e.TrainResponse\x12#\n\x0c\x65valResponse\x18\x02 \x01(\x0b\x32\r.EvalResponse\x12-\n\x11setParamsResponse\x18\x03 \x01(\x0b\x32\x12.SetParamsResponse\"9\n\nTrainOrder\x12\x17\n\x0fmodelParameters\x18\x01 \x01(\x0c\x12\x12\n\nconfigDict\x18\x02 \x01(\x0c\">\n\rTrainResponse\x12\x17\n\x0fmodelParameters\x18\x01 \x01(\x0c\x12\x14\n\x0cresponseDict\x18\x02 \x01(\x0c\"8\n\tEvalOrder\x12\x17\n\x0fmodelParameters\x18\x01 \x01(\x0c\x12\x12\n\nconfigDict\x18\x02 \x01(\x0c\"$\n\x0c\x45valResponse\x12\x14\n\x0cresponseDict\x18\x01 \x01(\x0c\")\n\x0eSetParamsOrder\x12\x17\n\x0fmodelParameters\x18\x01 \x01(\x0c\"\x13\n\x11SetParamsResponse\"9\n\x0f\x44isconnectOrder\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x15\n\rreconnectTime\x18\x02 \x01(\x05\x32\x41\n\x10\x43lientConnection\x12-\n\x07\x43onnect\x12\x0e.ClientMessage\x1a\x0e.ServerMessage(\x01\x30\x01\x62\x06proto3'
)
_SERVERMESSAGE = _descriptor.Descriptor(
name='ServerMessage',
full_name='ServerMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
#create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='trainOrder', full_name='ServerMessage.trainOrder', index=0,
number=1, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='evalOrder', full_name='ServerMessage.evalOrder', index=1,
number=2, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='disconnectOrder', full_name='ServerMessage.disconnectOrder', index=2,
number=3, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='setParamsOrder', full_name='ServerMessage.setParamsOrder', index=3,
number=4, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=27,
serialized_end=190,
)
_CLIENTMESSAGE = _descriptor.Descriptor(
name='ClientMessage',
full_name='ClientMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
#create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='trainResponse', full_name='ClientMessage.trainResponse', index=0,
number=1, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='evalResponse', full_name='ClientMessage.evalResponse', index=1,
number=2, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='setParamsResponse', full_name='ClientMessage.setParamsResponse', index=2,
number=3, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=193,
serialized_end=331,
)
_TRAINORDER = _descriptor.Descriptor(
name='TrainOrder',
full_name='TrainOrder',
filename=None,
file=DESCRIPTOR,
containing_type=None,
#create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='modelParameters', full_name='TrainOrder.modelParameters', index=0,
number=1, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='configDict', full_name='TrainOrder.configDict', index=1,
number=2, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=333,
serialized_end=390,
)
_TRAINRESPONSE = _descriptor.Descriptor(
name='TrainResponse',
full_name='TrainResponse',
filename=None,
file=DESCRIPTOR,
containing_type=None,
#create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='modelParameters', full_name='TrainResponse.modelParameters', index=0,
number=1, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='responseDict', full_name='TrainResponse.responseDict', index=1,
number=2, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=392,
serialized_end=454,
)
_EVALORDER = _descriptor.Descriptor(
name='EvalOrder',
full_name='EvalOrder',
filename=None,
file=DESCRIPTOR,
containing_type=None,
#create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='modelParameters', full_name='EvalOrder.modelParameters', index=0,
number=1, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='configDict', full_name='EvalOrder.configDict', index=1,
number=2, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=456,
serialized_end=512,
)
_EVALRESPONSE = _descriptor.Descriptor(
name='EvalResponse',
full_name='EvalResponse',
filename=None,
file=DESCRIPTOR,
containing_type=None,
#create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='responseDict', full_name='EvalResponse.responseDict', index=0,
number=1, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=514,
serialized_end=550,
)
_SETPARAMSORDER = _descriptor.Descriptor(
name='SetParamsOrder',
full_name='SetParamsOrder',
filename=None,
file=DESCRIPTOR,
containing_type=None,
#create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='modelParameters', full_name='SetParamsOrder.modelParameters', index=0,
number=1, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=552,
serialized_end=593,
)
_SETPARAMSRESPONSE = _descriptor.Descriptor(
name='SetParamsResponse',
full_name='SetParamsResponse',
filename=None,
file=DESCRIPTOR,
containing_type=None,
#create_key=_descriptor._internal_create_key,
fields=[
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=595,
serialized_end=614,
)
_DISCONNECTORDER = _descriptor.Descriptor(
name='DisconnectOrder',
full_name='DisconnectOrder',
filename=None,
file=DESCRIPTOR,
containing_type=None,
#create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='message', full_name='DisconnectOrder.message', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=b"".decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='reconnectTime', full_name='DisconnectOrder.reconnectTime', index=1,
number=2, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=616,
serialized_end=673,
)
_SERVERMESSAGE.fields_by_name['trainOrder'].message_type = _TRAINORDER
_SERVERMESSAGE.fields_by_name['evalOrder'].message_type = _EVALORDER
_SERVERMESSAGE.fields_by_name['disconnectOrder'].message_type = _DISCONNECTORDER
_SERVERMESSAGE.fields_by_name['setParamsOrder'].message_type = _SETPARAMSORDER
_CLIENTMESSAGE.fields_by_name['trainResponse'].message_type = _TRAINRESPONSE
_CLIENTMESSAGE.fields_by_name['evalResponse'].message_type = _EVALRESPONSE
_CLIENTMESSAGE.fields_by_name['setParamsResponse'].message_type = _SETPARAMSRESPONSE
DESCRIPTOR.message_types_by_name['ServerMessage'] = _SERVERMESSAGE
DESCRIPTOR.message_types_by_name['ClientMessage'] = _CLIENTMESSAGE
DESCRIPTOR.message_types_by_name['TrainOrder'] = _TRAINORDER
DESCRIPTOR.message_types_by_name['TrainResponse'] = _TRAINRESPONSE
DESCRIPTOR.message_types_by_name['EvalOrder'] = _EVALORDER
DESCRIPTOR.message_types_by_name['EvalResponse'] = _EVALRESPONSE
DESCRIPTOR.message_types_by_name['SetParamsOrder'] = _SETPARAMSORDER
DESCRIPTOR.message_types_by_name['SetParamsResponse'] = _SETPARAMSRESPONSE
DESCRIPTOR.message_types_by_name['DisconnectOrder'] = _DISCONNECTORDER
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
ServerMessage = _reflection.GeneratedProtocolMessageType('ServerMessage', (_message.Message,), {
'DESCRIPTOR' : _SERVERMESSAGE,
'__module__' : 'ClientConnection_pb2'
# @@protoc_insertion_point(class_scope:ServerMessage)
})
_sym_db.RegisterMessage(ServerMessage)
ClientMessage = _reflection.GeneratedProtocolMessageType('ClientMessage', (_message.Message,), {
'DESCRIPTOR' : _CLIENTMESSAGE,
'__module__' : 'ClientConnection_pb2'
# @@protoc_insertion_point(class_scope:ClientMessage)
})
_sym_db.RegisterMessage(ClientMessage)
TrainOrder = _reflection.GeneratedProtocolMessageType('TrainOrder', (_message.Message,), {
'DESCRIPTOR' : _TRAINORDER,
'__module__' : 'ClientConnection_pb2'
# @@protoc_insertion_point(class_scope:TrainOrder)
})
_sym_db.RegisterMessage(TrainOrder)
TrainResponse = _reflection.GeneratedProtocolMessageType('TrainResponse', (_message.Message,), {
'DESCRIPTOR' : _TRAINRESPONSE,
'__module__' : 'ClientConnection_pb2'
# @@protoc_insertion_point(class_scope:TrainResponse)
})
_sym_db.RegisterMessage(TrainResponse)
EvalOrder = _reflection.GeneratedProtocolMessageType('EvalOrder', (_message.Message,), {
'DESCRIPTOR' : _EVALORDER,
'__module__' : 'ClientConnection_pb2'
# @@protoc_insertion_point(class_scope:EvalOrder)
})
_sym_db.RegisterMessage(EvalOrder)
EvalResponse = _reflection.GeneratedProtocolMessageType('EvalResponse', (_message.Message,), {
'DESCRIPTOR' : _EVALRESPONSE,
'__module__' : 'ClientConnection_pb2'
# @@protoc_insertion_point(class_scope:EvalResponse)
})
_sym_db.RegisterMessage(EvalResponse)
SetParamsOrder = _reflection.GeneratedProtocolMessageType('SetParamsOrder', (_message.Message,), {
'DESCRIPTOR' : _SETPARAMSORDER,
'__module__' : 'ClientConnection_pb2'
# @@protoc_insertion_point(class_scope:SetParamsOrder)
})
_sym_db.RegisterMessage(SetParamsOrder)
SetParamsResponse = _reflection.GeneratedProtocolMessageType('SetParamsResponse', (
_message.Message,),{
'DESCRIPTOR' : _SETPARAMSRESPONSE,
'__module__' : 'ClientConnection_pb2'
# @@protoc_insertion_point(class_scope:SetParamsResponse)
})
_sym_db.RegisterMessage(SetParamsResponse)
DisconnectOrder = _reflection.GeneratedProtocolMessageType('DisconnectOrder', (_message.Message,), {
'DESCRIPTOR' : _DISCONNECTORDER,
'__module__' : 'ClientConnection_pb2'
# @@protoc_insertion_point(class_scope:DisconnectOrder)
})
_sym_db.RegisterMessage(DisconnectOrder)
_CLIENTCONNECTION = _descriptor.ServiceDescriptor(
name='ClientConnection',
full_name='ClientConnection',
file=DESCRIPTOR,
index=0,
serialized_options=None,
#create_key=_descriptor._internal_create_key,
serialized_start=675,
serialized_end=740,
methods=[
_descriptor.MethodDescriptor(
name='Connect',
full_name='ClientConnection.Connect',
index=0,
containing_service=None,
input_type=_CLIENTMESSAGE,
output_type=_SERVERMESSAGE,
serialized_options=None,
#create_key=_descriptor._internal_create_key,
),
])
_sym_db.RegisterServiceDescriptor(_CLIENTCONNECTION)
DESCRIPTOR.services_by_name['ClientConnection'] = _CLIENTCONNECTION
# @@protoc_insertion_point(module_scope)
================================================
FILE: federa/client/src/ClientConnection_pb2_grpc.py
================================================
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
from . import ClientConnection_pb2 as ClientConnection__pb2
class ClientConnectionStub():
"""Missing associated documentation comment in .proto file."""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.Connect = channel.stream_stream(
'/ClientConnection/Connect',
request_serializer=ClientConnection__pb2.ClientMessage.SerializeToString,
response_deserializer=ClientConnection__pb2.ServerMessage.FromString,
)
class ClientConnectionServicer():
"""Missing associated documentation comment in .proto file."""
def Connect(self, request_iterator, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_ClientConnectionServicer_to_server(servicer, server):
rpc_method_handlers = {
'Connect': grpc.stream_stream_rpc_method_handler(
servicer.Connect,
request_deserializer=ClientConnection__pb2.ClientMessage.FromString,
response_serializer=ClientConnection__pb2.ServerMessage.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'ClientConnection', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
# This class is part of an EXPERIMENTAL API.
class ClientConnection():
"""Missing associated documentation comment in .proto file."""
@staticmethod
def Connect(request_iterator,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.stream_stream(request_iterator, target,
'/ClientConnection/Connect',
ClientConnection__pb2.ClientMessage.SerializeToString,
ClientConnection__pb2.ServerMessage.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
================================================
FILE: federa/client/src/__init__.py
================================================
================================================
FILE: federa/client/src/client.py
================================================
from queue import Queue
import torch
import time
import grpc
from . import ClientConnection_pb2_grpc
from .ClientConnection_pb2 import ClientMessage
from .client_lib import train, evaluate, set_parameters
def client_start(config):
keep_going = True
wait_time = config["wait_time"]
ip_address = config["ip_address"]
device = torch.device(config["device"])
#device = torch.device("cuda:2" if torch.cuda.is_available() else "cpu")
while keep_going:
#wait for specified time before reconnecting
time.sleep(wait_time)
if config["encryption"] == 1:
ca_cert = config['ca']
root_certs = bytes(open(ca_cert).read(), 'utf-8')
credentials = grpc.ssl_channel_credentials(root_certs)
#create new gRPC channel to the server
channel = grpc.secure_channel(ip_address, options=[
('grpc.max_send_message_length', -1),
('grpc.max_receive_message_length', -1)
], credentials=credentials)
else:
channel = grpc.insecure_channel(ip_address, options=[
('grpc.max_send_message_length', -1),
('grpc.max_receive_message_length', -1)
])
stub = ClientConnection_pb2_grpc.ClientConnectionStub(channel)
client_buffer = Queue(maxsize = 10)
print("Connected with server")
#wait for incoming messages from the server in client_buffer
#then according to fields present in them call the appropraite function
for server_message in stub.Connect( iter(client_buffer.get, None) ):
if server_message.HasField("evalOrder"):
eval_order_message = server_message.evalOrder
eval_response_message = evaluate(eval_order_message, device)
message_to_server = ClientMessage(evalResponse = eval_response_message)
client_buffer.put(message_to_server)
if server_message.HasField("trainOrder"):
train_order_message = server_message.trainOrder
train_response_message = train(train_order_message, device)
message_to_server = ClientMessage(trainResponse = train_response_message)
client_buffer.put(message_to_server)
if server_message.HasField("setParamsOrder"):
set_parameters_order_message = server_message.setParamsOrder
set_parameters(set_parameters_order_message, device)
message_to_server = ClientMessage(setParamsResponse = None)
client_buffer.put(message_to_server)
if server_message.HasField("disconnectOrder"):
print("Current FL process is done ")
disconnect_order_message = server_message.disconnectOrder
message = disconnect_order_message.message
print(message)
reconnect_time = disconnect_order_message.reconnectTime
if reconnect_time == 0:
keep_going = False
break
wait_time = reconnect_time
================================================
FILE: federa/client/src/client_lib.py
================================================
import torch
from io import BytesIO
import json
import time
import os
from datetime import datetime
from codecarbon import OfflineEmissionsTracker
from .net import get_net
from .net_lib import test_model, load_data
from .net_lib import train_model, train_fedavg, train_scaffold, train_mimelite, train_mime, train_feddyn
from torch.utils.data import DataLoader
from .get_data import get_data
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from .ClientConnection_pb2 import EvalResponse, TrainResponse
#create a new directory inside FL_checkpoints and store the aggragted models in each round
fl_timestamp = f"{datetime.now().strftime('%Y-%m-%d %H-%M-%S')}"
save_dir_path = f"client_checkpoints/{fl_timestamp}"
os.makedirs(save_dir_path)
prev_grads = None
def evaluate(eval_order_message, device):
model_parameters_bytes = eval_order_message.modelParameters
model_parameters = torch.load( BytesIO(model_parameters_bytes), map_location="cpu" )
config_dict_bytes = eval_order_message.configDict
config_dict = json.loads( config_dict_bytes.decode("utf-8") )
client_id = config_dict["client_id"]
state_dict = model_parameters
print("Evaluation:",config_dict)
with open("config.json", "r", encoding='utf-8') as jsonfile:
config_dict = json.load(jsonfile)
model = get_net(config= config_dict).to(device)
model.load_state_dict(state_dict)
_, testset = get_data(config= config_dict)
testloader = DataLoader(testset, batch_size=config_dict['batch_size'])
#_, testloader, _ = load_data(config_dict)
eval_loss, eval_accuracy = test_model(model, testloader, device)
response_dict = {"eval_loss": eval_loss, "eval_accuracy": eval_accuracy, "client_id": client_id}
response_dict_bytes = json.dumps(response_dict).encode("utf-8")
eval_response_message = EvalResponse(responseDict = response_dict_bytes)
return eval_response_message
def train(train_order_message, device):
data_bytes = train_order_message.modelParameters
data = torch.load( BytesIO(data_bytes), map_location="cpu" )
model_parameters, control_variate, = data['model_parameters'], data['control_variate']
control_variate2 = data['control_variate2']
config_dict_bytes = train_order_message.configDict
config_dict = json.loads( config_dict_bytes.decode("utf-8") )
carbon_tracker = config_dict["carbon-tracker"]
model = get_net(config= config_dict)
model.load_state_dict(model_parameters)
model = model.to(device)
epochs = config_dict["epochs"]
if config_dict["timeout"]:
deadline = time.time() + config_dict["timeout"]
else:
deadline = None
#Run code carbon if the carbon-tracker flag is True
if carbon_tracker==1:
tracker = OfflineEmissionsTracker(country_iso_code="IND", output_dir = save_dir_path)
tracker.start()
trainloader, testloader, _ = load_data(config_dict)
print("Training started")
if config_dict['algorithm'] == 'mimelite':
model, control_variate = train_mimelite(model, control_variate, trainloader, epochs, device, deadline)
elif config_dict['algorithm'] == 'scaffold':
model, control_variate = train_scaffold(model, control_variate, trainloader, epochs, device, deadline)
elif config_dict['algorithm'] == 'mime':
model, control_variate = train_mime(model, control_variate, control_variate2, trainloader, epochs, device, deadline)
elif config_dict['algorithm'] == 'fedavg':
model = train_fedavg(model, trainloader, epochs, device, deadline)
elif config_dict['algorithm'] == 'feddyn':
global prev_grads
model, prev_grads = train_feddyn(model, trainloader, epochs, device, deadline, prev_grads)
else:
model = train_model(model, trainloader, epochs, device, deadline)
if carbon_tracker==1:
emissions: float = tracker.stop()
print(f"Emissions: {emissions} kg")
myJSON = json.dumps(config_dict)
json_path = save_dir_path + "/config.json"
with open(json_path, "w", encoding='utf-8') as jsonfile:
jsonfile.write(myJSON)
json_path = "config.json"
with open(json_path, "w", encoding='utf-8') as jsonfile:
jsonfile.write(myJSON)
trained_model_parameters = model.state_dict()
#Create a dictionary where model_parameters and control_variate are stored which needs to be sent to the server
data_to_send = {}
data_to_send['model_parameters'] = trained_model_parameters
data_to_send['control_variate'] = control_variate #If there is no control_variate, this will become None
buffer = BytesIO()
torch.save(data_to_send, buffer)
buffer.seek(0)
data_to_send_bytes = buffer.read()
print("Evaluation")
if config_dict['algorithm'] not in ('fedavg','feddyn','mime','mimelite'):
for key in trained_model_parameters:
trained_model_parameters[key] += model_parameters[key].to(device)
train_loss, train_accuracy = test_model(model, testloader, device)
response_dict = {"train_loss": train_loss, "train_accuracy": train_accuracy}
response_dict_bytes = json.dumps(response_dict).encode("utf-8")
train_response_message = TrainResponse(
modelParameters = data_to_send_bytes,
responseDict = response_dict_bytes)
save_model_state(model)
if carbon_tracker==1:
plot_emission()
return train_response_message
#replace current model with the model provided
def set_parameters(set_parameters_order_message, device):
model_parameters_bytes = set_parameters_order_message.modelParameters
model_parameters = torch.load( BytesIO(model_parameters_bytes), map_location="cpu" )
with open("config.json", "r", encoding='utf-8') as jsonfile:
config_dict = json.load(jsonfile)
model = get_net(config= config_dict).to(device)
model.load_state_dict(model_parameters)
save_model_state(model)
#save the current model to model_checkpoints
def save_model_state(model):
file_num = len(os.listdir(f"{save_dir_path}"))
filepath = f"{save_dir_path}/model_{file_num}.pt"
state_dict = model.state_dict()
torch.save(state_dict, filepath)
#save plot for communication round-wise carbon emmision
def plot_emission():
data = pd.read_csv(f"{save_dir_path}/emissions.csv")
plt.plot(np.arange(len(data.index)),data['emissions']*1000)
plt.xlabel('Communication Rounds')
plt.ylabel('Carbon Emmision (gm)')
plt.savefig(f"{save_dir_path}/emissions.png")
================================================
FILE: federa/client/src/data_utils.py
================================================
import torch
#from PIL import Image
from torch.utils import data
#from torchvision import transforms
#import pickle
class distributionDataloader(data.Dataset):
def __init__(
self,
config,
trainset,
data_idxs,
clientID = 0,
aug = False,
):
self.aug = aug
self.config = config
self.img_size = config["resize_size"]
self.trainset = trainset
self.niid_degree = config["niid"]
self.clientID = clientID
self.mean = 33.3184
self.stdv = 78.5675
# self.data_idxs = torch.load(data_path)['datapoints'][clientID]
self.data_idxs = data_idxs[clientID]
def __len__(self):
return len(self.data_idxs)
def __getitem__(self, index):
image = self.trainset[self.data_idxs[index]][0]
label = self.trainset[self.data_idxs[index]][1]
return image, label
================================================
FILE: federa/client/src/get_data.py
================================================
import os
from torchvision import transforms,datasets
from torch.utils import data
import numpy as np
from PIL import Image
# Define a function to get the train and test datasets based on the given configuration
def get_data(config):
# If the dataset is not custom, create a dataset folder
if config['dataset'] != 'CUSTOM':
dataset_path = "client_dataset"
if not os.path.exists(dataset_path):
os.makedirs(dataset_path)
# Get the train and test datasets for each supported dataset
if config['dataset'] == 'MNIST':
# Apply transformations to the images
apply_transform = transforms.Compose([transforms.Resize(config["resize_size"]), transforms.ToTensor()])
# Download and load the trainset
trainset = datasets.MNIST(root='client_dataset/MNIST', train=True, download=True, transform=apply_transform)
# Download and load the testset
testset = datasets.MNIST(root='client_dataset/MNIST', train=False, download=True, transform=apply_transform)
elif config['dataset'] == 'FashionMNIST':
apply_transform = transforms.Compose([transforms.Resize(config['resize_size']), transforms.ToTensor()])
trainset = datasets.FashionMNIST(root='client_dataset/FashionMNIST',
train=True, download=True, transform=apply_transform)
testset = datasets.FashionMNIST(root='client_dataset/FashionMNIST',
train=False, download=True, transform=apply_transform)
elif config['dataset'] == 'CIFAR10':
apply_transform = transforms.Compose([transforms.Resize(config['resize_size']), transforms.ToTensor()])
trainset = datasets.CIFAR10(root='client_dataset/CIFAR10',
train=True, download=True, transform=apply_transform)
testset = datasets.CIFAR10(root='client_dataset/CIFAR10',
train=False, download=True, transform=apply_transform)
elif config['dataset'] == 'CIFAR100':
apply_transform = transforms.Compose([transforms.Resize(config['resize_size']), transforms.ToTensor()])
trainset = datasets.CIFAR100(root='client_dataset/CIFAR100',
train=True, download=True, transform=apply_transform)
testset = datasets.CIFAR100(root='client_dataset/CIFAR100',
train=False, download=True, transform=apply_transform)
elif config['dataset'] == 'CUSTOM':
apply_transform = transforms.Compose([transforms.Resize(config['resize_size']), transforms.ToTensor()])
# Load the custom dataset
trainset = customDataset(root='client_custom_dataset/CUSTOM/train', transform=apply_transform)
testset = customDataset(root='client_custom_dataset/CUSTOM/test', transform=apply_transform)
else:
# Raise an error if an unsupported dataset is specified
raise ValueError(f"Unsupported dataset type: {config['dataset']}")
# Return the train and test datasets
return trainset, testset
class customDataset(data.Dataset):
def __init__(self, root, transform=None):
"""
Custom dataset class for loading image and label data from a folder of .npy files.
Args:
root (str): Path to the folder containing the .npy files.
transform (callable, optional): A function/transform that takes
an PIL image and returns a transformed version.
E.g, `transforms.RandomCrop`
"""
self.root = root
samples = sample_return(root)
self.samples = samples
self.transform = transform
def __getitem__(self, index):
"""
Retrieves a sample from the dataset at the given index.
Args:
index (int): Index of the sample to retrieve.
Returns:
img (PIL.Image): The image data.
label (int): The label for the image data.
"""
img, label= self.samples[index]
img = np.load(img)
img = Image.fromarray(img)
if self.transform is not None:
img = self.transform(img)
return img, label
def __len__(self):
return len(self.samples)
def sample_return(root):
# Initialize an empty list to hold the samples
newdataset = []
# Define a dictionary that maps label names to integer values
labels = {'Breast': 0, 'Chestxray':1, 'Oct': 2, 'Tissue': 3}
# Loop over each image in the root directory
for image in os.listdir(root):
# Initialize an empty list to hold the label
label=[]
# Get the full path of the image
path = os.path.join(root, image)
# Extract the label from the image filename
labels_str = image.split('_')[0]
label = labels[labels_str]
# Create a tuple containing the image path and its label, and append it to the list of samples
item = (path, label)
newdataset.append(item)
# Return the list of samples
return newdataset
================================================
FILE: federa/client/src/net.py
================================================
from torch import nn
from torchvision import models
class LeNet(nn.Module):
def __init__(self, in_channels=1, num_classes=10):
super().__init__()
self.conv1 = nn.Conv2d(in_channels, 6, kernel_size=5)
self.pool1 = nn.MaxPool2d(kernel_size=2,stride=2)
self.conv2 = nn.Conv2d(6, 16, kernel_size=5)
self.pool2 = nn.MaxPool2d(kernel_size=2,stride=2)
self.fc1 = nn.Linear(400, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, num_classes)
self.relu = nn.ReLU()
self.logSoftmax = nn.LogSoftmax(dim=1)
def forward(self, x):
x = self.conv1(x)
x = self.relu(x)
x = self.pool1(x)
x = self.conv2(x)
x = self.relu(x)
x = self.pool2(x)
x = x.view(-1, 400)
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
x = self.relu(x)
x = self.fc3(x)
x = self.logSoftmax(x)
return x
def get_net(config):
if config["net"] == 'LeNet':
if config['dataset'] in ['MNIST', 'FashionMNIST', 'CUSTOM']:
net = LeNet(in_channels=1, num_classes=10)
elif config['dataset'] == 'CIFAR10':
net = LeNet(in_channels=3, num_classes=10)
else:
net = LeNet(in_channels=3, num_classes=100)
if config["net"] == 'resnet18':
if config['dataset'] == 'CIFAR10':
net = models.resnet18(num_classes=10)
else:
net = models.resnet18(num_classes=100)
if config["net"] == 'resnet50':
if config['dataset'] == 'CIFAR10':
net = models.resnet50(num_classes=10)
else:
net = models.resnet50(num_classes=100)
if config["net"] == 'vgg16':
if config['dataset'] == 'CIFAR10':
net = models.vgg16(num_classes=10)
else:
net = models.vgg16(num_classes=100)
if config['net'] == 'AlexNet':
if config['dataset'] == 'CIFAR10':
net = models.alexnet(num_classes=10)
else:
net = models.alexnet(num_classes=100)
return net
================================================
FILE: federa/client/src/net_lib.py
================================================
import os
import time
from copy import deepcopy
from math import ceil
from tqdm import tqdm
import torch
from torch.utils.data import DataLoader
from .data_utils import distributionDataloader
from .get_data import get_data
# DEVICE = torch.device("cuda:2" if torch.cuda.is_available() else "cpu")
# #device id of this should be same in client_lib device
def load_data(config):
trainset, testset = get_data(config)
# Data distribution for non-custom datasets
if config['dataset'] != 'CUSTOM':
datasets = distributionDataloader(config, trainset, config['datapoints'], config['client_idx'])
trainloader = DataLoader(datasets, batch_size= config['batch_size'], shuffle=True)
testloader = DataLoader(testset, batch_size=config['batch_size'])
num_examples = {"trainset": len(datasets), "testset": len(testset)}
else:
trainloader = DataLoader(trainset, batch_size= config['batch_size'], shuffle=True)
testloader = DataLoader(testset, batch_size=config['batch_size'])
num_examples = {"trainset": len(trainset), "testset": len(testset)}
# Return data loaders and number of examples in train and test datasets
return trainloader, testloader, num_examples
def flush_memory():
torch.cuda.empty_cache()
def train_model(net, trainloader, epochs, device, deadline=None):
"""
Trains a neural network model on a given dataset using SGD optimizer with Cross Entropy Loss criterion.
Args:
net: neural network model
trainloader: PyTorch DataLoader object for training dataset
epochs: number of epochs to train the model
deadline: optional deadline time for training
Returns:
trained model with the difference between trained model and the received model
"""
x = deepcopy(net)
# Define the loss function and optimizer
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
# Set the model to training mode
net.train()
# Train the model for the specified number of epochs
for _ in tqdm(range(epochs)):
for images, labels in trainloader:
images, labels = images.to(device), labels.to(device)
optimizer.zero_grad()
loss = criterion(net(images), labels)
loss.backward()
optimizer.step()
# Check if the deadline time has been reached
if deadline:
current_time = time.time()
if current_time >= deadline:
print("deadline occurred.")
break
# Calculate the difference between the trained model and the received model
for param_net, param_x in zip(net.parameters(), x.parameters()):
param_net.data = param_net.data - param_x.data
return net
def train_fedavg(net, trainloader, epochs, device, deadline=None):
"""
Trains a given neural network using the Federated Averaging (FedAvg) algorithm.
Args:
net: A PyTorch neural network model
trainloader: A PyTorch DataLoader containing the training dataset
epochs: An integer specifying the number of training epochs
deadline: An optional deadline (in seconds) for the training process
Returns:
A trained PyTorch neural network model
"""
# Define loss function and optimizer
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
# Set model to train mode
net.train()
# Train the model for the specified number of epochs
for _ in tqdm(range(epochs)):
for images, labels in trainloader:
# Move data to device (GPU or CPU)
images, labels = images.to(device), labels.to(device)
# Zero the gradients
optimizer.zero_grad()
# Forward pass
outputs = net(images)
# Compute the loss
loss = criterion(outputs, labels)
# Backward pass
loss.backward()
# Update model parameters
optimizer.step()
# Check if deadline has been reached
if deadline:
current_time = time.time()
if current_time >= deadline:
print("Deadline occurred.")
break
# Return the trained model
return net
def train_feddyn(net, trainloader, epochs, device, deadline=None, prev_grads=None):
"""
Trains a given neural network using the FedDyn algorithm.
Args:
net: A PyTorch neural network model
trainloader: A PyTorch DataLoader containing the training dataset
epochs: An integer specifying the number of training epochs
deadline: An optional deadline (in seconds) for the training process
Returns:
A trained PyTorch neural network model
"""
x = deepcopy(net)
# prev_grads = None
if prev_grads is not None:
prev_grads = prev_grads.to(device)
else:
for param in net.parameters():
if not isinstance(prev_grads, torch.Tensor):
prev_grads = torch.zeros_like(param.view(-1))
prev_grads.to(device)
else:
prev_grads = torch.cat((prev_grads, torch.zeros_like(param.view(-1))), dim=0)
prev_grads.to(device)
criterion = torch.nn.CrossEntropyLoss()
lr = 0.1
alpha = 0.01
optimizer = torch.optim.SGD(net.parameters(), lr=lr)
for _ in tqdm(range(epochs)):
inputs,labels = next(iter(trainloader))
inputs, labels = inputs.float().to(device), labels.long().to(device)
output = net(inputs)
loss = criterion(output, labels) #Calculate the loss with respect to y's output and labels
#Dynamic Regularisation
lin_penalty = 0.0
curr_params = None
for param in net.parameters():
if not isinstance(curr_params, torch.Tensor):
curr_params = param.view(-1)
else:
curr_params = torch.cat((curr_params, param.view(-1)), dim=0)
lin_penalty = torch.sum(curr_params * prev_grads)
loss -= lin_penalty
quad_penalty = 0.0
for y, z in zip(net.parameters(), x.parameters()):
quad_penalty += torch.nn.functional.mse_loss(y.data, z.data, reduction='sum')
loss += (alpha/2) * quad_penalty
optimizer.zero_grad()
loss.backward()
torch.nn.utils.clip_grad_norm_(parameters=net.parameters(), max_norm=1) # Clip gradients
optimizer.step()
if deadline:
current_time = time.time()
if current_time >= deadline:
print("deadline occurred.")
break
#Calculate the difference between updated model (y) and the received model (x)
delta = None
for y, z in zip(net.parameters(), x.parameters()):
if not isinstance(delta, torch.Tensor):
delta = torch.sub(y.data.view(-1), z.data.view(-1))
else:
delta = torch.cat((delta, torch.sub(y.data.view(-1), z.data.view(-1))),dim=0)
#Update prev_grads using delta which is scaled by alpha
prev_grads = torch.sub(prev_grads, delta, alpha = alpha)
return net, prev_grads
def train_mimelite(net, state, trainloader, epochs, device, deadline=None):
"""
Trains a given neural network using the MimeLite algorithm.
Args:
net: A PyTorch neural network model
trainloader: A PyTorch DataLoader containing the training dataset
epochs: An integer specifying the number of training epochs
deadline: An optional deadline (in seconds) for the training process
Returns:
A trained PyTorch neural network model
In the case of MimeLite, control_variate is nothing but a state like in case of momentum method
"""
x = deepcopy(net)
criterion = torch.nn.CrossEntropyLoss()
lr = 0.001
momentum = 0.9
net.train()
for _ in tqdm(range(epochs)):
for images, labels in trainloader:
images, labels = images.to(device), labels.to(device)
loss = criterion(net(images), labels)
#Compute (full-batch) gradient of loss with respect to net's parameters
grads = torch.autograd.grad(loss,net.parameters())
#Update net's parameters using gradients
with torch.no_grad():
for param,grad,s in zip(net.parameters(), grads, state):
param.data = param.data - lr * ((1-momentum) * grad.data + momentum * s.to(device).data)
if deadline:
current_time = time.time()
if current_time >= deadline:
print("deadline occurred.")
break
#Compute gradient wrt the received model (x) using the wholde dataset
data = DataLoader(trainloader.dataset, batch_size = len(trainloader) * trainloader.batch_size, shuffle = True)
for images, labels in data:
images, labels = images.to(device), labels.to(device)
output = x(images)
loss = criterion(output, labels) #Calculate the loss with respect to y's output and labels
gradient_x = torch.autograd.grad(loss,x.parameters())
return net, gradient_x
def train_mime(net, state, control_variate, trainloader, epochs, device, deadline=None):
"""
Trains a given neural network using the Mime algorithm.
Args:
net: A PyTorch neural network model
trainloader: A PyTorch DataLoader containing the training dataset
epochs: An integer specifying the number of training epochs
deadline: An optional deadline (in seconds) for the training process
Returns:
A trained PyTorch neural network model
"""
x = deepcopy(net)
criterion = torch.nn.CrossEntropyLoss()
lr = 0.001
momentum = 0.9
net.train()
x.train()
#control_variate = control_variate.to(DEVICE)
for epoch in tqdm(range(epochs)):
for images, labels in trainloader:
images, labels = images.to(device), labels.to(device)
loss = criterion(net(images), labels)
#Compute (full-batch) gradient of loss with respect to net's parameters
grads_y = torch.autograd.grad(loss,net.parameters())
if epoch == 0:
output = x(images)
loss = criterion(output, labels)
grads_x = torch.autograd.grad(loss,x.parameters())
#Update net's parameters using gradients
with torch.no_grad():
for g_y, g_x, c in zip(grads_y, grads_x, control_variate):
g_y.data -= g_x.data + c.to(device)
for param,grad,s in zip(net.parameters(), grads_y, state):
param.data = param.data - lr * ((1-momentum) * grad.data + momentum * s.to(device).data)
if deadline:
current_time = time.time()
if current_time >= deadline:
print("deadline occurred.")
break
#Compute gradient wrt the received model (x) using the wholde dataset
data = DataLoader(trainloader.dataset, batch_size = len(trainloader) * trainloader.batch_size, shuffle = True)
for images, labels in data:
images, labels = images.to(device), labels.to(device)
output = x(images)
loss = criterion(output, labels) #Calculate the loss with respect to y's output and labels
gradient_x = torch.autograd.grad(loss,x.parameters())
return net, gradient_x
def train_scaffold(net, server_c, trainloader, epochs, device, deadline=None):
"""
Trains a given neural network using the Scaffold algorithm.
Args:
net: A PyTorch neural network model
trainloader: A PyTorch DataLoader containing the training dataset
epochs: An integer specifying the number of training epochs
deadline: An optional deadline (in seconds) for the training process
Returns:
A trained PyTorch neural network model
"""
x = deepcopy(net)
client_c = deepcopy(server_c)
criterion = torch.nn.CrossEntropyLoss()
lr = 0.001
for _ in tqdm(range(epochs)):
for images, labels in trainloader:
images, labels = images.to(device), labels.to(device)
loss = criterion(net(images), labels)
#Compute (full-batch) gradient of loss with respect to net's parameters
grads = torch.autograd.grad(loss,net.parameters())
#Update y's parameters using gradients, client_c and server_c [Algorithm line no:10]
for param,grad,s_c,c_c in zip(net.parameters(),grads,server_c,client_c):
s_c, c_c = s_c.to(device), c_c.to(device)
param.data = param.data - lr * (grad.data + (s_c.data - c_c.data))
if deadline:
current_time = time.time()
if current_time >= deadline:
print("deadline occurred.")
break
delta_c = [torch.zeros_like(param) for param in net.parameters()]
new_client_c = deepcopy(delta_c)
for param_net, param_x in zip(net.parameters(), x.parameters()):
param_net.data = param_net.data - param_x.data
a = (ceil(len(trainloader.dataset) / trainloader.batch_size) * epochs * lr)
for n_c, c_l, c_g, diff in zip(new_client_c, client_c, server_c, net.parameters()):
c_l = c_l.to(device)
c_g = c_g.to(device)
n_c.data += c_l.data - c_g.data - diff.data / a
#Calculate delta_c which equals to new_client_c-client_c
for d_c, n_c_l, c_l in zip(delta_c, new_client_c, client_c):
d_c = d_c.to(device)
c_l = c_l.to(device)
d_c.data.add_(n_c_l.data - c_l.data)
return net, delta_c
def test_model(net, testloader, device):
"""Evaluate the performance of a model on a test dataset.
Args:
net (torch.nn.Module): The neural network model to evaluate.
testloader (torch.utils.data.DataLoader): The data loader for the test dataset.
Returns:
Tuple: The average loss and accuracy of the model on the test dataset.
"""
criterion = torch.nn.CrossEntropyLoss()
net.eval()
test_loss, correct, total = 0.0, 0, 0
with torch.no_grad():
for images, labels in tqdm(testloader):
images, labels = images.to(device), labels.to(device)
outputs = net(images)
test_loss += criterion(outputs, labels).item()
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
test_loss /= len(testloader.dataset)
accuracy = correct / total
return test_loss, accuracy
================================================
FILE: federa/client/start_client.py
================================================
from .src.client import client_start
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--ip", type=str, default = "localhost:8214", help="IP address of the server")
parser.add_argument("--device", type=str, default = "cpu", help="Device to run the client on")
parser.add_argument('--ca', type = str, default= 'ca.pem', help= 'path to CA certificate')
parser.add_argument('--encryption', type = int, default= 0, help= '1 enables ssl encryption')
parser.add_argument('--wait_time', type = int, default= 30, help= 'time to wait before sending the next request')
args = parser.parse_args()
configs = {
"ip_address": args.ip,
"wait_time": args.wait_time,
"device": args.device,
"encryption": args.encryption,
"ca": args.ca,
}
if __name__ == '__main__':
client_start(configs)
================================================
FILE: federa/server/__init__.py
================================================
================================================
FILE: federa/server/src/ClientConnection_pb2.py
================================================
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: ClientConnection.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='ClientConnection.proto',
package='',
syntax='proto3',
serialized_options=None,
#create_key=_descriptor._internal_create_key,
serialized_pb=b'\n\x16\x43lientConnection.proto\"\xa3\x01\n\rServerMessage\x12\x1f\n\ntrainOrder\x18\x01 \x01(\x0b\x32\x0b.TrainOrder\x12\x1d\n\tevalOrder\x18\x02 \x01(\x0b\x32\n.EvalOrder\x12)\n\x0f\x64isconnectOrder\x18\x03 \x01(\x0b\x32\x10.DisconnectOrder\x12\'\n\x0esetParamsOrder\x18\x04 \x01(\x0b\x32\x0f.SetParamsOrder\"\x8a\x01\n\rClientMessage\x12%\n\rtrainResponse\x18\x01 \x01(\x0b\x32\x0e.TrainResponse\x12#\n\x0c\x65valResponse\x18\x02 \x01(\x0b\x32\r.EvalResponse\x12-\n\x11setParamsResponse\x18\x03 \x01(\x0b\x32\x12.SetParamsResponse\"9\n\nTrainOrder\x12\x17\n\x0fmodelParameters\x18\x01 \x01(\x0c\x12\x12\n\nconfigDict\x18\x02 \x01(\x0c\">\n\rTrainResponse\x12\x17\n\x0fmodelParameters\x18\x01 \x01(\x0c\x12\x14\n\x0cresponseDict\x18\x02 \x01(\x0c\"8\n\tEvalOrder\x12\x17\n\x0fmodelParameters\x18\x01 \x01(\x0c\x12\x12\n\nconfigDict\x18\x02 \x01(\x0c\"$\n\x0c\x45valResponse\x12\x14\n\x0cresponseDict\x18\x01 \x01(\x0c\")\n\x0eSetParamsOrder\x12\x17\n\x0fmodelParameters\x18\x01 \x01(\x0c\"\x13\n\x11SetParamsResponse\"9\n\x0f\x44isconnectOrder\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x15\n\rreconnectTime\x18\x02 \x01(\x05\x32\x41\n\x10\x43lientConnection\x12-\n\x07\x43onnect\x12\x0e.ClientMessage\x1a\x0e.ServerMessage(\x01\x30\x01\x62\x06proto3'
)
_SERVERMESSAGE = _descriptor.Descriptor(
name='ServerMessage',
full_name='ServerMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
#create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='trainOrder', full_name='ServerMessage.trainOrder', index=0,
number=1, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='evalOrder', full_name='ServerMessage.evalOrder', index=1,
number=2, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='disconnectOrder', full_name='ServerMessage.disconnectOrder', index=2,
number=3, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='setParamsOrder', full_name='ServerMessage.setParamsOrder', index=3,
number=4, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=27,
serialized_end=190,
)
_CLIENTMESSAGE = _descriptor.Descriptor(
name='ClientMessage',
full_name='ClientMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
#create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='trainResponse', full_name='ClientMessage.trainResponse', index=0,
number=1, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='evalResponse', full_name='ClientMessage.evalResponse', index=1,
number=2, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='setParamsResponse', full_name='ClientMessage.setParamsResponse', index=2,
number=3, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=193,
serialized_end=331,
)
_TRAINORDER = _descriptor.Descriptor(
name='TrainOrder',
full_name='TrainOrder',
filename=None,
file=DESCRIPTOR,
containing_type=None,
#create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='modelParameters', full_name='TrainOrder.modelParameters', index=0,
number=1, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='configDict', full_name='TrainOrder.configDict', index=1,
number=2, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=333,
serialized_end=390,
)
_TRAINRESPONSE = _descriptor.Descriptor(
name='TrainResponse',
full_name='TrainResponse',
filename=None,
file=DESCRIPTOR,
containing_type=None,
#create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='modelParameters', full_name='TrainResponse.modelParameters', index=0,
number=1, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='responseDict', full_name='TrainResponse.responseDict', index=1,
number=2, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=392,
serialized_end=454
gitextract_o4_ojofq/
├── .bandit
├── .coveragerc
├── .github/
│ └── workflows/
│ ├── publish.yml
│ ├── pytest_coverage.yml
│ ├── ubuntu.yml
│ └── windows.yml
├── .gitignore
├── CONDUCT.md
├── Dockerfile
├── LICENSE
├── README.md
├── client_custom_dataset/
│ └── CUSTOM/
│ ├── test/
│ │ ├── Breast_1_131.npy
│ │ ├── Breast_1_178.npy
│ │ ├── Breast_1_38.npy
│ │ ├── Breast_1_46.npy
│ │ ├── Breast_1_56.npy
│ │ ├── Breast_1_57.npy
│ │ ├── Breast_1_58.npy
│ │ ├── Chestxray_0_10192.npy
│ │ ├── Chestxray_0_2599.npy
│ │ ├── Chestxray_0_27.npy
│ │ ├── Chestxray_10_2647.npy
│ │ ├── Chestxray_10_7361.npy
│ │ ├── Chestxray_11_6369.npy
│ │ ├── Chestxray_12_3194.npy
│ │ ├── Chestxray_12_6281.npy
│ │ ├── Chestxray_1_1545.npy
│ │ ├── Chestxray_2_10770.npy
│ │ ├── Chestxray_2_1294.npy
│ │ ├── Chestxray_2_2942.npy
│ │ ├── Chestxray_3_4808.npy
│ │ ├── Chestxray_3_563.npy
│ │ ├── Chestxray_3_8533.npy
│ │ ├── Chestxray_3_9185.npy
│ │ ├── Chestxray_3_9271.npy
│ │ ├── Chestxray_3_9492.npy
│ │ ├── Chestxray_5_10699.npy
│ │ ├── Chestxray_5_3477.npy
│ │ ├── Chestxray_5_756.npy
│ │ ├── Chestxray_5_7941.npy
│ │ ├── Chestxray_5_8493.npy
│ │ ├── Chestxray_6_7326.npy
│ │ ├── Chestxray_7_10995.npy
│ │ ├── Chestxray_7_8642.npy
│ │ ├── Chestxray_7_9211.npy
│ │ ├── Chestxray_8_2448.npy
│ │ ├── Chestxray_9_1970.npy
│ │ ├── Oct_0_10252.npy
│ │ ├── Oct_0_10370.npy
│ │ ├── Oct_0_1901.npy
│ │ ├── Oct_0_2534.npy
│ │ ├── Oct_0_4375.npy
│ │ ├── Oct_0_521.npy
│ │ ├── Oct_0_5368.npy
│ │ ├── Oct_0_7082.npy
│ │ ├── Oct_0_72818.npy
│ │ ├── Oct_0_7570.npy
│ │ ├── Oct_0_9852.npy
│ │ ├── Oct_1_757.npy
│ │ ├── Oct_2_26531.npy
│ │ ├── Oct_2_3752.npy
│ │ ├── Oct_2_8134.npy
│ │ ├── Oct_2_8207.npy
│ │ ├── Oct_2_9648.npy
│ │ ├── Oct_3_1567.npy
│ │ ├── Oct_3_1669.npy
│ │ ├── Oct_3_2292.npy
│ │ ├── Oct_3_2794.npy
│ │ ├── Oct_3_4851.npy
│ │ ├── Oct_3_4912.npy
│ │ ├── Oct_3_5127.npy
│ │ ├── Oct_3_5626.npy
│ │ ├── Oct_3_5777.npy
│ │ ├── Oct_3_6087.npy
│ │ ├── Oct_3_6417.npy
│ │ ├── Oct_3_9802.npy
│ │ ├── Tissue_0_10673.npy
│ │ ├── Tissue_0_12024.npy
│ │ ├── Tissue_0_12038.npy
│ │ ├── Tissue_0_14742.npy
│ │ ├── Tissue_0_1487.npy
│ │ ├── Tissue_0_17483.npy
│ │ ├── Tissue_0_18694.npy
│ │ ├── Tissue_0_20122.npy
│ │ ├── Tissue_0_2373.npy
│ │ ├── Tissue_0_3171.npy
│ │ ├── Tissue_0_411.npy
│ │ ├── Tissue_0_4904.npy
│ │ ├── Tissue_0_6028.npy
│ │ ├── Tissue_0_7434.npy
│ │ ├── Tissue_0_8139.npy
│ │ ├── Tissue_0_8962.npy
│ │ ├── Tissue_0_9511.npy
│ │ ├── Tissue_0_9949.npy
│ │ ├── Tissue_3_8272.npy
│ │ ├── Tissue_3_9593.npy
│ │ ├── Tissue_4_10949.npy
│ │ ├── Tissue_4_16558.npy
│ │ ├── Tissue_4_17314.npy
│ │ ├── Tissue_4_18139.npy
│ │ ├── Tissue_4_2355.npy
│ │ ├── Tissue_5_17494.npy
│ │ ├── Tissue_5_22443.npy
│ │ ├── Tissue_6_11839.npy
│ │ ├── Tissue_6_12194.npy
│ │ ├── Tissue_6_13317.npy
│ │ ├── Tissue_6_14084.npy
│ │ ├── Tissue_6_15019.npy
│ │ ├── Tissue_6_15092.npy
│ │ ├── Tissue_6_15204.npy
│ │ ├── Tissue_6_17363.npy
│ │ ├── Tissue_6_19355.npy
│ │ ├── Tissue_6_19528.npy
│ │ ├── Tissue_6_21927.npy
│ │ ├── Tissue_6_37014.npy
│ │ ├── Tissue_7_14747.npy
│ │ ├── Tissue_7_14849.npy
│ │ ├── Tissue_7_18085.npy
│ │ ├── Tissue_7_18646.npy
│ │ ├── Tissue_7_21396.npy
│ │ ├── Tissue_7_21427.npy
│ │ ├── Tissue_7_2508.npy
│ │ ├── Tissue_7_2884.npy
│ │ ├── Tissue_7_7116.npy
│ │ └── Tissue_7_7248.npy
│ └── train/
│ ├── Breast_0_0.npy
│ ├── Breast_0_11.npy
│ ├── Breast_0_115.npy
│ ├── Breast_0_14.npy
│ ├── Breast_0_20.npy
│ ├── Breast_0_24.npy
│ ├── Breast_0_28.npy
│ ├── Breast_0_3.npy
│ ├── Breast_0_30.npy
│ ├── Breast_0_33.npy
│ ├── Breast_0_45.npy
│ ├── Breast_0_47.npy
│ ├── Breast_0_64.npy
│ ├── Breast_0_66.npy
│ ├── Breast_0_71.npy
│ ├── Breast_0_73.npy
│ ├── Breast_0_74.npy
│ ├── Breast_0_85.npy
│ ├── Breast_1_1.npy
│ ├── Breast_1_10.npy
│ ├── Breast_1_12.npy
│ ├── Breast_1_13.npy
│ ├── Breast_1_15.npy
│ ├── Breast_1_16.npy
│ ├── Breast_1_17.npy
│ ├── Breast_1_2.npy
│ ├── Breast_1_21.npy
│ ├── Breast_1_22.npy
│ ├── Breast_1_227.npy
│ ├── Breast_1_23.npy
│ ├── Breast_1_249.npy
│ ├── Breast_1_25.npy
│ ├── Breast_1_27.npy
│ ├── Breast_1_29.npy
│ ├── Breast_1_32.npy
│ ├── Breast_1_34.npy
│ ├── Breast_1_35.npy
│ ├── Breast_1_37.npy
│ ├── Breast_1_40.npy
│ ├── Breast_1_408.npy
│ ├── Breast_1_41.npy
│ ├── Breast_1_42.npy
│ ├── Breast_1_43.npy
│ ├── Breast_1_433.npy
│ ├── Breast_1_48.npy
│ ├── Breast_1_5.npy
│ ├── Breast_1_50.npy
│ ├── Breast_1_51.npy
│ ├── Breast_1_52.npy
│ ├── Breast_1_53.npy
│ ├── Breast_1_54.npy
│ ├── Breast_1_55.npy
│ ├── Breast_1_6.npy
│ ├── Breast_1_60.npy
│ ├── Breast_1_61.npy
│ ├── Breast_1_62.npy
│ ├── Breast_1_64.npy
│ ├── Breast_1_65.npy
│ ├── Breast_1_68.npy
│ ├── Breast_1_69.npy
│ ├── Breast_1_7.npy
│ ├── Breast_1_70.npy
│ ├── Breast_1_72.npy
│ ├── Breast_1_75.npy
│ ├── Breast_1_76.npy
│ ├── Breast_1_77.npy
│ ├── Breast_1_8.npy
│ ├── Breast_1_9.npy
│ ├── Chestxray_0_10696.npy
│ ├── Chestxray_0_10927.npy
│ ├── Chestxray_0_11206.npy
│ ├── Chestxray_0_2549.npy
│ ├── Chestxray_0_44.npy
│ ├── Chestxray_0_4584.npy
│ ├── Chestxray_0_474.npy
│ ├── Chestxray_0_4858.npy
│ ├── Chestxray_0_5282.npy
│ ├── Chestxray_0_6167.npy
│ ├── Chestxray_0_6235.npy
│ ├── Chestxray_0_6401.npy
│ ├── Chestxray_0_6403.npy
│ ├── Chestxray_0_6438.npy
│ ├── Chestxray_0_6482.npy
│ ├── Chestxray_0_7202.npy
│ ├── Chestxray_0_752.npy
│ ├── Chestxray_0_7551.npy
│ ├── Chestxray_0_8453.npy
│ ├── Chestxray_10_4463.npy
│ ├── Chestxray_11_1275.npy
│ ├── Chestxray_11_2068.npy
│ ├── Chestxray_11_3915.npy
│ ├── Chestxray_11_4063.npy
│ ├── Chestxray_11_64880.npy
│ ├── Chestxray_11_7570.npy
│ ├── Chestxray_11_9678.npy
│ ├── Chestxray_12_10521.npy
│ ├── Chestxray_12_1472.npy
│ ├── Chestxray_12_151.npy
│ ├── Chestxray_12_194.npy
│ ├── Chestxray_12_3225.npy
│ ├── Chestxray_12_3458.npy
│ ├── Chestxray_12_4112.npy
│ ├── Chestxray_12_4694.npy
│ ├── Chestxray_12_5795.npy
│ ├── Chestxray_12_7320.npy
│ ├── Chestxray_12_9084.npy
│ ├── Chestxray_1_10242.npy
│ ├── Chestxray_1_4797.npy
│ ├── Chestxray_1_6404.npy
│ ├── Chestxray_1_7034.npy
│ ├── Chestxray_1_7388.npy
│ ├── Chestxray_1_8324.npy
│ ├── Chestxray_1_8326.npy
│ ├── Chestxray_1_8907.npy
│ ├── Chestxray_2_10082.npy
│ ├── Chestxray_2_10125.npy
│ ├── Chestxray_2_10149.npy
│ ├── Chestxray_2_10349.npy
│ ├── Chestxray_2_10524.npy
│ ├── Chestxray_2_10638.npy
│ ├── Chestxray_2_10750.npy
│ ├── Chestxray_2_11137.npy
│ ├── Chestxray_2_1160.npy
│ ├── Chestxray_2_1177.npy
│ ├── Chestxray_2_1408.npy
│ ├── Chestxray_2_1727.npy
│ ├── Chestxray_2_1832.npy
│ ├── Chestxray_2_2029.npy
│ ├── Chestxray_2_2134.npy
│ ├── Chestxray_2_2535.npy
│ ├── Chestxray_2_3045.npy
│ ├── Chestxray_2_3462.npy
│ ├── Chestxray_2_3820.npy
│ ├── Chestxray_2_4261.npy
│ ├── Chestxray_2_5098.npy
│ ├── Chestxray_2_5125.npy
│ ├── Chestxray_2_5669.npy
│ ├── Chestxray_2_5987.npy
│ ├── Chestxray_2_6509.npy
│ ├── Chestxray_2_6807.npy
│ ├── Chestxray_2_7015.npy
│ ├── Chestxray_2_7113.npy
│ ├── Chestxray_2_7131.npy
│ ├── Chestxray_2_7152.npy
│ ├── Chestxray_2_7430.npy
│ ├── Chestxray_2_7706.npy
│ ├── Chestxray_2_7865.npy
│ ├── Chestxray_2_8054.npy
│ ├── Chestxray_2_8099.npy
│ ├── Chestxray_2_8955.npy
│ ├── Chestxray_2_9745.npy
│ ├── Chestxray_2_9882.npy
│ ├── Chestxray_2_9918.npy
│ ├── Chestxray_2_9951.npy
│ ├── Chestxray_3_10171.npy
│ ├── Chestxray_3_10717.npy
│ ├── Chestxray_3_1072.npy
│ ├── Chestxray_3_10733.npy
│ ├── Chestxray_3_11004.npy
│ ├── Chestxray_3_11050.npy
│ ├── Chestxray_3_1627.npy
│ ├── Chestxray_3_1767.npy
│ ├── Chestxray_3_18163.npy
│ ├── Chestxray_3_2116.npy
│ ├── Chestxray_3_2130.npy
│ ├── Chestxray_3_220.npy
│ ├── Chestxray_3_2320.npy
│ ├── Chestxray_3_2340.npy
│ ├── Chestxray_3_2410.npy
│ ├── Chestxray_3_2639.npy
│ ├── Chestxray_3_2759.npy
│ ├── Chestxray_3_3346.npy
│ ├── Chestxray_3_3435.npy
│ ├── Chestxray_3_3561.npy
│ ├── Chestxray_3_3650.npy
│ ├── Chestxray_3_3761.npy
│ ├── Chestxray_3_3919.npy
│ ├── Chestxray_3_3952.npy
│ ├── Chestxray_3_421.npy
│ ├── Chestxray_3_4216.npy
│ ├── Chestxray_3_4402.npy
│ ├── Chestxray_3_443.npy
│ ├── Chestxray_3_4675.npy
│ ├── Chestxray_3_4703.npy
│ ├── Chestxray_3_4836.npy
│ ├── Chestxray_3_4895.npy
│ ├── Chestxray_3_4919.npy
│ ├── Chestxray_3_4949.npy
│ ├── Chestxray_3_512.npy
│ ├── Chestxray_3_5301.npy
│ ├── Chestxray_3_5605.npy
│ ├── Chestxray_3_6751.npy
│ ├── Chestxray_3_7412.npy
│ ├── Chestxray_3_7657.npy
│ ├── Chestxray_3_7667.npy
│ ├── Chestxray_3_7801.npy
│ ├── Chestxray_3_8160.npy
│ ├── Chestxray_3_8298.npy
│ ├── Chestxray_3_8713.npy
│ ├── Chestxray_3_8954.npy
│ ├── Chestxray_3_9047.npy
│ ├── Chestxray_3_9081.npy
│ ├── Chestxray_3_9523.npy
│ ├── Chestxray_3_9811.npy
│ ├── Chestxray_3_982.npy
│ ├── Chestxray_4_1067.npy
│ ├── Chestxray_4_1162.npy
│ ├── Chestxray_4_1173.npy
│ ├── Chestxray_4_2288.npy
│ ├── Chestxray_4_3105.npy
│ ├── Chestxray_4_4324.npy
│ ├── Chestxray_4_6177.npy
│ ├── Chestxray_4_7510.npy
│ ├── Chestxray_4_7946.npy
│ ├── Chestxray_4_8534.npy
│ ├── Chestxray_4_8754.npy
│ ├── Chestxray_4_9122.npy
│ ├── Chestxray_4_9534.npy
│ ├── Chestxray_4_9580.npy
│ ├── Chestxray_5_10800.npy
│ ├── Chestxray_5_1091.npy
│ ├── Chestxray_5_1776.npy
│ ├── Chestxray_5_3935.npy
│ ├── Chestxray_5_4079.npy
│ ├── Chestxray_5_554.npy
│ ├── Chestxray_5_5938.npy
│ ├── Chestxray_5_6184.npy
│ ├── Chestxray_5_6391.npy
│ ├── Chestxray_5_9471.npy
│ ├── Chestxray_5_9729.npy
│ ├── Chestxray_6_1513.npy
│ ├── Chestxray_6_3188.npy
│ ├── Chestxray_6_5225.npy
│ ├── Chestxray_6_5805.npy
│ ├── Chestxray_6_7399.npy
│ ├── Chestxray_6_8382.npy
│ ├── Chestxray_6_8988.npy
│ ├── Chestxray_6_9056.npy
│ ├── Chestxray_6_9185.npy
│ ├── Chestxray_7_10100.npy
│ ├── Chestxray_7_10571.npy
│ ├── Chestxray_7_1145.npy
│ ├── Chestxray_7_1717.npy
│ ├── Chestxray_7_3195.npy
│ ├── Chestxray_7_5008.npy
│ ├── Chestxray_7_503.npy
│ ├── Chestxray_7_61644.npy
│ ├── Chestxray_7_69.npy
│ ├── Chestxray_7_7171.npy
│ ├── Chestxray_7_7260.npy
│ ├── Chestxray_7_7293.npy
│ ├── Chestxray_7_7542.npy
│ ├── Chestxray_7_7828.npy
│ ├── Chestxray_7_823.npy
│ ├── Chestxray_7_9268.npy
│ ├── Chestxray_8_17335.npy
│ ├── Chestxray_8_187.npy
│ ├── Chestxray_8_2918.npy
│ ├── Chestxray_8_3663.npy
│ ├── Chestxray_8_4409.npy
│ ├── Chestxray_8_6667.npy
│ ├── Chestxray_8_6771.npy
│ ├── Chestxray_8_8104.npy
│ ├── Chestxray_8_9794.npy
│ ├── Chestxray_9_2208.npy
│ ├── Chestxray_9_236.npy
│ ├── Chestxray_9_2714.npy
│ ├── Chestxray_9_6875.npy
│ ├── Chestxray_9_7803.npy
│ ├── Oct_0_10255.npy
│ ├── Oct_0_1033.npy
│ ├── Oct_0_10376.npy
│ ├── Oct_0_10487.npy
│ ├── Oct_0_1060.npy
│ ├── Oct_0_1173.npy
│ ├── Oct_0_1250.npy
│ ├── Oct_0_1373.npy
│ ├── Oct_0_1380.npy
│ ├── Oct_0_1399.npy
│ ├── Oct_0_1517.npy
│ ├── Oct_0_1524.npy
│ ├── Oct_0_1662.npy
│ ├── Oct_0_1684.npy
│ ├── Oct_0_1746.npy
│ ├── Oct_0_1924.npy
│ ├── Oct_0_2014.npy
│ ├── Oct_0_2158.npy
│ ├── Oct_0_2279.npy
│ ├── Oct_0_2548.npy
│ ├── Oct_0_2596.npy
│ ├── Oct_0_2722.npy
│ ├── Oct_0_2935.npy
│ ├── Oct_0_2954.npy
│ ├── Oct_0_2972.npy
│ ├── Oct_0_3006.npy
│ ├── Oct_0_3027.npy
│ ├── Oct_0_3071.npy
│ ├── Oct_0_3482.npy
│ ├── Oct_0_3485.npy
│ ├── Oct_0_3571.npy
│ ├── Oct_0_3607.npy
│ ├── Oct_0_3642.npy
│ ├── Oct_0_3859.npy
│ ├── Oct_0_3988.npy
│ ├── Oct_0_4289.npy
│ ├── Oct_0_4290.npy
│ ├── Oct_0_4333.npy
│ ├── Oct_0_449.npy
│ ├── Oct_0_450.npy
│ ├── Oct_0_4634.npy
│ ├── Oct_0_5293.npy
│ ├── Oct_0_5502.npy
│ ├── Oct_0_5688.npy
│ ├── Oct_0_5722.npy
│ ├── Oct_0_5798.npy
│ ├── Oct_0_5857.npy
│ ├── Oct_0_596.npy
│ ├── Oct_0_6403.npy
│ ├── Oct_0_6663.npy
│ ├── Oct_0_6760.npy
│ ├── Oct_0_6922.npy
│ ├── Oct_0_7047.npy
│ ├── Oct_0_7081.npy
│ ├── Oct_0_7107.npy
│ ├── Oct_0_7151.npy
│ ├── Oct_0_7218.npy
│ ├── Oct_0_7233.npy
│ ├── Oct_0_7331.npy
│ ├── Oct_0_7354.npy
│ ├── Oct_0_7581.npy
│ ├── Oct_0_7616.npy
│ ├── Oct_0_772.npy
│ ├── Oct_0_7767.npy
│ ├── Oct_0_7831.npy
│ ├── Oct_0_7892.npy
│ ├── Oct_0_7906.npy
│ ├── Oct_0_7992.npy
│ ├── Oct_0_8074.npy
│ ├── Oct_0_8106.npy
│ ├── Oct_0_8302.npy
│ ├── Oct_0_8346.npy
│ ├── Oct_0_8348.npy
│ ├── Oct_0_8489.npy
│ ├── Oct_0_851.npy
│ ├── Oct_0_8843.npy
│ ├── Oct_0_8955.npy
│ ├── Oct_0_9002.npy
│ ├── Oct_0_9224.npy
│ ├── Oct_0_9362.npy
│ ├── Oct_0_9377.npy
│ ├── Oct_0_9453.npy
│ ├── Oct_0_9587.npy
│ ├── Oct_0_9755.npy
│ ├── Oct_1_1207.npy
│ ├── Oct_1_1753.npy
│ ├── Oct_1_1796.npy
│ ├── Oct_1_2078.npy
│ ├── Oct_1_2182.npy
│ ├── Oct_1_2987.npy
│ ├── Oct_1_3566.npy
│ ├── Oct_1_4093.npy
│ ├── Oct_1_4149.npy
│ ├── Oct_1_4366.npy
│ ├── Oct_1_4436.npy
│ ├── Oct_1_5388.npy
│ ├── Oct_1_54.npy
│ ├── Oct_1_5800.npy
│ ├── Oct_1_6105.npy
│ ├── Oct_1_6414.npy
│ ├── Oct_1_65387.npy
│ ├── Oct_1_7773.npy
│ ├── Oct_1_8424.npy
│ ├── Oct_1_8527.npy
│ ├── Oct_1_8876.npy
│ ├── Oct_1_8976.npy
│ ├── Oct_1_9014.npy
│ ├── Oct_1_902.npy
│ ├── Oct_1_9097.npy
│ ├── Oct_1_9702.npy
│ ├── Oct_2_10143.npy
│ ├── Oct_2_10483.npy
│ ├── Oct_2_1052.npy
│ ├── Oct_2_10661.npy
│ ├── Oct_2_2610.npy
│ ├── Oct_2_26446.npy
│ ├── Oct_2_27682.npy
│ ├── Oct_2_3036.npy
│ ├── Oct_2_3249.npy
│ ├── Oct_2_4057.npy
│ ├── Oct_2_4370.npy
│ ├── Oct_2_5788.npy
│ ├── Oct_2_5962.npy
│ ├── Oct_2_5985.npy
│ ├── Oct_2_6369.npy
│ ├── Oct_2_7924.npy
│ ├── Oct_2_8401.npy
│ ├── Oct_2_9099.npy
│ ├── Oct_2_9163.npy
│ ├── Oct_2_9652.npy
│ ├── Oct_2_9760.npy
│ ├── Oct_3_10010.npy
│ ├── Oct_3_10059.npy
│ ├── Oct_3_10063.npy
│ ├── Oct_3_10164.npy
│ ├── Oct_3_10261.npy
│ ├── Oct_3_10341.npy
│ ├── Oct_3_10348.npy
│ ├── Oct_3_10360.npy
│ ├── Oct_3_10441.npy
│ ├── Oct_3_10444.npy
│ ├── Oct_3_10811.npy
│ ├── Oct_3_1092.npy
│ ├── Oct_3_1269.npy
│ ├── Oct_3_1370.npy
│ ├── Oct_3_1588.npy
│ ├── Oct_3_1671.npy
│ ├── Oct_3_1799.npy
│ ├── Oct_3_1820.npy
│ ├── Oct_3_1869.npy
│ ├── Oct_3_2031.npy
│ ├── Oct_3_2211.npy
│ ├── Oct_3_2217.npy
│ ├── Oct_3_2259.npy
│ ├── Oct_3_2277.npy
│ ├── Oct_3_2300.npy
│ ├── Oct_3_2320.npy
│ ├── Oct_3_2345.npy
│ ├── Oct_3_2388.npy
│ ├── Oct_3_25.npy
│ ├── Oct_3_2500.npy
│ ├── Oct_3_2530.npy
│ ├── Oct_3_2624.npy
│ ├── Oct_3_271.npy
│ ├── Oct_3_2777.npy
│ ├── Oct_3_2915.npy
│ ├── Oct_3_2921.npy
│ ├── Oct_3_3087.npy
│ ├── Oct_3_314.npy
│ ├── Oct_3_3240.npy
│ ├── Oct_3_3282.npy
│ ├── Oct_3_3379.npy
│ ├── Oct_3_3447.npy
│ ├── Oct_3_3492.npy
│ ├── Oct_3_36.npy
│ ├── Oct_3_3660.npy
│ ├── Oct_3_3685.npy
│ ├── Oct_3_3771.npy
│ ├── Oct_3_3895.npy
│ ├── Oct_3_3983.npy
│ ├── Oct_3_4006.npy
│ ├── Oct_3_4101.npy
│ ├── Oct_3_4393.npy
│ ├── Oct_3_4416.npy
│ ├── Oct_3_4499.npy
│ ├── Oct_3_4657.npy
│ ├── Oct_3_4711.npy
│ ├── Oct_3_4786.npy
│ ├── Oct_3_480.npy
│ ├── Oct_3_4887.npy
│ ├── Oct_3_4993.npy
│ ├── Oct_3_4996.npy
│ ├── Oct_3_4997.npy
│ ├── Oct_3_5083.npy
│ ├── Oct_3_5087.npy
│ ├── Oct_3_5098.npy
│ ├── Oct_3_5157.npy
│ ├── Oct_3_5187.npy
│ ├── Oct_3_5425.npy
│ ├── Oct_3_5501.npy
│ ├── Oct_3_5650.npy
│ ├── Oct_3_5657.npy
│ ├── Oct_3_5765.npy
│ ├── Oct_3_5805.npy
│ ├── Oct_3_5859.npy
│ ├── Oct_3_5967.npy
│ ├── Oct_3_5992.npy
│ ├── Oct_3_6058.npy
│ ├── Oct_3_6112.npy
│ ├── Oct_3_619.npy
│ ├── Oct_3_6209.npy
│ ├── Oct_3_6240.npy
│ ├── Oct_3_6277.npy
│ ├── Oct_3_6411.npy
│ ├── Oct_3_6561.npy
│ ├── Oct_3_6614.npy
│ ├── Oct_3_6674.npy
│ ├── Oct_3_6794.npy
│ ├── Oct_3_6903.npy
│ ├── Oct_3_7007.npy
│ ├── Oct_3_7102.npy
│ ├── Oct_3_7352.npy
│ ├── Oct_3_7453.npy
│ ├── Oct_3_7833.npy
│ ├── Oct_3_8099.npy
│ ├── Oct_3_823.npy
│ ├── Oct_3_8352.npy
│ ├── Oct_3_8399.npy
│ ├── Oct_3_8446.npy
│ ├── Oct_3_852.npy
│ ├── Oct_3_8542.npy
│ ├── Oct_3_8627.npy
│ ├── Oct_3_8752.npy
│ ├── Oct_3_8781.npy
│ ├── Oct_3_8817.npy
│ ├── Oct_3_8890.npy
│ ├── Oct_3_8911.npy
│ ├── Oct_3_9019.npy
│ ├── Oct_3_9356.npy
│ ├── Oct_3_9482.npy
│ ├── Oct_3_9592.npy
│ ├── Oct_3_9744.npy
│ ├── Oct_3_9875.npy
│ ├── Oct_3_9938.npy
│ ├── Tissue_0_10065.npy
│ ├── Tissue_0_10235.npy
│ ├── Tissue_0_10275.npy
│ ├── Tissue_0_10363.npy
│ ├── Tissue_0_10501.npy
│ ├── Tissue_0_10715.npy
│ ├── Tissue_0_10876.npy
│ ├── Tissue_0_10970.npy
│ ├── Tissue_0_1104.npy
│ ├── Tissue_0_11215.npy
│ ├── Tissue_0_11293.npy
│ ├── Tissue_0_11304.npy
│ ├── Tissue_0_11407.npy
│ ├── Tissue_0_11543.npy
│ ├── Tissue_0_11564.npy
│ ├── Tissue_0_11609.npy
│ ├── Tissue_0_11794.npy
│ ├── Tissue_0_11911.npy
│ ├── Tissue_0_12370.npy
│ ├── Tissue_0_12488.npy
│ ├── Tissue_0_12745.npy
│ ├── Tissue_0_12909.npy
│ ├── Tissue_0_13156.npy
│ ├── Tissue_0_13261.npy
│ ├── Tissue_0_13568.npy
│ ├── Tissue_0_13699.npy
│ ├── Tissue_0_13863.npy
│ ├── Tissue_0_14042.npy
│ ├── Tissue_0_14286.npy
│ ├── Tissue_0_14369.npy
│ ├── Tissue_0_14385.npy
│ ├── Tissue_0_14542.npy
│ ├── Tissue_0_14599.npy
│ ├── Tissue_0_14672.npy
│ ├── Tissue_0_14761.npy
│ ├── Tissue_0_14805.npy
│ ├── Tissue_0_1507.npy
│ ├── Tissue_0_15264.npy
│ ├── Tissue_0_154.npy
│ ├── Tissue_0_15446.npy
│ ├── Tissue_0_15489.npy
│ ├── Tissue_0_15550.npy
│ ├── Tissue_0_15846.npy
│ ├── Tissue_0_15920.npy
│ ├── Tissue_0_15943.npy
│ ├── Tissue_0_16003.npy
│ ├── Tissue_0_16179.npy
│ ├── Tissue_0_16471.npy
│ ├── Tissue_0_16578.npy
│ ├── Tissue_0_16604.npy
│ ├── Tissue_0_16671.npy
│ ├── Tissue_0_16729.npy
│ ├── Tissue_0_16738.npy
│ ├── Tissue_0_16811.npy
│ ├── Tissue_0_16840.npy
│ ├── Tissue_0_17170.npy
│ ├── Tissue_0_17171.npy
│ ├── Tissue_0_17285.npy
│ ├── Tissue_0_17376.npy
│ ├── Tissue_0_17412.npy
│ ├── Tissue_0_17486.npy
│ ├── Tissue_0_17613.npy
│ ├── Tissue_0_17929.npy
│ ├── Tissue_0_18094.npy
│ ├── Tissue_0_18387.npy
│ ├── Tissue_0_18481.npy
│ ├── Tissue_0_18485.npy
│ ├── Tissue_0_18497.npy
│ ├── Tissue_0_18545.npy
│ ├── Tissue_0_18552.npy
│ ├── Tissue_0_18581.npy
│ ├── Tissue_0_18612.npy
│ ├── Tissue_0_18634.npy
│ ├── Tissue_0_18715.npy
│ ├── Tissue_0_18737.npy
│ ├── Tissue_0_18825.npy
│ ├── Tissue_0_18933.npy
│ ├── Tissue_0_19059.npy
│ ├── Tissue_0_19110.npy
│ ├── Tissue_0_19120.npy
│ ├── Tissue_0_19162.npy
│ ├── Tissue_0_19290.npy
│ ├── Tissue_0_19312.npy
│ ├── Tissue_0_19356.npy
│ ├── Tissue_0_19436.npy
│ ├── Tissue_0_19781.npy
│ ├── Tissue_0_19861.npy
│ ├── Tissue_0_19937.npy
│ ├── Tissue_0_20028.npy
│ ├── Tissue_0_20365.npy
│ ├── Tissue_0_20416.npy
│ ├── Tissue_0_20423.npy
│ ├── Tissue_0_20465.npy
│ ├── Tissue_0_20502.npy
│ ├── Tissue_0_20740.npy
│ ├── Tissue_0_20901.npy
│ ├── Tissue_0_2091.npy
│ ├── Tissue_0_21093.npy
│ ├── Tissue_0_21164.npy
│ ├── Tissue_0_21240.npy
│ ├── Tissue_0_21398.npy
│ ├── Tissue_0_21504.npy
│ ├── Tissue_0_21546.npy
│ ├── Tissue_0_21663.npy
│ ├── Tissue_0_2183.npy
│ ├── Tissue_0_22081.npy
│ ├── Tissue_0_22085.npy
│ ├── Tissue_0_22135.npy
│ ├── Tissue_0_22355.npy
│ ├── Tissue_0_22468.npy
│ ├── Tissue_0_22513.npy
│ ├── Tissue_0_22534.npy
│ ├── Tissue_0_22550.npy
│ ├── Tissue_0_22615.npy
│ ├── Tissue_0_2285.npy
│ ├── Tissue_0_22873.npy
│ ├── Tissue_0_22928.npy
│ ├── Tissue_0_23157.npy
│ ├── Tissue_0_23203.npy
│ ├── Tissue_0_23279.npy
│ ├── Tissue_0_23295.npy
│ ├── Tissue_0_23422.npy
│ ├── Tissue_0_23562.npy
│ ├── Tissue_0_2737.npy
│ ├── Tissue_0_2896.npy
│ ├── Tissue_0_2965.npy
│ ├── Tissue_0_3072.npy
│ ├── Tissue_0_3132.npy
│ ├── Tissue_0_3156.npy
│ ├── Tissue_0_3214.npy
│ ├── Tissue_0_3264.npy
│ ├── Tissue_0_3382.npy
│ ├── Tissue_0_3487.npy
│ ├── Tissue_0_3652.npy
│ ├── Tissue_0_3802.npy
│ ├── Tissue_0_3864.npy
│ ├── Tissue_0_3966.npy
│ ├── Tissue_0_4209.npy
│ ├── Tissue_0_4414.npy
│ ├── Tissue_0_4466.npy
│ ├── Tissue_0_4795.npy
│ ├── Tissue_0_488.npy
│ ├── Tissue_0_4947.npy
│ ├── Tissue_0_4996.npy
│ ├── Tissue_0_5025.npy
│ ├── Tissue_0_5105.npy
│ ├── Tissue_0_5182.npy
│ ├── Tissue_0_5184.npy
│ ├── Tissue_0_5350.npy
│ ├── Tissue_0_5512.npy
│ ├── Tissue_0_5714.npy
│ ├── Tissue_0_5863.npy
│ ├── Tissue_0_5916.npy
│ ├── Tissue_0_5970.npy
│ ├── Tissue_0_6260.npy
│ ├── Tissue_0_6261.npy
│ ├── Tissue_0_6278.npy
│ ├── Tissue_0_6368.npy
│ ├── Tissue_0_65.npy
│ ├── Tissue_0_653.npy
│ ├── Tissue_0_6793.npy
│ ├── Tissue_0_6952.npy
│ ├── Tissue_0_7195.npy
│ ├── Tissue_0_7443.npy
│ ├── Tissue_0_7602.npy
│ ├── Tissue_0_7610.npy
│ ├── Tissue_0_7645.npy
│ ├── Tissue_0_77.npy
│ ├── Tissue_0_7807.npy
│ ├── Tissue_0_8051.npy
│ ├── Tissue_0_8072.npy
│ ├── Tissue_0_8147.npy
│ ├── Tissue_0_8340.npy
│ ├── Tissue_0_836.npy
│ ├── Tissue_0_8607.npy
│ ├── Tissue_0_8697.npy
│ ├── Tissue_0_8699.npy
│ ├── Tissue_0_8796.npy
│ ├── Tissue_0_8870.npy
│ ├── Tissue_0_913.npy
│ ├── Tissue_0_961.npy
│ ├── Tissue_0_9629.npy
│ ├── Tissue_0_9702.npy
│ ├── Tissue_0_9822.npy
│ ├── Tissue_1_1213.npy
│ ├── Tissue_1_13054.npy
│ ├── Tissue_1_13876.npy
│ ├── Tissue_1_14595.npy
│ ├── Tissue_1_14914.npy
│ ├── Tissue_1_15318.npy
│ ├── Tissue_1_15828.npy
│ ├── Tissue_1_17215.npy
│ ├── Tissue_1_17772.npy
│ ├── Tissue_1_18026.npy
│ ├── Tissue_1_19496.npy
│ ├── Tissue_1_19798.npy
│ ├── Tissue_1_1987.npy
│ ├── Tissue_1_20308.npy
│ ├── Tissue_1_20756.npy
│ ├── Tissue_1_21050.npy
│ ├── Tissue_1_2323.npy
│ ├── Tissue_1_4574.npy
│ ├── Tissue_1_483.npy
│ ├── Tissue_1_6495.npy
│ ├── Tissue_1_7192.npy
│ ├── Tissue_1_7418.npy
│ ├── Tissue_1_8376.npy
│ ├── Tissue_1_8601.npy
│ ├── Tissue_1_8790.npy
│ ├── Tissue_1_9741.npy
│ ├── Tissue_2_12291.npy
│ ├── Tissue_2_12512.npy
│ ├── Tissue_2_13211.npy
│ ├── Tissue_2_14652.npy
│ ├── Tissue_2_1538.npy
│ ├── Tissue_2_15651.npy
│ ├── Tissue_2_17690.npy
│ ├── Tissue_2_20081.npy
│ ├── Tissue_2_20348.npy
│ ├── Tissue_2_20909.npy
│ ├── Tissue_2_22554.npy
│ ├── Tissue_2_32155.npy
│ ├── Tissue_2_4327.npy
│ ├── Tissue_2_5861.npy
│ ├── Tissue_2_6910.npy
│ ├── Tissue_2_9569.npy
│ ├── Tissue_2_9599.npy
│ ├── Tissue_2_9684.npy
│ ├── Tissue_3_10163.npy
│ ├── Tissue_3_11736.npy
│ ├── Tissue_3_12666.npy
│ ├── Tissue_3_12794.npy
│ ├── Tissue_3_13262.npy
│ ├── Tissue_3_13850.npy
│ ├── Tissue_3_1443.npy
│ ├── Tissue_3_15028.npy
│ ├── Tissue_3_15037.npy
│ ├── Tissue_3_1526.npy
│ ├── Tissue_3_15283.npy
│ ├── Tissue_3_15641.npy
│ ├── Tissue_3_1584.npy
│ ├── Tissue_3_16139.npy
│ ├── Tissue_3_16275.npy
│ ├── Tissue_3_16431.npy
│ ├── Tissue_3_1673.npy
│ ├── Tissue_3_17222.npy
│ ├── Tissue_3_17288.npy
│ ├── Tissue_3_17682.npy
│ ├── Tissue_3_17823.npy
│ ├── Tissue_3_18447.npy
│ ├── Tissue_3_18679.npy
│ ├── Tissue_3_18706.npy
│ ├── Tissue_3_1891.npy
│ ├── Tissue_3_19517.npy
│ ├── Tissue_3_19530.npy
│ ├── Tissue_3_19595.npy
│ ├── Tissue_3_19725.npy
│ ├── Tissue_3_21530.npy
│ ├── Tissue_3_21678.npy
│ ├── Tissue_3_21791.npy
│ ├── Tissue_3_22927.npy
│ ├── Tissue_3_23085.npy
│ ├── Tissue_3_23161.npy
│ ├── Tissue_3_3332.npy
│ ├── Tissue_3_42135.npy
│ ├── Tissue_3_480.npy
│ ├── Tissue_3_492.npy
│ ├── Tissue_3_5199.npy
│ ├── Tissue_3_5292.npy
│ ├── Tissue_3_5334.npy
│ ├── Tissue_3_5376.npy
│ ├── Tissue_3_5378.npy
│ ├── Tissue_3_6005.npy
│ ├── Tissue_3_6065.npy
│ ├── Tissue_3_6238.npy
│ ├── Tissue_3_6310.npy
│ ├── Tissue_3_6344.npy
│ ├── Tissue_3_6730.npy
│ ├── Tissue_3_6861.npy
│ ├── Tissue_3_7346.npy
│ ├── Tissue_3_7502.npy
│ ├── Tissue_3_7831.npy
│ ├── Tissue_3_8562.npy
│ ├── Tissue_3_9809.npy
│ ├── Tissue_4_10991.npy
│ ├── Tissue_4_11167.npy
│ ├── Tissue_4_11184.npy
│ ├── Tissue_4_11425.npy
│ ├── Tissue_4_11664.npy
│ ├── Tissue_4_11790.npy
│ ├── Tissue_4_1208.npy
│ ├── Tissue_4_12407.npy
│ ├── Tissue_4_13305.npy
│ ├── Tissue_4_14365.npy
│ ├── Tissue_4_14431.npy
│ ├── Tissue_4_14691.npy
│ ├── Tissue_4_1501.npy
│ ├── Tissue_4_15191.npy
│ ├── Tissue_4_15266.npy
│ ├── Tissue_4_15269.npy
│ ├── Tissue_4_15273.npy
│ ├── Tissue_4_15333.npy
│ ├── Tissue_4_15662.npy
│ ├── Tissue_4_1600.npy
│ ├── Tissue_4_16887.npy
│ ├── Tissue_4_17707.npy
│ ├── Tissue_4_17947.npy
│ ├── Tissue_4_18588.npy
│ ├── Tissue_4_19067.npy
│ ├── Tissue_4_19602.npy
│ ├── Tissue_4_20012.npy
│ ├── Tissue_4_21513.npy
│ ├── Tissue_4_22008.npy
│ ├── Tissue_4_22293.npy
│ ├── Tissue_4_22427.npy
│ ├── Tissue_4_3675.npy
│ ├── Tissue_4_3731.npy
│ ├── Tissue_4_4221.npy
│ ├── Tissue_4_4419.npy
│ ├── Tissue_4_44906.npy
│ ├── Tissue_4_4744.npy
│ ├── Tissue_4_6584.npy
│ ├── Tissue_4_6589.npy
│ ├── Tissue_4_6739.npy
│ ├── Tissue_4_6827.npy
│ ├── Tissue_4_6904.npy
│ ├── Tissue_4_7830.npy
│ ├── Tissue_4_7968.npy
│ ├── Tissue_4_8010.npy
│ ├── Tissue_4_8585.npy
│ ├── Tissue_5_1049.npy
│ ├── Tissue_5_10618.npy
│ ├── Tissue_5_12264.npy
│ ├── Tissue_5_12835.npy
│ ├── Tissue_5_12894.npy
│ ├── Tissue_5_14246.npy
│ ├── Tissue_5_14371.npy
│ ├── Tissue_5_14841.npy
│ ├── Tissue_5_1639.npy
│ ├── Tissue_5_17423.npy
│ ├── Tissue_5_19155.npy
│ ├── Tissue_5_19755.npy
│ ├── Tissue_5_20836.npy
│ ├── Tissue_5_21381.npy
│ ├── Tissue_5_23079.npy
│ ├── Tissue_5_23084.npy
│ ├── Tissue_5_23166.npy
│ ├── Tissue_5_4184.npy
│ ├── Tissue_5_4787.npy
│ ├── Tissue_5_5071.npy
│ ├── Tissue_5_677.npy
│ ├── Tissue_5_7029.npy
│ ├── Tissue_5_7723.npy
│ ├── Tissue_5_7938.npy
│ ├── Tissue_5_8424.npy
│ ├── Tissue_5_8628.npy
│ ├── Tissue_6_10222.npy
│ ├── Tissue_6_10237.npy
│ ├── Tissue_6_10372.npy
│ ├── Tissue_6_10478.npy
│ ├── Tissue_6_10497.npy
│ ├── Tissue_6_10944.npy
│ ├── Tissue_6_10972.npy
│ ├── Tissue_6_1101.npy
│ ├── Tissue_6_11356.npy
│ ├── Tissue_6_11461.npy
│ ├── Tissue_6_11686.npy
│ ├── Tissue_6_11775.npy
│ ├── Tissue_6_119.npy
│ ├── Tissue_6_12285.npy
│ ├── Tissue_6_12712.npy
│ ├── Tissue_6_12874.npy
│ ├── Tissue_6_1291.npy
│ ├── Tissue_6_1295.npy
│ ├── Tissue_6_13046.npy
│ ├── Tissue_6_13250.npy
│ ├── Tissue_6_13321.npy
│ ├── Tissue_6_1335.npy
│ ├── Tissue_6_13369.npy
│ ├── Tissue_6_13715.npy
│ ├── Tissue_6_14052.npy
│ ├── Tissue_6_14469.npy
│ ├── Tissue_6_1468.npy
│ ├── Tissue_6_15347.npy
│ ├── Tissue_6_15468.npy
│ ├── Tissue_6_15472.npy
│ ├── Tissue_6_15603.npy
│ ├── Tissue_6_15999.npy
│ ├── Tissue_6_16265.npy
│ ├── Tissue_6_16560.npy
│ ├── Tissue_6_16636.npy
│ ├── Tissue_6_16930.npy
│ ├── Tissue_6_16985.npy
│ ├── Tissue_6_17098.npy
│ ├── Tissue_6_1725.npy
│ ├── Tissue_6_17308.npy
│ ├── Tissue_6_17357.npy
│ ├── Tissue_6_17462.npy
│ ├── Tissue_6_17968.npy
│ ├── Tissue_6_17979.npy
│ ├── Tissue_6_18189.npy
│ ├── Tissue_6_1838.npy
│ ├── Tissue_6_18661.npy
│ ├── Tissue_6_18676.npy
│ ├── Tissue_6_18883.npy
│ ├── Tissue_6_18893.npy
│ ├── Tissue_6_19159.npy
│ ├── Tissue_6_19308.npy
│ ├── Tissue_6_19401.npy
│ ├── Tissue_6_19430.npy
│ ├── Tissue_6_1946.npy
│ ├── Tissue_6_19776.npy
│ ├── Tissue_6_19930.npy
│ ├── Tissue_6_19935.npy
│ ├── Tissue_6_20138.npy
│ ├── Tissue_6_20273.npy
│ ├── Tissue_6_20359.npy
│ ├── Tissue_6_20534.npy
│ ├── Tissue_6_20857.npy
│ ├── Tissue_6_20977.npy
│ ├── Tissue_6_21009.npy
│ ├── Tissue_6_21052.npy
│ ├── Tissue_6_21207.npy
│ ├── Tissue_6_21295.npy
│ ├── Tissue_6_21514.npy
│ ├── Tissue_6_21539.npy
│ ├── Tissue_6_21851.npy
│ ├── Tissue_6_21926.npy
│ ├── Tissue_6_21973.npy
│ ├── Tissue_6_2203.npy
│ ├── Tissue_6_22133.npy
│ ├── Tissue_6_22138.npy
│ ├── Tissue_6_22348.npy
│ ├── Tissue_6_22357.npy
│ ├── Tissue_6_22475.npy
│ ├── Tissue_6_22642.npy
│ ├── Tissue_6_22907.npy
│ ├── Tissue_6_2296.npy
│ ├── Tissue_6_22988.npy
│ ├── Tissue_6_23056.npy
│ ├── Tissue_6_23287.npy
│ ├── Tissue_6_23485.npy
│ ├── Tissue_6_2518.npy
│ ├── Tissue_6_2800.npy
│ ├── Tissue_6_2841.npy
│ ├── Tissue_6_2933.npy
│ ├── Tissue_6_2978.npy
│ ├── Tissue_6_3307.npy
│ ├── Tissue_6_3309.npy
│ ├── Tissue_6_3506.npy
│ ├── Tissue_6_3536.npy
│ ├── Tissue_6_4076.npy
│ ├── Tissue_6_4133.npy
│ ├── Tissue_6_4359.npy
│ ├── Tissue_6_4373.npy
│ ├── Tissue_6_4524.npy
│ ├── Tissue_6_4591.npy
│ ├── Tissue_6_4726.npy
│ ├── Tissue_6_4749.npy
│ ├── Tissue_6_4882.npy
│ ├── Tissue_6_4905.npy
│ ├── Tissue_6_5016.npy
│ ├── Tissue_6_5115.npy
│ ├── Tissue_6_5250.npy
│ ├── Tissue_6_5648.npy
│ ├── Tissue_6_5723.npy
│ ├── Tissue_6_5851.npy
│ ├── Tissue_6_5879.npy
│ ├── Tissue_6_6110.npy
│ ├── Tissue_6_6229.npy
│ ├── Tissue_6_6292.npy
│ ├── Tissue_6_6439.npy
│ ├── Tissue_6_6542.npy
│ ├── Tissue_6_6602.npy
│ ├── Tissue_6_6749.npy
│ ├── Tissue_6_6841.npy
│ ├── Tissue_6_7207.npy
│ ├── Tissue_6_7236.npy
│ ├── Tissue_6_7756.npy
│ ├── Tissue_6_8011.npy
│ ├── Tissue_6_8196.npy
│ ├── Tissue_6_8227.npy
│ ├── Tissue_6_8382.npy
│ ├── Tissue_6_8700.npy
│ ├── Tissue_6_8818.npy
│ ├── Tissue_6_8988.npy
│ ├── Tissue_6_9130.npy
│ ├── Tissue_6_9150.npy
│ ├── Tissue_6_922.npy
│ ├── Tissue_6_945.npy
│ ├── Tissue_6_9465.npy
│ ├── Tissue_6_9501.npy
│ ├── Tissue_6_9528.npy
│ ├── Tissue_6_9640.npy
│ ├── Tissue_6_9849.npy
│ ├── Tissue_7_1044.npy
│ ├── Tissue_7_10916.npy
│ ├── Tissue_7_10989.npy
│ ├── Tissue_7_111.npy
│ ├── Tissue_7_11487.npy
│ ├── Tissue_7_11578.npy
│ ├── Tissue_7_11828.npy
│ ├── Tissue_7_12436.npy
│ ├── Tissue_7_12736.npy
│ ├── Tissue_7_12790.npy
│ ├── Tissue_7_12842.npy
│ ├── Tissue_7_13524.npy
│ ├── Tissue_7_13934.npy
│ ├── Tissue_7_1432.npy
│ ├── Tissue_7_14811.npy
│ ├── Tissue_7_14913.npy
│ ├── Tissue_7_14926.npy
│ ├── Tissue_7_14952.npy
│ ├── Tissue_7_15198.npy
│ ├── Tissue_7_15521.npy
│ ├── Tissue_7_15876.npy
│ ├── Tissue_7_1603.npy
│ ├── Tissue_7_16273.npy
│ ├── Tissue_7_16532.npy
│ ├── Tissue_7_16716.npy
│ ├── Tissue_7_17507.npy
│ ├── Tissue_7_17704.npy
│ ├── Tissue_7_17779.npy
│ ├── Tissue_7_17938.npy
│ ├── Tissue_7_18050.npy
│ ├── Tissue_7_18300.npy
│ ├── Tissue_7_18464.npy
│ ├── Tissue_7_1861.npy
│ ├── Tissue_7_20002.npy
│ ├── Tissue_7_20065.npy
│ ├── Tissue_7_2033.npy
│ ├── Tissue_7_20552.npy
│ ├── Tissue_7_2076.npy
│ ├── Tissue_7_20864.npy
│ ├── Tissue_7_21117.npy
│ ├── Tissue_7_21211.npy
│ ├── Tissue_7_21259.npy
│ ├── Tissue_7_21986.npy
│ ├── Tissue_7_22009.npy
│ ├── Tissue_7_22260.npy
│ ├── Tissue_7_22369.npy
│ ├── Tissue_7_2242.npy
│ ├── Tissue_7_2259.npy
│ ├── Tissue_7_23231.npy
│ ├── Tissue_7_23478.npy
│ ├── Tissue_7_2718.npy
│ ├── Tissue_7_3229.npy
│ ├── Tissue_7_3920.npy
│ ├── Tissue_7_4142.npy
│ ├── Tissue_7_45543.npy
│ ├── Tissue_7_4694.npy
│ ├── Tissue_7_4763.npy
│ ├── Tissue_7_4809.npy
│ ├── Tissue_7_4851.npy
│ ├── Tissue_7_5052.npy
│ ├── Tissue_7_5664.npy
│ ├── Tissue_7_6052.npy
│ ├── Tissue_7_6219.npy
│ ├── Tissue_7_640.npy
│ ├── Tissue_7_6526.npy
│ ├── Tissue_7_6702.npy
│ ├── Tissue_7_7044.npy
│ ├── Tissue_7_7065.npy
│ ├── Tissue_7_7235.npy
│ ├── Tissue_7_7722.npy
│ ├── Tissue_7_7859.npy
│ ├── Tissue_7_7914.npy
│ ├── Tissue_7_7993.npy
│ ├── Tissue_7_8054.npy
│ ├── Tissue_7_8107.npy
│ ├── Tissue_7_8200.npy
│ ├── Tissue_7_904.npy
│ ├── Tissue_7_9210.npy
│ ├── Tissue_7_9691.npy
│ └── Tissue_7_9759.npy
├── codecov.yml
├── configs/
│ ├── test_algorithms.json
│ ├── test_datasets.json
│ ├── test_models.json
│ ├── test_modules.json
│ ├── test_results.json
│ └── test_scalability.json
├── docs/
│ ├── Makefile
│ ├── make.bat
│ ├── requirements.txt
│ └── source/
│ ├── _autoapi_temp/
│ │ └── python/
│ │ └── module.rst
│ ├── conf.py
│ ├── contribution.rst
│ ├── index.rst
│ ├── installation.rst
│ ├── overview.rst
│ ├── refer.bib
│ ├── reference.rst
│ └── tutorials/
│ ├── algorithm.rst
│ ├── code_carbon.rst
│ ├── data_distribution.rst
│ ├── dataset.rst
│ ├── encryption.rst
│ ├── models.rst
│ ├── running.rst
│ └── tutorial.rst
├── federa/
│ ├── __init__.py
│ ├── client/
│ │ ├── __init__.py
│ │ ├── src/
│ │ │ ├── ClientConnection_pb2.py
│ │ │ ├── ClientConnection_pb2_grpc.py
│ │ │ ├── __init__.py
│ │ │ ├── client.py
│ │ │ ├── client_lib.py
│ │ │ ├── data_utils.py
│ │ │ ├── get_data.py
│ │ │ ├── net.py
│ │ │ └── net_lib.py
│ │ └── start_client.py
│ ├── server/
│ │ ├── __init__.py
│ │ ├── src/
│ │ │ ├── ClientConnection_pb2.py
│ │ │ ├── ClientConnection_pb2_grpc.py
│ │ │ ├── __init__.py
│ │ │ ├── algorithms/
│ │ │ │ ├── fedadagrad.py
│ │ │ │ ├── fedadam.py
│ │ │ │ ├── fedavg.py
│ │ │ │ ├── fedavgm.py
│ │ │ │ ├── feddyn.py
│ │ │ │ ├── fedyogi.py
│ │ │ │ ├── mime.py
│ │ │ │ ├── mimelite.py
│ │ │ │ └── scaffold.py
│ │ │ ├── client_connection_servicer.py
│ │ │ ├── client_manager.py
│ │ │ ├── client_wrapper.py
│ │ │ ├── distribution.py
│ │ │ ├── server.py
│ │ │ ├── server_evaluate/
│ │ │ │ ├── __init__.py
│ │ │ │ └── eval_lib.py
│ │ │ ├── server_lib.py
│ │ │ └── verification.py
│ │ └── start_server.py
│ └── tests/
│ ├── __init__.py
│ ├── minitest.json
│ ├── minitest.py
│ └── misc.py
├── requirements.txt
├── server_custom_dataset/
│ └── CUSTOM/
│ └── test/
│ ├── Breast_1_131.npy
│ ├── Breast_1_178.npy
│ ├── Breast_1_38.npy
│ ├── Breast_1_46.npy
│ ├── Breast_1_56.npy
│ ├── Breast_1_57.npy
│ ├── Breast_1_58.npy
│ ├── Chestxray_0_10192.npy
│ ├── Chestxray_0_2599.npy
│ ├── Chestxray_0_27.npy
│ ├── Chestxray_10_2647.npy
│ ├── Chestxray_10_7361.npy
│ ├── Chestxray_11_6369.npy
│ ├── Chestxray_12_3194.npy
│ ├── Chestxray_12_6281.npy
│ ├── Chestxray_1_1545.npy
│ ├── Chestxray_2_10770.npy
│ ├── Chestxray_2_1294.npy
│ ├── Chestxray_2_2942.npy
│ ├── Chestxray_3_4808.npy
│ ├── Chestxray_3_563.npy
│ ├── Chestxray_3_8533.npy
│ ├── Chestxray_3_9185.npy
│ ├── Chestxray_3_9271.npy
│ ├── Chestxray_3_9492.npy
│ ├── Chestxray_5_10699.npy
│ ├── Chestxray_5_3477.npy
│ ├── Chestxray_5_756.npy
│ ├── Chestxray_5_7941.npy
│ ├── Chestxray_5_8493.npy
│ ├── Chestxray_6_7326.npy
│ ├── Chestxray_7_10995.npy
│ ├── Chestxray_7_8642.npy
│ ├── Chestxray_7_9211.npy
│ ├── Chestxray_8_2448.npy
│ ├── Chestxray_9_1970.npy
│ ├── Oct_0_10252.npy
│ ├── Oct_0_10370.npy
│ ├── Oct_0_1901.npy
│ ├── Oct_0_2534.npy
│ ├── Oct_0_4375.npy
│ ├── Oct_0_521.npy
│ ├── Oct_0_5368.npy
│ ├── Oct_0_7082.npy
│ ├── Oct_0_72818.npy
│ ├── Oct_0_7570.npy
│ ├── Oct_0_9852.npy
│ ├── Oct_1_757.npy
│ ├── Oct_2_26531.npy
│ ├── Oct_2_3752.npy
│ ├── Oct_2_8134.npy
│ ├── Oct_2_8207.npy
│ ├── Oct_2_9648.npy
│ ├── Oct_3_1567.npy
│ ├── Oct_3_1669.npy
│ ├── Oct_3_2292.npy
│ ├── Oct_3_2794.npy
│ ├── Oct_3_4851.npy
│ ├── Oct_3_4912.npy
│ ├── Oct_3_5127.npy
│ ├── Oct_3_5626.npy
│ ├── Oct_3_5777.npy
│ ├── Oct_3_6087.npy
│ ├── Oct_3_6417.npy
│ ├── Oct_3_9802.npy
│ ├── Tissue_0_10673.npy
│ ├── Tissue_0_12024.npy
│ ├── Tissue_0_12038.npy
│ ├── Tissue_0_14742.npy
│ ├── Tissue_0_1487.npy
│ ├── Tissue_0_17483.npy
│ ├── Tissue_0_18694.npy
│ ├── Tissue_0_20122.npy
│ ├── Tissue_0_2373.npy
│ ├── Tissue_0_3171.npy
│ ├── Tissue_0_411.npy
│ ├── Tissue_0_4904.npy
│ ├── Tissue_0_6028.npy
│ ├── Tissue_0_7434.npy
│ ├── Tissue_0_8139.npy
│ ├── Tissue_0_8962.npy
│ ├── Tissue_0_9511.npy
│ ├── Tissue_0_9949.npy
│ ├── Tissue_3_8272.npy
│ ├── Tissue_3_9593.npy
│ ├── Tissue_4_10949.npy
│ ├── Tissue_4_16558.npy
│ ├── Tissue_4_17314.npy
│ ├── Tissue_4_18139.npy
│ ├── Tissue_4_2355.npy
│ ├── Tissue_5_17494.npy
│ ├── Tissue_5_22443.npy
│ ├── Tissue_6_11839.npy
│ ├── Tissue_6_12194.npy
│ ├── Tissue_6_13317.npy
│ ├── Tissue_6_14084.npy
│ ├── Tissue_6_15019.npy
│ ├── Tissue_6_15092.npy
│ ├── Tissue_6_15204.npy
│ ├── Tissue_6_17363.npy
│ ├── Tissue_6_19355.npy
│ ├── Tissue_6_19528.npy
│ ├── Tissue_6_21927.npy
│ ├── Tissue_6_37014.npy
│ ├── Tissue_7_14747.npy
│ ├── Tissue_7_14849.npy
│ ├── Tissue_7_18085.npy
│ ├── Tissue_7_18646.npy
│ ├── Tissue_7_21396.npy
│ ├── Tissue_7_21427.npy
│ ├── Tissue_7_2508.npy
│ ├── Tissue_7_2884.npy
│ ├── Tissue_7_7116.npy
│ └── Tissue_7_7248.npy
├── ssl/
│ ├── README.md
│ ├── ca-config.json
│ ├── ca-csr.json
│ ├── client-csr.json
│ └── server-csr.json
├── test/
│ ├── __init__.py
│ ├── benchtest/
│ │ ├── __init__.py
│ │ ├── test_results.py
│ │ └── test_scalability.py
│ ├── misc.py
│ └── unittest/
│ ├── __init__.py
│ ├── test_algorithms.py
│ ├── test_datasets.py
│ ├── test_models.py
│ └── test_modules.py
└── tutorials/
├── Code_Carbon_Tutorial.ipynb
├── Federated_Algorithm_Tutorial.ipynb
├── Number_of_clients_Tutorial.ipynb
├── Verifcation_module_tutorial.ipynb
├── accuracy_plot.py
├── data_distribution.ipynb
└── media_plot.ipynb
SYMBOL INDEX (199 symbols across 35 files)
FILE: federa/client/src/ClientConnection_pb2_grpc.py
class ClientConnectionStub (line 8) | class ClientConnectionStub():
method __init__ (line 11) | def __init__(self, channel):
class ClientConnectionServicer (line 24) | class ClientConnectionServicer():
method Connect (line 27) | def Connect(self, request_iterator, context):
function add_ClientConnectionServicer_to_server (line 34) | def add_ClientConnectionServicer_to_server(servicer, server):
class ClientConnection (line 48) | class ClientConnection():
method Connect (line 52) | def Connect(request_iterator,
FILE: federa/client/src/client.py
function client_start (line 11) | def client_start(config):
FILE: federa/client/src/client_lib.py
function evaluate (line 26) | def evaluate(eval_order_message, device):
function train (line 54) | def train(train_order_message, device):
function set_parameters (line 135) | def set_parameters(set_parameters_order_message, device):
function save_model_state (line 145) | def save_model_state(model):
function plot_emission (line 152) | def plot_emission():
FILE: federa/client/src/data_utils.py
class distributionDataloader (line 8) | class distributionDataloader(data.Dataset):
method __init__ (line 10) | def __init__(
method __len__ (line 33) | def __len__(self):
method __getitem__ (line 36) | def __getitem__(self, index):
FILE: federa/client/src/get_data.py
function get_data (line 8) | def get_data(config):
class customDataset (line 54) | class customDataset(data.Dataset):
method __init__ (line 55) | def __init__(self, root, transform=None):
method __getitem__ (line 72) | def __getitem__(self, index):
method __len__ (line 93) | def __len__(self):
function sample_return (line 96) | def sample_return(root):
FILE: federa/client/src/net.py
class LeNet (line 4) | class LeNet(nn.Module):
method __init__ (line 5) | def __init__(self, in_channels=1, num_classes=10):
method forward (line 17) | def forward(self, x):
function get_net (line 33) | def get_net(config):
FILE: federa/client/src/net_lib.py
function load_data (line 18) | def load_data(config):
function flush_memory (line 35) | def flush_memory():
function train_model (line 38) | def train_model(net, trainloader, epochs, device, deadline=None):
function train_fedavg (line 79) | def train_fedavg(net, trainloader, epochs, device, deadline=None):
function train_feddyn (line 130) | def train_feddyn(net, trainloader, epochs, device, deadline=None, prev_g...
function train_mimelite (line 208) | def train_mimelite(net, state, trainloader, epochs, device, deadline=None):
function train_mime (line 258) | def train_mime(net, state, control_variate, trainloader, epochs, device,...
function train_scaffold (line 316) | def train_scaffold(net, server_c, trainloader, epochs, device, deadline=...
function test_model (line 377) | def test_model(net, testloader, device):
FILE: federa/server/src/ClientConnection_pb2_grpc.py
class ClientConnectionStub (line 8) | class ClientConnectionStub():
method __init__ (line 11) | def __init__(self, channel):
class ClientConnectionServicer (line 24) | class ClientConnectionServicer():
method Connect (line 27) | def Connect(self, request_iterator, context):
function add_ClientConnectionServicer_to_server (line 34) | def add_ClientConnectionServicer_to_server(servicer, server):
class ClientConnection (line 48) | class ClientConnection():
method Connect (line 52) | def Connect(request_iterator,
FILE: federa/server/src/algorithms/fedadagrad.py
class fedadagrad (line 6) | class fedadagrad():
method __init__ (line 8) | def __init__(self, config):
method aggregate (line 14) | def aggregate(self,server_state_dict,state_dicts):
FILE: federa/server/src/algorithms/fedadam.py
class fedadam (line 6) | class fedadam():
method __init__ (line 8) | def __init__(self, config):
method aggregate (line 19) | def aggregate(self,server_state_dict,state_dicts):
FILE: federa/server/src/algorithms/fedavg.py
class fedavg (line 5) | class fedavg():
method __init__ (line 7) | def __init__(self, config):
method aggregate (line 10) | def aggregate(self,server_state_dict,state_dicts):
FILE: federa/server/src/algorithms/fedavgm.py
class fedavgm (line 5) | class fedavgm():
method __init__ (line 7) | def __init__(self, config):
method aggregate (line 13) | def aggregate(self,server_state_dict,state_dicts):
FILE: federa/server/src/algorithms/feddyn.py
class feddyn (line 6) | class feddyn():
method __init__ (line 8) | def __init__(self, config):
method aggregate (line 15) | def aggregate(self, server_model_state_dict, state_dicts):
FILE: federa/server/src/algorithms/fedyogi.py
class fedyogi (line 6) | class fedyogi():
method __init__ (line 8) | def __init__(self, config):
method aggregate (line 19) | def aggregate(self,server_state_dict,state_dicts):
FILE: federa/server/src/algorithms/mime.py
class mime (line 5) | class mime():
method __init__ (line 7) | def __init__(self, config):
method aggregate (line 12) | def aggregate(self,server_model_state_dict, optimizer_state, state_dic...
FILE: federa/server/src/algorithms/mimelite.py
class mimelite (line 5) | class mimelite():
method __init__ (line 7) | def __init__(self, config):
method aggregate (line 12) | def aggregate(self,server_model_state_dict, optimizer_state, state_dic...
FILE: federa/server/src/algorithms/scaffold.py
class scaffold (line 5) | class scaffold():
method __init__ (line 7) | def __init__(self, config):
method aggregate (line 12) | def aggregate(self,server_model_state_dict, control_variate, state_dic...
FILE: federa/server/src/client_connection_servicer.py
class ClientConnectionServicer (line 9) | class ClientConnectionServicer( ClientConnection_pb2_grpc.ClientConnecti...
method __init__ (line 10) | def __init__(self, client_manager):
method Connect (line 17) | def Connect(self, request_iterator, context):
FILE: federa/server/src/client_manager.py
class ClientManager (line 7) | class ClientManager:
method __init__ (line 8) | def __init__(self):
method select (line 14) | def select(self, num_of_clients = None, fraction = None, timeout = None):
method random_select (line 27) | def random_select(self, num_of_clients = None, fraction = None, timeou...
method register (line 44) | def register(self, client):
method num_connected_clients (line 52) | def num_connected_clients(self):
method deregister (line 55) | def deregister(self, client_index):
method wait_for (line 60) | def wait_for(self, minimum_clients, timeout):
FILE: federa/server/src/client_wrapper.py
class ClientWrapper (line 10) | class ClientWrapper:
method __init__ (line 11) | def __init__(self, send_buffer, recieve_buffer, client_id):
method train (line 21) | def train(self, model_parameters, control_variate, control_variate2, c...
method evaluate (line 62) | def evaluate(self, model_parameters, config_dict):
method set_parameters (line 85) | def set_parameters(self, model_parameters):
method check_disconnection (line 97) | def check_disconnection(self):
method is_disconnected (line 101) | def is_disconnected(self):
method disconnect (line 106) | def disconnect(self, reconnect_time = 0, message = "Thank you for part...
FILE: federa/server/src/distribution.py
function data_distribution (line 5) | def data_distribution(config, trainset, num_users):
FILE: federa/server/src/server.py
function server_runner (line 21) | def server_runner(client_manager, configurations):
function server_start (line 145) | def server_start(configurations):
FILE: federa/server/src/server_evaluate/eval_lib.py
function server_eval (line 4) | def server_eval(model_state_dict, config):
FILE: federa/server/src/server_lib.py
function load_data (line 15) | def load_data(config):
function get_data (line 22) | def get_data(config):
class customDataset (line 62) | class customDataset(data.Dataset):
method __init__ (line 63) | def __init__(self, root, transform=None):
method __getitem__ (line 72) | def __getitem__(self, index):
method __len__ (line 85) | def __len__(self):
function sample_return (line 88) | def sample_return(root):
class LeNet (line 104) | class LeNet(nn.Module):
method __init__ (line 105) | def __init__(self, in_channels=1, num_classes=10):
method forward (line 117) | def forward(self, x):
function get_net (line 133) | def get_net(config):
function train_model (line 163) | def train_model(net, trainloader):
function test_model (line 176) | def test_model(net, testloader):
function save_intial_model (line 192) | def save_intial_model(config):
FILE: federa/server/src/verification.py
function verify (line 8) | def verify(clients, trained_model_state_dicts, save_dir_path, threshold ...
function random_derangement (line 93) | def random_derangement(list_to_shuffle):
FILE: federa/tests/minitest.py
function create_train_test_for_fedavg (line 10) | def create_train_test_for_fedavg():
function create_train_test_for_fedadam (line 28) | def create_train_test_for_fedadam():
function create_train_test_for_verification_module (line 45) | def create_train_test_for_verification_module():
function create_train_test_for_timeout_module (line 64) | def create_train_test_for_timeout_module():
function create_train_test_for_intermediate_connection_module (line 83) | def create_train_test_for_intermediate_connection_module():
class TestTrainer_verification (line 103) | class TestTrainer_verification(create_train_test_for_verification_module...
class TestTrainer_timeout (line 107) | class TestTrainer_timeout(create_train_test_for_timeout_module()):
class TestTrainer_intermediate (line 111) | class TestTrainer_intermediate(create_train_test_for_intermediate_connec...
class TestTrainer_fedavg (line 115) | class TestTrainer_fedavg(create_train_test_for_fedavg()):
class TestTrainer_fedadam (line 119) | class TestTrainer_fedadam(create_train_test_for_fedadam()):
FILE: federa/tests/misc.py
function get_config (line 11) | def get_config(action, action2, config_path=""):
function tester (line 25) | def tester(configs , no_of_clients, late=None):
FILE: test/benchtest/test_results.py
function create_train_test_for_fedavg (line 8) | def create_train_test_for_fedavg():
function create_train_test_for_fedadagrad (line 26) | def create_train_test_for_fedadagrad():
function create_train_test_for_fedadam (line 44) | def create_train_test_for_fedadam():
function create_train_test_for_fedavgm (line 61) | def create_train_test_for_fedavgm():
function create_train_test_for_feddyn (line 79) | def create_train_test_for_feddyn():
function create_train_test_for_fedyogi (line 97) | def create_train_test_for_fedyogi():
function create_train_test_for_mime (line 114) | def create_train_test_for_mime():
function create_train_test_for_mimelite (line 132) | def create_train_test_for_mimelite():
function create_train_test_for_scaffold (line 150) | def create_train_test_for_scaffold():
class TestTrainer_fedavg (line 168) | class TestTrainer_fedavg(create_train_test_for_fedavg()):
class TestTrainer_fedadagrad (line 172) | class TestTrainer_fedadagrad(create_train_test_for_fedadagrad()):
class TestTrainer_fedadam (line 176) | class TestTrainer_fedadam(create_train_test_for_fedadam()):
class TestTrainer_fedavgm (line 180) | class TestTrainer_fedavgm(create_train_test_for_fedavgm()):
class TestTrainer_feddyn (line 184) | class TestTrainer_feddyn(create_train_test_for_feddyn()):
class TestTrainer_fedyogi (line 188) | class TestTrainer_fedyogi(create_train_test_for_fedyogi()):
class TestTrainer_mime (line 192) | class TestTrainer_mime(create_train_test_for_mime()):
class TestTrainer_mimelite (line 196) | class TestTrainer_mimelite(create_train_test_for_mimelite()):
class TestTrainer_scaffold (line 200) | class TestTrainer_scaffold(create_train_test_for_scaffold()):
FILE: test/benchtest/test_scalability.py
function create_train_test_for_four_clients (line 10) | def create_train_test_for_four_clients():
function create_train_test_for_six_clients (line 29) | def create_train_test_for_six_clients():
function create_train_test_for_five_rounds (line 49) | def create_train_test_for_five_rounds():
function create_train_test_for_ten_rounds (line 68) | def create_train_test_for_ten_rounds():
class TestTrainer_4 (line 89) | class TestTrainer_4(create_train_test_for_four_clients()):
class TestTrainer_6 (line 93) | class TestTrainer_6(create_train_test_for_six_clients()):
class TestTrainer_5_rounds (line 97) | class TestTrainer_5_rounds(create_train_test_for_five_rounds()):
class TestTrainer_10_rounds (line 101) | class TestTrainer_10_rounds(create_train_test_for_ten_rounds()):
FILE: test/misc.py
function get_config (line 13) | def get_config(action, action2, config_path=""):
function execute (line 29) | def execute(process):
function tester (line 33) | def tester(configs , no_of_clients, late=None):
function get_result (line 62) | def get_result(dataset, algorithm):
FILE: test/unittest/test_algorithms.py
function create_train_test_for_fedavg (line 8) | def create_train_test_for_fedavg():
function create_train_test_for_fedadagrad (line 26) | def create_train_test_for_fedadagrad():
function create_train_test_for_fedadam (line 44) | def create_train_test_for_fedadam():
function create_train_test_for_fedavgm (line 61) | def create_train_test_for_fedavgm():
function create_train_test_for_feddyn (line 79) | def create_train_test_for_feddyn():
function create_train_test_for_fedyogi (line 97) | def create_train_test_for_fedyogi():
function create_train_test_for_mime (line 114) | def create_train_test_for_mime():
function create_train_test_for_mimelite (line 132) | def create_train_test_for_mimelite():
function create_train_test_for_scaffold (line 150) | def create_train_test_for_scaffold():
class TestTrainer_fedavg (line 168) | class TestTrainer_fedavg(create_train_test_for_fedavg()):
class TestTrainer_fedadagrad (line 172) | class TestTrainer_fedadagrad(create_train_test_for_fedadagrad()):
class TestTrainer_fedadam (line 176) | class TestTrainer_fedadam(create_train_test_for_fedadam()):
class TestTrainer_fedavgm (line 180) | class TestTrainer_fedavgm(create_train_test_for_fedavgm()):
class TestTrainer_feddyn (line 184) | class TestTrainer_feddyn(create_train_test_for_feddyn()):
class TestTrainer_fedyogi (line 188) | class TestTrainer_fedyogi(create_train_test_for_fedyogi()):
class TestTrainer_mime (line 192) | class TestTrainer_mime(create_train_test_for_mime()):
class TestTrainer_mimelite (line 196) | class TestTrainer_mimelite(create_train_test_for_mimelite()):
class TestTrainer_scaffold (line 200) | class TestTrainer_scaffold(create_train_test_for_scaffold()):
FILE: test/unittest/test_datasets.py
function create_train_test_for_MNIST (line 9) | def create_train_test_for_MNIST():
function create_train_test_for_FashionMnist (line 27) | def create_train_test_for_FashionMnist():
function create_train_test_for_CIFAR10 (line 44) | def create_train_test_for_CIFAR10():
function create_train_test_for_CIFAR100 (line 62) | def create_train_test_for_CIFAR100():
function create_train_test_for_CUSTOM (line 80) | def create_train_test_for_CUSTOM():
class TestTrainer_MNIST (line 98) | class TestTrainer_MNIST(create_train_test_for_MNIST()):
class TestTrainer_FashionMNIST (line 102) | class TestTrainer_FashionMNIST(create_train_test_for_FashionMnist()):
class TestTrainer_CIFAR10 (line 106) | class TestTrainer_CIFAR10(create_train_test_for_CIFAR10()):
class TestTrainer_CIFAR100 (line 110) | class TestTrainer_CIFAR100(create_train_test_for_CIFAR100()):
class TestTrainer_CUSTOM (line 114) | class TestTrainer_CUSTOM(create_train_test_for_CUSTOM()):
FILE: test/unittest/test_models.py
function create_train_test_for_LeNet (line 12) | def create_train_test_for_LeNet():
function create_train_test_for_resnet18 (line 29) | def create_train_test_for_resnet18():
function create_train_test_for_resnet50 (line 46) | def create_train_test_for_resnet50():
function create_train_test_for_vgg16 (line 63) | def create_train_test_for_vgg16():
function create_train_test_for_AlexNet (line 80) | def create_train_test_for_AlexNet():
class TestTrainer_LeNet (line 97) | class TestTrainer_LeNet(create_train_test_for_LeNet()):
class TestTrainer_resnet18 (line 101) | class TestTrainer_resnet18(create_train_test_for_resnet18()):
class TestTrainer_resnet50 (line 105) | class TestTrainer_resnet50(create_train_test_for_resnet50()):
class TestTrainer_vgg16 (line 109) | class TestTrainer_vgg16(create_train_test_for_vgg16()):
class TestTrainer_AlexNet (line 113) | class TestTrainer_AlexNet(create_train_test_for_AlexNet()):
FILE: test/unittest/test_modules.py
function create_train_test_for_verification_module (line 12) | def create_train_test_for_verification_module():
function create_train_test_for_timeout_module (line 30) | def create_train_test_for_timeout_module():
function create_train_test_for_intermediate_connection_module (line 48) | def create_train_test_for_intermediate_connection_module():
class TestTrainer_verification (line 67) | class TestTrainer_verification(create_train_test_for_verification_module...
class TestTrainer_timeout (line 71) | class TestTrainer_timeout(create_train_test_for_timeout_module()):
class TestTrainer_intermediate (line 75) | class TestTrainer_intermediate(create_train_test_for_intermediate_connec...
FILE: tutorials/accuracy_plot.py
function read_values (line 5) | def read_values(txt_path):
function plot_round_vs_accuracy_1 (line 27) | def plot_round_vs_accuracy_1(algorithm_values, niids):
function plot_round_vs_accuracy_2 (line 55) | def plot_round_vs_accuracy_2(algorithm_values, niids):
function plot_niid_vs_accuracy (line 78) | def plot_niid_vs_accuracy(algorithm_values, niids):
Condensed preview — 1415 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (600K chars).
[
{
"path": ".bandit",
"chars": 61,
"preview": "[bandit]\ntargets: federa\n\n[bandit.test]\nseverity: MEDIUM,HIGH"
},
{
"path": ".coveragerc",
"chars": 169,
"preview": "[run]\nparallel = True\nconcurrency = multiprocessing, thread\n\n[report]\nomit = \n federa/server/start_server.py\n fede"
},
{
"path": ".github/workflows/publish.yml",
"chars": 1078,
"preview": "name: Build and Push Docker Image\n\non:\n push:\n branches:\n - main\n\nenv:\n DOCKER_HUB_USERNAME: anupamkliv\n DOCK"
},
{
"path": ".github/workflows/pytest_coverage.yml",
"chars": 1420,
"preview": "# This workflow will install Python dependencies, run tests and lint with a single version of Python\n# For more informat"
},
{
"path": ".github/workflows/ubuntu.yml",
"chars": 618,
"preview": "name: Ubuntu (latest)\n\non: [push]\n\npermissions:\n contents: read\n\n\njobs:\n interactive-kvasir: # from interactive-kvasir"
},
{
"path": ".github/workflows/windows.yml",
"chars": 1113,
"preview": "name: Windows (latest)\n\non: [push]\n\npermissions:\n contents: read\n\n\njobs:\n \n interactive-kvasir: # from interactive-kv"
},
{
"path": ".gitignore",
"chars": 0,
"preview": ""
},
{
"path": "CONDUCT.md",
"chars": 2770,
"preview": "# Contributor Code of Conduct\n## Introduction\n\nAs contributors and maintainers of this Federated Learning framework, we "
},
{
"path": "Dockerfile",
"chars": 1007,
"preview": "# Dockerfile\n\n# Determine the system architecture\nARG ARCHITECTURE\n\n# Use the official Python base image\nFROM python:3.1"
},
{
"path": "LICENSE",
"chars": 11395,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 20338,
"preview": "# Federated Learning Framework\n[:\n def __init__(self, in_channels=1, num_c"
},
{
"path": "federa/client/src/net_lib.py",
"chars": 15010,
"preview": "import os\r\nimport time\r\nfrom copy import deepcopy\r\nfrom math import ceil\r\nfrom tqdm import tqdm\r\n\r\n\r\nimport torch\r\n\r\nfro"
},
{
"path": "federa/client/start_client.py",
"chars": 824,
"preview": "from .src.client import client_start\nimport argparse\n\nparser = argparse.ArgumentParser()\nparser.add_argument(\"--ip\", typ"
},
{
"path": "federa/server/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "federa/server/src/ClientConnection_pb2.py",
"chars": 16361,
"preview": "# -*- coding: utf-8 -*-\n# Generated by the protocol buffer compiler. DO NOT EDIT!\n# source: ClientConnection.proto\n\"\"\"G"
},
{
"path": "federa/server/src/ClientConnection_pb2_grpc.py",
"chars": 2503,
"preview": "# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!\n\"\"\"Client and server classes corresponding to prot"
},
{
"path": "federa/server/src/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "federa/server/src/algorithms/fedadagrad.py",
"chars": 1415,
"preview": "import functools\nfrom collections import OrderedDict\nimport torch\n\n#averages all of the given state dicts\nclass fedadagr"
},
{
"path": "federa/server/src/algorithms/fedadam.py",
"chars": 1962,
"preview": "import functools\nfrom collections import OrderedDict\nimport torch\n\n#averages all of the given state dicts\nclass fedadam("
},
{
"path": "federa/server/src/algorithms/fedavg.py",
"chars": 816,
"preview": "import functools\nfrom collections import OrderedDict\n\n#averages all of the given state dicts\nclass fedavg():\n\n def __"
},
{
"path": "federa/server/src/algorithms/fedavgm.py",
"chars": 1427,
"preview": "import functools\nfrom collections import OrderedDict\n\n#averages all of the given state dicts\nclass fedavgm():\n\n def _"
},
{
"path": "federa/server/src/algorithms/feddyn.py",
"chars": 1652,
"preview": "import functools\nfrom collections import OrderedDict\nimport torch\n\n#averages all of the given state dicts\nclass feddyn()"
},
{
"path": "federa/server/src/algorithms/fedyogi.py",
"chars": 2092,
"preview": "import functools\nfrom collections import OrderedDict\nimport torch\n\n#averages all of the given state dicts\nclass fedyogi("
},
{
"path": "federa/server/src/algorithms/mime.py",
"chars": 1546,
"preview": "import functools\nfrom collections import OrderedDict\n\n#averages all of the given state dicts\nclass mime():\n\n def __in"
},
{
"path": "federa/server/src/algorithms/mimelite.py",
"chars": 1500,
"preview": "import functools\nfrom collections import OrderedDict\n\n#averages all of the given state dicts\nclass mimelite():\n\n def "
},
{
"path": "federa/server/src/algorithms/scaffold.py",
"chars": 1798,
"preview": "import functools\nfrom collections import OrderedDict\n\n#averages all of the given state dicts\nclass scaffold():\n\n def "
},
{
"path": "federa/server/src/client_connection_servicer.py",
"chars": 2089,
"preview": "\nfrom queue import Queue\n\nfrom . import ClientConnection_pb2_grpc\n\nfrom .client_wrapper import ClientWrapper\n\n#gRPC serv"
},
{
"path": "federa/server/src/client_manager.py",
"chars": 2531,
"preview": "\nimport random\nimport threading\nfrom math import ceil\n\n#holds references to all live client_wrapper objects\nclass Client"
},
{
"path": "federa/server/src/client_wrapper.py",
"chars": 4998,
"preview": "\nfrom io import BytesIO\nimport torch\nimport json\n\nfrom .ClientConnection_pb2 import ServerMessage, TrainOrder, EvalOrder"
},
{
"path": "federa/server/src/distribution.py",
"chars": 4687,
"preview": "import numpy as np\nimport torch\nimport random\nimport os\ndef data_distribution(config, trainset, num_users):\n labels ="
},
{
"path": "federa/server/src/server.py",
"chars": 8682,
"preview": "from .client_manager import ClientManager\nfrom .client_connection_servicer import ClientConnectionServicer\n\nfrom .verifi"
},
{
"path": "federa/server/src/server_evaluate/__init__.py",
"chars": 34,
"preview": "from .eval_lib import server_eval\n"
},
{
"path": "federa/server/src/server_evaluate/eval_lib.py",
"chars": 490,
"preview": "import torch\nfrom ..server_lib import load_data, get_net, test_model\n\ndef server_eval(model_state_dict, config):\n dev"
},
{
"path": "federa/server/src/server_lib.py",
"chars": 7175,
"preview": "import torch\nimport os\nfrom tqdm import tqdm\nfrom torchvision import transforms,datasets\nfrom torch.utils.data import Da"
},
{
"path": "federa/server/src/verification.py",
"chars": 4756,
"preview": "\nfrom random import randint\nfrom collections import OrderedDict\nfrom concurrent import futures\nimport copy\n\n##modify the"
},
{
"path": "federa/server/start_server.py",
"chars": 3408,
"preview": "import argparse\n\nfrom .src.server import server_start\nfrom .src.server_lib import save_intial_model\n\n'# the parameters t"
},
{
"path": "federa/tests/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "federa/tests/minitest.json",
"chars": 4423,
"preview": "{\n \"fedavg\":{\n \"server\": {\n \"algorithm\":\"fedavg\",\n \"num_of_clients\":1,\n \"frac"
},
{
"path": "federa/tests/minitest.py",
"chars": 4422,
"preview": "import unittest\nimport os\nimport sys\nfrom .misc import get_config, tester\nfrom ..server.src.server_lib import save_intia"
},
{
"path": "federa/tests/misc.py",
"chars": 1478,
"preview": "import os\nimport sys\nimport time\nimport json\n\nfrom torch.multiprocessing import Process\nfrom torch import multiprocessin"
},
{
"path": "requirements.txt",
"chars": 142,
"preview": "codecarbon==2.1.4\ngrpcio==1.53.0\nnumpy==1.23.4\nPillow==9.5.0\nprotobuf==3.20.2\ntorch>=2.0.0\ntorchvision>=0.15.1\ntqdm==4.6"
},
{
"path": "ssl/README.md",
"chars": 2111,
"preview": "# SSL Configuration\n\n## CFSSL Integration\n\nThis section provides instructions on using the CFSSL toolkit in conjunction "
},
{
"path": "ssl/ca-config.json",
"chars": 181,
"preview": "{\n \"signing\": {\n \"profiles\": {\n \"default\": {\n \"usages\": [\"signing\", \"key encipherment\", \"server auth\", \""
},
{
"path": "ssl/ca-csr.json",
"chars": 235,
"preview": "{\n \"CN\": \"Example CA\",\n \"key\": {\n \"algo\": \"rsa\",\n \"size\": 2048\n },\n \"names\": [\n {\n \"C\": \"US\",\n \"L"
},
{
"path": "ssl/client-csr.json",
"chars": 229,
"preview": "{\n \"CN\": \"TestClient\",\n \"key\": {\n \"algo\": \"rsa\",\n \"size\": 2048\n },\n \"names\": [\n {\n \"C\": \"US\",\n \"L"
},
{
"path": "ssl/server-csr.json",
"chars": 237,
"preview": "{\n \"CN\": \"server.example.com\",\n \"key\": {\n \"algo\": \"rsa\",\n \"size\": 2048\n },\n \"names\": [\n {\n \"C\": \"US\",\n"
},
{
"path": "test/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "test/benchtest/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "test/benchtest/test_results.py",
"chars": 6052,
"preview": "import unittest\nimport os\nimport sys\nfrom ..misc import get_config, tester\nsys.path.append(os.path.dirname(os.path.dirna"
},
{
"path": "test/benchtest/test_scalability.py",
"chars": 3015,
"preview": "import os\nimport sys\nimport unittest\nsys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))\nfrom f"
},
{
"path": "test/misc.py",
"chars": 2274,
"preview": "import os\nimport sys\nimport time\nimport json\n\nfrom torch.multiprocessing import Process\nfrom torch import multiprocessin"
},
{
"path": "test/unittest/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "test/unittest/test_algorithms.py",
"chars": 6069,
"preview": "import unittest\nimport os\nimport sys\nfrom ..misc import get_config, tester\nsys.path.append(os.path.dirname(os.path.dirna"
},
{
"path": "test/unittest/test_datasets.py",
"chars": 3494,
"preview": "import os\nimport sys\nimport unittest\n# add main directory to path\nsys.path.append(os.path.dirname(os.path.dirname(os.pat"
},
{
"path": "test/unittest/test_models.py",
"chars": 3431,
"preview": "import os\nimport sys\nimport unittest\n# add main directory to path\nsys.path.append(os.path.dirname(os.path.dirname(os.pat"
},
{
"path": "test/unittest/test_modules.py",
"chars": 2420,
"preview": "import os\nimport unittest\nimport sys\n\nsys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))\nfrom "
},
{
"path": "tutorials/Code_Carbon_Tutorial.ipynb",
"chars": 13477,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# Import Libraries\"\n ]\n },\n {\n "
},
{
"path": "tutorials/Federated_Algorithm_Tutorial.ipynb",
"chars": 14178,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# Import Libraries\"\n ]\n },\n {\n "
},
{
"path": "tutorials/Number_of_clients_Tutorial.ipynb",
"chars": 7123,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# Import Libraries\"\n ]\n },\n {\n "
},
{
"path": "tutorials/Verifcation_module_tutorial.ipynb",
"chars": 13770,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"markdown\",\n \"metadata\": {},\n \"source\": [\n \"# Import Libraries\"\n ]\n },\n {\n "
},
{
"path": "tutorials/accuracy_plot.py",
"chars": 5204,
"preview": "import os\nimport matplotlib.pyplot as plt\n\n\ndef read_values(txt_path):\n \"\"\"\n Reads accuracy and round values from "
},
{
"path": "tutorials/data_distribution.ipynb",
"chars": 186593,
"preview": "{\n \"cells\": [\n {\n \"attachments\": {},\n \"cell_type\": \"markdown\",\n \"id\": \"39c0e501\",\n \"metadata\": {},\n \"source\":"
},
{
"path": "tutorials/media_plot.ipynb",
"chars": 33308,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 4,\n \"metadata\": {},\n \"outputs\": [\n {\n \"name\":"
}
]
// ... and 1316 more files (download for full content)
About this extraction
This page contains the full source code of the anupamkliv/FedERA GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1415 files (557.9 KB), approximately 245.7k tokens, and a symbol index with 199 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.