详解TensorFlow的 tf.nn.softmax 函数:softmax 激活函数

  • Post category:Python

TensorFlow是一种强大的机器学习框架,它提供了许多常见的神经网络层和优化器。其中一个常见的神经网络层是tf.nn.softmax函数,它用于将输入转换为概率分布。本文将详细介绍tf.nn.softmax的作用和使用方法,并提供两个实例加深理解。

作用

tf.nn.softmax()函数用于将输入向量归一化为概率分布。概率分布是指一组数值,这些数值均在0和1之间,其总和为1。这通常用于分类问题中的输出层。softmax函数经常用于多类别分类问题中的最后一层,将输出变成具有概率含义的预测。

使用方法

tf.nn.softmax()函数有一个必须传递的参数logits,它是一个二维张量,包含了未缩放的对数概率。在函数内部,logits的每个元素将被除以其行中的所有未缩放对数概率的总和。最终,函数将返回一个二维的概率张量。下面是softmax函数的基本使用方法示例:

import tensorflow as tf

logits = tf.constant([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=tf.float32)
softmax_result = tf.nn.softmax(logits)
print(softmax_result)

在这个例子中,我们创建了一个大小为3×3的张量,每行包含3个未缩放的概率。然后我们调用tf.nn.softmax()函数,并将结果打印出来。结果应该是一个3×3的张量,每行包含3个概率,这些概率分别代表该行元素是归一化后的结果的概率。总之,每行的和都应该等于1。

我们可以通过以下示例为通道维进行softmax:

import tensorflow as tf

logits = tf.constant([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=tf.float32)
softmax_result = tf.nn.softmax(logits, axis=-1)
print(softmax_result)

在这个示例中,我们通过指定axis=-1参数来沿通道维执行softmax。结果应该与第一个示例的结果相同,因为默认情况下,tf.nn.softmax()函数将针对最后一个轴执行softmax。

示例

示例1:MNIST分类问题

下面是一个解决MNIST分类问题的示例。如下所示:

import tensorflow as tf
from tensorflow import keras

# 加载MNIST数据集
mnist = keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

# 对输入数据执行归一化
train_images = train_images / 255.0
test_images = test_images / 255.0

# 创建模型
model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(10)
])

# 编译模型
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

# 训练模型
model.fit(train_images, train_labels, epochs=10)

# 评估模型
test_loss, test_acc = model.evaluate(test_images, test_labels)
print('Test accuracy:', test_acc)

# 将模型的输出传递给softmax函数
probability_model = tf.keras.Sequential([model, tf.keras.layers.Softmax()])

# 进行新的预测
predictions = probability_model.predict(test_images)
print(predictions[0])

在这个示例中,我们首先加载MNIST数据集,并对输入数据执行归一化。然后我们创建了一个具有两个全连接层的Keras Sequential模型。第一个全连接层包含128个神经元,其激活函数为ReLU。第二个密集层具有10个神经元,这是分类层。我们在本例中省略了一些其他类型的层。我们编译这个模型,使用Adam优化器和稀疏交叉熵作为损失函数,随后在训练集上进行10次迭代。完成训练后,我们对测试集进行评估,得到测试准确度。

该模型的输出是未缩放的对数概率,我们使用tf.nn.softmax()函数将模型的输出转换为概率。这里我们将模型的输出传递给tf.keras.Sequential()函数,该函数用于创建新的模型,该模型在模型的输出上添加一层tf.keras.layers.Softmax()层。

示例2:解决retinopathy of prematurity二元分类问题

下面是一个解决病理近视赤道视网膜病变二元分类问题的示例。如下所示:

import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential

# 处理输入数据
input_shape = (224, 224, 3)
input_tensor = layers.Input(shape=input_shape)
model = Sequential([
    input_tensor,
    layers.Conv2D(64, (3, 3), padding='same', activation='relu'),
    layers.Conv2D(64, (3, 3), padding='same', activation='relu'),
    layers.MaxPooling2D((2, 2), strides=(2, 2)),
    layers.Conv2D(128, (3, 3), padding='same', activation='relu'),   
    layers.Conv2D(128, (3, 3), padding='same', activation='relu'),
    layers.MaxPooling2D((2, 2), strides=(2, 2)),  
    layers.Conv2D(256, (3, 3), padding='same', activation='relu'),   
    layers.Conv2D(256, (3, 3), padding='same', activation='relu'),   
    layers.Conv2D(256, (3, 3), padding='same', activation='relu'),   
    layers.MaxPooling2D((2, 2), strides=(2, 2)),  
    layers.Conv2D(512, (3, 3), padding='same', activation='relu'),   
    layers.Conv2D(512, (3, 3), padding='same', activation='relu'),   
    layers.Conv2D(512, (3, 3), padding='same', activation='relu'),   
    layers.MaxPooling2D((2, 2), strides=(2, 2)),  
    layers.Conv2D(512, (3, 3), padding='same', activation='relu'),  
    layers.Conv2D(512, (3, 3), padding='same', activation='relu'),  
    layers.Conv2D(512, (3, 3), padding='same', activation='relu'),  
    layers.MaxPooling2D((2, 2), strides=(2, 2)), 
    layers.Flatten(),  
    layers.Dense(4096, activation='relu'),  
    layers.Dense(4096, activation='relu'),
    layers.Dense(2, activation='softmax')
])

# 编译模型并训练数据
model.compile(optimizer=tf.optimizers.SGD(lr=0.01), loss='binary_crossentropy', metrics=['accuracy'])

# 在数据上进行训练
model.fit_generator(train_generator, epochs=10)

# 评估模型
test_loss, test_accuracy = model.evaluate(test_generator)

# 输出测试结果
print("Test accuracy:", test_accuracy)

在这个示例中,我们定义了一个拥有许多卷积和池化层的深度神经网络来解决对新生儿视网膜病变病程预测的过程。我们使用了VGG16原始论文中的层级结构。softmax函数被用作分类器的激活函数。我们使用二进制交叉熵作为损失函数,采用随机梯度下降(SGD)来优化模型。完成训练后,我们评估模型在测试集上的表现,得到测试准确度。

总结

在这篇文章中,我们介绍了使用TensorFlow的tf.nn.softmax()函数将神经元输出转化为概率。我们提供了softmax函数的使用方法,以及两个示例,使读者能够更好地理解softmax函数在实际神经网络应用中的作用。