一直对机器学习里的loss函数不太懂,这里做点笔记。

符号表示的含义,主要根据Andrew Ng的课程来的,\(m\)个样本,第\(i\)个样本为\(\vec x^{(i)}\),对应ground truth标签为\(y^{(i)}\)。

线性回归

假设函数:

\[\begin{align}
h_{\vec \theta}(\vec x^{(i)})
& = \vec \theta^T \vec x \\
\end{align}
\]

损失函数:

使用MSE(mean squared error)作为loss function

\[\begin{align}
J(\vec \theta)
& = \frac{1}{2m} \sum\limits_{i=1}^{m}(h_{\vec \theta}(\vec x^{(i)}-y^{(i)})^2 \\
\end{align}
\]

有mini-SGD梯度下降来优化

逻辑回归

逻辑回归用于二分类,所以也叫逻辑分类。

先把线性回归泛化为广义线性模型:

\[\begin{align}
h_{\vec \theta}(\vec x)
& = g^{-1}(\vec \theta^T \vec x^{(i)}) \\
\end{align}
\]

考虑到执行二分类,要预测的\(y^{(i)} \in {0,1}\),因此使用Sigmoid函数:

\[\begin{align}
g^{-1}(z)
& = \frac{1}{1+e^{-z}} \\
\end{align}
\]

得到逻辑回归的假设函数:

\[\begin{align}
h_{\vec \theta}(\vec x)
& = \frac{1}{1+e^{-\vec \theta^T \vec x}} \\
\end{align}
\]

获得逻辑回归的损失函数,则和线性模型不同。是从极大似然估计入手的,因为根据经验风险最小化的原则,应当搜索参数\(\vec \theta\)使得loss函数取值最小,数学表达式上等价于似然函数取最大。那么首先写出概率密度函数(p.d.f),似然函数是所有样本的概率密度乘积,再取对数,以及乘以\(-1\),就得到逻辑回归损失函数。

逻辑回归的每个样本\(\vec x^{(i)}\)对应的类别标签\(y^{(i)}\)服从两点分布(Bernoulli分布),其p.d.f为:

\[\begin{align}
f(y^{(i)}|\phi)
& = \phi^{y^{(i)}}(1-\phi)^{1-y^{(i)}} \\
\phi
& = h_{\vec \theta}(x^{(i)}) \\
\end{align}
\]

其中\(\phi\)表示\(p(y^{(i)}=1)\),也就是\(x^{(i)}\)被预测为正样本(“1”类)的概率。

对应的似然函数数为:

\[\begin{align}
l(\vec \theta)
& = \prod\limits_{i=1}^{m}p(y^{(i)}|h_{\vec \theta}(\vec x^{(i)})) \\
& = (h_{\vec \theta}(\vec x^{(i)})^{y^{(i)}})(1-h_{\vec \theta}(\vec x^{(i)}))^{1-y^{(i)}} \\
\end{align}
\]

则逻辑回归的损失函数(也即负对数似然函数为):

\[\begin{align}
J(\vec \theta)
& = -ln l(\vec \theta) \\
& = \sum\limits_{i=1}^{m}[y^{(i)}ln(h_{\vec \theta}(\vec x^{(i)}))+(1-y^{(i)})ln(1-h_{\vec \theta}(\vec x^{(i)}))] \\
\end{align}
\]

对应的优化求解,通常也是用梯度下降来搞

Softmax回归

考虑多类分类问题,\(y^{(i)} \in \{1,2,...,K\}\),则将逻辑回归扩展一下可以得到想要的假设函数和损失函数。

Softmax

Sigmoid是这样的映射:\(\sigma: \mathbb{R} \rightarrow \{0,1\}\)

Softmax则是这样的映射:\(\sigma: \mathbb{R}^{K} \rightarrow \{0,1\}^{K}\)

也即,Softmax对一个只有一个1的one-hot编码的类别标签向量\(\vec t^{(i)}\)做映射,效果上是\(\vec t^{(i)}\)的每个维度都被Softmax映射到\(\{0,1\}\)内,但并不是各个维度独立执行sigmoid,而是:

\[\begin{align}
Softmax(\vec x^{(i)})
& = [\frac{e^{x_1^{(i)}}}{\sum\limits_{j=1}^Ke^{x_j^{(i)}}};\frac{e^{x_2^{(i)}}}{\sum\limits_{j=1}^Ke^{x_j^{(i)}}}; ...; \frac{e^{x_K^{(i)}}}{\sum\limits_{j=1}^Ke^{x_j^{(i)}}};] \\
\end{align}
\]

所以,看到很多网上的资料写说softmax看作是sigmoid的泛化形式,我觉得有误导嫌疑,从公示上看并不像,仅仅是效果上相似。

Softmax回归的假设函数

相当于在线性回归对于各个类别的预测的概率向量基础上,包了一层Softmax:

\[\begin{align}
h_{\vec \theta}(\vec x^{(i)})
& = Softmax(\vec \theta_1^T\vec x^{(i)}; \vec \theta_2^T\vec x^{(i)}, ...;\vec \theta_K^T\vec x^{(i)}) \\
& = (p(y^{(i)}=1|\vec x^{(i)};\vec \theta_1); p(y^{(i)}=2|\vec x^{(i)};\vec \theta_1); ...; p(y^{(i)}=K|\vec x^{(i)};\vec \theta_1)) \\
& = \frac{1}{\sum\limits_{j=1}^Ke^{\vec \theta_j^T\vec x^{(i)}}}(e^{\vec \theta_1^T\vec x^{(i)}}; e^{\vec \theta_2^T\vec x^{(i)}}; ...; e^{\vec \theta_K^T\vec x^{(i)}}) \\
\end{align}
\]

Softmax回归的loss函数

依然是用负对数似然函数作为损失函数,只不过此时的p.d.f是服从多点分布的了:

\[\begin{align}
f(y^{(i)}|h_{\vec\theta}(\vec x^{(i)}))
& = \prod\limits_{j=1}^Kp(y^{(i)}=j) \\
& = \prod\limits_{j=1}^K(h_{\vec \theta_j}(\vec x^{(i)})^{y^{(i)}}) \\
\end{align}
\]

其似然函数为:

\[\begin{align}
l(\vec \theta)
& = \prod\limits_{i=1}^mf(y^{(i)}|h_{\vec\theta}(\vec x^{(i)})) \\
\end{align}
\]

使用负对数似然函数作为损失函数:

\[\begin{align}
J(\vec \theta)
& = -ln l(\vec \theta) \\
& = -\sum\limits_{i=1}^mlnf(y^{(i)}|h_{\vec \theta}(\vec x^{(i)})) \\
& = -\sum\limits_{i=1}^m \sum\limits_{j=1}^K y^{(i)}ln(h_{\vec\theta_j}(\vec x^{(i)})) \\
& = -\sum\limits_{i=1}^m \sum\limits_{j=1}^K (I(y^{(i)}=j)ln(h_{\vec\theta_j}(\vec x^{(i)}))) \\
& = -\sum\limits_{i=1}^m ln(\frac{e^{\vec\theta_{y^{(i)}}\vec x^{(i)}}}{\sum\limits_{l=1}^Ke^{\vec\theta_l^T \vec x^{(i)}}}) \\
\end{align}
\]


交叉熵损失函数Cross-Entropy Loss Function

逻辑回归是做二分类,其损失函数是2类情况下的Cross-Entropy Loss

Softmax回归是做多类分类,其损失函数是K类情况下的Cross-Entropy Loss:

\[\begin{align}
-\sum\limits_{c=1}^K{y_{gt}\log(y_{pred})}
\end{align}
\]

其中\(y_{gt}\)表示ground truth的y取值;\(y_{pred}\)表示分类器预测出来的y取值

Softmax Loss和Cross-Entropy Loss是一样的吗?

Cross-Entropy Loss,交叉熵损失函数。

严格说起来Cross-Entropy Loss则是规范属术语,而Softmax Loss不是规范术语。Softmax classifier是一个线性分类器,使用到了Cross-Entropy Loss函数。也就是说,交叉熵损失函数的梯度,告诉了Softmax分类器应该如何在SGD更新公式里更新参数\(\vec \theta\)。

但是,约定俗成的说法,当人们提到SoftmaxLoss时,说的就是Cross-Entropy Loss。

(ref: https://www.quora.com/Is-the-softmax-loss-the-same-as-the-cross-entropy-loss)

此外也注意到,Softmax回归和Logistic回归,它们的损失函数都是交叉熵损失函数。


Caffe里的线性回归、逻辑回归、softmax回归的损失函数

EuclideanLoss

EuclideanLoss作为线性回归的损失函数

SigmoidCrossEntropyLoss

SigmoidCrossEntropyLoss是计算cross-entropy (logistic) loss,也就是multi-label并且label相互独立,例如“民族歌曲、女声、优雅”这样的标签;当然也可用于互斥的label,也即多类分类展开为one-hot编码,但此时和SoftmaxWithLoss计算结果是不一样的。

这个函数具体实现的时候,为了数值的稳定性,做了处理。参考:http://www.caffecn.cn/?/question/25

SoftmaxWithLoss

SoftmaxWithLoss是计算multinomial logistic loss,也就是服从多点分布的情形,单个标签,one-hot编码后只有一个1,其计算结果和SigmoidCrossEntropyLoss不能混为一谈。

具体计算时,各个维度分别减去最大维度上的值再计算softmax(作为预测出的概率),然后套用到负对数似然损失函数中。参考shuzfan的博客:https://blog.csdn.net/shuzfan/article/details/51460895

二分类时,SigmoidCrossEntropyLoss和SoftmaxWithLoss的异同

两者相同的地方:都是用交叉熵作为损失函数的大模样

\[\frac{1}{m}\sum\limits_{i=1}^{m}[y^{(i)}\ln (\hat{y^{(i)}}) + (1-y^{(i)}) \ln (1-\hat{y^{(i)}})]
\]

其中\(\hat{y^{(i)}}\)也就是\(h_{\vec \theta}(\vec x^{(i)})\)

两者不同的地方:前者用sigmoid分别处理特征的各个维度,处理后作为预测的概率\(\hat y\);后者用softmax处理整个特征的各个维度。注意sigmoid是独立考虑计算各个维度的,而sofmax必须知道所有维度取值后才可以分别计算各个维度。

用代码运行结果验证:

取x=[3,5]作为分类器/回归器/损失函数的输入,对应的ground truth类别标签为1,one-hot编码后为[0,1]。

分别以EuclideanLoss、SigmoidCrossEntropyLoss、SoftmaxWithLoss作为loss函数进行计算(这里是为了示范,实际情况下分类任务不用EuclideanLoss)。

test.py:

#!/usr/bin/env python
# coding:utf-8 from __future__ import print_function
import os, sys
pycaffe_dir = '/home/chris/work/caffe-BVLC/python'
sys.path.insert(0, pycaffe_dir) import numpy as np
import caffe
from caffe import layers as L, params as P, to_proto
from caffe.proto import caffe_pb2
import yaml
from matplotlib import pyplot as plt x = np.array([3,5], dtype=np.float32)
x = x[np.newaxis, :] # single_label:把类别对应的索引作为single_label,从0开始
y1 = np.array([1], dtype=np.float32)
y1 = y1[np.newaxis, :] # full_label:one-hot编码格式的类别标签向量,只有一个1,其他都是0
y2 = np.array([0, 1], dtype=np.float32)
y2 = y2[np.newaxis, :] print('x.shape:', x.shape)
print('y1.shape:', y1.shape)
print('y2.shape:', y2.shape) caffe.set_mode_cpu()
solver = caffe.SGDSolver('solver.pt')
solver.net.blobs['data'].data[...] = x
solver.net.blobs['single_label'].data[...] = y1
solver.net.blobs['full_label'].data[...] = y2 solver.step(1)
print('===========================')
print('x: [3,5], y:1,i.e. [0,1]') # 0.12692806
# 也就是-math.log(math.exp(0)/(math.exp(-2)+math.exp(0)))
softmax_loss = solver.net.blobs['softmax_loss'].data
print('softmax_loss:', softmax_loss) # 3.0553026
# 也就是-(-3-math.log(1+math.exp(-3))-math.log(1+math.exp(-5)))
sigmoid_cross_entropy_loss = solver.net.blobs['sigmoid_cross_entropy_loss'].data
print('sigmoid_cross_entropy_loss:', sigmoid_cross_entropy_loss) # 12.5
euclidean_loss = solver.net.blobs['euclidean_loss'].data
print('euclidean_loss:', euclidean_loss)

solver.pt:

train_net: "train.pt"
base_lr: 0.1
display: 10
max_iter: 300
lr_policy: "step"
gamma: 0.1
momentum: 0.9
weight_decay: 0.0005
stepsize: 200
snapshot: 300
snapshot_prefix: "test"
solver_mode: CPU
device_id: 0

train.pt:

layer{
name: "data"
type: "Input"
top: "data"
top: "single_label"
top: "full_label"
input_param {
shape{
dim: 1
dim: 2
}
shape{
dim: 1
dim: 1
}
shape{
dim: 1
dim: 2
}
}
} layer {
name: "euclidean_loss"
type: "EuclideanLoss"
bottom: "data"
bottom: "full_label"
top: "euclidean_loss"
} layer{
name: "sigmoid_cross_entropy_loss"
type: "SigmoidCrossEntropyLoss"
bottom: "data"
bottom: "full_label"
top: "sigmoid_cross_entropy_loss"
} layer {
name: "softmax_loss"
type: "SoftmaxWithLoss"
bottom: "data"
bottom: "single_label"
top: "softmax_loss"
}

运行结果:

x: [3,5], y:1,i.e. [0,1]
softmax_loss: 0.12692806
sigmoid_cross_entropy_loss: 3.0553026
euclidean_loss: 12.5

loss函数学习笔记的更多相关文章

  1. C++学习基础十六-- 函数学习笔记

    C++ Primer 第七章-函数学习笔记 一步一个脚印.循序渐进的学习. 一.参数传递 每次调用函数时,都会重新创建函数所有的形参,此时所传递的实参将会初始化对应的形参. 「如果形参是非引用类型,则 ...

  2. contiki-main.c 中的process系列函数学习笔记 <contiki学习笔记之六>

    说明:本文依然依赖于 contiki/platform/native/contiki-main.c 文件. ---------------------------------------------- ...

  3. Swift2.0 函数学习笔记

    最近又有点忙,忙着找工作,忙着适应这个新环境.现在好了,上班两周周了,也适应过来了,又有时间安安静静的就行我们前面的学习了.今天这篇笔记,记录的就是函数的使用.下面这些代码基本上是理清楚了函数的额使用 ...

  4. MYSQL存储过程和函数学习笔记

    学至Tarena金牌讲师,金色晨曦科技公司技术总监沙利穆课程笔记的综合. 1. 什么是存储过程和函数 将SQL语句放入一个集合里,然后直接调用存储过程和函数来执行已经定义好的SQL语句,通过存储过程和 ...

  5. tensorflow函数学习笔记

    https://www.w3cschool.cn/tensorflow_python/tensorflow_python-4isv2ez3.html tf.trainable_variables返回的 ...

  6. Tensorflow 函数学习笔记

    A: A:## tf.argmax(A, axis).eval() 输出axis维度上最大的数的索引 axis=0:列,axis=1:行 A:## tf.add(a,b)  创建a+b的计算图 A:# ...

  7. jQuery 取消事件冒泡 阻止后续内容执行 闭包函数 (学习笔记)

    1.取消事件冒泡 <title>取消事件冒泡</title> <style> div { border:solid 1px black; } </style& ...

  8. Generator 函数学习笔记

    // 使用 function* 定义一个 generator 函数 function* helloWorldGenerator() { yield 'hello'; // yield 关键字作为暂停的 ...

  9. async 函数学习笔记

    async函数就是Generator函数的语法糖. var fs = require('fs'); var readFile = function (fileName) { return new Pr ...

随机推荐

  1. SpringCloud Zuul(路由网关)

    ⒈Zuul是什么? Zuul包含了两个最主要的功能,对请求的路由和过滤.其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础.过滤器功能则负责对请求的处理过程进行干预,是实 ...

  2. Web从入门到放弃<1>

    HTML大法: <01> <!DOCTYPE html> <html lang="en"> <head> <meta char ...

  3. 707. Design Linked List

    1. 原始题目 Design your implementation of the linked list. You can choose to use the singly linked list ...

  4. vsftp、ftps 搭建

    今天公司某个产品预上线,该产品需要向政府某部门提供一些数据. 该部门提交数据需要使用ftps,苦逼的我只能是测试环境搭建一套,用来测试提交数据. 先自行科普下ftps. 一.搭建vsftp 安装vsf ...

  5. 自学MVC看这里——全网最全ASP.NET MVC 教程汇总(转)

    自学MVC看这里——全网最全ASP.NET MVC 教程汇总   MVC架构已深得人心,微软也不甘落后,推出了Asp.net MVC.小编特意整理博客园乃至整个网络最具价值的MVC技术原创文章,为想要 ...

  6. boost 文件系统

    第 9 章 文件系统 目录 9.1 概述 9.2 路径 9.3 文件与目录 9.4 文件流 9.5 练习  该书采用 Creative Commons License 授权 9.1. 概述 库 Boo ...

  7. VIsual Studio编译OpenCV:无法打开python27_d.lib(python36_d.lib)的问题

    原文地址:http://blog.csdn.net/Chris_zhangrx/article/details/78947526 在用 VS2015 编译 Debug 版的 openCV 源码时,最后 ...

  8. ssdb主从及双主模型配置和简单管理

    ssdb主从及双主模型配置和简单管理 levelDB是一个key->value 的数据存储库,其只能在本地保存数据,支持持久化,并且支持保存非常大的数据,单机redis在保存较大数据的时候数十G ...

  9. matlab常用命令

    clc; %清屏 clear; %清除变量 close all; %关闭 doc %查看文档 meshgrid%采样mesh %网格曲面surf %光滑曲面plot %ezplotdiff figur ...

  10. Linux VPS基础命令 - cp复制文件命令

    cp命令在Linux VPS操作和应用过程中还是比较常用的,我们可以用来复制文件或者文件夹,重命名一个新的文件以及复制到其他路径中用于文件的转移. 举例用法: 1.复制root目录下的itbulu.c ...