Giter VIP home page Giter VIP logo

fastnn's Introduction

FastNN模型库(English version)

1. 简介

FastNN(Fast Neural Networks)是一个基于PAISoar实现分布式训练的基础算法库,当前FastNN只支持计算机视觉的部分经典算法,后续会逐步开放更多的先进模型。如需在机器学习平台PAI(Platform of Artificial Intelligence)试用FastNN分布式训练服务,可访问PAI平台官方主页开通,即可在PAI Studio或DSW-notebook上提交分布式机器学习任务,具体操作流程可参考TensorFlow组件使用手册FastNN-on-PAI-Studio使用手册及“快速试用”。

FastNN功能简介如下:

  • 模型支持

    a.部分经典计算机视觉模型,包括inception、resnet、mobilenet、vgg、alexnet、nasnet等;

    b.后续会增加计算机视觉、自然语言处理等领域的其他先进模型;

  • 数据并行训练(需要开通机器学习平台PAI服务,在PAI Studio或DSW-notebook试用)

    a.单机多卡

    b.多机多卡

  • 半精度训练

  • 模型训练类型

    a.模型预训练

    b.模型调优:默认只重载可训练的变量,如需对checkpoint选择性重载,可修改images/utils/misc_utils.py的get_assigment_map_from_checkpoint函数

我们选择ResNet-v1-50模型上在阿里云集群机器(GPU卡型为P100)上进行了大规模测试。从测试数据来看,PAISoar加速效果都非常理想,都能够取得接近线性scale的加速效果。

resnet_v1_50

2. 快速试用

本章节旨在给出FastNN库中已有模型的试用说明,具体试用流程分为两步:

  • 数据准备:包括本地数据准备和PAI Web数据准备;
  • 训练启动:包括本地执行脚本的编辑和PAI Web任务参数设置。

2.1 数据准备

为了方便试用FastNN算法库images目录下的计算机视觉模型,我们准备好了一些公开数据集或相应下载及格式转换脚本,包括图像数据cifar10、mnist以及flowers。

2.1.1 本地数据

借鉴TF-Slim库中提供数据下载及格式转换脚本(images/datasets/download_and_convert_data.py),以cifar10数据为例,脚本如下:

DATA_DIR=/tmp/data/cifar10
python download_and_convert_data.py \
	--dataset_name=cifar10 \
	--dataset_dir="${DATA_DIR}"

脚本执行完毕后,在/tmp/data/cifar10目录下有以下tfrecord文件:

$ ls ${DATA_DIR}
cifar10_train.tfrecord
cifar10_test.tfrecord
labels.txt

2.1.2 OSS数据

为了方便在PAI平台试用FastNN,cifar10、mnist、flowers数据已下载并转换为tfrecord后存储在公开oss上,可通过阿里机器学习平台PAI的“读取文件数据”组件访问。存储oss路径如下:

数据集 分类数 训练集 测试集 存储路径
mnist 10 3320 350 北京:oss://pai-online-beijing.oss-cn-beijing-internal.aliyuncs.com/fastnn-data/mnist/ 上海:oss://pai-online.oss-cn-shanghai-internal.aliyuncs.com/fastnn-data/mnist/
cifar10 10 50000 10000 北京:oss://pai-online-beijing.oss-cn-beijing-internal.aliyuncs.com/fastnn-data/cifar10/ 上海:oss://pai-online.oss-cn-shanghai-internal.aliyuncs.com/fastnn-data/cifar10/
flowers 5 60000 10000 北京:oss://pai-online-beijing.oss-cn-beijing-internal.aliyuncs.com/fastnn-data/flowers/ 上海:oss://pai-online.oss-cn-shanghai-internal.aliyuncs.com/fastnn-data/flowers/

2.2 训练启动

