JAX(一)

JAX(一),第1张

> JAX 是一个用于高性能数值计算的 Python 库,特别为机器学习领域的高性能计算设计。它的 API 基于 Numpy 构建,包含丰富的数值计算与科学计算函数。JAX其实是 TensorFlow 的一个简化库,结合 Autograd 和 XLA,可以支持部分 TensorFlow 的功能,但是比 TensorFlow 更加简洁易用。

> Python 和 Numpy 的广泛使用,使得 JAX 十分简洁、灵活、易于上手,学习成本也比较低。除了 Numpy 的 API 外,JAX 还包含一系列可拓展、可组合的系统功能,有力地支持了机器学习研究。这些功能特性主要包括:

- 可差分 :基于梯度的优化方法在机器学习领域具有十分重要的作用。JAX 可通过grad、hessian、jacfwd 和 jacrev 等函数转换,原生支持任意数值函数的前向和反向模式的自动微分。

- 向量化 :在机器学习中,通常需要在大规模的数据上运行相同的函数,例如计算整个批次的损失或每个样本的损失等。JAX 通过 vmap 变换提供了自动矢量化算法,大大简化了这种类型的计算,这使得研究人员在处理新算法时无需再去处理批量化的问题。JAX 同时还可以通过 pmap 转换支持大规模的数据并行,从而优雅地将单个处理器无法处理的大数据进行处理。

- JIT编译 :XLA (Accelerated Linear Algebra, 加速线性代数) 被用于 JIT 即时编译,在 GPU 和云 TPU 加速上执行 JAX 程序。JIT 编译与 JAX 的 API (与 Numpy 一致的数据函数) 为研发人员提供了便捷接入高性能计算的可能,无需特别的经验就能将计算运行在多个加速上。

Tensor-flow 默认使用一个gpu进行运算(如果有gpu的话)。具体的调用会在程序里。如果要使用多gpu的话要相应修改程序。

至于哪部份会放到gpu上跑,一般来说是model training的部分,因为这部分程序是computation intense。你可以把其他部分放到gpu上运行,但是由于cpu-gpu的通信时间较长,会使得程序执行的更慢。

TensorFlow支持同步训练和异步训练两种模型训练方式。

异步训练

异步训练即TensorFlow上每个节点上的任务为独立训练方式,不需要执行协调 *** 作,如下图所示:

同步训练

同步训练为TensorFlow上每个节点上的任务需要读入共享参数,执行并行化的梯度计算,然后将所有共享参数进行合并,如下图所示:

这篇文章主要是记录一下神经网络的参数量大致估算方法,计算过程利用的是mobilenet-v2来举例说明,如果对mobilenet-v2不太了解,可以参考文章 mobilenet-v1和mobilenet-v2详解 。

假设输入feature(如果是第一层就是了)的维度为

经过卷积后输出的feature的维度为

对于普通卷积来说,假设卷积的kernel大小为 ,该层卷积的参数量为

注意:因为现有的很多网络,卷积后都会跟上BN *** 作,所以一般卷积都不会加bias,所以这里都假设无bias的情况,mobilenet-v2里面的卷积是没有的

对于mobilenet来说是一个比较轻量级的网络,主要原因是利用了depthwise conv *** 作。对于depthwise conv来说,经过该类卷积后,会有 ,也就是卷积的通道数和输入通道数是一样的。这时,该卷积的参数量为

注意:拿TensorFlow来说,里面有个接口 tfnndepthwise_conv2d(

input, filter, strides, padding, rate=None, name=None, data_format=None,

dilations=None

) ,这个接口的输入filter参数包含一个叫channel_multiplier,这个参数可以使得 。上述说的是原始的depthwise( ),也是mobilenet里面使用的

这里的一层对应上表每一行

其中表格里的blockneck是一个函数,实现如下:

还要补充说明的是

在计算交叉熵之前,通常要用到softmax层来计算结果的概率分布。因为softmax层并不会改变最终的分类结果(排序),所以,tensorflow将softmax层与交叉熵函数进行封装,形成一个函数方便计算:tfnnsoftmax_cross_entropy_with_logits(logits= , labels=)。

为了加速计算过程,针对只有一个正确答案(例如MNIST识别)的分类问题,tensorflow提供了tfnnsparse_softmax_cross_entropy_with_logits(logits= , labels=)。

两个函数虽然功能类似,但是其参数labels有明显区别。tfnnsoftmax_cross_entropy_with_logits()中的logits和labels的shape都是[batch_size, num_classes],而tfnnsparse_softmax_cross_entropy_with_logits()中的labels是稀疏表示的,是 [0,num_classes)中的一个数值,代表正确分类结果。即sparse_softmax_cross_entropy_with_logits 直接用标签计算交叉熵,而 softmax_cross_entropy_with_logits 是标签的onehot向量参与计算。softmax_cross_entropy_with_logits 的 labels 是 sparse_softmax_cross_entropy_with_logits 的 labels 的一个独热版本(one hot version)。

PS:交叉熵是的log是ln

tensorflow添加自定义的auc计算operator

tensorflow可以很方便的添加用户自定义的operator(如果不添加也可以采用sklearn的auc计算函数或者自己写一个 但是会在python执行,这里希望在graph中也就是c++端执行这个计算)

这里根据工作需要添加一个计算auc的operator,只给出最简单实现,后续高级功能还是参考官方wiki

