当前位置:首页 >> 技术栈专业化分层 >> 【TensorFlow-windows】部分损失函数测试,长虹h5018

【TensorFlow-windows】部分损失函数测试,长虹h5018

cpugpu芯片开发光刻机 技术栈专业化分层 1
文件名:【TensorFlow-windows】部分损失函数测试,长虹h5018 【TensorFlow-windows】部分损失函数测试 前言

在TensorFlow中提供了挺多损失函数的,这里主要测试一下均方差与交叉熵相关的几个函数的计算流程。主要是测试来自于tf.nn与tf.losses的mean_square_error、sigmoid_cross_entry、softmax_cross_entry、sparse_softmax_cross_entry

国际惯例,参考博客:

官方文档

一文搞懂交叉熵在机器学习中的使用,透彻理解交叉熵背后的直觉

TensorFlow中多标签分类

预备 单热度编码one-hot

先复习一下one_hot编码,就是将真实标签转换为01标签,需要注意的是tf的one_hot编码中标签0代表的是1,0,0...而非0,0,0...

labels_n=np.array([0,1,2])labels_oh=tf.one_hot(labels_n,depth=3)with tf.Session() as sess:print(sess.run(labels_oh))'''[[1. 0. 0.][0. 1. 0.][0. 0. 1.]]''' softmax

通常将最后的输出规整到和为1的形式:

softmax = tf.exp(logits) / tf.reduce_sum(tf.exp(logits), axis)

设输出为z=(z1,z2,⋯ ,zn)z=(z_1,z_2,\cdots,z_n)z=(z1,z2,,zn),则 σ(z)j=ezj∑i=1nezk\sigma(z)_j=\frac{e^{z_j}}{\sum_{i=1}^n e^{z_k}} σ(z)j=i=1nezkezj

sigmoid

激活函数: f(x)=11+e−xf(x)=\frac{1}{1+e^{-x}} f(x)=1+ex1

交叉熵

多标签分类(每个样本可能属于多个标签),最后一层使用sigmoid激活:

−ylog⁡(P(y))−(1−y)log⁡(1−P(y))-y\log(P(y))-(1-y)\log(1-P(y)) ylog(P(y))(1y)log(1P(y))

单标签分类(每个样本只可能属于一个标签),最后一层使用softmax激活: −∑i=1nyilog⁡(P(yi))-\sum_{i=1}^n y_i\log(P(y_i)) i=1nyilog(P(yi))

准备测试

进入测试之前,需要先引入相关的包

import numpy as npimport tensorflow as tf

交叉熵相关函数的测试,使用的变量是

labels=np.array([[1,0,0],[0,1,0],[0,0,1]],dtype='float32')preds=np.array([[5,6,3],[7,5,1],[1,2,8]],dtype='float32') 均方差损失-MSE 原理

对应项相减的平方和的均值,通常用来做回归,计算预测值与真实值的误差

代码测试

定义相关变量:

ori_labels=np.array([[1,2,3]],dtype='float32')pred_labels=np.array([[5,3,3]],dtype='float32')

调用原本函数测试:

mse_op=tf.losses.mean_squared_error(labels=ori_labels,predictions=pred_labels)with tf.Session() as sess:print(sess.run(mse_op))'''5.6666665'''

手动实现过程:

with tf.Session() as sess:print(sess.run(tf.reduce_mean(tf.square(ori_labels-pred_labels))))'''5.6666665''' 总结

原理就是求原标签与预测标签的平方和损失的均值。

sigmoid_cross_entry 原理

使用sigmoid激活的交叉熵,毫无疑问,玩得多标签分类,流程是:

将输出用sigmoid激活使用多标签分类的交叉熵计算损失 代码测试

使用tf.losses中的交叉熵损失

tf_sce=tf.losses.sigmoid_cross_entropy(labels,preds)with tf.Session() as sess:print(sess.run(tf_sce))#2.3132434

使用tf.nn中的交叉熵损失:

tf_sce1=tf.nn.sigmoid_cross_entropy_with_logits(labels=labels,logits=preds)with tf.Session() as sess:print(sess.run(tf_sce1))'''[[6.7153485e-03 6.0024757e+00 3.0485873e+00][7.0009112e+00 6.7153485e-03 1.3132617e+00][1.3132617e+00 2.1269281e+00 3.3540637e-04]]'''

