随机生成1000个浮点数(均值为5,标准差为1),并从这些生成的数字中随机再选择100个,对这100个数字进行四舍五入,在统计操作后各个数字出现的次数,使用'数目表示不同数字的出现次数,并按数字从小到大打印出来,统计程序运行时间
该回答引用GPT:
使用Python编写程序,随机生成1000个浮点数(均值为5,标准差为1),从这些生成的数字中随机再选择100个,对这100个数字进行四舍五入,统计每个数字出现的次数,并按数字从小到大打印出来,同时记录程序运行时间。
import random
import time
# 生成1000个浮点数(均值为5,标准差为1)
nums = [random.gauss(5, 1) for _ in range(1000)]
# 从这些生成的数字中随机再选择100个
sample_nums = random.sample(nums, 100)
# 对这100个数字进行四舍五入
round_nums = [round(num) for num in sample_nums]
# 统计每个数字出现的次数
count_dict = {}
for num in round_nums:
if num in count_dict:
count_dict[num] += 1
else:
count_dict[num] = 1
# 按数字从小到大打印出来
start_time = time.time()
for num in sorted(count_dict.keys()):
print(f'{num}: {count_dict[num]}')
end_time = time.time()
# 记录程序运行时间
print(f'程序运行时间:{end_time - start_time}s')
如还有疑问,可留言帮助解决。
现在,开发者的福音来了,飞桨近期开源了基于核心框架构建的大规模分类库(PLSC: PaddlePaddle Large Scale Classification),为用户提供了大规模分类任务从训练到部署的全流程解决方案。只需数行代码,即可实现千万类别分类的神经网络。并且,通过PLSC库提供的serving功能用户可以快速部署模型,提供一站式服务。
简单易用,五行代码实现千万类别分类神经网络
飞桨大规模分类库PLSC(以下简称PLSC)封装了大规模分类神经网络实现,提供简洁易用的高层API,用户通过五行代码即可实现千万类别分类神经网络。
(1) 安装飞桨
可以参考官网下载并安装飞桨。
(2) 安装PLSC
执行下面的命令安装PLSC。
pip install plsc
(3) 准备模型训练配置代码,保存为train.py文件。
使用PLSC组建分类神经网络主要包括下面三个步骤:
1. 从plsc包导入Entry类,Entry类封装PLSC所有API的接口类;
2. 实例化Entry类的对象;
3. 调用Entry类的train方法,开始训练过程。
默认情况下,该训练脚本使用的loss值计算方法为'dist_arcface',即将全连接层参数切分到多张GPU卡的模型并行方案,需要使用两张或以上的GPU卡。
from plsc import Entryif __name__ == "main": ins = Entry() ins.set_class_num(1000000) #设置分类类别数 ins.train()
(4) 启动训练任务
可以使用下面的命令行启动训练任务,其中selected_gpus参数用于指定训练中使用的GPU卡。
python -m paddle.distributed.launch \
--selected_gpus=0,1,2,3,4,5,6,7 \
train.py
PLSC库在多个数据集上可以取得SOTA的训练精度,下表列出PLSC库分别使用MS1M-ArcFace和CASIA数据集作为训练数据,在不同验证数据集上取得的精度。
备注:上述模型训练使用的loss_type为'dist_arcface'。更多关于ArcFace的内容请参考
ArcFace: Additive Angular Margin Loss for Deep Face Recognition
https://arxiv.org/abs/1801.07698
PLSC支持多机分布式训练。一方面,通过多机分布式训练可以将全连接层参数切分到更多的GPU卡,从而支持千万类别分类,并且飞桨大规模分类库理论上支持的分类类别数随着使用的GPU卡数的增加而增加。例如,单机8张V100 GPU配置下支持的最大分类类别数相比不使用PLSC扩大2.52倍。
另一方面,使用多机分布式训练可以有效提升训练速度。
通过下面几行命令即可启动多机分布式训练。其中,cluster_node_ips参数用于指定所有训练节点的ip地址列表,node_ip参数用于指定当前训练节点的ip地址。
python -m paddle.distributed.launch \
--cluster_node_ips="127.0.0.1,127.0.0.2" \
--node_ip="127.0.0.1" \
--selected_gpus=0,1,2,3,4,5,6,7 \
train.py
下图给出使用不同数量的节点时的训练速度(吞吐)。实验中使用的训练数据集为MS1M-ArcFace,分类类别数为85742,每个节点配备8张NVIDIA V100 GPUs,backbone模型为ResNet50。如图所示,使用飞桨大规模分类库可以取得近似线性的加速比。
用户完成分类神经网络训练后,通常要基于得到的预训练模型部署预测服务。通过飞桨大规模分类库提供的serving功能可实现快速部署。
飞桨大规模分类库提供支持预测服务部署的serving端和client端。serving端基于飞桨服务器端部署库Paddle Serving开发,使用serving端功能可以基于预训练模型快速部署预测服务。client端则提供了和serving端的交互功能,用户通过client端提交查询请求并获取预测结果。只需三步即可完成部署。
(1) 安装serving端和client端。
pip install plsc-serving ujson
(2) 通过下面的脚本部署serving端:
from plsc_serving.run import PLSCServerfs = PLSCServer()# 设定使用的模型路径fs.with_model(model_path = '/XXX/XXX')# gpu_index指定使用的gpu,port指定使用的端口fs.run(gpu_index = 0, port = 8010)
(3) 通过下面的脚本使用client端功能:
from face_service import FaceService
with open('./data/00000000.jpg', 'rb') as f:
image = f.read()
fc = FaceService()
# 添加server端连接
fc.connect('127.0.0.1:8010')
#调用server端预测
result = fc.encode([image])
print(result[0])
fc.close()
单机8张Nvidia Tesla v100 GPU配置下,混合精度比常规单精度训练速度提升42%。
使用混合精度训练可以提升训练的速度,同时减少训练使用的显存开销。开启混合精度训练方法如下:
from plsc import Entry
def main(): ins = Entry() ins.set_mixed_precision(True) ins.train()if __name__ == "__main__":main()
在单机8张Nvidia Tesla v100 GPU配置下,对比resnet50模型单精度训练和混合精度训练的效果,混合精度训练速度可提升42%:
关于混合精度训练的内容请参考:
https://arxiv.org/abs/1710.03740
实际业务中,一种常见的数据存储格式是将图像数据编码为base64格式,训练数据文件的每一行存储一张base64格式编码的图像数据和该图像的标签,并通常以制表符('\t')分隔图像数据和图像标签。
神经网络训练过程中,通常需要对训练数据做全局shuffle。此外,需要切分训练数据,确保每张GPU卡使用相同数量的训练数据。对Base64格式的数据做全局shuffle的开销较大,若在训练过程中执行全局shuffle,会严重影响训练速度。
飞桨大规模分类库内置Base64格式数据预处理工具,可以对训练数据做全局shuffle,并将训练数据均分到多个数据文件,确保数据文件的数量和训练中使用的GPU卡数相同,且每个数据文档包含相同数量的训练数据。训练效率显著提升。
我们有时需要基于预训练模型做fine-tuning这种场景下,fine-tuning阶段的训练GPU卡数和预训练阶段使用的GPU卡数可能不同,尤其是当预训练和fine-tuning是分别由不同的组织执行时。考虑全连接层参数是根据使用的GPU卡数切分的这一情形,当fine-tuning阶段和预训练阶段使用不同的GPU卡数时,在加载模型参数前,用户需要重构模型参数,以适应fine-tuning阶段的GPU卡数。为了简化用户操作,飞桨大规模分类库提供了自动化的模型参数重构功能。当fine-tuning阶段使用的GPU卡数和预训练阶段不同时,飞桨大规模分类库在加载预训练模型参数时会自动根据fine-tuning阶段使用的GPU卡数重构预训练模型参数,以适应fine-tuning阶段的GPU卡数。