Basic properties Yongxing Tensorflow notes -7 loss function neural network and

Here Insert Picture Description

First, the basic properties of neural networks:

Four basic properties of neural networks:

  • (1) Nonlinear: common feature is the nonlinear nature. Intelligent human brain is a kind of non-linear phenomena. Artificial neurons in two different activation or inhibition state, they are nonlinear mathematically. By the threshold neurons better network performance, fault tolerance can be improved and the storage capacity of the network.
  • (2) without limitation: a plurality of neural networks are typically connected by a wide range of neurons. Overall behavior of a system depends not only on the characteristics of individual neurons, but also depends on the interaction between the cells and interconnect. To simulate the brain through a large number of non-limiting connection between the elements. Associative memory is a typical example of the unlimited.
  • (3) very qualitative: artificial neural network with adaptive, self-learning ability and self-organization. Neural network processing information not only will change, and nonlinear dynamic system itself is also changing. Iterative process commonly used to describe the evolution of a dynamic system.
  • (4) non-convexity: Under certain conditions, the direction of the evolution of the system depends on the particular state of the function. For example, extreme energy function corresponds to a relatively stable state of the system. Refers to the non-convex function having a plurality of extrema, the system having a plurality of stable equilibrium, resulting in the diversity of the system evolution.

In addition:
1, the complexity of the neural network:
the number of layers and the neural network is generally used in the neural network represents the number of parameters to be optimized.
2, the number of layers of the neural network:
generally not included in the input layer, a hidden layer the number of layers = n + 1 output layer
3, the neural network parameters to be optimized:
number of all the neural network parameters w + all parameters b number

Second, what is the loss function?

  • Loss function (loss function) or a cost function (cost function) is a random event, or the value of the mapping random variable related non-negative real numbers to indicate "risk" or "loss" of the function of random events. In the application, the loss function normally as a learning criterion linked to the optimization problem, namely solved by minimizing the loss function and assessment models.

Third, why should use the loss function?

  • 机器学习中被用于模型的参数估计(parameteric estimation),机器学习中,损失函数是模型输出和正确结果间概率分布差异的量化,计算损失(loss)
  • 损失(loss):用来表示预测值(y)与已知答案(y_)的差距。在训练神经网络时,通过不断 改变神经网络中所有参数,使损失函数不断减小,从而训练出更高准确率的神经网络模型 。

四、基本函数:

1、tf.random_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)

函数用于从服从指定正态分布的数值中取出指定个数的值。

  • shape: 输出张量的形状,必选
  • mean: 正态分布的均值,默认为0
  • stddev: 正态分布的标准差,默认为1.0
  • dtype: 输出的类型,默认为tf.float32
  • seed: 随机数种子,是一个整数,当设置之后,每次生成的随机数都一样
  • name: 操作的名称
2、tf.greater(a,b)

功能:比较a、b两个值的大小
返回值:一个列表,元素值都是true和false

3、tf.where:函数有三个参数,根据第一个条件是否成立,当为True的时候选择第二个参数中的值,否则使用第三个参数中的值。
4、tf.clip_by_value(1-y,1e-10,1.0) 运用的是交叉熵而不是二次代价函数。

功能:可以将一个张量中的数值限制在一个范围之内。(可以避免一些运算错误:可以保证在进行log运算时,不会出现log0这样的错误或者大于1的概率)

  • 参数:(1)1-y:input数据(2)1e-10、1.0是对数据的限制。
    • 当1-y小于1e-10时,输出1e-10;
    • 当1-y大于1e-10小于1.0时,输出原值;
    • 当1-y大于1.0时,输出1.0;
5、tf.argmax(input,axis)根据axis取值的不同返回每行或者每列最大值的索引。
  • 参数:
    • _sentinel:用于防止positional参数。内部的,不要使用。
    • labels:一个Tensor,与logits具有相同的类型和shape。
    • logits:一个Tensor,类型为float32或float64。
    • name:操作的名称(可选)。
6、tf.reduce_mean 函数用于计算张量tensor沿着指定的数轴(tensor的某一维度)上的的平均值,主要用作降维或者计算tensor的平均值。
reduce_mean(input_tensor,
                axis=None,
                keep_dims=False,
                name=None,
                reduction_indices=None)
  • 第一个参数input_tensor: 输入的待降维的tensor;
  • 第二个参数axis: 指定的轴,如果不指定,则计算所有元素的均值;
  • 第三个参数keep_dims:是否降维度,设置为True,输出的结果保持输入* * tensor的形状,设置为False,输出结果会降低维度;
  • 第四个参数name: 操作的名称;
  • 第五个参数 reduction_indices:在以前版本中用来指定轴,已弃用;