注意tensorflow现在和最初的官方wiki有变化,原wiki貌似是需要重新bazel编译整个tensorflow,然后使用比如tfuser_opauc这样。

目前wiki给出的方式>=060版本,采用plug-in的方式,更加灵活可以直接用g++编译一个so载入,解耦合,省去了编译tensorflow过程,即插即用。

首先auc的operator计算的文件

tensorflow/core/user_ops/auccc

/ Copyright 2015 Google Inc All Rights Reserved

Licensed under the Apache License, Version 20 (the "License");

you may not use this file except in compliance with the License

You may obtain a copy of the License at

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

==============================================================================/

// An auc Op

#include "tensorflow/core/framework/oph"

#include "tensorflow/core/framework/op_kernelh"

using namespace tensorflow;

using std::vector;

//@TODO add weight as optional input

REGISTER_OP("Auc")

Input("predicts: T1")

Input("labels: T2")

Output("z: float")

Attr("T1: {float, double}")

Attr("T2: {float, double}")

//Attr("T1: {float, double}")

//Attr("T2: {int32, int64}")

SetIsCommutative()

Doc(R"doc(

Given preidicts and labels output it's auc

)doc");

class AucOp : public OpKernel {

public:

explicit AucOp(OpKernelConstruction context) : OpKernel(context) {}

template<typename ValueVec>

void index_sort(const ValueVec& valueVec, vector<int>& indexVec)

{

indexVecresize(valueVecsize());

for (size_t i = 0; i < indexVecsize(); i++)

{

indexVec[i] = i;

}

std::sort(indexVecbegin(), indexVecend(),

[&valueVec](const int l, const int r) { return valueVec(l) > valueVec(r); });

}

void Compute(OpKernelContext context) override {

// Grab the input tensor

const Tensor& predicts_tensor = context->input(0);

const Tensor& labels_tensor = context->input(1);

auto predicts = predicts_tensorflat<float>(); //输入能接受float double那么这里如何都处理

auto labels = labels_tensorflat<float>();

vector<int> indexes;

index_sort(predicts, indexes);

typedef float Float;

Float oldFalsePos = 0;

Float oldTruePos = 0;

Float falsePos = 0;

Float truePos = 0;

Float oldOut = std::numeric_limits<Float>::infinity();

Float result = 0;

for (size_t i = 0; i < indexessize(); i++)

{

int index = indexes[i];

Float label = labels(index);

Float prediction = predicts(index);

Float weight = 10;

//Pval3(label, output, weight);

if (prediction != oldOut) //存在相同值得情况是特殊处理的

{

result += 05 (oldTruePos + truePos) (falsePos - oldFalsePos);

oldOut = prediction;

oldFalsePos = falsePos;

oldTruePos = truePos;

}

if (label > 0)

truePos += weight;

else

falsePos += weight;

}

result += 05 (oldTruePos + truePos) (falsePos - oldFalsePos);

Float AUC = result / (truePos falsePos);

// Create an output tensor

Tensor output_tensor = NULL;

TensorShape output_shape;

OP_REQUIRES_OK(context, context->allocate_output(0, output_shape, &output_tensor));

output_tensor->scalar<float>()() = AUC;

}

};

REGISTER_KERNEL_BUILDER(Name("Auc")Device(DEVICE_CPU), AucOp);

编译:

$cat gen-sosh

TF_INC=$(python -c 'import tensorflow as tf; print(tfsysconfigget_include())')

TF_LIB=$(python -c 'import tensorflow as tf; print(tfsysconfigget_lib())')

i=$1

o=${i/cc/so}

g++ -std=c++11 -shared $i -o $o -I $TF_INC -l tensorflow_framework -L $TF_LIB -fPIC -Wl,-rpath $TF_LIB

$sh gen-sosh auccc

会生成aucso

使用的时候

auc_module = tfload_op_library('aucso')

#auc = tfuser_opsauc #060之前的tensorflow 自定义op方式

auc = auc_moduleauc

evaluate_op = auc(py_x, Y) #py_x is predicts, Y is labels

定义一个稀疏tensor。

将一个稀疏tensor转换成稠密tensor。

计算ctc_loss。

主要参数1:labels: int32 SparseTensor 是数据的真实标签,一般是先用sparse_placeholder(),然后在session中feed训练数据batch_y。batch_y为 SparseTensor 利用sparse_tuple_from(y)函数计算得到。

sparse_tuple_from(y)函数的输入是在train_y中随机选择大小为 batch_size 的数据,输出是一个(indices, values, shape)形式的三元组。

主要参数2:inputs:是三维 float Tensor logits是网络向前传播inference计算的结果。形状为[max_time_step, batch_size, num_classes]这里的num_classes是中文字典的大小,及992个汉字加1个空白,所以num_classes=993。输入图像经过卷积之后的大小为[batch_size, 11, 1, 512],max_time_step=512,是通道数,可以看作是512个特征序列。

主要参数3:sequence_length:一维 int32 向量注意是向量,不是 Tensor !!!长度为batch_size(批处理大小),值为max_len(ctc的最大输出长度,这个长度是自己定义的!合理即可!)的可以按照下面的方式定义。

占位符。在session中feed训练数据。

以上就是关于JAX(一)全部的内容,包括:JAX(一)、安装了GPU enable的Tensorflow,就是自动调用cuda进行计算的吗、TensorFlow 训练模型等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9613897.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-30
下一篇2023-04-30

发表评论

登录后才能评论

评论列表(0条)

    保存