我们可以从下图查看 Gluon 的代码形式,前面一段可以看出 Gluon 使用的是符号式的执行构建神经网络,后面一部分构建 Softmax 交叉熵损失函数、计算梯度和执行反向传播等都十分简洁。net.hybridize() 函数可以将命令式执行转换为符号式执行。 总地来说符号式的执行更高效和便携,但是很难使用,而命令式的执行更灵活却可能比较慢。但是在 Gluon 中,我们可以使用命令式的执行开发模型,使用符号式的执行部署模型。因此,Gluon 将同时具备两种方法的优点,并且可以更加高效地应用在科研研究和产品中。 下面,我们分别从Gluon中的卷积神经网络和并行计算详细介绍Gluon的使用过程和特点,希望能和大家共同体会Gluon的命令式开发和符号式部署的高效性。 Gluon 中的卷积神经网络 现在我们看一下如何使用 gluon 来简洁的表示一个卷积神经网络。 from __future__ import print_functionimport mxnet as mxfrom mxnet import nd, autogradfrom mxnet import gluonimport numpy as npmx.random.seed(1) 设置环境 ctx = mx.gpu() 抓取 MNIST 数据集 mnist = mx.test_utils.get_mnist()batch_size = 64train_data = mx.io.NDArrayIter(mnist["train_data"], mnist["train_label"], batch_size, shuffle=True)test_data = mx.io.NDArrayIter(mnist["test_data"], mnist["test_label"], batch_size, shuffle=True) 定义一个卷积神经网络 如果要改变模型,你仅需要对这些代码行进行操作,atv直播,现在让我们使用 gluon.nn 填加一对卷积层。 net = gluon.nn.Sequential()with net.name_scope(): net.add(gluon.nn.Conv2D(channels=20, kernel_size=5, activation='relu')) net.add(gluon.nn.MaxPool2D(pool_size=2, strides=2)) net.add(gluon.nn.Conv2D(channels=50, kernel_size=5, activation='relu')) net.add(gluon.nn.MaxPool2D(pool_size=2, strides=2)) net.add(gluon.nn.Flatten()) net.add(gluon.nn.Dense(500, activation="relu")) net.add(gluon.nn.Dense(10)) 参数初始化 net.collect_params().initialize(mx.init.Xavier(magnitude=2.24), ctx=ctx) Softmax 交叉熵损失函数 loss = gluon.loss.SoftmaxCrossEntropyLoss() 优化器 trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': .1}) 编写评估循环以计算精度 def evaluate_accuracy(data_iterator, net): numerator = 0. denominator = 0. data_iterator.reset() for i, batch in enumerate(data_iterator): data = batch.data[0].as_in_context(ctx) label = batch.label[0].as_in_context(ctx) label_one_hot = nd.one_hot(label, 10) output = net(data) predictions = nd.argmax(output, axis=1) numerator += nd.sum(predictions == label) denominator += data.shape[0] return (numerator / denominator).asscalar() 训练循环 epochs = 10for e in range(epochs): train_data.reset() moving_loss = 0. for i, batch in enumerate(train_data): data = batch.data[0].as_in_context(ctx) label = batch.label[0].as_in_context(ctx) with autograd.record(): output = net(data) cross_entropy = loss(output, label) cross_entropy.backward() trainer.step(data.shape[0]) moving_loss = .99 * moving_loss + .01 * nd.mean(cross_entropy).asscalar() test_accuracy = evaluate_accuracy(test_data, net) train_accuracy = evaluate_accuracy(train_data, net) print("Epoch %d. Loss: %e, Train_acc %.4f, Test_acc %.4f" % (e, moving_loss, train_accuracy, test_accuracy)) Epoch 0. Loss: 7.431280e-02, Train_acc 0.9664, Test_acc 0.9627Epoch 1. Loss: 4.358178e-02, Train_acc 0.9845, Test_acc 0.9816Epoch 2. Loss: 3.054833e-02, Train_acc 0.9913, Test_acc 0.9878Epoch 3. Loss: 2.258651e-02, Train_acc 0.9942, Test_acc 0.9896Epoch 4. Loss: 1.622117e-02, Train_acc 0.9954, Test_acc 0.9900Epoch 5. Loss: 1.204737e-02, Train_acc 0.9958, Test_acc 0.9900Epoch 6. Loss: 9.149311e-03, Train_acc 0.9963, Test_acc 0.9896Epoch 7. Loss: 7.570230e-03, Train_acc 0.9962, Test_acc 0.9892Epoch 8. Loss: 5.724863e-03, Train_acc 0.9978, Test_acc 0.9900Epoch 9. Loss: 4.022369e-03, Train_acc 0.9984, Test_acc 0.9912 结论 (责任编辑:本港台直播) |