Tensorflow学习(3)-损失函数

本文深入探讨了激活函数如ReLU、Sigmoid、Tanh在神经网络中的作用,以及经典损失函数如交叉熵、均方误差在分类和回归问题中的应用。通过自定义损失函数示例,展示了如何优化模型以最大化特定业务目标。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

激活函数去线性化

常用的有tf.nn.relu、tf.sigmoid(0~1)、tf.tanh(-1~1)。

经典损失函数-分类问题(交叉熵cross entropy)

cross_entropy = -tf.reduce_mean(y_*tf.log(tf.clip_by_value(y,1e-10,1)))

注意这里的y_,y可能为一个矩阵,需要注意的是要使用“*”而不是使用tf.matmul(),因为我们不是想要使用矩阵乘法。具体区别在书77页。

得到一个n x m大小的矩阵后,n是batch_size,m为分类的类数。reduce_mean来取平均值。

有个疑问就是按照交叉熵的公式应该是把n * m个数加起来除以n,但是如果使用reduce_mean是除以n*m。

Tensorflow的封装

因为交叉熵一般会与softmax回归一起使用,所以进行了封装

cross_entropy = tf.nn.softmax_cross_entropy_with_logits(labels=y_,logits=y)

在只有一个正确答案的分类问题中,下面这个函数可以进一步加速计算过程  //sparse:稀少的,稀疏的

cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y_,logits=y)

经典损失函数-回归问题(均方误差MES,mean squared error)

mse = tf.reduce_mean(tf.square(y_ - y))

自定义损失函数

例如:在预测商品销量时,如果预测多了厂家会损失成本,预测少了厂家会损失利润,但是每个产品成本只有一块,而利润有十块,这时均方误差就不能很好的最大化销售利润。

这时的损失函数可以设定为当y(预测数据)>y_,loss = 1(y - y_);当y<_y,loss = 10(y - y_)。通过这样的自定义损失函数的优化,模型提供的预测值更有可能最大化收益。

可以通过以下代码来实现这个损失函数  //reduce有缩小的意思,可以理解为缩小维度

loss = tf.reduce_sum(tf.where(tf.greater(y, y_), (y - y_) * 1, (y_ - y) * 10))

使用下面的程序测试以下这个损失函数的效果

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, seed=1))
# 前向传播,没有隐藏层
y = tf.matmul(x, w1)

# 定义预测多了和少了的成本
loss_less = 10
loss_more = 1
# 损失函数
loss = tf.reduce_sum(tf.where(tf.greater(y, y_), loss_more * (y - y_), loss_less * (y_ - y)))

train_step = tf.train.AdamOptimizer(0.001).minimize(loss)

# 通过随机数生成一个模拟数据集
rdm = RandomState(1)
data_size = 128
X = rdm.rand(data_size, 2)
# 设置回归的正确值为两个输入的和加上一个随机量
# 加上随机量的是因为避免最后能完全正确预测,不同的损失函数的效果就看不出来了
Y = [[x1 + x2 + rdm.random() / 10.0 - 0.05] for (x1, x2) in X]

# 训练神经网络
with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    STEP = 20000
    for i in range(STEP):
        start = (i * batch_size) % data_size
        end = min(start + batch_size, data_size)
        sess.run(train_step, feed_dict={x: X[start:end], y_: Y[start:end]})
        if i % 1000 == 0:
            print(sess.run(w1))

最后可以发现w1的值都比[1,1]要大。可以通过改变loss_less,loss_more的值来感受区别。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值