使用流程实现:

#先计算sigmoid,再计算交叉熵preds_sigmoid=tf.sigmoid(preds)ce=-labels*tf.log(preds_sigmoid)-(1-labels)*(tf.log(1-preds_sigmoid))# ce= - tf.reduce_sum(labels*tf.log(preds_sigmoid),-1)with tf.Session() as sess:print(sess.run(ce))print(sess.run(tf.reduce_mean(ce)))'''[[6.7153242e-03 6.0024934e+00 3.0485876e+00][7.0009704e+00 6.7153242e-03 1.3132617e+00][1.3132617e+00 2.1269276e+00 3.3539196e-04]]2.3132522''' 总结

多标签分类,输入是原始和预测标签的编码

tf.losses中的计算结果是tf.nn中计算结果的均值

softmax_cross_entry 原理

使用softmax激活,显然就是单标签分类的情况,流程是:

将输出用softmax激活计算单标签分类的交叉熵损失 代码测试

使用tf.losses中的函数:

tf_sce=tf.losses.softmax_cross_entropy(labels,preds)with tf.Session() as sess:print(sess.run(tf_sce))#1.160502

使用tf.nn中的函数:

tf_sce1=tf.nn.softmax_cross_entropy_with_logits(labels=labels,logits=preds)with tf.Session() as sess:print(sess.run(tf_sce1))#[1.3490121 2.129109 0.00338493]

使用流程计算:

#先计算softmax,再计算交叉熵preds_sigmoid=tf.nn.softmax(preds)ce= - tf.reduce_sum(labels*tf.log(preds_sigmoid),-1)# ce=-labels*tf.log(preds_sigmoid)-(1-labels)*(tf.log(1-preds_sigmoid))with tf.Session() as sess:print(sess.run(ce))print(sess.run(tf.reduce_mean(ce)))'''[1.3490121 2.129109 0.00338495]1.1605021''' 总结 用于单标签分类,输入是真实和预测标签的单热度编码tf.losses中的计算结果是tf.nn中计算结果的均值 sparse_softmax_cross_entry 原理

还是看到softmax,依旧是单标签分类,但是多了个sparse,代表输入标签可以是非单热度标签,流程:

将原标签转为单热度编码将输出用softmax激活计算单标签分类的交叉熵 代码测试

假设原始标签的非单热度编码是:

labels_n=np.array([0,1,2])

利用tf.losses中的损失函数:

tf_scen=tf.losses.sparse_softmax_cross_entropy(labels=labels_n,logits=preds)with tf.Session() as sess:print(sess.run(tf_sce))#1.160502

利用tf.nn中的损失函数:

tf_sce1=tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels_n,logits=preds)with tf.Session() as sess:print(sess.run(tf_sce1))print(sess.run(tf.reduce_mean(tf_sce1)))'''[1.3490121 2.129109 0.00338493]1.160502'''

利用流程实现:

labels_onehot=tf.one_hot(labels_n,depth=3)preds_sigmoid=tf.nn.softmax(preds)ce= - tf.reduce_sum(labels_onehot*tf.log(preds_sigmoid),-1)# ce=-labels*tf.log(preds_sigmoid)-(1-labels)*(tf.log(1-preds_sigmoid))with tf.Session() as sess:print(sess.run(labels_onehot))print(sess.run(ce))print(sess.run(tf.reduce_mean(ce))) '''[[1. 0. 0.][0. 1. 0.][0. 0. 1.]][1.3490121 2.129109 0.00338495]1.1605021''' 总结 有sparse代表原始标签不用转成单热度编码适用于单标签分类tf.losses是tf.nn中函数的均值 总结

本文主要对比了:

tf.nn、tf.losses中同一类损失函数的使用方法与区别分析计算流程,并实现验证了解TensorFlow中回归、单标签分类、多标签分类的损失函数的选择

博客代码:

链接:https://pan.baidu.com/s/1b40rNxjdOIIE2g7_Afctiw 提取码:0sb0

协助本站SEO优化一下,谢谢!
关键词不能为空
同类推荐
«    2025年12月    »
1234567
891011121314
15161718192021
22232425262728
293031
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
搜索
最新留言
文章归档
网站收藏
友情链接