TensorFlow入门--Chapter02

深层神经网络

1 深层神经网络


1.1 深度学习基本概念

维基百科定义:一类通过多层非线性变换对高复杂性数据建模算法的集合
两个重要特性:多层非线性


1.2 线性模型的局限性

  • 线性模型的最大特点是任意线性模型的组合任然是线性模型
  • 一个线性模型通过输入得到输出的函数被称为一个线性变换

缺点:由于现实中的问题往往不具有线性,因此线性模型解决的问题具有局限性


1.3 使用激活函数去线性化

chapter01 介绍的神经网络是一个线性模型,原因是对神经元结构的输出为所有输入的加权和,线性模型具有局限性

解决:如果将每个神经元的输出通过一个非线性函数(激活函数),那么整个神经网络就是非线性的了,去线性化前后对比代码如下:

#只展示部分代码
#去线性化之前
#random_normal生成随机的符合正态分布且 方差为1(stddev=1) 的 2x3数组
w1 = tf.Variable(tf.random_normal([2, 3],stddev=1, seed=1))
w2 = tf.Variable(tf.random_normal([3, 1],stddev=1, seed=1))
x = tf.placeholder(tf.float32, shape=(1, 2), name="input")
a = tf.matmul(x,w1)
y = tf.matmul(a,w2)

#去线性化之后
a = tf.nn.relu(tf.matmul(x, w1) + biases1)
y = tf.nn.relu(tf.matmul(x, w2) + biases2)

  • 常见激活函数
函数名 函数作用
tf.nn.relu relu函数的定义:f(x)=max(x,0),x<0时,输出始终为0。x>0时,导数为1
tf.sigmoid 可以将整个实数区间映射到(0,1)区间
tf.tanh tanh是双曲正切函数,它将整个实数区间映射到了(-1,1),anh的收敛速度比sigmoid快

2 损失函数定义

神经网络模型的效果和优化的目标都是通过 损失函数 来定义的


2.1 经典损失函数

分类问题和回归问题是监督学习的两大种类

  • 分类问题:解决的是将不同的样本分到事先定义好的类别中
  1. 损失函数:交叉熵(刻画了连个概率分布之间的距离,分类问题中经常用)
  2. Softmax回归:交叉熵刻画的是概率分布之间的距离,然而神经网络输出并不一定是概率分布,概率分布刻画的是不同事件发生的概率,Softmax将神经网络的输出变成一个概率分布。
    在这里插入图片描述
    此时便可用交叉熵计算预测和真实的概率分布之间的距离了。
#没softmax回归的交叉熵损失函数
#tf.clip_by_value(A, min, max):张量A,A中元素的值都压缩在min和max之间。小于min的让它等于min,大于max的元素的值等于max
cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0)))

  1. 交叉熵和Softmax回归
    因为经常交叉熵和softmax一起使用,所以TensorFlow对这两个功能进行了封装,tf.nn.sotfmax_cross_entropy_with_logits()函数 即softmax回归后的交叉熵损失函数
#labels代表是真实值,logist代表是预测值(神经网络输出的结果)
cross_entropy = tf.nn.sotfmax_cross_entropy_with_logits(labels=y_, logist = y)
#在只有一个正确答案的时候,可以用tf.nn.sparse_softmax_cross_entropy_with_logits函数加速计算
  • 回归问题:对具体数值的预测,要预测的不是事先定义好的类别,而是一个任意实数
  1. 损失函数:最常用的就是均方误差(MSE)
#y代表神经网络输出答案,y_代表标准答案
mse = tf.reduce_mean(tf.square(y_ - y))

2.2 自定义损失函数

引入:在预测商品销售时,如果预测多了,即预测值大于真实值,则会使商家亏生产商品的成本,如果预测少了,即预测值小于真实值,则会使商家少挣很多利润。假如成本为1元,利润为10元,多预测一个亏1元,少预测一个少挣10元。
如果神经网络最小化的是均值误差,那么有可能此模型无法最大化利润,为了最大化利润可以将损失函数和利润联系起来


