1. 简介
卷积神经网络(Convolutional Neural Network,CNN)是深度学习中一种重要的算法模型,常用于计算机视觉等领域。Numpy是Python中用于科学计算的扩展库,拥有丰富的数组、矩阵运算工具。
在本文中,我们将使用Numpy实现卷积神经网络(CNN)模型,这对于对卷积神经网络有一定了解但想深入理解其原理的读者是非常有帮助的。
2. CNN模型基础
2.1 卷积神经网络概述
卷积神经网络(CNN)是一种能够对输入进行学习和分类的深度神经网络模型,常用于图像识别、计算机视觉等应用领域。卷积神经网络利用了卷积核(或滤波器)对输入数据进行卷积计算,从而提取出数据中的特征信息,便于后续处理。通常,卷积神经网络由一系列卷积层、池化层和全连接层组成。
2.2 CNN模型主要层次
卷积神经网络主要包括卷积层、池化层和全连接层三种类型的层次。
卷积层:卷积层是卷积神经网络中最重要的层,其主要功能是提取输入数据中的特征信息。该层利用卷积核对输入数据进行计算,并将计算结果输出到下一层。
池化层: 池化层的作用是对卷积层输出的特征图进行降维处理,以减少后续处理的计算量。常见的池化操作包括最大池化(Max Pooling)和平均池化(Average Pooling)。
全连接层:全连接层是卷积神经网络中最后一层,其主要作用是将前面卷积层和池化层的输出结果映射到输出结果,通常是进行分类、识别等任务。
3. 用Numpy实现CNN模型
3.1 准备工作
在这个示例中,我们将使用Numpy实现一个简单的卷积神经网络,用于对手写数字进行识别。首先,我们需要安装几个Python库:
pip install numpy matplotlib sklearn
3.2 数据预处理
在这个示例中,我们将使用MNIST数据集作为输入数据。需要对数据进行标准化处理,将像素点数据缩放到0到1之间,以便进行后续处理。
from sklearn.datasets import fetch_openml
import numpy as np
data = fetch_openml('mnist_784', version=1, cache=True)['data']
data = data / 255
labels = fetch_openml('mnist_784', version=1, cache=True)['target']
labels = np.array(list(map(int, labels)))
3.3 构造CNN模型
下面是一个简单的CNN模型,它由一个卷积层、一个池化层以及一个全连接层三部分组成。
class ConvolutionalNeuralNetwork:
def __init__(self):
self.C1 = ConvolutionalLayer(num_kernels=8, kernel_size=5, input_channels=1, stride=1, padding='same')
self.P2 = MaxPoolingLayer(pool_size=2, stride=2)
self.F3 = FullyConnectedLayer(num_inputs=4 * 4 * 8, num_outputs=10, activation_fn='sigmoid')
def forward(self, X):
Z1 = self.C1.forward(X)
A1 = relu(Z1) # relu作为激活函数
P2 = self.P2.forward(A1)
F3_input = P2.reshape(P2.shape[0], -1)
A3 = self.F3.forward(F3_input)
return A3
3.4 模型训练
使用交叉熵作为损失函数,使用反向传播算法进行梯度下降训练模型。
nn = ConvolutionalNeuralNetwork()
costs = [] #用于存储每次迭代的损失函数值
for _ in range(10):
permutation = np.random.permutation(labels.shape[0])
X, Y = data[permutation,:][:1000], labels[permutation][:1000]
Y = np.eye((np.max(Y) + 1))[Y].T
A3 = nn.forward(X.reshape(-1, 1, 28, 28))
cost = cross_entropy_loss(Y, A3) # 使用交叉熵作为损失函数
dA3 = A3 - Y
nn.F3.backward(dA3)
dP2 = nn.F3.derivative() @ dA3
nn.P2.backward(dP2.reshape(P2.shape))
dA1 = nn.P2.derivative() @ dP2.reshape(P2.shape)
dZ1 = relu_derivative(nn.C1.forward(X.reshape(-1, 1, 28, 28))) * dA1
nn.C1.backward(dZ1)
nn.C1.update(0.1)
nn.F3.update(0.1)
costs.append(cost)
plt.plot(costs)
3.5 模型预测
对于新的输入数据,我们使用训练好的模型进行预测。
permutation = np.random.permutation(test_labels.shape[0])
X, Y = test_data[permutation,:][:100], test_labels[permutation][:100]
Y = np.eye((np.max(Y) + 1))[Y].T
pred = np.argmax(nn.forward(X.reshape(-1, 1, 28, 28)), axis=0)
accuracy = np.mean(pred == np.argmax(Y, axis=0)) * 100
print(f'Accuracy: {accuracy}%')
4. 总结
本文通过使用Numpy实现卷积神经网络(CNN)模型,并以MNIST手写数字识别为例进行模型训练和预测。
CNN模型是深度学习中经典的模型之一,较好地解决了计算机视觉等领域中的图像分类、识别等问题。Numpy是Python中使用广泛的科学计算库,其优秀的数组和矩阵计算能力为实现复杂的数学计算提供了强大的工具。