在深度学习中,softmax函数和交叉熵函数是两个重要的概念。softmax函数是用来将多个输出值映射到[0,1]之间,同时使得它们的和为1。交叉熵函数是用来计算两个概率分布之间的距离,常用于分类任务中的损失函数。Python是一种广泛应用于深度学习领域的编程语言,本文将介绍如何使用Python编写softmax函数和交叉熵函数,并给出相应的实例。
一、softmax函数
softmax函数的数学表达式如下:
$$ y_i = \frac{e^{x_i}}{\sum_{j=1}^{n} e^{x_j}} $$
其中,$x_i$表示输入向量的第$i$个元素,$n$表示输入向量的维度,$y_i$表示输出向量的第$i$个元素。softmax函数的作用是将输入向量映射到一个概率分布,其中每个元素的值在[0,1]之间且和为1。在神经网络中,softmax函数常用于多分类任务中最后一层的输出。
使用Python实现softmax函数的代码如下:
```python
import numpy as np
def softmax(x):
return np.exp(x) / np.sum(np.exp(x), axis=0)
```
其中,np.exp(x)表示对输入向量的每个元素求指数,np.sum(np.exp(x), axis=0)表示对这些指数求和。最终的输出向量即为每个指数除以总和。
二、交叉熵函数
交叉熵函数的数学表达式如下:
$$ H(p,q) = -\sum_{x} p(x) \log q(x) $$
其中,$p(x)$表示真实的概率分布,$q(x)$表示预测的概率分布,$x$表示可能的类别。交叉熵函数的值越小,表示两个概率分布越接近。在神经网络中,交叉熵函数常用于分类任务中的损失函数。
使用Python实现交叉熵函数的代码如下:
```python
import numpy as np
def cross_entropy(p, q):
return -np.sum(p * np.log(q))
```
其中,p和q都是概率分布,可以用numpy数组表示。np.log(q)表示对每个元素求自然对数,p * np.log(q)表示对应元素相乘。最终的输出即为所有元素的乘积之和的相反数。
三、实例
下面给出一个简单的实例,使用softmax函数和交叉熵函数实现手写数字分类。该实例使用MNIST数据集,包含60000张训练图片和10000张测试图片,每张图片大小为28x28像素。我们将图片展开成一维向量,大小为784。
首先,我们需要加载数据集:
```python
from tensorflow.keras.datasets import mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(60000, 784) / 255.0
X_test = X_test.reshape(10000, 784) / 255.0
```
将每个像素的值除以255,使得它们的范围在[0,1]之间。然后,我们可以使用softmax函数和交叉熵函数来训练模型:
```python
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder(categories='auto')
y_train = encoder.fit_transform(y_train.reshape(-1, 1)).toarray()
y_test = encoder.transform(y_test.reshape(-1, 1)).toarray()
def train(X, y, lr, epochs):
W = np.random.randn(784, 10) * 0.01
b = np.zeros((1, 10))
for i in range(epochs):
z = np.dot(X, W) + b
a = softmax(z)
cost = cross_entropy(y, a)
dW = np.dot(X.T, a - y) / X.shape[0]
db = np.mean(a - y, axis=0, keepdims=True)
W -= lr * dW
b -= lr * db
if i % 100 == 0:
print(f'Epoch {i}, cost {cost:.4f}')
return W, b
W, b = train(X_train, y_train, lr=0.01, epochs=1000)
```
此处我们使用随机梯度下降算法来训练模型,lr表示学习率,epochs表示迭代次数。在每次迭代中,我们先计算模型的输出$a$和损失函数的值$cost$,然后计算梯度$dW$和$db$,最后更新参数$W$和$b$。
最后,我们可以使用测试集来评估模型的性能:
```python
def predict(X, W, b):
z = np.dot(X, W) + b
a = softmax(z)
return np.argmax(a, axis=1)
y_pred = predict(X_test, W, b)
accuracy = np.mean(y_pred == np.argmax(y_test, axis=1))
print(f'Accuracy: {accuracy:.4f}')
```
我们可以得到模型在测试集上的准确率为0.9259。这个结果并不是很好,但是可以通过增加网络的层数、隐藏层的大小、调整学习率等方法进行改进。
四、