FastNN模型库主文件为train_image_classifiers.py,其中训练脚本最常用的有以下六个参数:

  • task_type:字符串类型。取值为“pretrain”、“finetune”之一,指出任务类型为模型预训练或模型调优;
  • enable_paisoar:布尔类型。默认True,本地试用时需置为False。
  • dataset_name:字符串类型。默认mock,指出训练数据解析文件,如images/datasets目录下的cifar10.py、flowers.py、mnist.py文件。
  • train_files:字符串类型。默认None,以“,”为分隔符表示所有训练文件。
  • dataset_dir:字符串类型。默认None,指出训练数据路径。
  • model_name:字符串类型。默认inception_resnet_v2,指明模型名称,包括resnet_v1_50、vgg、inception等,详见images/models目录下的所有模型。 特别地,当task_type=finetune时,需额外指定model_dir、ckpt_file_name参数,分别指明模型checkpoint路径及checkpoint文件名。 下面分为“本地试用”、“PAI平台运行”两个章节详述试用方法。

2.2.1 本地试用

本地不支持PAISoar功能,即不支持分布式训练。若只需要本地试用FastNN模型库的单机单卡场景下的训练,需要在执行脚本中设置用户参数enable_paisoar=False,另外有以下软件需求:

软件 版本
python >=2.7.6
TensorFlow >=1.8
CUDA >= 9.0
cuDNN >= 7.0

下面以Resnet-v1-50模型在cifar10数据训练为例梳理试用流程。

2.2.1.1 预训练脚本
DATASET_DIR=/tmp/data/cifar10
TRAIN_FILES=cifar10_train.tfrecord
python train_image_classifiers.py \
	--task_type=pretrain \ 
	--enable_paisoar=False \
	--dataset_name=cifar10 \
	--train_files="${TRAIN_FILES}" \
	--dataset_dir="${DATASET_DIR}" \
	--model_name=resnet_v1_50
2.2.1.2 模型调优脚本
MODEL_DIR=/path/to/model_ckpt
CKPT_FILE_NAME=resnet_v1_50.ckpt
DATASET_DIR=/tmp/data/cifar10
TRAIN_FILES=cifar10_train.tfrecord
python train_image_classifiers.py \
	--task_type=finetune \
	--enable_paisoar=False \
	--dataset_name=cifar10 \
	--train_files="${TRAIN_FILES}" \
	--dataset_dir="${DATASET_DIR}" \
	--model_name=resnet_v1_50 \
	--model_dir="${MODEL_DIR}" \
	--ckpt_file_name="${CKPT_FILE_NAME}"

2.2.2 PAI平台运行

机器学习平台PAI目前支持的框架包括 TensorFlow(兼容开源TF1.4、1.8版本),MXNet 0.9.5, Caffe rc3。TensorFlow 和 MXNet 支持用户自己编写的 Python 代码, Caffe 支持用户自定义网络文件。其中tensorflow框架内置PAISoar功能,支持单机多卡、多机多卡的分布式训练。如需在PAI平台试用FastNN,请参考FastNN-On-PAI文档。

3. 用户参数指南

FastNN库综合各个模型及PAISoar框架的需求,统一将可能用到的超参定义在flags.py文件(支持用户自定义新超参)中,参数可分为以下六大类:

  • 数据集参数:确定训练集的基本属性,如训练集存储路径dataset_dir;
  • 数据预处理参数:数据预处理函数及dataset pipeline相关参数;
  • 模型参数:模型训练基本超參,包括model_name、batch_size等;
  • 学习率参数:学习率及其相关调优参数;
  • 优化器参数:优化器及其相关参数;
  • 日志参数:关于输出日志的参数;
  • 性能调优参数:混合精度等其他调优参数。

3.1 数据集参数

#名称 #类型 #描述
dataset_name string 指定输入数据名称,默认mock
dataset_dir string 指定本地输入数据集路径,默认为None
num_sample_per_epoch integer 数据集总样本数
num_classes integer 数据分类数,默认100
train_files string 训练数据文件名,文件间分隔符为逗号,如"0.tfrecord,1.tfrecord"