五、如果选择正确的损失函数?

损失函数可以让我们看到模型的优劣,并且为我们提供了优化的方向,但是我们必须知道没有任何一种损失函数适用于所有的模型。损失函数的选取依赖于参数的数量、异常值、机器学习算法、梯度下降的效率、导数求取的难易和预测的置信度等若干方面。

对应回归问题我们一般选择均方误差。(回归预测建模是将输入变量(X)的映射函数(f)近似为连续输出变量(y)的任务。比如:预测房屋可以出售特定的价值)

1、均方误差(mse):

n 个样本的预测值 y 与已知答案 y_之差的平方和,再求平均值。
数学表达式:
Here Insert Picture Description
tensorflow下:

loss_mse = tf.reduce_mean(tf.square(y_ - y)) #均方误差 (一般y_为答案 y为计算结果)
  • 例题1:
    预测酸奶日销量 y,x1 和 x2 是影响日销量的两个因素。
    应提前采集的数据有:一段时间内,每日的 x1 因素、x2 因素和销量 y_。采集的数据尽量多。
    在本例中用销量预测产量,最优的产量应该等于销量。由于目前没有数据集,所以拟造了一套数 据集。利用 Tensorflow 中函数随机生成 x1、 x2,制造标准答案 y_ = x1 + x2,为了更真实,求和后 还加了正负 0.05 的随机噪声。
    我们把这套自制的数据集喂入神经网络,构建一个一层的神经网络,拟合预测酸奶日销量的函数。
import tensorflow as tf
import numpy as np
seed = 23455 #随机种子
batahSize = 8 #定义每一轮喂入数据的数量
STEPS = 20000 #训练轮数

rdm = np.random.RandomState(seed) #设置的seed相同取出地随机数就一样
X = rdm.rand(32,2) #生成 [32,2] 的随机数矩阵

Y = [[x1+x2+(rdm.rand()/10.0-0.05)] for (x1,x2) in X]
# 等价于
# Y = []
# for x1,x2 in X :
#     Y.append([x1+x2+(rdm.rand()/10.0-0.05)])

#定义神经网络的输入
x = tf.placeholder(tf.float32,shape=(None,2))
y_ = tf.placeholder(tf.float32,shape=(None,1))

#定义学习参数:权重w
w1 = tf.Variable(tf.random_normal([2,1],stddev=1,seed=1))

#定义 前向传播的过程 OP
y = tf.matmul(x,w1)

#定义损失函数
loss = tf.reduce_sum(tf.square(y_-y))

#设置优化器。设定学习率
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss)

init = tf.global_variables_initializer()
with tf.Session() as sess :
    sess.run(init)
    for i in range(STEPS):
        start = (i*batahSize) % 32 #数据只有32组,不断利用
        end = (i*batahSize) % 32 + batahSize
        sess.run(train_step,feed_dict={x:X[start:end],y_:Y[start:end]})
        if i % 200 == 0:
            print("第%d轮"%i)
            print("loss:",sess.run(loss,feed_dict={x:X[start:end],y_:Y[start:end]}))
    print("最后一次训练的loss为:",sess.run(loss,feed_dict={x:X[start:end],y_:Y[start:end]}))

在分类问题中,我们一般使用交叉熵作为损失函数:

2、交叉熵(Cross Entropy):

表示两个概率分布之间的距离。交叉熵越大,两个概率分布距离越远,两个概率分布越相异;交叉熵越小,两个概率分布距离越近,两个概率分布越相似。
交叉熵计算公式:
Here Insert Picture Description
tensorflow 二分类问题下:

