{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Convolutional Neural Networks (LeNet)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"ExecuteTime": {
"end_time": "2019-07-03T22:31:52.883626Z",
"start_time": "2019-07-03T22:31:49.625348Z"
}
},
"outputs": [],
"source": [
"import d2l\n",
"from mxnet import autograd, gluon, init, np, npx\n",
"from mxnet.gluon import nn\n",
"npx.set_np()\n",
"\n",
"train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size=256)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"The model"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"ExecuteTime": {
"end_time": "2019-07-03T22:31:52.895271Z",
"start_time": "2019-07-03T22:31:52.887012Z"
}
},
"outputs": [],
"source": [
"net = nn.Sequential()\n",
"net.add(nn.Conv2D(channels=6, kernel_size=5, padding=2, activation='sigmoid'),\n",
" nn.AvgPool2D(pool_size=2, strides=2),\n",
" nn.Conv2D(channels=16, kernel_size=5, activation='sigmoid'),\n",
" nn.AvgPool2D(pool_size=2, strides=2),\n",
" nn.Dense(120, activation='sigmoid'),\n",
" nn.Dense(84, activation='sigmoid'),\n",
" nn.Dense(10))"
]
},
{
"cell_type": "raw",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Printing the output shape at each layer"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"ExecuteTime": {
"end_time": "2019-07-03T22:31:52.923597Z",
"start_time": "2019-07-03T22:31:52.897356Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"conv0 output shape:\t (1, 6, 28, 28)\n",
"pool0 output shape:\t (1, 6, 14, 14)\n",
"conv1 output shape:\t (1, 16, 10, 10)\n",
"pool1 output shape:\t (1, 16, 5, 5)\n",
"dense0 output shape:\t (1, 120)\n",
"dense1 output shape:\t (1, 84)\n",
"dense2 output shape:\t (1, 10)\n"
]
}
],
"source": [
"X = np.random.uniform(size=(1, 1, 28, 28))\n",
"net.initialize()\n",
"for layer in net:\n",
" X = layer(X)\n",
" print(layer.name, 'output shape:\\t', X.shape)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Evaluate accuracy on GPU."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"ExecuteTime": {
"end_time": "2019-07-03T22:31:52.932596Z",
"start_time": "2019-07-03T22:31:52.927756Z"
}
},
"outputs": [],
"source": [
"def evaluate_accuracy_gpu(net, data_iter, ctx=None):\n",
" if not ctx: # Query the first device the first parameter is on.\n",
" ctx = list(net.collect_params().values())[0].list_ctx()[0]\n",
" metric = d2l.Accumulator(2) # num_corrected_examples, num_examples\n",
" for X, y in data_iter:\n",
" X, y = X.as_in_context(ctx), y.as_in_context(ctx)\n",
" metric.add(d2l.accuracy(net(X), y), y.size)\n",
" return metric[0]/metric[1]"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"The training function on GPU."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"ExecuteTime": {
"end_time": "2019-07-03T22:31:52.959329Z",
"start_time": "2019-07-03T22:31:52.936473Z"
}
},
"outputs": [],
"source": [
"def train_ch5(net, train_iter, test_iter, num_epochs, lr, ctx=d2l.try_gpu()):\n",
" net.initialize(force_reinit=True, ctx=ctx, init=init.Xavier())\n",
" loss = gluon.loss.SoftmaxCrossEntropyLoss()\n",
" trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': lr})\n",
" animator = d2l.Animator(xlabel='epoch', xlim=[0,num_epochs],\n",
" legend=['train loss','train acc','test acc'])\n",
" timer = d2l.Timer()\n",
" for epoch in range(num_epochs):\n",
" metric = d2l.Accumulator(3) # train_loss, train_acc, num_examples\n",
" for i, (X, y) in enumerate(train_iter):\n",
" timer.start()\n",
" # The only difference compared to train_epoch_ch3\n",
" X, y = X.as_in_context(ctx), y.as_in_context(ctx)\n",
" with autograd.record():\n",
" y_hat = net(X)\n",
" l = loss(y_hat, y)\n",
" l.backward()\n",
" trainer.step(X.shape[0])\n",
" metric.add(l.sum(), d2l.accuracy(y_hat, y), X.shape[0])\n",
" timer.stop()\n",
" train_loss, train_acc = metric[0]/metric[2], metric[1]/metric[2]\n",
" if (i+1) % 50 == 0:\n",
" animator.add(epoch + i/len(train_iter),\n",
" (train_loss, train_acc, None))\n",
" test_acc = evaluate_accuracy_gpu(net, test_iter)\n",
" animator.add(epoch+1, (None, None, test_acc))\n",
" print('loss %.3f, train acc %.3f, test acc %.3f' % (\n",
" train_loss, train_acc, test_acc))\n",
" print('%.1f exampes/sec on %s'%(metric[2]*num_epochs/timer.sum(), ctx))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Now let's train the model."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"ExecuteTime": {
"end_time": "2019-07-03T22:32:30.126159Z",
"start_time": "2019-07-03T22:31:52.964939Z"
},
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"loss 0.479, train acc 0.820, test acc 0.825\n",
"52694.5 exampes/sec on gpu(0)\n"
]
},
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
"