资讯专栏INFORMATION COLUMN

Python - softmax 实现

史占广 / 938人阅读

摘要:函数将任意维的实值向量转换为取值范围在之间的维实值向量,并且总和为。将原始输入映射到区间,并且总和为,常用于表征概率。这个性质用于保证数值的稳定性。当输入一个较大的数值时,函数将会超出限制,导致出错。

Softmax

softmax函数将任意n维的实值向量转换为取值范围在(0,1)之间的n维实值向量,并且总和为1。
例如:向量softmax([1.0, 2.0, 3.0]) ------> [0.09003057, 0.24472847, 0.66524096]

性质:

因为softmax是单调递增函数,因此不改变原始数据的大小顺序。

将原始输入映射到(0,1)区间,并且总和为1,常用于表征概率。

softmax(x) = softmax(x+c), 这个性质用于保证数值的稳定性。

softmax的实现及数值稳定性

一个最简单的计算给定向量的softmax的实现如下:

import numpy as np
def softmax(x):
"""Compute the softmax of vector x."""
    exp_x = np.exp(x)
    softmax_x = exp_x / np.sum(exp_x)
    return softmax_x 

让我们来测试一下上面的代码:

softmax([1, 2, 3])
array([0.09003057, 0.24472847, 0.66524096])

但是,当我们尝试输入一个比较大的数值向量时,就会出错:

softmax([1000, 2000, 3000])
array([nan, nan, nan])

这是由numpy中的浮点型数值范围限制所导致的。当输入一个较大的数值时,sofmax函数将会超出限制,导致出错。
为了解决这一问题,这时我们就能用到sofmax的第三个性质,即:softmax(x) = softmax(x+c),
一般在实际运用中,通常设定c = - max(x)。
接下来,我们重新定义softmax函数:

import numpy as np
def softmax(x):
"""Compute the softmax in a numerically stable way."""
    x = x - np.max(x)
    exp_x = np.exp(x)
    softmax_x = exp_x / np.sum(exp_x)
    return softmax_x

然后再次测试一下:

softmax([1000, 2000, 3000])
array([ 0.,  0.,  1.])

Done!

以上都是基于向量上的softmax实现,下面提供了基于向量以及矩阵的softmax实现,代码如下:

import numpy as np
def softmax(x):
    """
    Compute the softmax function for each row of the input x.

    Arguments:
    x -- A N dimensional vector or M x N dimensional numpy matrix.

    Return:
    x -- You are allowed to modify x in-place
    """
    orig_shape = x.shape

    if len(x.shape) > 1:
        # Matrix
        exp_minmax = lambda x: np.exp(x - np.max(x))
        denom = lambda x: 1.0 / np.sum(x)
        x = np.apply_along_axis(exp_minmax,1,x)
        denominator = np.apply_along_axis(denom,1,x) 
        
        if len(denominator.shape) == 1:
            denominator = denominator.reshape((denominator.shape[0],1))
        
        x = x * denominator
    else:
        # Vector
        x_max = np.max(x)
        x = x - x_max
        numerator = np.exp(x)
        denominator =  1.0 / np.sum(numerator)
        x = numerator.dot(denominator)
    
    assert x.shape == orig_shape
    return x

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/38689.html

相关文章

  • mnist 机器学习入门笔记(一) 学习softmax模型

    摘要:首先需要添加一个新的占位符用于输入正确值计算交叉熵的表达式可以实现为现在我们知道我们需要我们的模型做什么啦,用来训练它是非常容易的。 学习softmax回归模型 一. 下载mnist数据集 新建一个download.py 代码如下: Functions for downloading and reading MNIST data. from __future__ import abso...

    shengguo 评论0 收藏0
  • 使用 LSTM 智能作诗送新年祝福

    摘要:经过第一步的处理已经把古诗词词语转换为可以机器学习建模的数字形式,因为我们采用算法进行古诗词生成,所以还需要构建输入到输出的映射处理。 LSTM 介绍 序列化数据即每个样本和它之前的样本存在关联,前一数据和后一个数据有顺序关系。深度学习中有一个重要的分支是专门用来处理这样的数据的——循环神经网络。循环神经网络广泛应用在自然语言处理领域(NLP),今天我们带你从一个实际的例子出发,介绍循...

    lauren_liuling 评论0 收藏0

发表评论

0条评论

史占广

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<