今天是学习的第二天了,今天学的东西很多,到现在还感觉头大,慢慢搞吧。今天主要是学习了Loss函数的选择,包括最原始的loss函数以及后来的加入正则化的loss函数,然后就是学习了神经网络的优化问题,主要的两个算法,梯度下降算法以及反向传播算法。然后学习了通过指数衰减来设置学习率,通过正则化来解决过拟合问题。
下面时今天的学习笔记:
1.神经网络的类型:
a.如果输入为所有输入的加权和,那么这个而神经网络就是线性模型
b.如果将神经网络中每个节点的输出通过一个非线性的函数,那么就是一个非线性模型
一般这种输出通过一个非线性的激活函数以及一个偏置项实现。(如图02-1所示)
2.加入偏置项的前向传播算法定义
偏置项可以被表达为一个输出永远为1的节点
a = tf.nn.relu(tf.matmul(x,w1)+b1)
y = tf.nn.relu(tf.matmul(a,w2)+b2)
a = tf.sigmoid(tf.matmul(x,w1)+b1)
y = tf.sigmoid(tf.matmul(a,w2)+b2)
a = tf.tanh(tf.matmul(x,w1)+b1)
y = tf.tanh(tf.matmul(a,w2)+b2)
3.几种常用的非线性激活函数
a.ReLU函数 f(x) = max(x,0)
b.sigmoid函数 (最常用的) f(x) = 1/(1+e^-x)
c.tanh函数 f(x) = (1-e^-2x) / (1+e^-2x)
在代码中就是tf.nn.relu tf.sogmoid tf.tanh
4.损失函数(loss function)
a.分类问题:将通过的样本经过模型后 分到事先定义好的类别中去
分类问题也可以看成一个概率分布问题,输出结果就是这个样本属于哪个类别的概率
loss function:交叉熵
2元分类:一般的输出是yes 或者no 用来将样本分成两类
n元分类:输出有n个 将样本分成n类,如识别手写数字就是一个10元分类问题,输出结果为0-9 是个数字
通常的输出是一个多为数组,[0,1,0,0]表示这个类别是第二个类别
通常情况下输出越接近我们期待的输出数组越好,所以我们要判断输出向量和期望的而向量有多接近
通过 交叉熵(cross entropy)来判断。交叉熵表示的是两个概率分布之间有多接近,也是一种loss函数
公式如图02-5所示,规定p是正确答案,q是预测值,如果交叉熵越小那么两个概率分布越接近。
代码实现交叉熵验证:
cross_entropy = -tf.redece_mean(y_*tf.log(tf.clip_by_value(y,1e-10,1.0)))
其中y_表示正确结果即多维数组,y表示的是经过训练后的预测结果
clip_by_value可以将一个张量中的数值限制在一个范围之内
clip_by_value(vector,x,y):在vector中如果某一个值小于x则替换成x 相同的如果某一值大于y则替换成y
问题:怎么将前向传播得到的结果编程概率分布
解决:通过 Sortmax()回归 Sortmax可以将神经网络的输出变成一个概率分布
通过sortmax处理输出结果后,输出变为概率分布
通常sortmax与cross_entropy会一起使用所有tensorflow进行了封装通过如下代码可以求解交叉熵
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(y,y_)
同上面一样,y表示的是经过训练后的预测结果,y_是标准答案
b.回归问题:主要解决的对具体数值的预测。一般解决回归问题的神经网络只有一个输出,这个输出就是预测值
回归问题中最常用的Loss 函数是均方误差 (MSE)公式如图02-6所示 代码实现
mse = tf.reduce_mean(tf.square(y-y_))
y表示的是经过训练后的预测结果,y_是标准答案
c.自定义所示函数:
有些时候通过自定义损失函数,可以使得神经网络优化的结果更加接近实际问题的需求
5.神经网络的优化算法
通过 反向传播算法(backpropagation) 以及梯度下降算法(gradiect decent)调整圣经网络中参数的取值
每次计算一小部分的训练数据的损失函数,这一小部分数据被称为一个batch
6.一个神经网络训练的基本过程:
#设置batch 的大小,即每次训练的一小部分数据,也就是样本的个数
batch_size = n
#x为训练数据,每次输入batch_size个样本
#y_为样本的准确答案 即lable 每次给batch_size个样本
x = tf.placeholder(tf.float32,shape=(batch_size,2))
y_ = tf.placeholder(tf.float32,shape=(batch_size,1))
#定义Loss函数,并且选择优化算法找到最小的loss
loss = ...(分类和回归的Loss不一样,而且Loss也可以自定义)
#优化器也可以选择不同的优化器,比如梯度下降优化器
train_step = tf.train..AdamOptimizer(0.001).minimize(loss)
#开始i训练
with tf.Sesson() as sess:
sess.run(init)
#通过迭代来更新参数
for i in range(STEPS):
#每一次迭代都要准备好batch_size个样本
this_X ,this_Y = ...#训练数据其中this_Y为lable
sess.run(train_step,feed_dit={x:this_X,y_:this_Y})
7.神经网络的进一步优化
a.设置学习率
学习率不能过大也不能过小,所以tensorflow提供了一种两更加灵活的方法设置
指数衰减法:
tf.train.exponetial_decay()函数实现了指数衰减学习率:
这个函数先使用一个较大的学习率来快速获得一个较优解,然后逐步的减小学习率,然后慢慢的趋于稳定
函数的代码使用:
l_step = tf.Variable(0)
#通过函数生成学习率
lr = tf.train.exponetial_decay(0.1,l_step,100,0.96,staircase=True)
参数的意义:
第一个参数initial learning rate:初始的学习率
第二个参数global_step:用于衰减计算的全局步
第三个参数 decay_steps:每多少轮变化一次
第四个参数 decay_rate:变化的比例
第五个参数staircase:如果为true那么会以不连续的间隔改变学习率
8.过拟合问题:
简单来说就是模型将训练数据模拟的非常好,很好的记住了每一个训练中的特征,很好的模拟了训练数据
这个模型过度的拟合了数据中的噪音,却没有很好的反映数据整体的规律,当用此模型进行预测的时候,
往往效果不是很好 (一个学生将一类题目的练习题做的非常好,但是没有掌握这类题的解题规律,最后考试出现
这一类题目,有可能得不了高分)
解决过拟合问题:正则化(regularization)
思想:在计算损失函数是加入一项正则项,用这个正则项来描述模型的复杂程度
R(w)是刻画复杂度的函数它前面还有一项参数表示一个比例
R(w)常用的有两种:L1正则化(权值的和) 和 L2正则化(权值平方的和)
代码示例:
w = tf.Varialbe(tf.random_normal([2,1]))
y = tf.matmul(x,w)
#L2正则
loss = tf.reduce_mean(tf.square(y_-y))+tf.contrib.layers.l2_regularizer(lambda)(w)
#这个loss有两部分组成第一部分为均方差,第二部分为正则化,lambda表示正则化项的权重
9.滑动平均模型
在使用随机梯度下降算法训练圣经网络时,使用滑动平均模型可以提高模型的表现
tf.train.ExponentialMovingAverage
10.训练神经网络
a.在神经网络的结构上
深度学习一方面需要使用激活函数实现神经网络的去线性化,另一方面需要是以哦那个一个或者多个
隐藏层使得神经网络的结构更深。
b.在训练神经网络:
使用指数衰减来设置学习率,使用正则化来避免过拟合,使用滑动平均模型使得最终的模型更加健壮。
总结一下:果然第一天学的东西是最简单的emmmm,今天开始已经有点头大了,学完优化的理论知识,然后从下午开始比着样例做一个手写数字的识别,代码码完,出了好多错误已经慢慢改完了,现在最大的问题就是一个next_batch()函数了,就是对于整个神经网络来说,我还不能很轻松的控制它的数据流。明天再看吧,现在有点头疼哈哈。明天继续学习,然后自己把修改好的网络测试一下,控制一下数据流,截取数据集的一部分进行测试。