3.2 数据预处理参数

#名称 #类型 #描述
preprocessing_name string 预处理方法名,默认None
shuffle_buffer_size integer 样本粒度进行shuffle的buffer大小,默认1024
num_parallel_batches integer 与batch_size乘积为map_and_batch的并行线程数,默认8
prefetch_buffer_size integer 预取N个batch数据,默认N=32
num_preprocessing_threads integer 预取线程数,默认为16
datasets_use_caching bool 以内存为开销进行输入数据的压缩缓存

3.3 模型参数

#名称 #类型 #描述
task_type string 支持模型预训练(pretrain)和模型调优(finetune), 默认取值pretrain
model_name string 指定模型名称,默认inception_resnet_v2
num_epochs integer 训练epochs,默认100
weight_decay float 模型权重衰减系数, 默认0.00004
max_gradient_norm float 根据全局归一化值进行梯度裁剪, 默认取值为None,不进行梯度裁剪
batch_size integer 批大小, 默认32
model_dir string checkpoin所在路径,默认为None
ckpt_file_name string checkpoint文件名,默认为None

3.4 学习率参数

#名称 #类型 #描述
warmup_steps integer 逆衰减学习率的迭代数. 默认0.
warmup_scheme string 学习率逆衰减的方式. 可选:'t2t' 指Tensor2Tensor, 初始化为指定学习率的1/100,然后exponentiate逆衰减到指定学习率为止
decay_scheme string 学习率衰减的方式. 可选:1、luong234: 在2/3的总迭代数之后, 开始4次衰减,衰减系数为1/2; 2、luong5: 在1/2的总迭代数之后, 开始5次衰减,衰减系数为1/2; 3、luong10: 在1/2的总迭代数之后, 开始10次衰减,衰减系数为1/2.
learning_rate_decay_factor float 学习率衰减系数, 默认0.94
learning_rate_decay_type string 学习率衰减类型. 可选["fixed", "exponential", "polynomial"], 默认exponential
learning_rate float 学习率初始值,默认0.01
end_learning_rate float 衰减时学习率值的下限,默认0.0001

3.5 优化器参数

#名称 #类型 #描述
optimizer string 优化器名称, 取值["adadelta", "adagrad", "adam", "ftrl", "momentum", "sgd","rmsprop"]. 默认"rmsprop"
adadelta_rho float adadelta的衰减系数, default 0.95, specially for Adadelta
adagrad_initial_accumulator_value float AdaGrad积累器的起始值, 默认0.1, Adagrada优化器专用参数
adam_beta1 float 一次动量预测的指数衰减率, 默认0.9, Adam优化器专用参数
adam_beta2 float 二次动量预测的指数衰减率, 默认0.999, Adam优化器专用参数
opt_epsilon float 优化器偏置值, 默认1.0, Adam优化器专用参数
ftrl_learning_rate_power float 学习率参数的幂参数, 默认-0.5, Ftrl优化器专用参数
ftrl_initial_accumulator_value float FTRL积累器的起始, 默认0.1, Ftrl优化器专用参数
ftrl_l1 float FTRL l1正则项, 默认0.0, Ftrl优化器专用参数
ftrl_l2 float FTRL l2正则项, 默认0.0, Ftrl优化器专用参数
momentum float MomentumOptimizer的动量参数, 默认0.9, Momentum优化器专用参数
rmsprop_momentum float RMSPropOptimizer的动量参数, 默认0.9
rmsprop_decay float RMSProp的衰减系数, 默认0.9

3.6 日志参数

#名称 #类型 #描述
stop_at_step integer 训练总迭代数, 默认100
log_loss_every_n_iters integer 打印loss信息的迭代频率, 默认10
profile_every_n_iters integer 打印timeline的迭代频率, 默认0
profile_at_task integer 输出timeline的机器对应索引, 默认0,对应chief worker
log_device_placement bool 是否输出device placement信息, 默认False
print_model_statistics bool 是否输出可训练变量信息, 默认false
hooks string 指定训练hooks, 默认"StopAtStepHook,ProfilerHook,LoggingTensorHook,CheckpointSaverHook"

