神经网络自定义损失函数

神经网络中损失函数定义的是损失,所有要结果利益最大化,定义的损失函数应该刻画成本或者代价。下面的公式为当预测多于真实值和预测少于真实值时有不同损失系数的损失函数:
损失函数
其中yi为一个batch中第i个数据的正确答案,yi’为神经网络得到的预测值,a和b是常量。在TensorFlow中,可以使用以下代码实现:

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

tf.greater函数是比较两个输入张量中每一个元素的大小,并返回结果。tf.where函数有三个参数,第一个为选择条件根据,若为True,则返回第二个参数值,若为False,则返回第三个参数值。注意:tf.greater和tf.where两个函数都是在元素级别进行数据比较。(tf.where的前身为tf.select,但现在TensorFlow中无法使用tf.select)如:

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()) #输出v1中元素是否比v2中元素大
print(tf.where(tf.greater(v1, v2), v1, v2).eval()) #若v1比v2大,输出v1,反之输出v2
sess.close()

>>[False False  True  True]
[ 4.  3.  3.  4.]

下面将使用一个简单的神经网络程序来反应这个损失函数对训练结果的影响:

#此神经网络拥有两个输入节点,一个输出节点,没有隐藏层
import tensorflow as tf
#使用numpy工具包生成随机数据集
from numpy.random import RandomState

batch_size = 8 #训练集大小为8

#定义两个输入节点
x = tf.placeholder(tf.float32, shape=[None, 2], name='x-input')
#定义回归问题的一个输出节点,真实值
y_ = tf.placeholder(tf.float32, shape=[None, 1], name='y-input')

#声明w1、w2两个变量,通过设定seed参数随机种子,随机种子相同,则每次使用此代码都生成相同的随机数
#stddev为标准差,没有mean设定均值,则均值默认为0
w1 = tf.Variable(tf.random_normal([2, 1], stddev=1, seed=1)) #w1为输入到隐藏层的权重,2*1的矩阵
y = tf.matmul(x, w1) #y为预测的输出值

#定义预测多了和预测少了的成本
loss_less = 10 #预测值少于真实值,损失10
loss_more = 1 #预测值多余真实值,损失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) #rdm为伪随机数发生器,种子为1,只要种子相同,该发生器每次生成的随机数都是一样的
dataset_size = 128
X = rdm.rand(dataset_size, 2) #生成随机数,大小为128*2的矩阵
#设置回归的正确值为两个输入的和加上一个随机量。加上随机量是为了模拟不可预测的噪音,否则不同损失函数的意义就不大了。
#一般来说均值为一个均值为0的小量,设噪音是在-0.05~0.05之间的随机数
Y = [[x1+x2+rdm.rand()/10.0-0.05] for (x1, x2) in X]  #rdm.rand()生成的数据为0.级,列表解析格式
#用X中的x1和x2计算Y=x1+x2+rdm.rand()/10.0-0.05

#训练神经网络
with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)   #随机数被初始化
    STEPS = 5000
    for i in range(5000):
        start = (i*batch_size) % dataset_size
        end = min(start+batch_size, dataset_size)
        sess.run(train_step, feed_dict={x: X[start:end], y_: Y[start:end]})
    print(sess.run(w1))

>>[[ 1.01934695]
 [ 1.04280889]]

可得出预测的结果为1.02x1+1.04x2,真实结果为x1+x2,预测结果要比真实结果偏大,因为在损失函数中指定了预测少了的损失更大。若使用MSE作为损失函数,则输出结果为0.97x1+1.02x2,这个预测值离标准答案更近。所以,对于相同的神经网络,不同的损失函数对训练得到的模型影响不同。

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值