ce= -tf.reduce_mean(y_* tf.log(tf.clip_by_value(y, 1e -12, 1.0)))
  • 另外我们还可以用来测试神经网络准确性的比较:
    两个神经网络模型解决二分类问题中,已知标准答案为 y_ = (1, 0),第一个神经网络模型预测结果为
    6 y1=(0.6, 0.4),第二个神经网络模型预测结果为 y2=(0.8, 0.2),判断哪个神经网络模型预测的结果更接 近标准答案。
    根据交叉熵的计算公式得:
    H1((1,0),(0.6,0.4)) = -(1log0.6 + 0log0.4) ≈ -(-0.222 + 0) = 0.222
    H2((1,0),(0.8,0.2)) = -(1log0.8 + 0log0.2) ≈ -(-0.097 + 0) = 0.097
    由于 0.222>0.097,所以预测结果 y2 与标准答案 y_更接近,y2 预测更准确。

另外在tensorflow中
针对分类问题,有四个交叉熵函数,分别是:

1、tf.nn.sigmoid_cross_entropy_with_logits
output = tf.nn.sigmoid_cross_entropy_with_logits(logits=y, labels=y_))
  • 计算方式:对输入的logits先通过sigmoid函数计算,再计算它们的交叉熵,但是它对交叉熵的计算方式进行了优化,使得的结果不至于溢出。
    • 适用:每个类别相互独立但互不排斥的情况:例如一幅图可以同时包含一条狗和一只大象。
    • output不是一个数,而是一个batch中每个样本的loss,所以一般配合tf.reduce_mean(loss)使用。
  • 返回:
    • 与具有分量logistic损失的logits有着相同shape的Tensor。
    • 可能引发的异常:
      ValueError:如果logits和labels没有相同的shape。
softmax 函数:将 n 分类的 n 个输出(y1,y2…yn)变为满足以下概率分布要求的函数。

Here Insert Picture Description
Here Insert Picture Description
softmax 函数应用:在 n 分类中,模型会有 n 个输出,即 y1,y2…yn,其中 yi 表示第 i 种情况出现的可 能性大小。将 n 个输出经过 softmax 函数,可得到符合概率分布的分类结果。

2、tf.nn.softmax_cross_entropy_with_logits
tf.nn.softmax_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, dim=-1, name=None)
  • 参数:
    • _sentinel:用于防止positional参数。内部的,不要使用。
    • labels:沿着类维度的每个向量应该保持有效的概率分布,例如:对于标签shape为[batch_size, num_classes]的情况,labels[i]的每一行必须是有效的概率分布。
    • logits:未缩放的日志概率。
    • dim:类维度。默认为-1,这是最后一个维度。
    • name:操作的名称(可选)。
  • 返回:
    • 一个Tensor,包含softmax交叉熵损失的。它的类型与logits相同,它的shape与labels是相同的,除了它没有labels的最后一个维度。
  • 计算方式:对输入的logits先通过softmax函数计算,再计算它们的交叉熵,但是它对交叉熵的计算方式进行了优化,使得结果不至于溢出。
  • 适用:每个类别相互独立且排斥的情况,一幅图只能属于一类,而不能同时包含一条狗和一只大象。
  • output:不是一个数,而是一个batch中每个样本的loss,所以一般配合tf.reduce_mean(loss)使用。
3、tf.nn.sparse_softmax_cross_entropy_with_logits
tf.nn.sparse_softmax_cross_entropy_with_logits(_sentinel=None,labels=None,logits=None, name=None)
  • 参数:
    • _sentinel:用于防止位置参数。内部,不要使用。
    • labels:Tensor,shape为[d_0, d_1, …, d_{r-1}](其中r是labels的秩和结果)并且类型为int32或int64。每个labels中的条目必须是[0, num_classes)中的索引。当此操作在CPU上运行时,其他值将引发异常,并返回NaN,以获取GPU上相应的损失和梯度行。
    • logits:shape为[d_0, d_1, …, d_{r-1}, num_classes]和类型为float16,float32或 float64的未缩放日志概率。
    • name:操作的名称(可选)。
  • 返回:
    • 一个Tensor,与labels形状相同、与具有SoftMax交叉熵损失的logits具有相同的类型。
  • 计算方式:对输入的logits先通过softmax函数计算,再计算它们的交叉熵,但是它对交叉熵的计算方式进行了优化,使得结果不至于溢出。
  • 适用:每个类别相互独立且排斥的情况,一幅图只能属于一类,而不能同时包含一条狗和一只大象 。
  • output不是一个数,而是一个batch中每个样本的loss,所以一般配合tf.reduce_mean(loss)使用。

在 Tensorflow 中,一般让模型的输出经过 sofemax 函数,以获得输出分类的概率分布,再与标准 答案对比,求出交叉熵,得到损失函数,用如下函数实现:

