softmax中axis参数

本文通过实例详细解析了在TensorFlow中使用Softmax函数时,轴参数(axis)的不同设置如何影响计算结果,对比了在二维和三维数组上的具体差异。

从caffe中我们看到softmax有下面这些参数

// Message that stores parameters used by SoftmaxLayer, SoftmaxWithLossLayer
message SoftmaxParameter {
  enum Engine {
    DEFAULT = 0;
    CAFFE = 1;
    CUDNN = 2;
  }
  optional Engine engine = 1 [default = DEFAULT];

  // The axis along which to perform the softmax -- may be negative to index
  // from the end (e.g., -1 for the last axis).
  // Any other axes will be evaluated as independent softmaxes.
  optional int32 axis = 2 [default = 1];
}

一般来说axis也不需要修改,默认设为1,即在c上做计算。
那么设置不同的axis,结果有什么不同?我们举个例子一目了然;

import tensorflow as tf
import numpy as np

a = np.array([[1, 2, 3], [1, 2, 3]])
a = tf.cast(a, tf.float32)
#>>> a
#tf.Tensor: shape=(2, 3), dtype=float32, numpy=
#array([[1., 2., 3.],
#       [1., 2., 3.]], dtype=float32)>
# 

s1 = tf.nn.softmax(a,axis=0)
print(s1)
#tf.Tensor(
#[[0.5 0.5 0.5]
#[0.5 0.5 0.5]], shape=(2, 3), dtype=float32)

s2 = tf.nn.softmax(a,axis=1)
print(s2)
#tf.Tensor(
#[[0.09003057 0.24472848 0.66524094]
#[0.09003057 0.24472848 0.66524094]], shape=(2, 3), dtype=float32)


我们来看看计算过程:
axis = 0时(表示纵轴,方向从上到下)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

axis = 1时(表示横轴,方向从左到右)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
再举一个三维数组深入理解一下

import tensorflow as tf
import numpy as np

a = np.array([[[1, 2, 3], [1, 2, 3]],[[4, 5, 6], [4, 5, 6]]])
a = tf.cast(a, tf.float32)
#>>> a
#<tf.Tensor: shape=(2, 2, 3), dtype=float32, numpy=
#array([[[1., 2., 3.],
#        [1., 2., 3.]],
#
#       [[4., 5., 6.],
#        [4., 5., 6.]]], dtype=float32)>
#
s1 = tf.nn.softmax(a,axis=0)
print(s1)
#tf.Tensor(
#[[[0.04742587 0.04742587 0.04742587]
#  [0.04742587 0.04742587 0.04742587]]
#
# [[0.95257413 0.95257413 0.95257413]
#  [0.95257413 0.95257413 0.95257413]]], shape=(2, 2, 3), dtype=float32)

s2 = tf.nn.softmax(a,axis=1)
print(s2)
#tf.Tensor(
#[[[0.5 0.5 0.5]
#  [0.5 0.5 0.5]]
#
# [[0.5 0.5 0.5]
#  [0.5 0.5 0.5]]], shape=(2, 2, 3), dtype=float32)

s3 = tf.nn.softmax(a,axis=2)
print(s3)
#tf.Tensor(
#[[[0.09003057 0.24472848 0.66524094]
#  [0.09003057 0.24472848 0.66524094]]
#
# [[0.09003057 0.24472848 0.66524094]
#  [0.09003057 0.24472848 0.66524094]]], shape=(2, 2, 3), dtype=float32)

计算过程如下:
axis=0时
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
。。。再来重复上面3个计算3次

axis=1时(1和2的计算和上面二维差不多)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
。。。

在这里插入图片描述
axis=2时
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

