概述
在【深度学习】多层感知机(一)Python从零开始实现双层感知机一文中,我们使用Python实现了一个单隐藏层的神经网络,并在MNIST手写数据集上进行了实验,最后得到了95%左右的识别准确率。
本文使用MXNet深度学习框架来实现上述博文中的单隐藏层神经网络,同样使用MNIST手写数据集进行实验。由于隐藏层和输出层都是全连接的,这样的神经网络也称之为多层感知机。下图表示一个拥有5个隐藏层节点的双层感知机(输入层不做任何操作,一般不计入层数)。
本文需要的先导知识:
实现和实验
# coding=utf-8
# author: BebDong
# 2018/12/19
# 多层感知机的gluon实现,使用MNIST手写数据集进行实验
from mxnet.gluon import data as gdata
from mxnet.gluon import loss as gloss
from mxnet.gluon import nn
from mxnet import init, gluon, autograd
# 计算单批次准确率
def accuracy(label_pred, label):
return (label_pred.argmax(axis=1) == label.astype('float32')).mean().asscalar()
# 评估测试准确率
def evaluate_accuracy(test_iter, net):
acc = 0
for feature, label in test_iter:
acc += accuracy(net(feature), label)
return acc / len(test_iter)
# 数据批量大小
batch_size = 256
# 加载数据,第一次运行将自动下载
mnist_train = gdata.vision.MNIST(train=True)
mnist_test = gdata.vision.MNIST(train=False)
# 转换数据格式
transformer = gdata.vision.transforms.ToTensor()
train_iter = gdata.DataLoader(mnist_train.transform_first(transformer), batch_size, shuffle=True)
test_iter = gdata.DataLoader(mnist_test.transform_first(transformer), batch_size, shuffle=False)
# 定义模型:单隐藏层,100个节点,激活函数选用ReLU
num_hidden_layer = 100
net = nn.Sequential()
net.add(nn.Dense(num_hidden_layer, activation='relu'), nn.Dense(10))
# 初始化参数
net.initialize(init.Normal(sigma=0.01))
# 定义损失函数:交叉熵
loss_function = gloss.SoftmaxCrossEntropyLoss()
# 定义优化算法:小批量随机梯度下降
trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.3})
# 训练
epochs = 20
for epoch in range(epochs):
# 训练损失
train_acc_sum = 0
# 训练准确率
train_loss_sum = 0
# 按批更新权重
for feature, label in train_iter:
with autograd.record():
label_pred = net(feature)
los = loss_function(label_pred, label)
los.backward()
trainer.step(batch_size)
train_loss_sum += los.mean().asscalar()
train_acc_sum += accuracy(label_pred, label)
print('epoch %d, loss %.4f, train acc %.3f' % (epoch + 1, train_loss_sum / len(train_iter), train_acc_sum / len(train_iter)))
# 测试,得出准确率
test_acc = evaluate_accuracy(test_iter, net)
print("Training done, test accuracy is: ", test_acc)
我的实验结果如下,使用ReLU
激活函数,在迭代20次,学习率=0.3时准确率在98%左右。
使用Sigmoid激活函数,其他参数不变:
net.add(nn.Dense(num_hidden_layer, activation='sigmoid'), nn.Dense(10))
结果如下,准确率也在95%左右。