ce = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1))
cem = tf.reduce_mean(ce)
4、tf.nn.weighted_cross_entropy_with_logits
tf.nn.weighted_cross_entropy_with_logits(labels,logits, pos_weight, name=None) 
  • 计算具有权重的sigmoid交叉熵sigmoid_cross_entropy_with_logits()
    logits和target必须具有相同的类型和形状。
  • 参数:
    • labels:一个张量,与logits具有相同的类型和形状。
    • logits:一个张量,类型为float32或float64。
    • pos_weight:正样本中使用的系数。
    • name:操作的名称(任选)。
  • 返回:
    • 与具有常量预算逻辑损失的日志具有相同形状的张量。

3、自定义损失函数:

根据问题的实际情况,定制合理的损失函数。
例如:
对于预鲜牛奶日销量问题,如果预测销量大于实际销量则会损失成本;如果预测销量小于实际销量则 会损失利润。在实际生活中,往往制造一盒鲜牛奶的成本和销售一盒鲜牛奶的利润是不等价的。因此,需要使用符合该问题的自定义损失函数。
自定义损失函数为:
Here Insert Picture Description
其中,损失定义成分段函数:
Here Insert Picture Description
损失函数表示,若预测结果 y 小于标准答案 y_,损失函数为利润乘以预测结果 y 与标准答案 y_之差; 若预测结果 y 大于标准答案 y_,损失函数为成本乘以预测结果 y 与标准答案 y_之差。
用 Tensorflow 函数表示为:
loss = tf.reduce_sum(tf.where(tf.greater(y,y_),COST(y-y_),PROFIT(y_-y)))
Here Insert Picture Description

import tensorflow as tf
import numpy as np
seed = 23455 #随机种子
batahSize = 8 #定义每一轮喂入数据的数量
cost = 1 #酸奶成本1元,利润9元
profit = 9
STEPS = 20000 #训练轮数

rdm = np.random.RandomState(seed) #设置的seed相同取出地随机数就一样
X = rdm.rand(32,2) #生成 [32,2] 的随机数矩阵

Y = [[x1+x2+(rdm.rand()/10.0-0.05)] for (x1,x2) in X]
# 等价于
# Y = []
# for x1,x2 in X :
#     Y.append([x1+x2+(rdm.rand()/10.0-0.05)])

#定义神经网络的输入
x = tf.placeholder(tf.float32,shape=(None,2))
y_ = tf.placeholder(tf.float32,shape=(None,1))

#定义学习参数:权重w
w1 = tf.Variable(tf.random_normal([2,1],stddev=1,seed=1))

#定义 前向传播的过程 OP
y = tf.matmul(x,w1)

#定义损失函数
#酸奶成本1元,利润9元
loss = tf.reduce_sum(tf.where(tf.greater(y,y_),(y-y_)*cost,(y_-y)*profit))

#设置优化器。设定学习率
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss)

init = tf.global_variables_initializer()
with tf.Session() as sess :
    sess.run(init)
    for i in range(STEPS):
        start = (i*batahSize) % 32 #数据只有32组,不断利用
        end = (i*batahSize) % 32 + batahSize
        sess.run(train_step,feed_dict={x:X[start:end],y_:Y[start:end]})
        if i % 200 == 0:
            print("第%d轮"%i)
            print("loss:",sess.run(loss,feed_dict={x:X[start:end],y_:Y[start:end]}))
    print("最后一次训练的loss为:",sess.run(loss,feed_dict={x:X[start:end],y_:Y[start:end]}))

由代码执行结果可知, 神经网络最终参数为 w1=1.03, w2=1.05,销量预测结果为 y =1.03x1 + 1.05x2。由此可见,采用自定义损失函数预测的结果大于采用均方误差预测的结果,更符合实际需求。
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description
由执行结果可知,神经网络最终参数为 w1=0.96,w2=0.97,销量预测结果为 y =0.96x1 + 0.97x2。 因此,采用自定义损失函数预测的结果小于采用均方误差预测的结果,更符合实际需求。

本文有借鉴:北京大学助教的Tensorflow笔记

发布了45 篇原创文章 · 获赞 28 · 访问量 1万+

Guess you like

Origin blog.csdn.net/m0_43505377/article/details/103908993