Tensorflow笔记之(损失函数)

常用的损失函数有:
1.均方误差: tf.reduce_mean(tf.square(真实值 - 预测值))
2.自定义损失函数:
3.交叉熵:tf.nn.softmax_cross_entropy_with_logits(lables = 真实值, logits = 预测值)

通过预测酸奶日销量与影响因素x1,x2之间关系,理解损失函数的用法。

1.均方误差: tf.reduce_mean(tf.square(真实值 - 预测值))

import tensorflow as tf
import numpy as np

BATCH_SIZE = 8
STEP = 5000 * BATCH_SIZE
LR = 1e-3

np.random.seed(1)
#构建数据集
X = np.random.random([32, 2])
Y_ = [[x1 + x2 + (np.random.rand()/10 - 0.05)] for x1, x2 in X]

#定义占位符
x = tf.placeholder(tf.float32, shape=(None, 2))
y_ = tf.placeholder(tf.float32, shape=(None, 1))

#定义权重
W1 = tf.Variable(tf.random_normal([2, 1], stddev=1))
# W2 = tf.Variable(tf.random_normal([3, 1], stddev=1))

#构建前向传播过程
y = tf.matmul(x, W1)
# y = tf.matmul(a, W2)

#定义损失函数,梯度下降减小损失
loss = tf.reduce_mean(tf.square(y_ - y))
train_step = tf.train.GradientDescentOptimizer(LR).minimize(loss)

#创建会话,开始训练
with tf.Session() as sess:
    init = tf.global_variables_initializer()
    sess.run(init)
    length = len(X)
    for i in range(STEP):
        start = (i * BATCH_SIZE) % length
        end = start + BATCH_SIZE
        sess.run(train_step, feed_dict={x: X[start: end], y_: Y_[start: end]})
        if i % 1000 == 0:
            loss_ = sess.run(loss, feed_dict={x: X, y_: Y_})
            # print(i, loss_)
            print(sess.run(W1))

打印结果:

 W1中的x1权重与x2的权重是在逐渐接近于1,与我们之间的生成公式是一致的。

上述代码是使用均方误差来减小损失,从而默认认为销量预测多了或者预测少了都是一样的,而实际上预测多了损失的是成本,预测少了损失的是利润。

所以在这里使用均方误差作为损失函数是没法讲利益最大化的,所以就要用到自定义的损失函数。

计算预测值与真实值之间的损失的累计和,所以可以吧损失定义为一个分段函数

# loss = tf.reduce_mean(tf.square(y_ - y))
#tf.greater(y, y_) a > b ? 输出true, false 
#tf.where(条件语句, 为True执行, 为False执行)
loss = tf.reduce_sum(tf.where(tf.greater(y, y_), (y - y_)*COST, (y_ - y)*PROFIT))
import tensorflow as tf
import numpy as np

BATCH_SIZE = 8
STEP = 5000 * BATCH_SIZE
LR = 1e-3
COST = 1
PROFIT = 9

if __name__ == '__main__':
    np.random.seed(1)
    # 构建数据集
    X = np.random.random([32, 2])
    Y_ = [[x1 + x2 + (np.random.rand() / 10 - 0.05)] for x1, x2 in X]

    # 定义占位符
    x = tf.placeholder(tf.float32, shape=(None, 2))
    y_ = tf.placeholder(tf.float32, shape=(None, 1))

    # 定义权重
    W1 = tf.Variable(tf.random_normal([2, 1], stddev=1))
    # W2 = tf.Variable(tf.random_normal([3, 1], stddev=1))

    # 构建前向传播过程
    y = tf.matmul(x, W1)
    # y = tf.matmul(a, W2)

    # 定义损失函数,梯度下降减小损失
    #tf.greater(y, y_) a > b ? 输出true, false 
    #tf.where(条件语句, 为True执行, 为False执行)
    loss = tf.reduce_sum(tf.where(tf.greater(y, y_), (y - y_)*COST, (y_ - y)*PROFIT))
    train_step = tf.train.GradientDescentOptimizer(LR).minimize(loss)

    # 创建会话,开始训练
    with tf.Session() as sess:
        init = tf.global_variables_initializer()
        sess.run(init)
        length = len(X)
        for i in range(STEP):
            start = (i * BATCH_SIZE) % length
            end = start + BATCH_SIZE
            sess.run(train_step, feed_dict={x: X[start: end], y_: Y_[start: end]})
            if i % 1000 == 0:
                loss_ = sess.run(loss, feed_dict={x: X, y_: Y_})
                # print(i, loss_)
                print(sess.run(W1))

可见模型在往多里预测,因为成本1元而利润9元,所以模型会往多里预测。

当我们把成本改成9元利润改成1元时得到如下结果 

 可见模型在往少里进行预测。

原文地址:https://www.cnblogs.com/answerThe/p/11468595.html