<think>好的,用户想知道如何在Softmax模型中实现手写数字识别,特别是需要示例教程。首先,我需要回忆一下Softmax回归的基本原理。Softmax通常用于多分类问题,而MNIST数据集正好是一个包含0-9手写数字的经典数据集,非常适合作为例子。 接下来,我应该整理实现步骤。通常,这个过程包括数据预处理、模型定义、训练过程和结果评估。根据引用[2]中的信息,MNIST数据集已经预处理为784维的向量,所以可能需要加载数据并标准化。同时,引用[3]和[4]提到使用numpy和一些超参数调整,比如学习率、batch size,还有momentum的应用。这些都需要在步骤中体现出来。 然后,我需要考虑代码示例的结构。用户可能需要一个简单的Python示例,使用numpy而不是深度学习框架,以便更清楚地展示原理。Softmax的模型部分需要参数初始化,比如权重矩阵W的形状应该是(784,10),因为输入是784维,输出是10类。前向计算中的softmax函数要注意数值稳定性,减去最大值防止指数溢出,这在引用[3]中提到的防止除以零的小数字可能相关。 训练过程部分,需要实现梯度下降,可能包括动量。引用[1]和[4]对比了有无动量的情况,所以代码中需要体现这一点。比如,可以设置一个动量参数,在更新权重时考虑之前的梯度。损失函数使用交叉熵,准确率计算则是比较预测类别和真实标签。 超参数调整部分,用户可能想知道学习率、batch size的影响,以及如何记录训练过程中的损失和准确率,画出曲线。这部分需要在代码中留出注释或者变量,方便用户调整。 最后,生成相关问题时要围绕用户可能进一步想了解的内容,比如数据预处理的细节、参数初始化的方法、动量优化原理、超参数影响等。确保问题覆盖用户可能遇到的后续疑问,并引导他们深入探索。 现在需要检查LaTeX格式是否正确,所有数学公式如softmax函数、交叉熵损失、梯度更新等都要用$...$或$$...$$包裹。例如,softmax的公式应该是$$ \text{Softmax}(z_i) = \frac{e^{z_i}}{\sum_{j=1}^C e^{z_j}} $$,而交叉熵损失则是$ L = -\frac{1}{N}\sum_{n=1}^N \sum_{c=1}^C y_{n,c} \log(p_{n,c}) $。确保代码块中的Python语法正确,特别是缩进和函数定义。 另外,引用标记要正确添加,比如在提到动量梯度下降时引用[^1],在数据描述时引用[^2],在代码中的epsilon引用[^3],以及在超参数调整部分引用[^4]。这样用户能对应到相关的参考资料。 总结步骤时,要分点明确,从数据准备到模型训练逐步引导用户。同时,示例代码要简洁,避免不必要的复杂,让用户容易理解和修改。可能还需要提醒用户注意的地方,比如数值稳定性处理,动量项的初始化,以及准确率的计算方法。 最后,相关问题需要涵盖实现细节、优化方法、超参数影响和扩展应用,帮助用户进一步学习。例如,如何防止过拟合、不同优化器的比较、处理更大的数据集等,这些都是用户可能感兴趣的方向。</think>### Softmax实现手写数字识别教程 #### 一、实现原理 Softmax回归是逻辑回归的多分类扩展,通过计算归一化概率分布实现分类。对于MNIST数据集(28x28像素图像),将输入展平为784维向量$ \mathbf{x} \in \mathbb{R}^{784} $,输出层计算: $$ \text{Softmax}(z_i) = \frac{e^{z_i}}{\sum_{j=1}^{10} e^{z_j}} \quad \text{其中} \ z_i = \mathbf{W}^T\mathbf{x} + \mathbf{b} $$ 交叉熵损失函数为: $$ L = -\frac{1}{N}\sum_{n=1}^N \sum_{c=1}^{10} y_{n,c} \log(p_{n,c}) $$ 其中$y_{n,c}$为真实标签的one-hot编码。 #### 二、实现步骤 1. **数据预处理** ```python # 加载MNIST数据集(需提前下载) train_images = np.load('mnist_train_images.npy') / 255.0 # 归一化 train_labels = np.load('mnist_train_labels.npy') test_images = np.load('mnist_test_images.npy') / 255.0 test_labels = np.load('mnist_test_labels.npy') ``` 2. **模型初始化** ```python W = np.random.randn(784, 10) * 0.01 # 权重矩阵 b = np.zeros((1, 10)) # 偏置项 momentum_W = np.zeros_like(W) # 动量梯度缓存[^1] ``` 3. **前向计算** ```python def softmax(z): z -= np.max(z, axis=1, keepdims=True) # 数值稳定性处理 exp_z = np.exp(z) return exp_z / np.sum(exp_z, axis=1, keepdims=True) def forward(X): return softmax(X.dot(W) + b) ``` 4. **训练过程(含动量优化)** ```python learning_rate = 0.1 beta = 0.9 # 动量系数[^4] batch_size = 64 for epoch in range(100): for i in range(0, len(train_images), batch_size): X_batch = train_images[i:i+batch_size] y_batch = train_labels[i:i+batch_size] # 计算梯度 probs = forward(X_batch) grad = X_batch.T.dot(probs - y_batch) / batch_size # 动量更新 momentum_W = beta * momentum_W + (1 - beta) * grad W -= learning_rate * momentum_W ``` 5. **评估结果** ```python test_probs = forward(test_images) pred_labels = np.argmax(test_probs, axis=1) accuracy = np.mean(pred_labels == test_labels) print(f"测试准确率: {accuracy:.4f}") # 典型结果约92% ``` #### 三、关键优化点 1. **动量加速收敛**:通过累积历史梯度方向,减少震荡[^1] 2. **学习率调整**:当准确率停滞时可尝试降至0.01 3. **批标准化**:添加`X_batch = (X_batch - np.mean(X_batch)) / (np.std(X_batch) + 1e-8)`提升稳定性
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值