机器学习-关于自定义损失函数(tensorflow笔记)

对于回归问题,最常用的损失函数是均方误差(MSE,mean squared error),但是对于实际问题,MSE可能是最接近于真实答案,但却不是能使实际问题利益最大化的选择。比如对于预测商品销量的问题,如果预测多了(预测值大于真实销量),损失的是商品的成本,如果预测少了(预测值小于真实销量),损失的是商品的利润。那有可能多预测一个少挣1元,而少预测一个就可能少挣10元。因此需要将损失函数与利润直接联系起来。
于是用这个函数去刻画损失:

Loss(y,y')=∑f(yi,yi'),f(x,y)=a(x-y)(当x>y时),f(x,y)=b(y-x)(当x<=y时),a等于10,b等于1,符合了实际情况。
因此用tensorflow去训练神经网络完成这件事情。
import tensorflow as tf
from numpy.random import RandomState

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.0,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_op = tf.global_variables_initializer()
    sess.run(init_op)
    STEPS = 5000
    for i in range(STEPS):
        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))

此时的w1为:
也就是说比x1+x2大,因为预测少了损失更大,这样确实更符合逻辑。

若用均方误差作为损失函数,w1=[0.97437561,1.0243336]显然接近真实值,但并不是我们期待的更好的预测结果。

你可能感兴趣的:(机器/深度学习)