aboutsummaryrefslogtreecommitdiff
path: root/backend/microservice/cnn.ipynb
blob: 07e5793f03d1990b7b22a79e19d182af3b2cba56 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "cnn.ipynb",
      "provenance": [],
      "collapsed_sections": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "id": "6F26G3XmhJzo"
      },
      "outputs": [],
      "source": [
        "from keras.datasets import mnist"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "(X_train, y_train), (X_test, y_test) = mnist.load_data()"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "ETsULRXo3rZ4",
        "outputId": "94f13f89-d4d1-48f8-c2de-c5786ff04c9c"
      },
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz\n",
            "11493376/11490434 [==============================] - 0s 0us/step\n",
            "11501568/11490434 [==============================] - 0s 0us/step\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "Ocekivace se matrice, tj. tenzori sa 3 dimenzije (treca dimenzija zbog boje, ovde je samo 1 kanal za boju)."
      ],
      "metadata": {
        "id": "urRMnUU64KHq"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "X_train.shape"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "GtjP-YsE3tFv",
        "outputId": "f4d098ed-0ff0-4d38-aa8a-f4de93cdf5e2"
      },
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(60000, 28, 28)"
            ]
          },
          "metadata": {},
          "execution_count": 3
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "import keras.backend as K"
      ],
      "metadata": {
        "id": "825S6a-u3w1l"
      },
      "execution_count": 4,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# (60000, 1, 28, 28)\n",
        "# (60000, 28, 28, 1)\n",
        "img_size = X_train.shape[1]\n",
        "if K.image_data_format() == 'channels_first':\n",
        "    X_train = X_train.reshape(X_train.shape[0], 1, img_size, img_size)\n",
        "    X_test = X_test.reshape(X_test.shape[0], 1, img_size, img_size)\n",
        "else:\n",
        "    X_train = X_train.reshape(X_train.shape[0], img_size, img_size, 1)\n",
        "    X_test = X_test.reshape(X_test.shape[0], img_size, img_size, 1)"
      ],
      "metadata": {
        "id": "NJIy4hbh4El3"
      },
      "execution_count": 5,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "X_train.shape"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "zx4gXXu44Fv_",
        "outputId": "08cd45d3-a6d4-4861-d4f4-309efe3e6d45"
      },
      "execution_count": 6,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(60000, 28, 28, 1)"
            ]
          },
          "metadata": {},
          "execution_count": 6
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "Normalizacija [0, 1]"
      ],
      "metadata": {
        "id": "oU_3WQlC_uEz"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "X_train = X_train / 255"
      ],
      "metadata": {
        "id": "gJtMCJgs4jOU"
      },
      "execution_count": 7,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "X_test = X_test / 255"
      ],
      "metadata": {
        "id": "GzHqfIzL4jLx"
      },
      "execution_count": 8,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "y_train.shape"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "WdL5WmJx4jI9",
        "outputId": "d6a3c2f9-33f5-4e82-8d98-973bf8e46961"
      },
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(60000,)"
            ]
          },
          "metadata": {},
          "execution_count": 9
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "y_train[0]"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "tClA8nQI4jGY",
        "outputId": "04d0adc2-722d-4071-e9df-539b36b09b07"
      },
      "execution_count": 10,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "5"
            ]
          },
          "metadata": {},
          "execution_count": 10
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "Da bi postojalo 10 kategorija."
      ],
      "metadata": {
        "id": "LEwFN_Bn_541"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "from tensorflow.keras.utils import to_categorical"
      ],
      "metadata": {
        "id": "h9CACgTC4jDo"
      },
      "execution_count": 11,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "num_classes = 10\n",
        "y_train = to_categorical(y_train, num_classes)\n",
        "y_test = to_categorical(y_test, num_classes)"
      ],
      "metadata": {
        "id": "_Ql0QF8l4jBD"
      },
      "execution_count": 12,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "y_train.shape"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "t4smFP-g4i9n",
        "outputId": "9eed648e-c031-435d-e02f-064d67bcc837"
      },
      "execution_count": 13,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(60000, 10)"
            ]
          },
          "metadata": {},
          "execution_count": 13
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "Instanca je niz od 10 brojeva."
      ],
      "metadata": {
        "id": "r_hUC23OAJg9"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "y_train[0]"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "EDmHkxEk4i6o",
        "outputId": "edfffee9-b9ef-48f1-d54a-f0b675de2416"
      },
      "execution_count": 14,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([0., 0., 0., 0., 0., 1., 0., 0., 0., 0.], dtype=float32)"
            ]
          },
          "metadata": {},
          "execution_count": 14
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "Conv2D - za konvolucione mreze, za slike je 2D.\n",
        "\n",
        "Konvolucija se dobro primenjuje na slike u 2D ili zvuk u 1D, reci kao signali u 1D."
      ],
      "metadata": {
        "id": "yJBdA5gyAPpl"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "from keras.models import Sequential\n",
        "from keras.layers import Conv2D, MaxPooling2D, Dense, Flatten, Dropout"
      ],
      "metadata": {
        "id": "-vtDm0Vc4i3I"
      },
      "execution_count": 15,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "input_shape - potreban je za konvolucioni model"
      ],
      "metadata": {
        "id": "A0WBV8azDxW2"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "input_shape = X_train.shape[1:]\n",
        "input_shape"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "jZ6siLr34izw",
        "outputId": "7846accd-3886-451a-8d75-64d06a997dc2"
      },
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(28, 28, 1)"
            ]
          },
          "metadata": {},
          "execution_count": 16
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "Broj filtera prvi argument Conv2D\n",
        "\n",
        "kernel_size - velicina filtera (uglavnom neparnih dimenzija, male dimenzije)\n",
        "\n",
        "strides - za preskakanje pozicija, da bi se brze smanjila dimenzija\n",
        "\n",
        "padding - 'same' (da se dobije rezultat iste dimenzije koje je slika, u novi okvir od 1pix se stavljaju 0 sa 'same'), moze da se u taj okvir stave vrednosti suseda.\n",
        "\n",
        "input_shape - dimenzija ulaza\n",
        "\n",
        "pool_size - npr iz kvadrata velicine 2x2 da se izvlaci broj (max, mean)\n",
        "\n",
        "\n",
        "Dropout - koristi se za regularizaciju mreze, izlazi iz 20% neurona iz Pool-a da se postave na nulu, kao da nista nije ni radjeno, aktivan je dok se trenira. Random bira 20% neurona koje ubija.\n",
        "\n",
        "Dense - broj neurona i aktivaciona funkcija\n",
        "\n"
      ],
      "metadata": {
        "id": "LlaYMi4_Alb1"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "model = Sequential()\n",
        "model.add(Conv2D(32, kernel_size=(3,3), strides=(1,1), padding='same', activation='relu', input_shape=input_shape))\n",
        "model.add(MaxPooling2D(pool_size=(2,2)))\n",
        "model.add(Conv2D(64, kernel_size=(3,3), strides=(1,1), padding='same', activation='relu'))\n",
        "model.add(MaxPooling2D(pool_size=(2,2)))\n",
        "#\n",
        "model.add(Dropout(0.2))\n",
        "model.add(Flatten())\n",
        "model.add(Dense(units=64, activation='relu'))\n",
        "#\n",
        "model.add(Dropout(0.5))\n",
        "model.add(Dense(units=num_classes, activation='softmax'))\n",
        "model.summary()"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "SnK4smzd4iwr",
        "outputId": "a79cf3b2-d8ea-479c-984a-cdb8b73d5ecb"
      },
      "execution_count": 17,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Model: \"sequential\"\n",
            "_________________________________________________________________\n",
            " Layer (type)                Output Shape              Param #   \n",
            "=================================================================\n",
            " conv2d (Conv2D)             (None, 28, 28, 32)        320       \n",
            "                                                                 \n",
            " max_pooling2d (MaxPooling2D  (None, 14, 14, 32)       0         \n",
            " )                                                               \n",
            "                                                                 \n",
            " conv2d_1 (Conv2D)           (None, 14, 14, 64)        18496     \n",
            "                                                                 \n",
            " max_pooling2d_1 (MaxPooling  (None, 7, 7, 64)         0         \n",
            " 2D)                                                             \n",
            "                                                                 \n",
            " dropout (Dropout)           (None, 7, 7, 64)          0         \n",
            "                                                                 \n",
            " flatten (Flatten)           (None, 3136)              0         \n",
            "                                                                 \n",
            " dense (Dense)               (None, 64)                200768    \n",
            "                                                                 \n",
            " dropout_1 (Dropout)         (None, 64)                0         \n",
            "                                                                 \n",
            " dense_1 (Dense)             (None, 10)                650       \n",
            "                                                                 \n",
            "=================================================================\n",
            "Total params: 220,234\n",
            "Trainable params: 220,234\n",
            "Non-trainable params: 0\n",
            "_________________________________________________________________\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])"
      ],
      "metadata": {
        "id": "Bv0EvIlZ4is2"
      },
      "execution_count": 18,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "history = model.fit(X_train, y_train, batch_size=128, epochs=10, validation_split=0.2)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "W2zXNUkw4ioY",
        "outputId": "cb484853-3b12-486b-c144-1e72136172b4"
      },
      "execution_count": 19,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Epoch 1/10\n",
            "375/375 [==============================] - 13s 7ms/step - loss: 0.4608 - accuracy: 0.8555 - val_loss: 0.0848 - val_accuracy: 0.9748\n",
            "Epoch 2/10\n",
            "375/375 [==============================] - 2s 6ms/step - loss: 0.1591 - accuracy: 0.9525 - val_loss: 0.0590 - val_accuracy: 0.9812\n",
            "Epoch 3/10\n",
            "375/375 [==============================] - 2s 6ms/step - loss: 0.1208 - accuracy: 0.9646 - val_loss: 0.0449 - val_accuracy: 0.9866\n",
            "Epoch 4/10\n",
            "375/375 [==============================] - 2s 6ms/step - loss: 0.0975 - accuracy: 0.9720 - val_loss: 0.0465 - val_accuracy: 0.9858\n",
            "Epoch 5/10\n",
            "375/375 [==============================] - 2s 6ms/step - loss: 0.0868 - accuracy: 0.9744 - val_loss: 0.0412 - val_accuracy: 0.9879\n",
            "Epoch 6/10\n",
            "375/375 [==============================] - 2s 6ms/step - loss: 0.0773 - accuracy: 0.9766 - val_loss: 0.0415 - val_accuracy: 0.9882\n",
            "Epoch 7/10\n",
            "375/375 [==============================] - 2s 6ms/step - loss: 0.0712 - accuracy: 0.9787 - val_loss: 0.0362 - val_accuracy: 0.9902\n",
            "Epoch 8/10\n",
            "375/375 [==============================] - 2s 6ms/step - loss: 0.0642 - accuracy: 0.9802 - val_loss: 0.0371 - val_accuracy: 0.9892\n",
            "Epoch 9/10\n",
            "375/375 [==============================] - 2s 6ms/step - loss: 0.0630 - accuracy: 0.9812 - val_loss: 0.0306 - val_accuracy: 0.9909\n",
            "Epoch 10/10\n",
            "375/375 [==============================] - 2s 6ms/step - loss: 0.0563 - accuracy: 0.9825 - val_loss: 0.0347 - val_accuracy: 0.9894\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "from matplotlib import pyplot as plt"
      ],
      "metadata": {
        "id": "8f4ZN18N4ikp"
      },
      "execution_count": 20,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "Dropout je radio samo na trening skupu, ne radi na validacionom, zato su nelogicni rezultati (bolji na validacionom nego na testnom skupu)."
      ],
      "metadata": {
        "id": "AwcWe9MbH9ZO"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "plt.plot(history.epoch, history.history['loss'])\n",
        "plt.plot(history.epoch, history.history['val_loss'])"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 283
        },
        "id": "Jx0cOiCE4igN",
        "outputId": "e02c5758-79b4-48ce-f5bf-a1c95f65c640"
      },
      "execution_count": 21,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[<matplotlib.lines.Line2D at 0x7fe9903865d0>]"
            ]
          },
          "metadata": {},
          "execution_count": 21
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "plt.plot(history.epoch, history.history['accuracy'])\n",
        "plt.plot(history.epoch, history.history['val_accuracy'])"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 283
        },
        "id": "vGQGssWQ4icK",
        "outputId": "bb08a961-eada-4eaf-8a67-d24d65538d32"
      },
      "execution_count": 22,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[<matplotlib.lines.Line2D at 0x7fe99008fe90>]"
            ]
          },
          "metadata": {},
          "execution_count": 22
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "model.evaluate(X_test, y_test)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "A5qKGSYk4iXv",
        "outputId": "a9808af4-27b1-44ee-f04e-600b3f30c50f"
      },
      "execution_count": 23,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "313/313 [==============================] - 1s 3ms/step - loss: 0.0262 - accuracy: 0.9913\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[0.02624542824923992, 0.9912999868392944]"
            ]
          },
          "metadata": {},
          "execution_count": 23
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "from sklearn.metrics import confusion_matrix, classification_report\n",
        "import numpy as np"
      ],
      "metadata": {
        "id": "OHRAg-Ve4iTT"
      },
      "execution_count": 24,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "y_test.shape"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "lvhYZZTP4iNw",
        "outputId": "968b0dbc-bad0-49c6-d5c6-7845347fbda2"
      },
      "execution_count": 25,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(10000, 10)"
            ]
          },
          "metadata": {},
          "execution_count": 25
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "y_true = np.argmax(y_test, axis=1)\n",
        "y_pred = np.argmax(model.predict(X_test), axis=1)\n",
        "\n",
        "confusion_matrix(y_true, y_pred)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "0pTT09_74iCJ",
        "outputId": "a48493c9-d3cd-4fea-a3af-57fe60de8a85"
      },
      "execution_count": 26,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([[ 978,    0,    0,    0,    0,    0,    1,    1,    0,    0],\n",
              "       [   0, 1131,    2,    1,    0,    0,    0,    1,    0,    0],\n",
              "       [   1,    2, 1023,    1,    0,    0,    0,    5,    0,    0],\n",
              "       [   0,    0,    2, 1003,    0,    2,    0,    2,    1,    0],\n",
              "       [   0,    0,    0,    0,  972,    0,    1,    0,    1,    8],\n",
              "       [   1,    0,    0,    6,    0,  881,    3,    1,    0,    0],\n",
              "       [   4,    2,    1,    0,    2,    2,  947,    0,    0,    0],\n",
              "       [   0,    1,    4,    0,    0,    0,    0, 1022,    1,    0],\n",
              "       [   1,    1,    3,    1,    0,    1,    2,    1,  961,    3],\n",
              "       [   1,    1,    0,    0,    2,    3,    0,    6,    1,  995]])"
            ]
          },
          "metadata": {},
          "execution_count": 26
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "print(classification_report(y_true, y_pred))"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "P1AzFKyi_I24",
        "outputId": "5ba6243a-7315-481c-983b-6a255a74a2d9"
      },
      "execution_count": 27,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "              precision    recall  f1-score   support\n",
            "\n",
            "           0       0.99      1.00      0.99       980\n",
            "           1       0.99      1.00      1.00      1135\n",
            "           2       0.99      0.99      0.99      1032\n",
            "           3       0.99      0.99      0.99      1010\n",
            "           4       1.00      0.99      0.99       982\n",
            "           5       0.99      0.99      0.99       892\n",
            "           6       0.99      0.99      0.99       958\n",
            "           7       0.98      0.99      0.99      1028\n",
            "           8       1.00      0.99      0.99       974\n",
            "           9       0.99      0.99      0.99      1009\n",
            "\n",
            "    accuracy                           0.99     10000\n",
            "   macro avg       0.99      0.99      0.99     10000\n",
            "weighted avg       0.99      0.99      0.99     10000\n",
            "\n"
          ]
        }
      ]
    }
  ]
}