3.7 性能调优参数

#名称 #类型 #描述
use_fp16 bool 是否进行半精度训练, 默认True
loss_scale float 训练中loss值scale的系数, 默认1.0
enable_paisoar bool 是否使用paisoar,默认True.
protocol string 默认grpc.rdma集群可用“grpc+verbs”提升数据存取效率

4. 如何实现自定义需求

若已有模型等实现满足不了需求,可通过继承dataset/models/preprocessing接口进一步开发。在此之前需要了解fastnn库的基本流程(以images为例,代码入口文件为train_image_classifiers.py),整体代码架构流程如下:

# 初始化models中某模型得到network_fn,并可能返回输入参数train_image_size;
    network_fn = nets_factory.get_network_fn(
            FLAGS.model_name,
            num_classes=FLAGS.num_classes,
            weight_decay=FLAGS.weight_decay,
            is_training=(FLAGS.task_type in ['pretrain', 'finetune']))
# 若用户指定参数FLAGS.preprocessing_name,则初始化数据预处理函数得到preprocess_fn;
    preprocessing_fn = preprocessing_factory.get_preprocessing(
                FLAGS.model_name or FLAGS.preprocessing_name,
                is_training=(FLAGS.task_type in ['pretrain', 'finetune']))
# 用户指定dataset_name,选择正确的tfrecord格式,同步调用preprocess_fn解析数据集得到数据dataset_iterator;
    dataset_iterator = dataset_factory.get_dataset_iterator(FLAGS.dataset_name,
                                                            train_image_size,
                                                            preprocessing_fn,
                                                            data_sources,
# 根据network_fn、dataset_iterator,定义计算loss的函数loss_fn:
    def loss_fn():
    	with tf.device('/cpu:0'):
      		images, labels = dataset_iterator.get_next()
        logits, end_points = network_fn(images)
        loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=tf.cast(logits, tf.float32), weights=1.0)
        if 'AuxLogits' in end_points:
          loss += tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=tf.cast(end_points['AuxLogits'], tf.float32), weights=0.4)
        return loss
# 调用PAI-Soar API封装loss_fn、tf原生optimizer
    opt = paisoar.ReplicatedVarsOptimizer(optimizer, clip_norm=FLAGS.max_gradient_norm)
    loss = optimizer.compute_loss(loss_fn, loss_scale=FLAGS.loss_scale)
# 依据opt和loss形式化定义training tensor
    train_op = opt.minimize(loss, global_step=global_step)

因此,为了进一步开发新需求,开发者需要了解dataset、models、preprocessing三个接口的使用。

4.1 增加数据集API

FastNN库已实现支持读取tfrecord格式的数据,并基于TFRecordDataset接口实现dataset pipeline以供模型训练试用,几乎可掩盖数据预处理时间。另外,目前实现逻辑在数据分片实现不够精细,要求用户在数据准备时尽量保证数据能平均分配到每台机器,即:

  • 每个tfreocrd文件的样本数量几乎一样;
  • 每个worker处理的tfrecord文件数几乎一致。

若数据格式同为tfrecord,可参考datasets目录下cifar10/mnist/flowers各文件等,以cifar10数据为例:

  • 假设cifar10数据的key_to_features格式为:
features={
        'image/encoded': tf.FixedLenFeature((), tf.string, default_value=''),
        'image/format': tf.FixedLenFeature((), tf.string, default_value='png'),
        'image/class/label': tf.FixedLenFeature(
          [], tf.int64, default_value=tf.zeros([], dtype=tf.int64)),
}
  • 在datasets目录下创建数据解析文件cifar10.py,并编辑内容示例如下:
