从python基础重新入门视频记录到现在整整三个月,这三个月真正地去了解了python另一个主要使用tensorflow,终于算是入一点门了,最初的python入门视频说这部分入门以后再做一个视频记录一下,现在就可以开始了。
这三个月主要有三个阶段吧,
第一个阶段认识tensorflow基本概念,重点有张量、计算图(静态计算图/动态计算图)、自动微分机制,其实看过之后还是似懂非懂,算是了解是什么,内部原理还不明白,内容详见1。
第二个阶段初识tensorflow如何构建模型,这个过程主要是看各种教程去了解tensorflow构建模型的各个过程,这个时间各个部分比较碎片,不太有整体概念。
有两个教程比较推荐:
一是:30天吃掉那只TensorFlow2.(https://www.kesci.com/home/column/5d8ef3c3037db3002d3aa3a0)
二是:简单粗暴 TensorFlow 2 (https://tf.wiki/zh_hans/)
三是:Keras中文文档(https://keras.io/zh/layers/embeddings/)
现在想来还是应该动手实现印象和理解比较深刻,不动手写不知道自己可以写出多少bug。。。
这部分的每一个细节都应该吃透。
1、数据读取,数据管道
使用 tf.data API 可以构建数据输入管道,在训练的过程中分批逐渐读入,轻松处理大量的数据,不同的数据格式,以及不同的数据转换。
2、特征列
使用特征列可以将类别特征转换为one-hot编码特征,将连续特征构建分桶特征,以及对多个特征生成交叉特征等等。
要创建特征列,请调用 tf.feature_column 模块的函数。所有九个函数都会返回一个 Categorical-Column 或一个Dense-Column 对象,所有的Catogorical Column类型最终都要通过indicator_column转换成Dense Column类型才能传入模型!
3、激活函数
在模型中使用:
model.add(layers.Dense(32,input_shape=(None,16),activation=tf.nn.relu))#通过activation参数指定
(1)Sigmoid又叫作 Logistic 激活函数,它将实数值压缩进 0 到 1 的区间内,还可以在预测概率的输出层中使用。该函数将大的负数转换成 0,将大的正数转换成 1。
sigmoid3个缺点:
梯度消失
不以0为中心
指数函数计算代价高
下一个要讨论的非线性激活函数解决了 Sigmoid 函数中值域期望不为 0 的问题。
tanh函数
在实践中,Tanh 函数的使用优先性高于 Sigmoid 函数。负数输入被当作负值,零输入值的映射接近零,正数输入被当作正值。唯一的缺点是:
1. Tanh 函数也会有梯度消失的问题,因此在饱和时也会「杀死」梯度。
为了解决梯度消失问题,我们来讨论另一个非线性激活函数——修正线性单元(rectified linear unit,ReLU),该函数明显优于前面两个函数,是现在使用最广泛的函数。
relu
当输入 x<0 时,输出为 0,当 x> 0 时,输出为 x。该激活函数使网络更快速地收敛。它不会饱和,即它可以对抗梯度消失问题,至少在正区域(x> 0 时)可以这样,因此神经元至少在一半区域中不会把所有零进行反向传播。由于使用了简单的阈值化(thresholding),ReLU 计算效率很高。但是 ReLU 神经元也存在一些缺点:
1. 不以零为中心:和 Sigmoid 激活函数类似,ReLU 函数的输出不以零为中心。
2. 前向传导(forward pass)过程中,如果 x < 0,则神经元保持非激活状态,且在后向传导(backward pass)中「杀死」梯度。这样权重无法得到更新,网络无法学习。
为了解决 ReLU 激活函数中的梯度消失问题,当 x < 0 时,我们使用 Leaky ReLU——该函数试图修复 dead ReLU 问题。下面我们就来详细了解 Leaky ReLU。
Leaky ReLU 的概念是:当 x < 0 时,它得到 0.1 的正梯度。该函数一定程度上缓解了 dead ReLU 问题,但是使用该函数的结果并不连贯。尽管它具备 ReLU 激活函数的所有特征,如计算高效、快速收敛、在正区域内不会饱和。
Leaky ReLU 可以得到更多扩展。不让 x 乘常数项,而是让 x 乘超参数,这看起来比 Leaky ReLU 效果要好。该扩展就是 Parametric ReLU。
详见3.
4、损失函数
model.compile(optimizer="rmsprop",loss="sparse_categorical_crossentropy",metrics=["AUC"])
自定义损失函数:
classFocalLoss(losses.Loss):
def__init__(self,gamma=2.0,alpha=0.25):
self.gamma=gamma
self.alpha=alpha
defcall(self,y_true,y_pred):
pt_1=tf.where(tf.equal(y_true,1),y_pred,tf.ones_like(y_pred))
pt_0=tf.where(tf.equal(y_true,0),y_pred,tf.zeros_like(y_pred))
loss=-tf.sum(self.alpha*tf.pow(1.-pt_1,self.gamma)*tf.log(1e-07+pt_1))\-tf.sum((1-self.alpha)*tf.pow(pt_0,self.gamma)*tf.log(1.-pt_0+1e-07))
returnloss
一般来说,监督学习的目标函数由损失函数和正则化项组成。(Objective = Loss + Regularization).
对于keras模型,目标函数中的正则化项一般在各层中指定,例如使用Dense的 kernel_regularizer 和 bias_regularizer等参数指定权重使用l1或者l2正则化项,此外还可以用kernel_constraint 和 bias_constraint等参数约束权重的取值范围,这也是一种正则化手段。
损失函数在模型编译时候指定。对于回归模型,通常使用的损失函数是平方损失函数 mean_squared_error。
对于二分类模型,通常使用的是二元交叉熵损失函数 binary_crossentropy。
对于多分类模型,如果label是one-hot编码的,则使用交叉熵损失函数 categorical_crossentropy。如果label是序号编码的,则需要使用稀疏类别交叉熵损失函数 sparse_categorical_crossentropy。
以及hinge(合页损失函数,用于二分类,最著名的应用是作为支持向量机SVM的损失函数,类实现形式为 Hinge)。
如果有需要,也可以自定义损失函数,自定义损失函数需要接收两个张量y_true,y_pred作为输入参数,并输出一个标量作为损失函数值,即损失函数定义的是预测值和真实值之间的gap。
5、优化器optimizers
优化器主要使用apply_gradients方法传入变量和对应梯度从而来对给定变量进行迭代,或者直接使用minimize方法对目标函数进行迭代优化。
当然,更常见的使用是在编译时将优化器传入keras的Model,通过调用model.fit实现对Loss的的迭代优化。
初始化优化器时会创建一个变量optimier.iterations用于记录迭代的次数。因此优化器和tf.Variable一样,一般需要在@tf.function外创建。
(1)optimizer=tf.keras.optimizers.SGD(learning_rate=0.01)
dy_dx=tape.gradient(y,x)
optimizer.apply_gradients(grads_and_vars=[(dy_dx,x)])
(2)model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=0.01),loss=myloss)
(3)@tf.function
deftrain(epoch=1000):
for_intf.range(epoch):
optimizer.minimize(f,[x])
tf.print("epoch = ",optimizer.iterations)
return(f())
6、评估指标
通常人们还会从其它角度评估模型的好坏,这就是评估指标。通常损失函数都可以作为评估指标,如MAE,MSE,CategoricalCrossentropy等也是常用的评估指标。
但评估指标不一定可以作为损失函数,例如AUC,Accuracy,Precision。因为评估指标不要求连续可导,而损失函数通常要求连续可导。
编译模型时,可以通过列表形式指定多个评估指标。
如果有需要,也可以自定义评估指标。
自定义评估指标需要接收两个张量y_true,y_pred作为输入参数,并输出一个标量作为评估值。
也可以对tf.keras.metrics.Metric进行子类化,重写初始化方法, update_state方法, result方法实现评估指标的计算逻辑,从而得到评估指标的类的实现形式。
由于训练的过程通常是分批次训练的,而评估指标要跑完一个epoch才能够得到整体的指标结果。因此,类形式的评估指标更为常见。即需要编写初始化方法以创建与计算指标结果相关的一些中间变量,编写update_state方法在每个batch后更新相关中间变量的状态,编写result方法输出最终指标结果。
补充ROC,AUC
1)ROC:???
2)AUC:ROC曲线下面的面积,用于二分类,直观解释为随机抽取一个正样本和一个负样本,正样本的预测值大于负样本的概率)。
详见4
第三个阶段是再识tensorflow如何构建模型,在初步的了解之后,再重新看这部分内容,开始有更多的了解,也开始有一些整体的概念,了解构建模型作为一个整体的过程。
比如说1:重新了解tensorflow是什么,为什么是tensorflow,tensorflow做了什么。
这个总结写得比较好,TensorFlow 是开源的端到端的机器学习平台,提供了丰富的工具链,推动了机器学习的前沿研究,支撑了大规模生产使用,支持多平台灵活部署。
为什么是tensorflow,TensorFlow 2 重点关注易用性,同时兼具可扩展性和高性能,降低了机器学习的门槛。
tensorflow做了什么,首先看tensorflow需要做什么,然后tensorflow就做了什么。
(1)对于学生和研究者:模型的建立与训练
模型在计算机中具体要如何实现。这时,你希望能有一个程序库,帮助你把书本上的公式和算法运用于实践。
1、数学概念表示、2、建立模型和损失函数、3、求偏导、4、优化方法更新模型参数
(2)开发者和工程师:模型的调用与部署
如果你是一位在 IT 行业沉淀多年的开发者或者工程师,你可能已经对大学期间学到的数学知识不再熟悉(“多元函数…… 求偏微分?那是什么东西?”)。然而,你可能希望在你的产品中加入一些与人工智能相关的功能,抑或需要将已有的深度学习模型部署到各种场景中。
这个目前还没有做过。
内容详见2.
比如2:重新了解模型建立和训练
1、模型和层
Keras 有两个重要的概念: 模型(Model) 和 层(Layer)
层将各种计算流程和变量进行了封装(例如基本的全连接层,CNN 的卷积层、池化层等),而模型则将各种层进行组织和连接,并封装成一个整体,描述了如何将输入数据通过各种层以及运算而得到输出。在需要模型调用的时候,使用 y_pred = model(X) 的形式即可。Keras 在 tf.keras.layers 下内置了深度学习中大量常用的的预定义层,同时也允许我们自定义层。
(1)自定义模型
Keras 模型以类的形式呈现,我们可以通过继承 tf.keras.Model 这个 Python 类来定义自己的模型。在继承类中,我们需要重写 __init__() (构造函数,初始化)和 call(input) (模型调用)两个方法,同时也可以根据需要增加自定义的方法。
(2)自定义层
自定义层需要继承 tf.keras.layers.Layer 类,并重写 __init__ 、 build 和 call 三个方法,例如,如果我们要自己实现一个 本章第一节 中的全连接层( tf.keras.layers.Dense ),可以按如下方式编写。此代码在 build 方法中创建两个变量,并在 call 方法中使用创建的变量进行运算。
(3)自定义损失函数
自定义损失函数需要继承 tf.keras.losses.Loss 类,重写 call 方法即可,输入真实值 y_true 和模型预测值 y_pred ,输出模型预测值和真实值之间通过自定义的损失函数计算出的损失值。下面的示例为均方差损失函数:
classMeanSquaredError(tf.keras.losses.Loss):
defcall(self,y_true,y_pred):
return tf.reduce_mean(tf.square(y_pred-y_true))
(4)自定义评估指标
自定义评估指标需要继承 tf.keras.metrics.Metric 类,并重写 __init__ 、 update_state 和 result 三个方法。下面的示例对前面用到的 SparseCategoricalAccuracy 评估指标类做了一个简单的重实现:
classSparseCategoricalAccuracy(tf.keras.metrics.Metric):
...
2、构建和训练模型的方式
构建模型的三种方式:
1)Sequential按层顺序创建模型
2)函数式API创建任意结构模型
3)Model子类化创建自定义模型
训练模型的三种方式:
1)内置fit方法
2)内置train_on_batch方法
该内置方法相比较fit方法更加灵活,可以不通过回调函数而直接在批次层次上更加精细地控制训练的过程。
3)自定义训练循环
自定义训练循环无需编译模型,直接利用优化器根据损失函数反向传播迭代参数,拥有最高的灵活性。
todo:
基础示例:多层感知机(MLP)https://tf.wiki/zh_hans/basic/models.html#mlp
参考资料:
1、https://www.jianshu.com/writer#/notebooks/48128813/notes/80699278
2、https://www.jianshu.com/p/3623f1dbbf81
3、https://zhuanlan.zhihu.com/p/98472075
4、ROC及AUC计算方法及原理https://blog.csdn.net/yinyu19950811/article/details/81288287