paddle(一)
一、概述
一个机器学习的框架,提供了深度学习需要的神经网络,激活函数等主要功能。
基础概念
Program
一次模型训练就是一个program,通过执行器执行,默认环境下是执行fluid.default_startup_program(),用户对计算的描述都将写入一段Program。Fluid 中的 Program 替代了传统框架中模型的概念,通过对顺序执行、条件选择和循环执行三种执行结构的支持,做到对任意复杂模型的描述。
import paddle.fluid as fluid import numpy as np data = fluid.layers.data(name="input8", shape=[-1, 32,32], dtype="float32") label = fluid.layers.data(name="label8", shape=[1], dtype="int") fc_out = fluid.layers.fc(input=data, size=2) predict = fluid.layers.softmax(input=fc_out) result=fluid.layers.auc(input=predict, label=label) place = fluid.CPUPlace() exe = fluid.Executor(place) exe.run(fluid.default_startup_program()) x = np.random.rand(3,32,32).astype("float32") y = np.array([1,0,1]) output= exe.run(feed={"input8": x,"label8": y}, fetch_list=[result[0]]) print(output)
Block 是高级语言中变量作用域的概念,在编程语言中,Block是一对大括号,其中包含局部变量定义和一系列指令或操作符。编程语言中的控制流结构 if-else 和 for 在深度学习中可以被等效为:
如上文所说,Fluid 中的 Block 描述了一组以顺序、选择或是循环执行的 Operator 以及 Operator 操作的对象:Tensor。
Operator定义了一些列操作包括数学操作,神经网络操作,张量操作等,封装在paddle.fluid.layers , paddle.fluid.nets。
ParamAttr用于设置一个op的参数。
import paddle.fluid as fluid import numpy as np x = fluid.layers.data(name='x', shape=[1], dtype='int64', lod_level=1) emb = fluid.layers.embedding(input=x, size=(128, 100)) # embedding_0.w_0 emb = fluid.layers.Print(emb) # Tensor[embedding_0.tmp_0] # default name fc_none = fluid.layers.fc(input=emb, size=1) # fc_0.w_0, fc_0.b_0 fc_none = fluid.layers.Print(fc_none) # Tensor[fc_0.tmp_1] fc_none1 = fluid.layers.fc(input=emb, size=1) # fc_1.w_0, fc_1.b_0 fc_none1 = fluid.layers.Print(fc_none1) # Tensor[fc_1.tmp_1] # name in ParamAttr w_param_attrs = fluid.ParamAttr(name="fc_weight", learning_rate=0.5, trainable=True) print(w_param_attrs.name) # fc_weight # name == 'my_fc' my_fc1 = fluid.layers.fc(input=emb, size=1, name='my_fc', param_attr=w_param_attrs) # fc_weight, my_fc.b_0 my_fc1 = fluid.layers.Print(my_fc1) # Tensor[my_fc.tmp_1] my_fc2 = fluid.layers.fc(input=emb, size=1, name='my_fc', param_attr=w_param_attrs) # fc_weight, my_fc.b_1 my_fc2 = fluid.layers.Print(my_fc2) # Tensor[my_fc.tmp_3] place = fluid.CPUPlace() x_data = np.array([[1],[2],[3]]).astype("int64") x_lodTensor = fluid.create_lod_tensor(x_data, [[1, 2]], place) exe = fluid.Executor(place) exe.run(fluid.default_startup_program()) ret = exe.run(feed={'x': x_lodTensor}, fetch_list=[fc_none, fc_none1, my_fc1, my_fc2], return_numpy=False)
二、神经网络
卷积层 conv2d,conv3d
参数:卷积需要依据滑动步长(stride)、填充长度(padding)、卷积核窗口大小(filter size)、分组数(groups)、扩张系数(dilation rate)来决定如何计算。groups最早在 AlexNet 中引入, 可以理解为将原始的卷积分为独立若干组卷积计算。
import paddle.fluid as fluid import numpy as np data = fluid.layers.data(name='data', shape=[3, 32, 32], dtype='float32') param_attr = fluid.ParamAttr(name='conv2d.weight', initializer=fluid.initializer.Xavier(uniform=False), learning_rate=0.001) res = fluid.layers.conv2d(input=data, num_filters=2, filter_size=3, act="relu", param_attr=param_attr) place = fluid.CPUPlace() exe = fluid.Executor(place) exe.run(fluid.default_startup_program()) x = np.random.rand(1, 3, 32, 32).astype("float32") output = exe.run(feed={"data": x}, fetch_list=[res]) print(output)
池化 pool2d,pool3d
池化的作用是对输入特征做下采样和降低过拟合。降低过拟合是减小输出大小的结果,它同样也减少了后续层中的参数的数量。
池化通常只需要将前一层的特征图作为输入,此外需要一些参数来确定池化具体的操作。在PaddlePaddle中我们同样通过设定池化的大小,方式,步长,是否是全局池化,是否使用cudnn,是否使用ceil函数计算输出等参数来选择具体池化的方式。 PaddlePaddle中有针对定长图像特征的二维(pool2d)、三维卷积(pool3d),RoI池化(roi_pool),以及针对序列的序列池化(sequence_pool),同时也有池化计算的反向过程,下面先介绍2D/3D池化,以及RoI池化,再来介绍序列池化。
数学操作 exp,tanh,sqrt,abs,ceil,floor,sin,cos,square,reduce,matmul,less_than,sum,equal
激活函数
激活函数将非线性的特性引入到神经网络当中。
relu, tanh, sigmoid, elu, relu6, pow, stanh, hard_sigmoid, swish, prelu, brelu, leaky_relu, soft_relu, thresholded_relu, maxout, logsigmoid, hard_shrink, softsign, softplus, tanh_shrink, softshrink, exp。
损失函数
square_error_cost,cross_entropy ,softmax_with_cross_entropy,sigmoid_cross_entropy_with_logits,nce , hsigmoid,rank_loss 和 margin_rank_loss。
数据的输入输出
fluid.layers.data 层构建网络,并通过 executor.run(feed=...) 的方式读入数据。数据读取和模型训练/预测的过程是同步进行的。
用户可通过 executor.run(fetch_list=[...], return_numpy=...) 的方式 fetch期望的输出变量,通过设置 return_numpy 参数设置是否将输出数据转为numpy array。 若 return_numpy 为 False ,则返回 LoDTensor 类型数据。
控制流
用于控制神经网络的执行过程
IfElse,While,Swith,DynamicRNN,staticRNN
import numpy as np import paddle.fluid as fluid x = fluid.layers.data(name='x', shape=[4, 1], dtype='float32', append_batch_size=False) y = fluid.layers.data(name='y', shape=[4, 1], dtype='float32', append_batch_size=False) x_d = np.array([[3], [1], [-2], [-3]]).astype(np.float32) y_d = np.zeros((4, 1)).astype(np.float32) # 比较x, y对元素的大小,输出cond, cond是shape为[4, 1],数据类型为bool的2-D tensor。 # 根据输入数据x_d, y_d,可以推断出cond中的数据为[[true], [true], [false], [false]] cond = fluid.layers.greater_than(x, y) # 同其他常见OP不同的是,该OP返回的ie是一个IfElse OP的对象 ie = fluid.layers.IfElse(cond) with ie.true_block(): # 在这个block中,根据cond条件,获取x中对应条件为true维度的数据,并减去10 out_1 = ie.input(x) out_1 = out_1 - 10 ie.output(out_1) with ie.false_block(): # 在这个block中,根据cond条件,获取x中对应条件为false维度的数据,并加上10 out_1 = ie.input(x) out_1 = out_1 + 10 ie.output(out_1) # 根据cond条件将两个block中处理后的数据进行合并,此处的output为输出,类型为List,List中的元素类型为Variable。 output = ie() # [array([[-7.], [-9.], [ 8.], [ 7.]], dtype=float32)] # 将输出List中的第一个Variable获取出来,并计算所有元素和 out = fluid.layers.reduce_sum(output[0]) exe = fluid.Executor(fluid.CPUPlace()) exe.run(fluid.default_startup_program()) res = exe.run(fluid.default_main_program(), feed={"x":x_d, "y":y_d}, fetch_list=[out]) print(res)
张量
assign,cast,concat,sums,argsort,argmax,argmin,ones,zeros,reverse