"""Provides data for the Cifar10 dataset.
The dataset scripts used to create the dataset can be found at:
utils/scripts/data/download_and_convert_cifar10.py
"""
from __future__ import division
from __future__ import print_function

import tensorflow as tf
"""Expect func_name is ‘parse_fn’
"""
def parse_fn(example):
  with tf.device("/cpu:0"):
    features = tf.parse_single_example(
      example,
      features={
        'image/encoded': tf.FixedLenFeature((), tf.string, default_value=''),
        'image/format': tf.FixedLenFeature((), tf.string, default_value='png'),
        'image/class/label': tf.FixedLenFeature(
          [], tf.int64, default_value=tf.zeros([], dtype=tf.int64)),
      }
    )
    image = tf.image.decode_jpeg(features['image/encoded'], channels=3)
    label = features['image/class/label']
    return image, label
  • 在datasets/dataset_factory.py补足dataset_map
from datasets import cifar10
datasets_map = {
    'cifar10': cifar10,
}
  • 执行任务脚本时,可通过指定参数dataset_name=cifar10和train_files=cifar10_train.tfrecord使用cifar10数据进行模型训练。

如需读取其他数据格式,需要自行实现dataset pipeline构建逻辑(参考utils/dataset_utils.py)。

4.2 增加模型API

开发者如需完成新模型的开发,参考images/models目录下各模型代码,有以下要求:

  • 单机单卡代码跑通,并能正常收敛;
  • 单机单卡代码暴露出输入/输出接口,输入属性包括Type/Shape等对应于preprocessing输出属性,以及输出属性包括Type/Shape等对应数据集label的属性;
  • 没有实现任何分布式逻辑。

datasets、preprocessing逻辑在仅开发新模型时可直接复用,关于模型需要做以下操作:

  • models/model_factory.py中models_map和arg_scopes_map增加新模型的定义,可参考model_factory.py中对已有模型的定义;
  • 正常收敛的新模型代码导入到project的images/models目录即可。

4.3 增加数据预处理API

开发者如需自定义新的数据预处理流程,有以下要求:

  • 暴露出输入/输出接口,输入的属性(包括Type/Shape等)对应于dataset输出的属性,以及输出属性(包括Type/Shape等)对应算法模型输入的属性;

具体步骤如下:

  • preprocessing_factory.py中preprocessing_fn_map增加新的预处理函数的定义;

  • 预处理函数代码导入到project的images/preprocessing下即可,可参考已有实现,如inception_preprocessing.py等

4.4 增加损失函数API

FastNN库images的主文件train_image_classifiers中默认使用tf.losses.sparse_softmax_cross_entropy构造loss_fn,若需要构造自定义的损失函数,直接修改主文件中的loss_fn。值得注意的是,使用PAISoar做分布式时,loss_fn要求只返回loss,若需返回自定义参数,可通过全局参数传输,可参考主文件中loss_fn返回accuracy。

5. 总结与致谢

在本手册里面我们简单的介绍了阿里机器学习平台PAI在FastNN算法库的一些工作。我们深信这些工作能够帮助算法同学快速的进行模型的迭代、支持更大规模的样本训练和更大空间上的模型创新的想象力。接下来PAI还会持续的在分布式上进行更多的创新工作,包括更优性能的模型并行、通信梯度压缩等。

FastNN是基于阿里机器学习平台PAI的PAISoar组件实现分布式训练的基础算法库,包含计算机视觉领域目前state-of-art的经典模型,后续会支持NLP等领域的模型,包括Bert、XLNet、GPT-2、NMT等。目前FastNN聚焦于模型训练分布式性能的加速,其中images模型直接引用TensorFlow-Slim image classification model library的实现。感谢TensorFlow社区贡献计算机视觉领域经典模型的开源实现,如有不妥之处,敬请指正。

fastnn's People

Contributors

charles9304 avatar adoda avatar alibaba-oss avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.