2024年1月9日学习总结

目录

  • 学习目标
  • 学习内容
    • 联邦学习基础:why, what, how
      • why?
      • what?
      • how?
    • 联邦学习的例子——CIFAR-10数据集(分类问题)
      • 1、import libararies
      • 2、hyper-parameters
      • 3、加载并且划分数据
      • 4、创建神经网络模型
      • 5、helper functions
        • (1)client_update
        • (2)server_aggregate
        • (3)test
      • 6、实例化模型
      • 7、训练模型
      • 7、整体流程
    • 查看不同类型数据的方法
      • 1、dataframe
      • 2、ndarray
      • 3、Dictionary
      • 4、list
      • 5、tuple

学习目标

  • 完成集中学习的代码部分
  • 对联邦学习进行了解
  • 对学习过程中遇到的问题进行总结

学习内容

联邦学习基础:why, what, how

why?

深度学习对于数据的需求是贪得无厌的(insatiable),越多的数据训练的效果越好。ALphaGo学习了大约30万场的比赛模式才在2016年打败了人类玩家。如果能够不受限制的访问几大洲的所有医院数十亿的医疗记录,那么预测各类疾病的概率将会非常的精确。但是有数据保护法的管控,使用超级大量的数据来进行训练模型是不可能的。
高质量的数据像是一个个孤岛存储在世界各地的边缘设备上。在不违反隐私法的前提下把他们整合到一起得到他们的预测能力是非常困难的(herculean)的任务。联邦学习就是解决这一困境的!

what?

联邦学习提供了一个聪明的方式,连接机器学习模型和能够有效训练模型所需的数据
联邦学习工作可以比喻成:殖民地(colonies)和领土(territories)是如何组成共和国(republic)或联邦(federation)的。
分布的边缘设备使用自己的数据训练自己的local model,然后组合在一起创造一个global model(听起来像是分布式学习💦),联邦学习就是分布学习的一种形式,但是它和传统的HPC(high performance computing)不同,HPC的目的是减少训练的时间,因为你也知道经历45天的训练,想要记得上一次调整的超参数是多么困难😰。但是FL的目标是无论数据在哪里,都要获取数据,并将其用于模型训练。在HPC中,训练数据首先被收集在一起并随机化,然后作为碎片跨多个计算节点共享。这些过程产生了独立且同分布(IID)的数据,从而提高了随机梯度下降的性能。但是FL学习是不能生成IID数据的,FL数据大多是非IID的,并且系统必须具有能够承受这种现象的架构。

how?

传统的FL学习结构由中心的管理员(curator)或者服务器(server)协调训练的。客户端(clients)大多数是边缘设备,数量可能多达几百万,这些设备在每次训练的过程中至少与服务器通信两次。

  • 首先,客户端都从服务器接收当前的全局模型权重(global model weights)
  • 然后,在每个本地数据上训练它以生成更新的参数
  • 将这些参数上传到服务器进行聚合(aggregation)

联邦学习的例子——CIFAR-10数据集(分类问题)

1、import libararies

###############################
##### importing libraries #####
###############################

import os
import random
from tqdm import tqdm
import numpy as np
import torch, torchvision
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data.dataset import Dataset   
torch.backends.cudnn.benchmark=True

2、hyper-parameters

##### Hyperparameters for federated learning #########
num_clients = 20
num_selected = 6
num_rounds = 150
epochs = 5
batch_size = 32
  1. num_clients: 客户端的数量。将全部数据平均分给每个client
  2. num_selected: 在num_clients中随机选择num-clients个客户端进行训练(每个communication round)。通常是30%
  3. num_rounds: 需要运行的communication 轮数。在每一个communication round中,从num_clients中随机抽出num_selected个客户端进行原理,然后聚合各自的模型参数成为一个global model
  4. epoch: 每一个被选择的客户端需要训练的轮数
  5. batch_size: 批量的加载数据

3、加载并且划分数据

本教程使用CIFAR10数据集。它由10个类别的6万张32x32像素的彩色图像组成。有5万张训练图像和1万张测试图像。在训练批次中,每个班级有5000张图像,总共有50000张。在PyTorch中,CIFAR 10可以在torchvision模块的帮助下使用。
在本教程中,图像被平均地划分为客户机,因此表示平衡(IID)情况。

  1. 加载图像,并对图像进行预处理
# Image augmentation 
transform_train = transforms.Compose([
    transforms.RandomCrop(32, padding=4),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])

# Loading CIFAR10 using torchvision.datasets
traindata = datasets.CIFAR10('./data', train=True, download=True,
                       transform= transform_train)
  1. 将训练数据分给num_clients个客户端