依据上面引入

  • 定义损失函数
    预测值>真实值 与 预测值<真实值 有不同的损失函数
    L o s s ( y , y ) = i = 1 N f ( y i , y i ) Loss(y,y&#x27;)=\sum_{i=1}^Nf(y_i,y_i&#x27;) , f ( x , y ) = { a ( x y ) x &gt; y b ( y x ) x y f(x,y) = \begin{cases} a(x-y) &amp; x&gt;y \\b(y-x) &amp; x\leq y \end{cases}

与均值方差类似: y i y_i 为一个batch中第i个数据的正确答案, y i y_i&#x27; 为神经网络得到的预测值,a=10代表 y i &gt; y i y_i &gt;y_i&#x27; 的代价,b=1代表 y i &lt; y i y_i&lt;y_i&#x27; 的代价
通过对这个自定义损失函数的优化,模型提供的预测值可能达到最大收益。

#tf.where函数类似C语言中的三目运算符 : ?,参数一为true时选第二个参数false选第三个
#tf.greater(v1,v2),比较v1和v2的值,v1>v2返回true否则false,v1,v2是张量

loss = tf.reduce_sum(tf.where(tf.greater(v1,v2), (v1-v2)*a, (v2-v1)*b))

#案例
import tensorflow as tf
v1 = tf.constant([1.0,2.0,3.0,4.0])
v2 = tf.constant([4.0,3.0,2.0,1.0])
sess = tf.InteractiveSession()
print(tf.greater(v1, v2).eval())
## 输出:[False False  True  True]
print(tf.where(tf.greater(v1,v2),v1,v2).eval())
## 输出:[4. 3. 3. 4.]
  • 损失函数对训练结果的影响
#损失函数对模型的影响
import tensorflow as tf
from numpy.random import RandomState

#定义batch的大小
batch_size = 8

#两个输入节点
x = tf.placeholder(tf.float32, shape=(None, 2), name='x-input')

#回归问题一般只有一个输出节点
y_ = tf.placeholder(tf.float32, shape=(None, 1), name='y-input')

#定义了一个单层的神经网络前向传播的过程,这里就是简单的加权和
w1 = tf.Variable(tf.random_normal([2,1], stddev=1, seed=1))
y = tf.matmul(x, w1)

#定义预测多了和预测少了的成本
loss_less = 10
loss_more = 1
loss = tf.reduce_sum(tf.where(tf.greater(y, y_),(y-y_)*loss_more,(y_-y)*loss_less))
train_step = tf.train.AdamOptimizer(0.001).minimize(loss)

#通过随机数生成一个模拟数据集
rdm = RandomState(1)
dataset_size = 128
X = rdm.rand(dataset_size, 2)

#设置真实值,为两个输入的和加上一个随机量(为了加入不可预测的噪音)否则不同损失函数意义不大, 噪音一般均值为0的小量,这里设置为-0.05~0.05
Y = [[x1 + x2 + rdm.rand()/10.0 - 0.05] for(x1, x2) in X]

#训练神经网络
with tf.Session() as sess:
    init = tf.global_variables_initializer()
    sess.run(init)
    for i in range(5000):
        #每次选一个batch的数据量来训练
        start = (i*batch_size) % dataset_size
        end = min(start+batch_size, dataset_size) #start和end之间相差一个batch
        #训练
        sess.run(train_step, feed_dict={x: X[start:end], y_:Y[start:end]})
        print(sess.run(w1))

输出结果:
在这里插入图片描述

2.3 神经网络优化算法

  • 梯度下降算法:不能保证优化的函数达到全局最优解

  • 随机梯度下降算法:可能无法达到局部最优
    这个算法的优化不是全部的数据集上的损失函数,而是在每一次的迭代过程中,随机优化某一条数据上的损失函数

  • batch:为了综合梯度下降和随机梯度下降算法,采用折中办法,每次集散一小部分训练数据的损失函数,这一小部分被称为一个batch


猜你喜欢

转载自blog.csdn.net/qq_38558834/article/details/84640930