【深度学习】4-梯度确认时遇bug:写了个糟糕的softmax函数

简介: 【深度学习】4-梯度确认时遇bug:写了个糟糕的softmax函数

1. softmax函数代码


import numpy as np
def softmax(a): 
    a -= np.max(a)
    exp_a = np.exp(a)
    return exp_a / np.sum(exp_a)

2. 不能正确处理批量样本


我们对比一下处理单个样本和批量样本的情况:

a = np.array([1, 2, 3])
b = np.array([ [1, 2, 3], [1, 2, 3]])
softmax(a), softmax(b)

输出:

(array([0.09003057, 0.24472847, 0.66524096]),
 array([[0.04501529, 0.12236424, 0.33262048],
        [0.04501529, 0.12236424, 0.33262048]]))

容易发现,对应的值,后者的结果都是前者的一半。问题就在np.sum(exp_a)这里:

在批量数据(矩阵)情况下,我们本意是每个样本求得一个和值,即按行求和。它却将所有数据相加而仅得到一个和值。


再验证一下:

a = np.array([1, 2, 3])
b = np.array([[1, 2, 3], [1, 2, 3], [1, 2, 3]])
softmax(a), softmax(b)

输出:

(array([0.09003057, 0.24472847, 0.66524096]),
 array([[0.03001019, 0.08157616, 0.22174699],
        [0.03001019, 0.08157616, 0.22174699],
        [0.03001019, 0.08157616, 0.22174699]]))

可以看到,样本数增加为 3 个时,后者的输出也相应地变成了前者的三分之一。此时前者输出的 3 个数和为 1 ,而后者是输出的 9 个数和为 1。


现在单样本和批量的输出之间还具有倍数关系,如果每个样本是数据不同,那么将会更加乱套:


a = np.array([1, 2, 3])
b = np.array([[1, 2, 3], [4, 5, 6]])
softmax(a), softmax(b)

输出:

(array([0.09003057, 0.24472847, 0.66524096]),
 array([[0.00426978, 0.01160646, 0.03154963],
        [0.08576079, 0.23312201, 0.63369132]]))

3. 解决方案


分情况处理即可:


def softmax(x):
    if x.ndim == 2:
        x = x.T
        x = x - np.max(x, axis=0)
        y = np.exp(x) / np.sum(np.exp(x), axis=0)
        return y.T 
    x = x - np.max(x) 
    return np.exp(x) / np.sum(np.exp(x))

注:此代码来自前言提到的书本

我们之前分析了,其实就是求和函数的问题,因此我尝试着能不能写得更加简洁和统一些。


但是我没有成功,因为会遇到一些细节处理上的问题,例如批量情况下:最大值 max 也应当是按行求得;np.sum得到的是一维数组,为了最后相除时能够进行广播,进行转置是有必要的。


不过修改代码的尝试倒是加深了我对它的理解。


感谢阅读


文章知识点与官方知识档案匹配,可进一步学习相关知识

Python入门技能树人工智能基于Python的监督学习146892 人正在系统学习中

相关文章
|
5月前
|
机器学习/深度学习 人工智能 自然语言处理
梯度下降求极值,机器学习&深度学习
梯度下降求极值,机器学习&深度学习
46 0
|
11月前
|
机器学习/深度学习 PyTorch 算法框架/工具
深度学习Pytorch-Tensor函数
深度学习Pytorch-Tensor函数
67 0
|
10天前
|
机器学习/深度学习 算法
深度学习中的自适应抱团梯度下降法
【10月更文挑战第7天】 本文探讨了深度学习中一种新的优化算法——自适应抱团梯度下降法,它结合了传统的梯度下降法与现代的自适应方法。通过引入动态学习率调整和抱团策略,该方法在处理复杂网络结构时展现了更高的效率和准确性。本文详细介绍了算法的原理、实现步骤以及在实际应用中的表现,旨在为深度学习领域提供一种创新且有效的优化手段。
|
11天前
|
机器学习/深度学习 编解码
深度学习笔记(三):神经网络之九种激活函数Sigmoid、tanh、ReLU、ReLU6、Leaky Relu、ELU、Swish、Mish、Softmax详解
本文介绍了九种常用的神经网络激活函数:Sigmoid、tanh、ReLU、ReLU6、Leaky ReLU、ELU、Swish、Mish和Softmax,包括它们的定义、图像、优缺点以及在深度学习中的应用和代码实现。
58 0
深度学习笔记(三):神经网络之九种激活函数Sigmoid、tanh、ReLU、ReLU6、Leaky Relu、ELU、Swish、Mish、Softmax详解
|
11天前
|
机器学习/深度学习 Python
深度学习笔记(六):如何运用梯度下降法来解决线性回归问题
这篇文章介绍了如何使用梯度下降法解决线性回归问题,包括梯度下降法的原理、线性回归的基本概念和具体的Python代码实现。
41 0
|
2月前
|
机器学习/深度学习 PyTorch 算法框架/工具
深度学习中的梯度消失与梯度爆炸问题解析
【8月更文挑战第31天】深度学习模型在训练过程中常常遇到梯度消失和梯度爆炸的问题,这两个问题严重影响了模型的收敛速度和性能。本文将深入探讨这两个问题的原因、影响及解决策略,并通过代码示例具体展示如何在实践中应用这些策略。
|
3月前
|
机器学习/深度学习 算法
现代深度学习框架构建问题之tinyDL中机器学习的通用组件与深度学习如何解决
现代深度学习框架构建问题之tinyDL中机器学习的通用组件与深度学习如何解决
58 2
|
2月前
|
机器学习/深度学习 算法
|
4月前
|
机器学习/深度学习 人工智能 算法
【机器学习】深度探索:从基础概念到深度学习关键技术的全面解析——梯度下降、激活函数、正则化与批量归一化
【机器学习】深度探索:从基础概念到深度学习关键技术的全面解析——梯度下降、激活函数、正则化与批量归一化
53 3
|
4月前
|
机器学习/深度学习 人工智能 Serverless
【深度学习】神经网络中的激活函数:释放非线性的力量
【深度学习】神经网络中的激活函数:释放非线性的力量
130 1