# Dividing the training data into num_clients, with each client having equal number of images
traindata_split = torch.utils.data.random_split(traindata, [int(traindata.data.shape[0] / num_clients) for _ in range(num_clients)])
  1. 将训练样本转化成深度学习的格式
# Creating a pytorch loader for a Deep Learning model
train_loader = [torch.utils.data.DataLoader(x, batch_size=batch_size, shuffle=True) for x in traindata_split]
  1. 对测试集进行预处理以及转成深度学习格式
# Normalizing the test images
transform_test = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])

# Loading the test iamges and thus converting them into a test_loader
test_loader = torch.utils.data.DataLoader(
        datasets.CIFAR10('./data', train=False, transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))])
        ), batch_size=batch_size, shuffle=True)

4、创建神经网络模型

VGG19(16个卷积层,3个完全连接层,5个MaxPool层和1个SoftMax层)在本教程中使用。还有VGG11、VGG13和VGG16等VGG的其他变体。

#################################
##### Neural Network model #####
#################################

cfg = {
    'VGG11': [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
    'VGG13': [64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
    'VGG16': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'],
    'VGG19': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M'],
}

class VGG(nn.Module):
    def __init__(self, vgg_name):
        super(VGG, self).__init__()
        self.features = self._make_layers(cfg[vgg_name])
        self.classifier = nn.Sequential(
            nn.Linear(512, 512),
            nn.ReLU(True),
            nn.Linear(512, 512),
            nn.ReLU(True),
            nn.Linear(512, 10)
        )

    def forward(self, x):
        out = self.features(x)
        out = out.view(out.size(0), -1)
        out = self.classifier(out)
        output = F.log_softmax(out, dim=1)
        return output

    def _make_layers(self, cfg):
        layers = []
        in_channels = 3
        for x in cfg:
            if x == 'M':
                layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
            else:
                layers += [nn.Conv2d(in_channels, x, kernel_size=3, padding=1),
                           nn.BatchNorm2d(x),
                           nn.ReLU(inplace=True)]
                in_channels = x
        layers += [nn.AvgPool2d(kernel_size=1, stride=1)]
        return nn.Sequential(*layers)

我们定义了一个名为VGG的类,它继承了nn.Module。这个类有两个主要方法:__init__和forward。__init__方法用于初始化网络结构,包括定义卷积层和全连接层。forward方法用于前向传播输入数据通过网络,并返回输出结果。
在__init__方法中,我们首先调用父类的__init__方法,然后定义了一个名为features的成员变量,它包含了VGG网络的卷积层。接下来,我们定义了一个名为classifier的成员变量,它包含了VGG网络的全连接层。最后,我们在forward方法中定义了如何处理输入数据,并返回输出结果。
_make_layers方法用于构建VGG网络的卷积层。它首先定义了一个名为layers的空列表,用于存储网络结构中的层。然后,我们遍历cfg列表,其中cfg是一个包含VGG网络结构配置的列表。如果x等于’M’,表示这是一个最大池化层,我们添加一个nn.MaxPool2d层;否则,表示这是一个卷积层,我们添加一个nn.Conv2d层、一个nn.BatchNorm2d层和一个nn.ReLU激活层。最后,我们添加一个平均池化层,并返回nn.Sequential(*layers),即网络结构中的所有层。

5、helper functions

(1)client_update

client_update函数使用privent client data训练client模型。这是在num_selected clients中进行的本地训练

def client_update(client_model, optimizer, train_loader, epoch=5):
    """
    This function updates/trains client model on client data
    """
    model.train()
    for e in range(epoch):
        for batch_idx, (data, target) in enumerate(train_loader):
            data, target = data.cuda(), target.cuda()
            optimizer.zero_grad()
            output = client_model(data)
            loss = F.nll_loss(output, target)
            loss.backward()
            optimizer.step()
    return loss.item()
  • 首先,我们使用client_model.train()将客户端模型设置为训练模式。
  • 然后,我们使用一个for循环遍历训练轮数。在每一轮中,我们使用另一个for循环遍历训练数据加载器中的数据。
  • 对于每个数据batch,我们将数据和目标标签从CPU转移到GPU上,并使用optimizer.zero_grad()将梯度清零。
  • 接下来,我们使用客户端模型对数据进行前向传播,并计算损失。output = client_model(data)
  • 然后,我们使用loss.backward()计算梯度。
  • 最后,我们使用optimizer.step()更新客户端模型的参数。
(2)server_aggregate

server_aggregate函数聚合从每个客户机接收到的模型权重,并用更新后的权重更新全局模型。在本教程中,采用权重的平均值并将其聚合为全局权重。

def server_aggregate(global_model, client_models):
    """
    This function has aggregation method 'mean'
    """
    ### This will take simple mean of the weights of models ###
      global_dict = global_model.state_dict()
      for k in global_dict.keys():
          global_dict[k] = torch.stack([client_models[i].state_dict()[k].float() for i in range(len(client_models))], 0).mean(0)
      global_model.load_state_dict(global_dict)
      for model in client_models:
          model.load_state_dict(global_model.state_dict())
  • 首先,我们使用global_model.state_dict()获取全局模型的参数字典。
  • 然后,我们使用一个for循环遍历全局模型的参数字典中的每个键(参数名称)。
  • 对于每个参数,我们使用torch.stack()将所有客户端模型的相应参数堆叠在一起,并使用float()将其转换为浮点数类型。
  • 接下来,我们使用mean()函数计算参数的平均值。
  • 最后,我们使用global_model.load_state_dict()将计算出的平均值加载到全局模型的参数字典中。
  • 接下来,我们使用另一个for循环遍历客户端模型列表,并使用model.load_state_dict()将全局模型的参数字典加载到每个客户端模型中,以实现全局模型在每个客户端模型的平均值。
(3)test

test函数输入global模型和test loader,返回test loss和accuracy

def test(global_model, test_loader):
    """This function test the global model on test data and returns test loss and test accuracy """
    global_model.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.cuda(), target.cuda()
            output = global_model(data)
            test_loss += F.nll_loss(output, target, reduction='sum').item()  # sum up batch loss
            pred = output.argmax(dim=1, keepdim=True)  # get the index of the max log-probability
            correct += pred.eq(target.view_as(pred)).sum().item()

    test_loss /= len(test_loader.dataset)
    acc = correct / len(test_loader.dataset)

    return test_loss, acc
  • 首先,我们使用global_model.eval()将全局模型设置为评估模式,以便在测试过程中关闭dropout等正则化技术。
  • 然后,我们初始化测试损失为0,正确分类的样本数为0
  • 使用torch.no_grad()上下文,用于在代码块中禁用梯度计算。
  • 我们遍历test_loader中的每个数据样本。
  • 对于每个数据样本data,target,我们将数据和目标标签从CPU加载到GPU上
  • 并使用全局模型对其进行前向传播。output = global_model(data)
  • 我们使用F.nll_loss()计算输出与目标标签之间的交叉熵损失,并使用reduction='sum’将其转换为单个数值。
  • 接下来,我们使用test_loss += …将每个样本的损失累加到测试损失中。
  • 最后,我们使用pred = output.argmax(dim=1, keepdim=True)计算输出中最大概率的索引,并将其与目标标签进行比较。
  • 使用pred.eq(target.view_as(pred))比较预测索引和实际索引,并将它们转换为布尔值。
  • 使用sum().item()计算布尔值的总和,并将其除以测试数据加载器中样本的数量以获得测试准确性。
  • 最后,我们返回测试损失和测试准确性。

6、实例化模型

############################################
#### Initializing models and optimizer  ####
############################################

#### global model ##########
global_model =  VGG('VGG19').cuda()

############## client models ##############
client_models = [ VGG('VGG19').cuda() for _ in range(num_selected)]
for model in client_models:
    model.load_state_dict(global_model.state_dict()) ### initial synchronizing with global model 

############### optimizers ################
opt = [optim.SGD(model.parameters(), lr=0.1) for model in client_models]

7、训练模型

###### List containing info about learning #########
losses_train = []
losses_test = []
acc_train = []
acc_test = []
# Runnining FL

for r in range(num_rounds):
    # select random clients
    client_idx = np.random.permutation(num_clients)[:num_selected]
    # client update
    loss = 0
    for i in tqdm(range(num_selected)):
        loss += client_update(client_models[i], opt[i], train_loader[client_idx[i]], epoch=epochs)
    
    losses_train.append(loss)
    # server aggregate
    server_aggregate(global_model, client_models)
    
    test_loss, acc = test(global_model, test_loader)
    losses_test.append(test_loss)
    acc_test.append(acc)
    print('%d-th round' % r)
    print('average train loss %0.3g | test loss %0.3g | test acc: %0.3f' % (loss / num_selected, test_loss, acc))

7、整体流程

在这里插入图片描述

查看不同类型数据的方法

首先要查看变量的数据类型:type(object)

1、dataframe

使用万能函数

def basic_eda(df):
    print("-------------------------------TOP 5 RECORDS-----------------------------")
    print(df.head(5))
    print("-------------------------------INFO--------------------------------------")
    print(df.info())
    print("-------------------------------Describe----------------------------------")
    print(df.describe())
    print("-------------------------------Columns-----------------------------------")
    print(df.columns)
    print("-------------------------------Data Types--------------------------------")
    print(df.dtypes)
    print("----------------------------Missing Values-------------------------------")
    print(df.isnull().sum())
    print("----------------------------NULL values----------------------------------")
    print(df.isna().sum())
    print("--------------------------Shape Of Data---------------------------------")
    print(df.shape)
    print("============================================================================ \n")
  • df.head():查看前几行数据,默认是5
  • df.info:打印dataframe的简要摘要,包括索引的数据类型dtype和列的数据类型dtype,非空值的数量和内存使用情况。
    在这里插入图片描述
  • df.describe:describe()函数用于生成描述性统计信息。 描述性统计数据:数值类型的包括均值,标准差,最大值,最小值,分位数等;类别的包括个数,类别的数目,最高数量的类别及出现次数等;输出将根据提供的内容而有所不同
    在这里插入图片描述
  • df.colunms:查看列
  • df.dtypes:查看元素的数据类型
  • df.shape:查看dataframe的形状

2、ndarray

  • ndarray.type:查看元素类型
  • ndarray.shape:查看数组的形状
  • ndarray.ndim:查看数组维度
  • ndarry.size:查看数组的全部元素个数
  • len(ndarray):计算的是数组的行数,相当于ndarray.shape[0]

3、Dictionary

  • dict.keys():返回字典全部的key
  • dict.size❌‘dict’ object has no attribute ‘size’
  • numpy.size(dict)❌无法获得字典大小
  • len(dict):返回字典key-value对的个数

4、list

  • list.size❌‘list’ object has no attribute ‘size’
  • numpy.size(list):查看列表全部元素的个数
  • len(list):同numpy.size(list)一样

5、tuple

  • tuple.size❌‘tuple’ object has no attribute ‘size’
  • numpy.size(tuple):查看元组全部元素的个数
  • len(tuple):同numpy.size(tuple)一样

okkksleeeeep!

在这里插入图片描述

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

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

相关文章

Spark Core--加强

RDD的持久化 RDD缓存 当RDD被重复使用,或者计算该RDD比较容易出错,而且需要消耗比较多的资源和时间的时候,我们就可以将该RDD缓存起来。 主要作用: 提升Spark程序的计算效率 注意事项: RDD的缓存可以存储在内存或者是磁盘上,甚至…

RBAC权限管理概念

基于RBAC模型的权限设计:如何设计系统权限体系? | 人人都是产品经理 一,什么是RBAC RBAC(基于角色的权限控制)模型的核心是在用户和权限之间引入了角色的概念。取消了用户和权限的直接关联,改为通过用户关联角色、角色关联权限的…

虾皮如何查看自己的店铺

在虾皮(Shopee)平台上查看自己的店铺是非常重要的,因为它可以帮助您了解店铺的运营情况、管理商品和处理客户服务等。下面是在虾皮平台上查看店铺的步骤: 先给大家推荐一款shopee知虾数据运营工具知虾免费体验地址(复制…

nn网络层-卷积层

一、1d/2d/3d Convolution 卷积运算:卷积核在输入信号(图像)上滑动,相应位置上进行乘加卷积核:又称为滤波器,过滤器,可认为是某种模式,某种特征。卷积过程类似于用一个模版去图像上…

【JAVA】怎么确保一个集合不能被修改

🍎个人博客:个人主页 🏆个人专栏: JAVA ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 示例: 不可修改的List: 不可修改的Set: 不可修改的Map: 结语 我的其他博…

强化学习在生成式预训练语言模型中的研究现状简单调研

1. 绪论 本文旨在深入探讨强化学习在生成式预训练语言模型中的应用,特别是在对齐优化、提示词优化和经验记忆增强提示词等方面的具体实践。通过对现有研究的综述,我们将揭示强化学习在提高生成式语言模型性能和人类对话交互的关键作用。虽然这些应用展示…

STM32F103C8T6内部自带Bootloader模式之使用FlyMcu烧写程序

简介 实现自己的Bootloader前, 使用一下STM32内部自带的Bootloader对STM进行烧写 步骤 下载FlyMCU 参考 普中STM32-PZ6806L 使用FlyMcu串口烧录程序 Boot选择 Boot0->1 , Boot1->0 进到系统存储器 打开FlyMCU 1 选择串口波特率 2 选择程序 3 不需要使用辅助引脚 4 开…

Linux网络配置与抓包工具介绍

目录 一、配置命令 1. ifconfig 1.1 概述信息解析 1.2 常用格式 2. ip 2.1 ip link 数据链路层 2.2 ip addr 网络层 2.3 路由 3. hostname 3.1 临时修改主机名 3.2 永久修改主机名 4. route 5. netstat 6. ss 7. ping 8. traceroute 9. nslookup 10. 永久修…

书生·浦语大模型全链路开源体系 学习笔记 第三课

huggingface-cli: command not found 按照该文档解决即可 https://github.com/huggingface/huggingface_hub/issues/1079 具体如下: 1、确保环境已将安装huggingface-cli 2、版本需要旧版,pip install huggingface_hub0.20.1 3、再按如下执行 # T…

WCF几种寄宿方式IIS、Winform、控制台、Windows服务

WCF寄宿方式是一种非常灵活的操作,可以在IIS服务、Windows服务、Winform程序、控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者方便、高效提供服务调用。本文分别对这几种方式进行详细介绍并开发例子进行说明,以求大家对WCF寄宿的方式进行全面的认识和了解。 1、 WC…

计算机毕业设计 基于SpringBoot的项目申报系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…

探索雷盛537威士忌的魅力:从观色、闻香到品鉴

威士忌,这一源于苏格兰的特别烈酒,以其丰富的味蕾和特别的魅力征服了全球的品鉴者。品鉴威士忌不仅仅是一种感官体验,更是一种探索和发现的旅程。在本文中,我们将以雷盛537威士忌为例,与您深入了解品鉴威士忌的全过程&…

React-Hoc高阶组件与css-in-js技术

Hoc高阶组件 Higher - Order Components:在原有组件基础之上加工后新生成得到的新组件。【高阶组件】 const NewComponent HOC(YourComponent) 通俗的来讲,高阶组件就相当于手机壳,通过包装组件,增强组件功能。 HOC实现步骤&…

三分钟轻松搞懂 HashMap 死循环问题!

三分钟轻松搞懂 HashMap 死循环问题! HashMap 死循环发生在 JDK 1.7 版本中,形成死循环的原因是 HashMap 在 JDK 1.7 使用的是头插法,头插法 链表 多线程并发 HashMap 扩容,这几个点加在一起就形成了 HashMap 的死循环。 前置…

Adding Conditional Control to Text-to-Image Diffusion Models——【代码复现】

官方实现代码地址:lllyasviel/ControlNet: Let us control diffusion models! (github.com) 一、前言 此项目的使用需要显存大于8G,训练自己的ControlNet或需要更大,因此请注意查看自身硬件是否符合。 在此之前请确保已经安装好python以及…

【UE Niagara学习笔记】05 - 喷射火焰顶部的蓝色火焰

在上一篇博客(【UE Niagara学习笔记】04 - 火焰喷射时的黑烟效果)的基础上继续实现在火焰喷射的起点位置生成蓝色火焰的效果。 目录 效果 步骤 1. 创建新的发射器 2. 减少粒子生成数量 3. 减小粒子初始大小 4. 减少粒子喷射距离 5. 减少粒子初始…

在Linux上搭建Maven仓库

目录 一、下载安装包二、安装maven三、修改配置文件settings.xml四、配置环境变量五、测试maven是否可用 一、下载安装包 我在这里为大家准备好了apache-maven-3.5.0-bin.tar.gz,百度网盘下载链接如下: 链接:https://pan.baidu.com/s/1bGun…

python编程使用selenium模拟登陆淘宝实例代码

selenium简介 selenium 是一个web的自动化测试工具,不少学习功能自动化的同学开始首选selenium ,相因为它相比QTP有诸多有点: * 免费,也不用再为破解QTP而大伤脑筋* 小巧,对于不同的语言它只是一个包而已&#xff0c…

AFL进阶教学——插桩、执行、覆盖率收集与反馈(解析)

AFL(American Fuzzy Lop)是一个面向安全的模糊测试工具,它使用编译时插桩技术和遗传算法,可以自动发现触发目标二进程程序的测试用例,从而大大提高测试代码的功能覆盖率。本文主要讲述AFL是如何实现插桩的,…

提升网络安全重要要素IP地址

在数字化时代,网络安全已经成为人们关注的焦点。本文将深入探讨网络安全与IP地址之间的紧密联系,以及IP地址在构建数字世界的前沿堡垒中的关键作用。 网络安全是当今数字社会中不可忽视的挑战之一。而IP地址,作为互联网通信的基础协议&#…