├── README.md └── Sentiment_Analysis_Series_part_1.ipynb /README.md: -------------------------------------------------------------------------------- 1 | # Sentiment-classification-using-XLNet 2 | Fine-tuning XLNet model for sentiment classification. 3 | Find my medium article on sentiment-analysis using XLNet here 4 | 5 | About XLNet: 6 | 11 | 12 | The notebook is divided into following parts: 13 |
    14 |
  1. Install and import all the dependencies required to set the code working.
  2. 15 |
  3. Prepare data
  4. 16 |
  5. Writing function to perform train step and evaluation.
  6. 17 |
  7. Fine-tuning XLNet model.
  8. 18 |
  9. Evaluate performance of the model.
  10. 19 |
  11. Making predictions on raw text.
  12. 20 |
21 | 22 | Results: 23 | 26 | -------------------------------------------------------------------------------- /Sentiment_Analysis_Series_part_1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Sentiment Analysis Series part-1.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [], 9 | "authorship_tag": "ABX9TyNxtXs+TX1Ira4fPz7vjXW1", 10 | "include_colab_link": true 11 | }, 12 | "kernelspec": { 13 | "name": "python3", 14 | "display_name": "Python 3" 15 | }, 16 | "accelerator": "GPU", 17 | "widgets": { 18 | "application/vnd.jupyter.widget-state+json": { 19 | "bd7d4d34bd6d46ae985741702b456aaf": { 20 | "model_module": "@jupyter-widgets/controls", 21 | "model_name": "HBoxModel", 22 | "state": { 23 | "_view_name": "HBoxView", 24 | "_dom_classes": [], 25 | "_model_name": "HBoxModel", 26 | "_view_module": "@jupyter-widgets/controls", 27 | "_model_module_version": "1.5.0", 28 | "_view_count": null, 29 | "_view_module_version": "1.5.0", 30 | "box_style": "", 31 | "layout": "IPY_MODEL_e8135d40c9c4460d9ce1eb0885c562e4", 32 | "_model_module": "@jupyter-widgets/controls", 33 | "children": [ 34 | "IPY_MODEL_0954f506d85d4723a3b32b6606db0015", 35 | "IPY_MODEL_297ea592ec1b44558448159860cd1aa0" 36 | ] 37 | } 38 | }, 39 | "e8135d40c9c4460d9ce1eb0885c562e4": { 40 | "model_module": "@jupyter-widgets/base", 41 | "model_name": "LayoutModel", 42 | "state": { 43 | "_view_name": "LayoutView", 44 | "grid_template_rows": null, 45 | "right": null, 46 | "justify_content": null, 47 | "_view_module": "@jupyter-widgets/base", 48 | "overflow": null, 49 | "_model_module_version": "1.2.0", 50 | "_view_count": null, 51 | "flex_flow": null, 52 | "width": null, 53 | "min_width": null, 54 | "border": null, 55 | "align_items": null, 56 | "bottom": null, 57 | "_model_module": "@jupyter-widgets/base", 58 | "top": null, 59 | "grid_column": null, 60 | "overflow_y": null, 61 | "overflow_x": null, 62 | "grid_auto_flow": null, 63 | "grid_area": null, 64 | "grid_template_columns": null, 65 | "flex": null, 66 | "_model_name": "LayoutModel", 67 | "justify_items": null, 68 | "grid_row": null, 69 | "max_height": null, 70 | "align_content": null, 71 | "visibility": null, 72 | "align_self": null, 73 | "height": null, 74 | "min_height": null, 75 | "padding": null, 76 | "grid_auto_rows": null, 77 | "grid_gap": null, 78 | "max_width": null, 79 | "order": null, 80 | "_view_module_version": "1.2.0", 81 | "grid_template_areas": null, 82 | "object_position": null, 83 | "object_fit": null, 84 | "grid_auto_columns": null, 85 | "margin": null, 86 | "display": null, 87 | "left": null 88 | } 89 | }, 90 | "0954f506d85d4723a3b32b6606db0015": { 91 | "model_module": "@jupyter-widgets/controls", 92 | "model_name": "FloatProgressModel", 93 | "state": { 94 | "_view_name": "ProgressView", 95 | "style": "IPY_MODEL_ed27989647d140eca7d3bf745145a3a0", 96 | "_dom_classes": [], 97 | "description": "Downloading: 100%", 98 | "_model_name": "FloatProgressModel", 99 | "bar_style": "success", 100 | "max": 798011, 101 | "_view_module": "@jupyter-widgets/controls", 102 | "_model_module_version": "1.5.0", 103 | "value": 798011, 104 | "_view_count": null, 105 | "_view_module_version": "1.5.0", 106 | "orientation": "horizontal", 107 | "min": 0, 108 | "description_tooltip": null, 109 | "_model_module": "@jupyter-widgets/controls", 110 | "layout": "IPY_MODEL_f97490f8dee84ccc8029e401abe1042e" 111 | } 112 | }, 113 | "297ea592ec1b44558448159860cd1aa0": { 114 | "model_module": "@jupyter-widgets/controls", 115 | "model_name": "HTMLModel", 116 | "state": { 117 | "_view_name": "HTMLView", 118 | "style": "IPY_MODEL_8d146a11180d4d918cbfc302fc7d2971", 119 | "_dom_classes": [], 120 | "description": "", 121 | "_model_name": "HTMLModel", 122 | "placeholder": "​", 123 | "_view_module": "@jupyter-widgets/controls", 124 | "_model_module_version": "1.5.0", 125 | "value": " 798k/798k [00:37<00:00, 21.2kB/s]", 126 | "_view_count": null, 127 | "_view_module_version": "1.5.0", 128 | "description_tooltip": null, 129 | "_model_module": "@jupyter-widgets/controls", 130 | "layout": "IPY_MODEL_73e86ec287c541d3a189620dd50c33b5" 131 | } 132 | }, 133 | "ed27989647d140eca7d3bf745145a3a0": { 134 | "model_module": "@jupyter-widgets/controls", 135 | "model_name": "ProgressStyleModel", 136 | "state": { 137 | "_view_name": "StyleView", 138 | "_model_name": "ProgressStyleModel", 139 | "description_width": "initial", 140 | "_view_module": "@jupyter-widgets/base", 141 | "_model_module_version": "1.5.0", 142 | "_view_count": null, 143 | "_view_module_version": "1.2.0", 144 | "bar_color": null, 145 | "_model_module": "@jupyter-widgets/controls" 146 | } 147 | }, 148 | "f97490f8dee84ccc8029e401abe1042e": { 149 | "model_module": "@jupyter-widgets/base", 150 | "model_name": "LayoutModel", 151 | "state": { 152 | "_view_name": "LayoutView", 153 | "grid_template_rows": null, 154 | "right": null, 155 | "justify_content": null, 156 | "_view_module": "@jupyter-widgets/base", 157 | "overflow": null, 158 | "_model_module_version": "1.2.0", 159 | "_view_count": null, 160 | "flex_flow": null, 161 | "width": null, 162 | "min_width": null, 163 | "border": null, 164 | "align_items": null, 165 | "bottom": null, 166 | "_model_module": "@jupyter-widgets/base", 167 | "top": null, 168 | "grid_column": null, 169 | "overflow_y": null, 170 | "overflow_x": null, 171 | "grid_auto_flow": null, 172 | "grid_area": null, 173 | "grid_template_columns": null, 174 | "flex": null, 175 | "_model_name": "LayoutModel", 176 | "justify_items": null, 177 | "grid_row": null, 178 | "max_height": null, 179 | "align_content": null, 180 | "visibility": null, 181 | "align_self": null, 182 | "height": null, 183 | "min_height": null, 184 | "padding": null, 185 | "grid_auto_rows": null, 186 | "grid_gap": null, 187 | "max_width": null, 188 | "order": null, 189 | "_view_module_version": "1.2.0", 190 | "grid_template_areas": null, 191 | "object_position": null, 192 | "object_fit": null, 193 | "grid_auto_columns": null, 194 | "margin": null, 195 | "display": null, 196 | "left": null 197 | } 198 | }, 199 | "8d146a11180d4d918cbfc302fc7d2971": { 200 | "model_module": "@jupyter-widgets/controls", 201 | "model_name": "DescriptionStyleModel", 202 | "state": { 203 | "_view_name": "StyleView", 204 | "_model_name": "DescriptionStyleModel", 205 | "description_width": "", 206 | "_view_module": "@jupyter-widgets/base", 207 | "_model_module_version": "1.5.0", 208 | "_view_count": null, 209 | "_view_module_version": "1.2.0", 210 | "_model_module": "@jupyter-widgets/controls" 211 | } 212 | }, 213 | "73e86ec287c541d3a189620dd50c33b5": { 214 | "model_module": "@jupyter-widgets/base", 215 | "model_name": "LayoutModel", 216 | "state": { 217 | "_view_name": "LayoutView", 218 | "grid_template_rows": null, 219 | "right": null, 220 | "justify_content": null, 221 | "_view_module": "@jupyter-widgets/base", 222 | "overflow": null, 223 | "_model_module_version": "1.2.0", 224 | "_view_count": null, 225 | "flex_flow": null, 226 | "width": null, 227 | "min_width": null, 228 | "border": null, 229 | "align_items": null, 230 | "bottom": null, 231 | "_model_module": "@jupyter-widgets/base", 232 | "top": null, 233 | "grid_column": null, 234 | "overflow_y": null, 235 | "overflow_x": null, 236 | "grid_auto_flow": null, 237 | "grid_area": null, 238 | "grid_template_columns": null, 239 | "flex": null, 240 | "_model_name": "LayoutModel", 241 | "justify_items": null, 242 | "grid_row": null, 243 | "max_height": null, 244 | "align_content": null, 245 | "visibility": null, 246 | "align_self": null, 247 | "height": null, 248 | "min_height": null, 249 | "padding": null, 250 | "grid_auto_rows": null, 251 | "grid_gap": null, 252 | "max_width": null, 253 | "order": null, 254 | "_view_module_version": "1.2.0", 255 | "grid_template_areas": null, 256 | "object_position": null, 257 | "object_fit": null, 258 | "grid_auto_columns": null, 259 | "margin": null, 260 | "display": null, 261 | "left": null 262 | } 263 | }, 264 | "c2b26508fa464328b2b30c851a0366fe": { 265 | "model_module": "@jupyter-widgets/controls", 266 | "model_name": "HBoxModel", 267 | "state": { 268 | "_view_name": "HBoxView", 269 | "_dom_classes": [], 270 | "_model_name": "HBoxModel", 271 | "_view_module": "@jupyter-widgets/controls", 272 | "_model_module_version": "1.5.0", 273 | "_view_count": null, 274 | "_view_module_version": "1.5.0", 275 | "box_style": "", 276 | "layout": "IPY_MODEL_18e0ec87d07d4c0bb3930b5cef204963", 277 | "_model_module": "@jupyter-widgets/controls", 278 | "children": [ 279 | "IPY_MODEL_bac82e5dc1974ef4ac18f743ecfb72b5", 280 | "IPY_MODEL_35d3d0c2b7004a6b87420e55a94ddcaf" 281 | ] 282 | } 283 | }, 284 | "18e0ec87d07d4c0bb3930b5cef204963": { 285 | "model_module": "@jupyter-widgets/base", 286 | "model_name": "LayoutModel", 287 | "state": { 288 | "_view_name": "LayoutView", 289 | "grid_template_rows": null, 290 | "right": null, 291 | "justify_content": null, 292 | "_view_module": "@jupyter-widgets/base", 293 | "overflow": null, 294 | "_model_module_version": "1.2.0", 295 | "_view_count": null, 296 | "flex_flow": null, 297 | "width": null, 298 | "min_width": null, 299 | "border": null, 300 | "align_items": null, 301 | "bottom": null, 302 | "_model_module": "@jupyter-widgets/base", 303 | "top": null, 304 | "grid_column": null, 305 | "overflow_y": null, 306 | "overflow_x": null, 307 | "grid_auto_flow": null, 308 | "grid_area": null, 309 | "grid_template_columns": null, 310 | "flex": null, 311 | "_model_name": "LayoutModel", 312 | "justify_items": null, 313 | "grid_row": null, 314 | "max_height": null, 315 | "align_content": null, 316 | "visibility": null, 317 | "align_self": null, 318 | "height": null, 319 | "min_height": null, 320 | "padding": null, 321 | "grid_auto_rows": null, 322 | "grid_gap": null, 323 | "max_width": null, 324 | "order": null, 325 | "_view_module_version": "1.2.0", 326 | "grid_template_areas": null, 327 | "object_position": null, 328 | "object_fit": null, 329 | "grid_auto_columns": null, 330 | "margin": null, 331 | "display": null, 332 | "left": null 333 | } 334 | }, 335 | "bac82e5dc1974ef4ac18f743ecfb72b5": { 336 | "model_module": "@jupyter-widgets/controls", 337 | "model_name": "FloatProgressModel", 338 | "state": { 339 | "_view_name": "ProgressView", 340 | "style": "IPY_MODEL_d8893bea6edb4154b051b344cae1636c", 341 | "_dom_classes": [], 342 | "description": "Downloading: 100%", 343 | "_model_name": "FloatProgressModel", 344 | "bar_style": "success", 345 | "max": 760, 346 | "_view_module": "@jupyter-widgets/controls", 347 | "_model_module_version": "1.5.0", 348 | "value": 760, 349 | "_view_count": null, 350 | "_view_module_version": "1.5.0", 351 | "orientation": "horizontal", 352 | "min": 0, 353 | "description_tooltip": null, 354 | "_model_module": "@jupyter-widgets/controls", 355 | "layout": "IPY_MODEL_d8c49d3421e843a6a2aadd20565ea5d2" 356 | } 357 | }, 358 | "35d3d0c2b7004a6b87420e55a94ddcaf": { 359 | "model_module": "@jupyter-widgets/controls", 360 | "model_name": "HTMLModel", 361 | "state": { 362 | "_view_name": "HTMLView", 363 | "style": "IPY_MODEL_3524b098b1944e5ba752f1fbfcb50aef", 364 | "_dom_classes": [], 365 | "description": "", 366 | "_model_name": "HTMLModel", 367 | "placeholder": "​", 368 | "_view_module": "@jupyter-widgets/controls", 369 | "_model_module_version": "1.5.0", 370 | "value": " 760/760 [00:42<00:00, 17.9B/s]", 371 | "_view_count": null, 372 | "_view_module_version": "1.5.0", 373 | "description_tooltip": null, 374 | "_model_module": "@jupyter-widgets/controls", 375 | "layout": "IPY_MODEL_0cba445897514d4b98192e28890df304" 376 | } 377 | }, 378 | "d8893bea6edb4154b051b344cae1636c": { 379 | "model_module": "@jupyter-widgets/controls", 380 | "model_name": "ProgressStyleModel", 381 | "state": { 382 | "_view_name": "StyleView", 383 | "_model_name": "ProgressStyleModel", 384 | "description_width": "initial", 385 | "_view_module": "@jupyter-widgets/base", 386 | "_model_module_version": "1.5.0", 387 | "_view_count": null, 388 | "_view_module_version": "1.2.0", 389 | "bar_color": null, 390 | "_model_module": "@jupyter-widgets/controls" 391 | } 392 | }, 393 | "d8c49d3421e843a6a2aadd20565ea5d2": { 394 | "model_module": "@jupyter-widgets/base", 395 | "model_name": "LayoutModel", 396 | "state": { 397 | "_view_name": "LayoutView", 398 | "grid_template_rows": null, 399 | "right": null, 400 | "justify_content": null, 401 | "_view_module": "@jupyter-widgets/base", 402 | "overflow": null, 403 | "_model_module_version": "1.2.0", 404 | "_view_count": null, 405 | "flex_flow": null, 406 | "width": null, 407 | "min_width": null, 408 | "border": null, 409 | "align_items": null, 410 | "bottom": null, 411 | "_model_module": "@jupyter-widgets/base", 412 | "top": null, 413 | "grid_column": null, 414 | "overflow_y": null, 415 | "overflow_x": null, 416 | "grid_auto_flow": null, 417 | "grid_area": null, 418 | "grid_template_columns": null, 419 | "flex": null, 420 | "_model_name": "LayoutModel", 421 | "justify_items": null, 422 | "grid_row": null, 423 | "max_height": null, 424 | "align_content": null, 425 | "visibility": null, 426 | "align_self": null, 427 | "height": null, 428 | "min_height": null, 429 | "padding": null, 430 | "grid_auto_rows": null, 431 | "grid_gap": null, 432 | "max_width": null, 433 | "order": null, 434 | "_view_module_version": "1.2.0", 435 | "grid_template_areas": null, 436 | "object_position": null, 437 | "object_fit": null, 438 | "grid_auto_columns": null, 439 | "margin": null, 440 | "display": null, 441 | "left": null 442 | } 443 | }, 444 | "3524b098b1944e5ba752f1fbfcb50aef": { 445 | "model_module": "@jupyter-widgets/controls", 446 | "model_name": "DescriptionStyleModel", 447 | "state": { 448 | "_view_name": "StyleView", 449 | "_model_name": "DescriptionStyleModel", 450 | "description_width": "", 451 | "_view_module": "@jupyter-widgets/base", 452 | "_model_module_version": "1.5.0", 453 | "_view_count": null, 454 | "_view_module_version": "1.2.0", 455 | "_model_module": "@jupyter-widgets/controls" 456 | } 457 | }, 458 | "0cba445897514d4b98192e28890df304": { 459 | "model_module": "@jupyter-widgets/base", 460 | "model_name": "LayoutModel", 461 | "state": { 462 | "_view_name": "LayoutView", 463 | "grid_template_rows": null, 464 | "right": null, 465 | "justify_content": null, 466 | "_view_module": "@jupyter-widgets/base", 467 | "overflow": null, 468 | "_model_module_version": "1.2.0", 469 | "_view_count": null, 470 | "flex_flow": null, 471 | "width": null, 472 | "min_width": null, 473 | "border": null, 474 | "align_items": null, 475 | "bottom": null, 476 | "_model_module": "@jupyter-widgets/base", 477 | "top": null, 478 | "grid_column": null, 479 | "overflow_y": null, 480 | "overflow_x": null, 481 | "grid_auto_flow": null, 482 | "grid_area": null, 483 | "grid_template_columns": null, 484 | "flex": null, 485 | "_model_name": "LayoutModel", 486 | "justify_items": null, 487 | "grid_row": null, 488 | "max_height": null, 489 | "align_content": null, 490 | "visibility": null, 491 | "align_self": null, 492 | "height": null, 493 | "min_height": null, 494 | "padding": null, 495 | "grid_auto_rows": null, 496 | "grid_gap": null, 497 | "max_width": null, 498 | "order": null, 499 | "_view_module_version": "1.2.0", 500 | "grid_template_areas": null, 501 | "object_position": null, 502 | "object_fit": null, 503 | "grid_auto_columns": null, 504 | "margin": null, 505 | "display": null, 506 | "left": null 507 | } 508 | }, 509 | "62d0e9673815468ba407019771a0b2ba": { 510 | "model_module": "@jupyter-widgets/controls", 511 | "model_name": "HBoxModel", 512 | "state": { 513 | "_view_name": "HBoxView", 514 | "_dom_classes": [], 515 | "_model_name": "HBoxModel", 516 | "_view_module": "@jupyter-widgets/controls", 517 | "_model_module_version": "1.5.0", 518 | "_view_count": null, 519 | "_view_module_version": "1.5.0", 520 | "box_style": "", 521 | "layout": "IPY_MODEL_6af011b92bd3462b937cea74a2094579", 522 | "_model_module": "@jupyter-widgets/controls", 523 | "children": [ 524 | "IPY_MODEL_47a41f0a294f42cbb2c9ec3916ca100e", 525 | "IPY_MODEL_3d9a5c47f9fb44ffa41f91cc37b8ee6e" 526 | ] 527 | } 528 | }, 529 | "6af011b92bd3462b937cea74a2094579": { 530 | "model_module": "@jupyter-widgets/base", 531 | "model_name": "LayoutModel", 532 | "state": { 533 | "_view_name": "LayoutView", 534 | "grid_template_rows": null, 535 | "right": null, 536 | "justify_content": null, 537 | "_view_module": "@jupyter-widgets/base", 538 | "overflow": null, 539 | "_model_module_version": "1.2.0", 540 | "_view_count": null, 541 | "flex_flow": null, 542 | "width": null, 543 | "min_width": null, 544 | "border": null, 545 | "align_items": null, 546 | "bottom": null, 547 | "_model_module": "@jupyter-widgets/base", 548 | "top": null, 549 | "grid_column": null, 550 | "overflow_y": null, 551 | "overflow_x": null, 552 | "grid_auto_flow": null, 553 | "grid_area": null, 554 | "grid_template_columns": null, 555 | "flex": null, 556 | "_model_name": "LayoutModel", 557 | "justify_items": null, 558 | "grid_row": null, 559 | "max_height": null, 560 | "align_content": null, 561 | "visibility": null, 562 | "align_self": null, 563 | "height": null, 564 | "min_height": null, 565 | "padding": null, 566 | "grid_auto_rows": null, 567 | "grid_gap": null, 568 | "max_width": null, 569 | "order": null, 570 | "_view_module_version": "1.2.0", 571 | "grid_template_areas": null, 572 | "object_position": null, 573 | "object_fit": null, 574 | "grid_auto_columns": null, 575 | "margin": null, 576 | "display": null, 577 | "left": null 578 | } 579 | }, 580 | "47a41f0a294f42cbb2c9ec3916ca100e": { 581 | "model_module": "@jupyter-widgets/controls", 582 | "model_name": "FloatProgressModel", 583 | "state": { 584 | "_view_name": "ProgressView", 585 | "style": "IPY_MODEL_767ef584a8ed49b4ae8ee7835208fb44", 586 | "_dom_classes": [], 587 | "description": "Downloading: 100%", 588 | "_model_name": "FloatProgressModel", 589 | "bar_style": "success", 590 | "max": 467042463, 591 | "_view_module": "@jupyter-widgets/controls", 592 | "_model_module_version": "1.5.0", 593 | "value": 467042463, 594 | "_view_count": null, 595 | "_view_module_version": "1.5.0", 596 | "orientation": "horizontal", 597 | "min": 0, 598 | "description_tooltip": null, 599 | "_model_module": "@jupyter-widgets/controls", 600 | "layout": "IPY_MODEL_769eba56a67d4d71b76f1240fd154a4e" 601 | } 602 | }, 603 | "3d9a5c47f9fb44ffa41f91cc37b8ee6e": { 604 | "model_module": "@jupyter-widgets/controls", 605 | "model_name": "HTMLModel", 606 | "state": { 607 | "_view_name": "HTMLView", 608 | "style": "IPY_MODEL_f6cc72303ee14b548a2c4c1282a1784b", 609 | "_dom_classes": [], 610 | "description": "", 611 | "_model_name": "HTMLModel", 612 | "placeholder": "​", 613 | "_view_module": "@jupyter-widgets/controls", 614 | "_model_module_version": "1.5.0", 615 | "value": " 467M/467M [00:06<00:00, 72.4MB/s]", 616 | "_view_count": null, 617 | "_view_module_version": "1.5.0", 618 | "description_tooltip": null, 619 | "_model_module": "@jupyter-widgets/controls", 620 | "layout": "IPY_MODEL_b9235fdb071742628781944bb3b6608d" 621 | } 622 | }, 623 | "767ef584a8ed49b4ae8ee7835208fb44": { 624 | "model_module": "@jupyter-widgets/controls", 625 | "model_name": "ProgressStyleModel", 626 | "state": { 627 | "_view_name": "StyleView", 628 | "_model_name": "ProgressStyleModel", 629 | "description_width": "initial", 630 | "_view_module": "@jupyter-widgets/base", 631 | "_model_module_version": "1.5.0", 632 | "_view_count": null, 633 | "_view_module_version": "1.2.0", 634 | "bar_color": null, 635 | "_model_module": "@jupyter-widgets/controls" 636 | } 637 | }, 638 | "769eba56a67d4d71b76f1240fd154a4e": { 639 | "model_module": "@jupyter-widgets/base", 640 | "model_name": "LayoutModel", 641 | "state": { 642 | "_view_name": "LayoutView", 643 | "grid_template_rows": null, 644 | "right": null, 645 | "justify_content": null, 646 | "_view_module": "@jupyter-widgets/base", 647 | "overflow": null, 648 | "_model_module_version": "1.2.0", 649 | "_view_count": null, 650 | "flex_flow": null, 651 | "width": null, 652 | "min_width": null, 653 | "border": null, 654 | "align_items": null, 655 | "bottom": null, 656 | "_model_module": "@jupyter-widgets/base", 657 | "top": null, 658 | "grid_column": null, 659 | "overflow_y": null, 660 | "overflow_x": null, 661 | "grid_auto_flow": null, 662 | "grid_area": null, 663 | "grid_template_columns": null, 664 | "flex": null, 665 | "_model_name": "LayoutModel", 666 | "justify_items": null, 667 | "grid_row": null, 668 | "max_height": null, 669 | "align_content": null, 670 | "visibility": null, 671 | "align_self": null, 672 | "height": null, 673 | "min_height": null, 674 | "padding": null, 675 | "grid_auto_rows": null, 676 | "grid_gap": null, 677 | "max_width": null, 678 | "order": null, 679 | "_view_module_version": "1.2.0", 680 | "grid_template_areas": null, 681 | "object_position": null, 682 | "object_fit": null, 683 | "grid_auto_columns": null, 684 | "margin": null, 685 | "display": null, 686 | "left": null 687 | } 688 | }, 689 | "f6cc72303ee14b548a2c4c1282a1784b": { 690 | "model_module": "@jupyter-widgets/controls", 691 | "model_name": "DescriptionStyleModel", 692 | "state": { 693 | "_view_name": "StyleView", 694 | "_model_name": "DescriptionStyleModel", 695 | "description_width": "", 696 | "_view_module": "@jupyter-widgets/base", 697 | "_model_module_version": "1.5.0", 698 | "_view_count": null, 699 | "_view_module_version": "1.2.0", 700 | "_model_module": "@jupyter-widgets/controls" 701 | } 702 | }, 703 | "b9235fdb071742628781944bb3b6608d": { 704 | "model_module": "@jupyter-widgets/base", 705 | "model_name": "LayoutModel", 706 | "state": { 707 | "_view_name": "LayoutView", 708 | "grid_template_rows": null, 709 | "right": null, 710 | "justify_content": null, 711 | "_view_module": "@jupyter-widgets/base", 712 | "overflow": null, 713 | "_model_module_version": "1.2.0", 714 | "_view_count": null, 715 | "flex_flow": null, 716 | "width": null, 717 | "min_width": null, 718 | "border": null, 719 | "align_items": null, 720 | "bottom": null, 721 | "_model_module": "@jupyter-widgets/base", 722 | "top": null, 723 | "grid_column": null, 724 | "overflow_y": null, 725 | "overflow_x": null, 726 | "grid_auto_flow": null, 727 | "grid_area": null, 728 | "grid_template_columns": null, 729 | "flex": null, 730 | "_model_name": "LayoutModel", 731 | "justify_items": null, 732 | "grid_row": null, 733 | "max_height": null, 734 | "align_content": null, 735 | "visibility": null, 736 | "align_self": null, 737 | "height": null, 738 | "min_height": null, 739 | "padding": null, 740 | "grid_auto_rows": null, 741 | "grid_gap": null, 742 | "max_width": null, 743 | "order": null, 744 | "_view_module_version": "1.2.0", 745 | "grid_template_areas": null, 746 | "object_position": null, 747 | "object_fit": null, 748 | "grid_auto_columns": null, 749 | "margin": null, 750 | "display": null, 751 | "left": null 752 | } 753 | } 754 | } 755 | } 756 | }, 757 | "cells": [ 758 | { 759 | "cell_type": "markdown", 760 | "metadata": { 761 | "id": "view-in-github", 762 | "colab_type": "text" 763 | }, 764 | "source": [ 765 | "\"Open" 766 | ] 767 | }, 768 | { 769 | "cell_type": "code", 770 | "metadata": { 771 | "id": "txqNzM1xIPIR", 772 | "colab_type": "code", 773 | "outputId": "efffa915-6104-4a1c-c751-90e516fad837", 774 | "colab": { 775 | "base_uri": "https://localhost:8080/", 776 | "height": 120 777 | } 778 | }, 779 | "source": [ 780 | "from google.colab import drive\n", 781 | "drive.mount('/content/drive')" 782 | ], 783 | "execution_count": 0, 784 | "outputs": [ 785 | { 786 | "output_type": "stream", 787 | "text": [ 788 | "Go to this URL in a browser: https://accounts.google.com/o/oauth2/auth?client_id=947318989803-6bn6qk8qdgf4n4g3pfee6491hc0brc4i.apps.googleusercontent.com&redirect_uri=urn%3aietf%3awg%3aoauth%3a2.0%3aoob&response_type=code&scope=email%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdocs.test%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdrive%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdrive.photos.readonly%20https%3a%2f%2fwww.googleapis.com%2fauth%2fpeopleapi.readonly\n", 789 | "\n", 790 | "Enter your authorization code:\n", 791 | "··········\n", 792 | "Mounted at /content/drive\n" 793 | ], 794 | "name": "stdout" 795 | } 796 | ] 797 | }, 798 | { 799 | "cell_type": "code", 800 | "metadata": { 801 | "id": "3m6sGbnGeXHk", 802 | "colab_type": "code", 803 | "outputId": "21365dc2-00df-4fcd-8b66-f1aee796f89f", 804 | "colab": { 805 | "base_uri": "https://localhost:8080/", 806 | "height": 351 807 | } 808 | }, 809 | "source": [ 810 | "!nvidia-smi" 811 | ], 812 | "execution_count": 0, 813 | "outputs": [ 814 | { 815 | "output_type": "stream", 816 | "text": [ 817 | "Sun Jun 14 03:02:22 2020 \n", 818 | "+-----------------------------------------------------------------------------+\n", 819 | "| NVIDIA-SMI 450.36.06 Driver Version: 418.67 CUDA Version: 10.1 |\n", 820 | "|-------------------------------+----------------------+----------------------+\n", 821 | "| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |\n", 822 | "| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |\n", 823 | "| | | MIG M. |\n", 824 | "|===============================+======================+======================|\n", 825 | "| 0 Tesla P100-PCIE... Off | 00000000:00:04.0 Off | 0 |\n", 826 | "| N/A 34C P0 27W / 250W | 0MiB / 16280MiB | 0% Default |\n", 827 | "| | | ERR! |\n", 828 | "+-------------------------------+----------------------+----------------------+\n", 829 | " \n", 830 | "+-----------------------------------------------------------------------------+\n", 831 | "| Processes: |\n", 832 | "| GPU GI CI PID Type Process name GPU Memory |\n", 833 | "| ID ID Usage |\n", 834 | "|=============================================================================|\n", 835 | "| No running processes found |\n", 836 | "+-----------------------------------------------------------------------------+\n" 837 | ], 838 | "name": "stdout" 839 | } 840 | ] 841 | }, 842 | { 843 | "cell_type": "code", 844 | "metadata": { 845 | "id": "HqQKcukJAicL", 846 | "colab_type": "code", 847 | "outputId": "548f009b-9187-47f5-fc78-8275907438b5", 848 | "colab": { 849 | "base_uri": "https://localhost:8080/", 850 | "height": 605 851 | } 852 | }, 853 | "source": [ 854 | "!pip install transformers" 855 | ], 856 | "execution_count": 0, 857 | "outputs": [ 858 | { 859 | "output_type": "stream", 860 | "text": [ 861 | "Collecting transformers\n", 862 | "\u001b[?25l Downloading https://files.pythonhosted.org/packages/48/35/ad2c5b1b8f99feaaf9d7cdadaeef261f098c6e1a6a2935d4d07662a6b780/transformers-2.11.0-py3-none-any.whl (674kB)\n", 863 | "\u001b[K |████████████████████████████████| 675kB 2.8MB/s \n", 864 | "\u001b[?25hRequirement already satisfied: tqdm>=4.27 in /usr/local/lib/python3.6/dist-packages (from transformers) (4.41.1)\n", 865 | "Requirement already satisfied: requests in /usr/local/lib/python3.6/dist-packages (from transformers) (2.23.0)\n", 866 | "Collecting sacremoses\n", 867 | "\u001b[?25l Downloading https://files.pythonhosted.org/packages/7d/34/09d19aff26edcc8eb2a01bed8e98f13a1537005d31e95233fd48216eed10/sacremoses-0.0.43.tar.gz (883kB)\n", 868 | "\u001b[K |████████████████████████████████| 890kB 15.5MB/s \n", 869 | "\u001b[?25hCollecting tokenizers==0.7.0\n", 870 | "\u001b[?25l Downloading https://files.pythonhosted.org/packages/14/e5/a26eb4716523808bb0a799fcfdceb6ebf77a18169d9591b2f46a9adb87d9/tokenizers-0.7.0-cp36-cp36m-manylinux1_x86_64.whl (3.8MB)\n", 871 | "\u001b[K |████████████████████████████████| 3.8MB 12.9MB/s \n", 872 | "\u001b[?25hRequirement already satisfied: dataclasses; python_version < \"3.7\" in /usr/local/lib/python3.6/dist-packages (from transformers) (0.7)\n", 873 | "Collecting sentencepiece\n", 874 | "\u001b[?25l Downloading https://files.pythonhosted.org/packages/d4/a4/d0a884c4300004a78cca907a6ff9a5e9fe4f090f5d95ab341c53d28cbc58/sentencepiece-0.1.91-cp36-cp36m-manylinux1_x86_64.whl (1.1MB)\n", 875 | "\u001b[K |████████████████████████████████| 1.1MB 26.3MB/s \n", 876 | "\u001b[?25hRequirement already satisfied: regex!=2019.12.17 in /usr/local/lib/python3.6/dist-packages (from transformers) (2019.12.20)\n", 877 | "Requirement already satisfied: numpy in /usr/local/lib/python3.6/dist-packages (from transformers) (1.18.5)\n", 878 | "Requirement already satisfied: packaging in /usr/local/lib/python3.6/dist-packages (from transformers) (20.4)\n", 879 | "Requirement already satisfied: filelock in /usr/local/lib/python3.6/dist-packages (from transformers) (3.0.12)\n", 880 | "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.6/dist-packages (from requests->transformers) (2020.4.5.1)\n", 881 | "Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.6/dist-packages (from requests->transformers) (2.9)\n", 882 | "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.6/dist-packages (from requests->transformers) (1.24.3)\n", 883 | "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.6/dist-packages (from requests->transformers) (3.0.4)\n", 884 | "Requirement already satisfied: six in /usr/local/lib/python3.6/dist-packages (from sacremoses->transformers) (1.12.0)\n", 885 | "Requirement already satisfied: click in /usr/local/lib/python3.6/dist-packages (from sacremoses->transformers) (7.1.2)\n", 886 | "Requirement already satisfied: joblib in /usr/local/lib/python3.6/dist-packages (from sacremoses->transformers) (0.15.1)\n", 887 | "Requirement already satisfied: pyparsing>=2.0.2 in /usr/local/lib/python3.6/dist-packages (from packaging->transformers) (2.4.7)\n", 888 | "Building wheels for collected packages: sacremoses\n", 889 | " Building wheel for sacremoses (setup.py) ... \u001b[?25l\u001b[?25hdone\n", 890 | " Created wheel for sacremoses: filename=sacremoses-0.0.43-cp36-none-any.whl size=893260 sha256=97710e3620e53f263dc38f0e295f2e16da22030a818999315a002e1088be2cf9\n", 891 | " Stored in directory: /root/.cache/pip/wheels/29/3c/fd/7ce5c3f0666dab31a50123635e6fb5e19ceb42ce38d4e58f45\n", 892 | "Successfully built sacremoses\n", 893 | "Installing collected packages: sacremoses, tokenizers, sentencepiece, transformers\n", 894 | "Successfully installed sacremoses-0.0.43 sentencepiece-0.1.91 tokenizers-0.7.0 transformers-2.11.0\n" 895 | ], 896 | "name": "stdout" 897 | } 898 | ] 899 | }, 900 | { 901 | "cell_type": "code", 902 | "metadata": { 903 | "id": "U8FRjwBo15uT", 904 | "colab_type": "code", 905 | "colab": {} 906 | }, 907 | "source": [ 908 | "!pip install -q -U watermark" 909 | ], 910 | "execution_count": 0, 911 | "outputs": [] 912 | }, 913 | { 914 | "cell_type": "code", 915 | "metadata": { 916 | "id": "3DNdmQhn2D43", 917 | "colab_type": "code", 918 | "outputId": "ab9b076b-e566-4104-ccb7-95d16d360c85", 919 | "colab": { 920 | "base_uri": "https://localhost:8080/", 921 | "height": 134 922 | } 923 | }, 924 | "source": [ 925 | "%reload_ext watermark\n", 926 | "%watermark -v -p numpy,pandas,torch,transformers" 927 | ], 928 | "execution_count": 0, 929 | "outputs": [ 930 | { 931 | "output_type": "stream", 932 | "text": [ 933 | "CPython 3.6.9\n", 934 | "IPython 5.5.0\n", 935 | "\n", 936 | "numpy 1.18.5\n", 937 | "pandas 1.0.4\n", 938 | "torch 1.5.0+cu101\n", 939 | "transformers 2.11.0\n" 940 | ], 941 | "name": "stdout" 942 | } 943 | ] 944 | }, 945 | { 946 | "cell_type": "markdown", 947 | "metadata": { 948 | "id": "Mk0GnvUQIdxc", 949 | "colab_type": "text" 950 | }, 951 | "source": [ 952 | "### Making the necessary imports" 953 | ] 954 | }, 955 | { 956 | "cell_type": "code", 957 | "metadata": { 958 | "id": "dOpc8w_12D1f", 959 | "colab_type": "code", 960 | "outputId": "2163b72f-d590-48e3-ab75-d956198150a8", 961 | "colab": { 962 | "base_uri": "https://localhost:8080/", 963 | "height": 87 964 | } 965 | }, 966 | "source": [ 967 | "import transformers\n", 968 | "from transformers import XLNetTokenizer, XLNetModel, AdamW, get_linear_schedule_with_warmup\n", 969 | "import torch\n", 970 | "\n", 971 | "import numpy as np\n", 972 | "import pandas as pd\n", 973 | "import seaborn as sns\n", 974 | "import matplotlib.pyplot as plt\n", 975 | "from matplotlib import rc\n", 976 | "from sklearn.model_selection import train_test_split\n", 977 | "from sklearn.metrics import confusion_matrix, classification_report, accuracy\n", 978 | "from collections import defaultdict\n", 979 | "from textwrap import wrap\n", 980 | "from pylab import rcParams\n", 981 | "\n", 982 | "from torch import nn, optim\n", 983 | "from keras.preprocessing.sequence import pad_sequences\n", 984 | "from torch.utils.data import TensorDataset,RandomSampler,SequentialSampler\n", 985 | "from torch.utils.data import Dataset, DataLoader\n", 986 | "import torch.nn.functional as F" 987 | ], 988 | "execution_count": 0, 989 | "outputs": [ 990 | { 991 | "output_type": "stream", 992 | "text": [ 993 | "/usr/local/lib/python3.6/dist-packages/statsmodels/tools/_testing.py:19: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead.\n", 994 | " import pandas.util.testing as tm\n", 995 | "Using TensorFlow backend.\n" 996 | ], 997 | "name": "stderr" 998 | } 999 | ] 1000 | }, 1001 | { 1002 | "cell_type": "code", 1003 | "metadata": { 1004 | "id": "qAICzZNo2Dyw", 1005 | "colab_type": "code", 1006 | "outputId": "dd0b17dd-a7d5-4f20-9244-38cd860de614", 1007 | "colab": { 1008 | "base_uri": "https://localhost:8080/", 1009 | "height": 33 1010 | } 1011 | }, 1012 | "source": [ 1013 | "%matplotlib inline\n", 1014 | "%config InlineBackend.figure_format='retina'\n", 1015 | "\n", 1016 | "sns.set(style='whitegrid', palette='muted', font_scale=1.2)\n", 1017 | "\n", 1018 | "HAPPY_COLORS_PALETTE = [\"#01BEFE\", \"#FFDD00\", \"#FF7D00\", \"#FF006D\", \"#ADFF02\", \"#8F00FF\"]\n", 1019 | "\n", 1020 | "sns.set_palette(sns.color_palette(HAPPY_COLORS_PALETTE))\n", 1021 | "\n", 1022 | "rcParams['figure.figsize'] = 12, 8\n", 1023 | "\n", 1024 | "RANDOM_SEED = 42\n", 1025 | "np.random.seed(RANDOM_SEED)\n", 1026 | "torch.manual_seed(RANDOM_SEED)\n", 1027 | "\n", 1028 | "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n", 1029 | "device" 1030 | ], 1031 | "execution_count": 0, 1032 | "outputs": [ 1033 | { 1034 | "output_type": "execute_result", 1035 | "data": { 1036 | "text/plain": [ 1037 | "device(type='cuda', index=0)" 1038 | ] 1039 | }, 1040 | "metadata": { 1041 | "tags": [] 1042 | }, 1043 | "execution_count": 7 1044 | } 1045 | ] 1046 | }, 1047 | { 1048 | "cell_type": "markdown", 1049 | "metadata": { 1050 | "id": "gC-WS1hYIxkr", 1051 | "colab_type": "text" 1052 | }, 1053 | "source": [ 1054 | "### Data Preprocessing" 1055 | ] 1056 | }, 1057 | { 1058 | "cell_type": "code", 1059 | "metadata": { 1060 | "id": "jJ83RaRG2Dv8", 1061 | "colab_type": "code", 1062 | "outputId": "69fd3bb8-b85f-42f7-9185-e26fddbf2d11", 1063 | "colab": { 1064 | "base_uri": "https://localhost:8080/", 1065 | "height": 196 1066 | } 1067 | }, 1068 | "source": [ 1069 | "df = pd.read_csv('/content/drive/My Drive/NLP/Sentiment Analysis Series/imdb.csv')\n", 1070 | "df.head()" 1071 | ], 1072 | "execution_count": 0, 1073 | "outputs": [ 1074 | { 1075 | "output_type": "execute_result", 1076 | "data": { 1077 | "text/html": [ 1078 | "
\n", 1079 | "\n", 1092 | "\n", 1093 | " \n", 1094 | " \n", 1095 | " \n", 1096 | " \n", 1097 | " \n", 1098 | " \n", 1099 | " \n", 1100 | " \n", 1101 | " \n", 1102 | " \n", 1103 | " \n", 1104 | " \n", 1105 | " \n", 1106 | " \n", 1107 | " \n", 1108 | " \n", 1109 | " \n", 1110 | " \n", 1111 | " \n", 1112 | " \n", 1113 | " \n", 1114 | " \n", 1115 | " \n", 1116 | " \n", 1117 | " \n", 1118 | " \n", 1119 | " \n", 1120 | " \n", 1121 | " \n", 1122 | " \n", 1123 | " \n", 1124 | " \n", 1125 | " \n", 1126 | " \n", 1127 | "
reviewsentiment
0One of the other reviewers has mentioned that ...positive
1A wonderful little production. <br /><br />The...positive
2I thought this was a wonderful way to spend ti...positive
3Basically there's a family where a little boy ...negative
4Petter Mattei's \"Love in the Time of Money\" is...positive
\n", 1128 | "
" 1129 | ], 1130 | "text/plain": [ 1131 | " review sentiment\n", 1132 | "0 One of the other reviewers has mentioned that ... positive\n", 1133 | "1 A wonderful little production.

The... positive\n", 1134 | "2 I thought this was a wonderful way to spend ti... positive\n", 1135 | "3 Basically there's a family where a little boy ... negative\n", 1136 | "4 Petter Mattei's \"Love in the Time of Money\" is... positive" 1137 | ] 1138 | }, 1139 | "metadata": { 1140 | "tags": [] 1141 | }, 1142 | "execution_count": 8 1143 | } 1144 | ] 1145 | }, 1146 | { 1147 | "cell_type": "code", 1148 | "metadata": { 1149 | "id": "4J5-ddIc2DtI", 1150 | "colab_type": "code", 1151 | "outputId": "fbe01f11-3cfd-405d-c00a-a945cde3a8c7", 1152 | "colab": { 1153 | "base_uri": "https://localhost:8080/", 1154 | "height": 644 1155 | } 1156 | }, 1157 | "source": [ 1158 | "from sklearn.utils import shuffle\n", 1159 | "df = shuffle(df)\n", 1160 | "df.head(20)" 1161 | ], 1162 | "execution_count": 0, 1163 | "outputs": [ 1164 | { 1165 | "output_type": "execute_result", 1166 | "data": { 1167 | "text/html": [ 1168 | "
\n", 1169 | "\n", 1182 | "\n", 1183 | " \n", 1184 | " \n", 1185 | " \n", 1186 | " \n", 1187 | " \n", 1188 | " \n", 1189 | " \n", 1190 | " \n", 1191 | " \n", 1192 | " \n", 1193 | " \n", 1194 | " \n", 1195 | " \n", 1196 | " \n", 1197 | " \n", 1198 | " \n", 1199 | " \n", 1200 | " \n", 1201 | " \n", 1202 | " \n", 1203 | " \n", 1204 | " \n", 1205 | " \n", 1206 | " \n", 1207 | " \n", 1208 | " \n", 1209 | " \n", 1210 | " \n", 1211 | " \n", 1212 | " \n", 1213 | " \n", 1214 | " \n", 1215 | " \n", 1216 | " \n", 1217 | " \n", 1218 | " \n", 1219 | " \n", 1220 | " \n", 1221 | " \n", 1222 | " \n", 1223 | " \n", 1224 | " \n", 1225 | " \n", 1226 | " \n", 1227 | " \n", 1228 | " \n", 1229 | " \n", 1230 | " \n", 1231 | " \n", 1232 | " \n", 1233 | " \n", 1234 | " \n", 1235 | " \n", 1236 | " \n", 1237 | " \n", 1238 | " \n", 1239 | " \n", 1240 | " \n", 1241 | " \n", 1242 | " \n", 1243 | " \n", 1244 | " \n", 1245 | " \n", 1246 | " \n", 1247 | " \n", 1248 | " \n", 1249 | " \n", 1250 | " \n", 1251 | " \n", 1252 | " \n", 1253 | " \n", 1254 | " \n", 1255 | " \n", 1256 | " \n", 1257 | " \n", 1258 | " \n", 1259 | " \n", 1260 | " \n", 1261 | " \n", 1262 | " \n", 1263 | " \n", 1264 | " \n", 1265 | " \n", 1266 | " \n", 1267 | " \n", 1268 | " \n", 1269 | " \n", 1270 | " \n", 1271 | " \n", 1272 | " \n", 1273 | " \n", 1274 | " \n", 1275 | " \n", 1276 | " \n", 1277 | " \n", 1278 | " \n", 1279 | " \n", 1280 | " \n", 1281 | " \n", 1282 | " \n", 1283 | " \n", 1284 | " \n", 1285 | " \n", 1286 | " \n", 1287 | " \n", 1288 | " \n", 1289 | " \n", 1290 | " \n", 1291 | " \n", 1292 | "
reviewsentiment
33553I really liked this Summerslam due to the look...positive
9427Not many television shows appeal to quite as m...positive
199The film quickly gets to a major chase scene w...negative
12447Jane Austen would definitely approve of this o...positive
39489Expectations were somewhat high for me when I ...negative
42724I've watched this movie on a fairly regular ba...positive
10822For once a story of hope highlighted over the ...positive
49498Okay, I didn't get the Purgatory thing the fir...positive
4144I was very disappointed with this series. It h...negative
36958The first 30 minutes of Tinseltown had my fing...negative
43106jeez, this was immensely boring. the leading m...negative
38695Great just great! The West Coast got \"Dirty\" H...positive
6188It's made in 2007 and the CG is bad for a movi...negative
1414This movie stinks majorly. The only reason I g...negative
18471We can start with the wooden acting but this f...negative
29282This movie starts off somewhat slowly and gets...positive
15177This is a slightly uneven entry with one stand...positive
34304I was first introduced to John Waters films by...positive
12609This movie has very good acting by virtually a...positive
12144I can't help but notice the negative reviews t...positive
\n", 1293 | "
" 1294 | ], 1295 | "text/plain": [ 1296 | " review sentiment\n", 1297 | "33553 I really liked this Summerslam due to the look... positive\n", 1298 | "9427 Not many television shows appeal to quite as m... positive\n", 1299 | "199 The film quickly gets to a major chase scene w... negative\n", 1300 | "12447 Jane Austen would definitely approve of this o... positive\n", 1301 | "39489 Expectations were somewhat high for me when I ... negative\n", 1302 | "42724 I've watched this movie on a fairly regular ba... positive\n", 1303 | "10822 For once a story of hope highlighted over the ... positive\n", 1304 | "49498 Okay, I didn't get the Purgatory thing the fir... positive\n", 1305 | "4144 I was very disappointed with this series. It h... negative\n", 1306 | "36958 The first 30 minutes of Tinseltown had my fing... negative\n", 1307 | "43106 jeez, this was immensely boring. the leading m... negative\n", 1308 | "38695 Great just great! The West Coast got \"Dirty\" H... positive\n", 1309 | "6188 It's made in 2007 and the CG is bad for a movi... negative\n", 1310 | "1414 This movie stinks majorly. The only reason I g... negative\n", 1311 | "18471 We can start with the wooden acting but this f... negative\n", 1312 | "29282 This movie starts off somewhat slowly and gets... positive\n", 1313 | "15177 This is a slightly uneven entry with one stand... positive\n", 1314 | "34304 I was first introduced to John Waters films by... positive\n", 1315 | "12609 This movie has very good acting by virtually a... positive\n", 1316 | "12144 I can't help but notice the negative reviews t... positive" 1317 | ] 1318 | }, 1319 | "metadata": { 1320 | "tags": [] 1321 | }, 1322 | "execution_count": 9 1323 | } 1324 | ] 1325 | }, 1326 | { 1327 | "cell_type": "code", 1328 | "metadata": { 1329 | "id": "uMSFcIqsdZyH", 1330 | "colab_type": "code", 1331 | "outputId": "47589740-52a5-4744-d34f-2e3e36e7b1ec", 1332 | "colab": { 1333 | "base_uri": "https://localhost:8080/", 1334 | "height": 33 1335 | } 1336 | }, 1337 | "source": [ 1338 | "df = df[:24000]\n", 1339 | "len(df)" 1340 | ], 1341 | "execution_count": 0, 1342 | "outputs": [ 1343 | { 1344 | "output_type": "execute_result", 1345 | "data": { 1346 | "text/plain": [ 1347 | "24000" 1348 | ] 1349 | }, 1350 | "metadata": { 1351 | "tags": [] 1352 | }, 1353 | "execution_count": 10 1354 | } 1355 | ] 1356 | }, 1357 | { 1358 | "cell_type": "code", 1359 | "metadata": { 1360 | "id": "GluMm1Nj2DqK", 1361 | "colab_type": "code", 1362 | "colab": {} 1363 | }, 1364 | "source": [ 1365 | "import re\n", 1366 | "def clean_text(text):\n", 1367 | " text = re.sub(r\"@[A-Za-z0-9]+\", ' ', text)\n", 1368 | " text = re.sub(r\"https?://[A-Za-z0-9./]+\", ' ', text)\n", 1369 | " text = re.sub(r\"[^a-zA-z.!?'0-9]\", ' ', text)\n", 1370 | " text = re.sub('\\t', ' ', text)\n", 1371 | " text = re.sub(r\" +\", ' ', text)\n", 1372 | " return text" 1373 | ], 1374 | "execution_count": 0, 1375 | "outputs": [] 1376 | }, 1377 | { 1378 | "cell_type": "code", 1379 | "metadata": { 1380 | "id": "8HpgvTb72wtm", 1381 | "colab_type": "code", 1382 | "colab": {} 1383 | }, 1384 | "source": [ 1385 | "df['review'] = df['review'].apply(clean_text)" 1386 | ], 1387 | "execution_count": 0, 1388 | "outputs": [] 1389 | }, 1390 | { 1391 | "cell_type": "code", 1392 | "metadata": { 1393 | "id": "ptC13l5r25qH", 1394 | "colab_type": "code", 1395 | "outputId": "531b8ac0-a6e2-4750-eadb-2ac2aa3ee628", 1396 | "colab": { 1397 | "base_uri": "https://localhost:8080/", 1398 | "height": 398 1399 | } 1400 | }, 1401 | "source": [ 1402 | "rcParams['figure.figsize'] = 8, 6\n", 1403 | "sns.countplot(df.sentiment)\n", 1404 | "plt.xlabel('review score');" 1405 | ], 1406 | "execution_count": 0, 1407 | "outputs": [ 1408 | { 1409 | "output_type": "display_data", 1410 | "data": { 1411 | "image/png": "iVBORw0KGgoAAAANSUhEUgAABCQAAAL6CAYAAADucodsAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAgAElEQVR4nOzde3BUZZ7G8eeEXICQQGJC2ABREEHSApk1OiIsguDU6gyrMKMGlFFJ5OIFFlxXGGFBnRItC2V2uYyVYAIqZLxlQWd0Ry5yTXSMJrgJRJEAwWimMYQYQpJuuvePVPfm0p0EyDlJ4Pupour0ed/3d95uq6ann5zzvobb7XYLAAAAAADAQgEdPQEAAAAAAHD5IZAAAAAAAACWI5AAAAAAAACWI5AAAAAAAACWI5AAAAAAAACWI5AAAAAAAACWI5AAAAAAAACWI5AAAAAAAACWI5AAAAAAAACWI5AAAAAAAACWI5AAAAAAAACWI5AAAAAAAACWC+zoCeDSVlhYqNraWnXr1k0hISEdPR0AAAAAQDuqra3VuXPnFBISovj4+PMaSyABU9XW1srlcsnlcsnhcHT0dAAAAAAAJqitrT3vMQQSMFW3bt3kcrkUEBCgnj17dvR0AAAAAADtqLq6Wi6XS926dTvvsQQSMFVISIgcDod69uypYcOGdfR0AAAAAADtqKioSFVVVRf0iD6LWgIAAAAAAMsRSAAAAAAAAMsRSAAAAAAAAMsRSAAAAAAAAMsRSAAAAAAAAMsRSAAAAAAAAMsRSAAAAAAAAMsRSAAAAAAAAMsRSAAAAAAAAMsRSAAAAAAAAMsRSAAAAAAAAMsRSAAAAAAAAMsRSAAAAAAAAMsRSAAAAAAAAMsRSAAAAAAAAMsRSAAAAAAAAMsRSAAAAAAAAMsRSAAAAAAAAMsRSAAAAAAAAMsFdvQEzOB2u3XkyBEdOHDA+6+oqEgOh0OStH37dg0YMMDv+PLycm3fvl05OTk6ePCgvv/+ezkcDkVERMhms2ny5Mn653/+Z3Xr1q3VuZSXlysjI0Pbtm1TaWmpgoODNWjQIE2ePFlJSUkKDGz9P0FRUZE2bNig7OxsnTx5Ur1795bNZlNSUpImTJjQps9k586dyszMVEFBgU6fPq2oqCiNHj1aDzzwgIYNG9amGgAAAAAAtBfD7Xa7O3oS7e3EiROaOHGi3/aWAokDBw5o2rRpcjqdLV7jH//xH7VmzRpFRkb67VNYWKhZs2bJbrf7bE9ISFBaWprCwsL81sjKytLSpUu9YUpT06ZN0/Lly1uc67Jly5SZmemzLTg4WM8995zuuuuuFmtcqKKiIlVVValXr14EHwAAAABwibmY33yX/CMb/fr102233abExMQ29T979qycTqf69OmjGTNmKDU1VZ988ok+/fRTbd68Wb/4xS8kSV988YXmzp0rl8vls05FRYXmzJkju92u8PBwrVixQnv27NHHH3+sOXPmyDAM5eXlaeHChX7nkpubqyVLlsjhcGjo0KFav369srOz9d5772nSpEmSpM2bNys1NdVvjdTUVG8YMWnSJL333nvKzs7W+vXrNXToUNXV1enpp59Wbm5umz4fAAAAAADawyV5h0RVVZVycnI0atQoRUdHS5L+67/+S6tXr5bU8h0ShYWFysnJ0X333aeQkBCffZYuXaq33npLkvTKK6/ojjvuaNbnpZdeUlpamgzD0BtvvNEsEFm3bp1WrVolqT40GDduXLMad999tw4cOKCoqCh98MEHioiI8La53W4lJydr37596tmzp7Zv397sbo3y8nJNnDhR1dXVGjt2rHc+HqdOndKvfvUrnTx5UqNGjfK+p/bEHRIAAAAAcOniDokmevXqpUmTJnnDiPMRHx+vmTNn+g0jJGnBggUKCKj/6Pbs2dOs3el0en/cjx8/3ufdGcnJyerTp48kadOmTc3av/rqKx04cECSlJKS0iiMkCTDMPTEE09Ikqqrq7Vly5ZmNbKyslRdXS1JWrhwYaMwQpIiIiKUkpIiScrPz1dBQYHf9wwAAAAAQHu6JAMJs0VGRuqKK66QJP39739v1v7555+rsrJSknT77bf7rBEcHOx97GL//v2qqalp1L5z507vsb8aNptNcXFxkqQdO3Y0a/fUiIuLk81m81mjYW1fNQAAAAAAMAOBxAVwOBw6ffq0pPq7MZpqeKdBQkKC3zqettraWh0+fNhnjZiYGPXr189vjVGjRjW7ZtManj6+9OvXTzExMX5rAAAAAABgBgKJC/DJJ5+orq5OkvSzn/2sWXtxcbEkKSAgQLGxsX7rNFzHwjOm6euBAwe2OBdPjTNnzqisrMx7vqyszPu4RltrNJ0DAAAAAABmIZA4T3V1dXr55Zcl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\n", 1412 | "text/plain": [ 1413 | "
" 1414 | ] 1415 | }, 1416 | "metadata": { 1417 | "tags": [], 1418 | "image/png": { 1419 | "width": 530, 1420 | "height": 381 1421 | } 1422 | } 1423 | } 1424 | ] 1425 | }, 1426 | { 1427 | "cell_type": "code", 1428 | "metadata": { 1429 | "id": "2I-Du1vR3EZN", 1430 | "colab_type": "code", 1431 | "colab": {} 1432 | }, 1433 | "source": [ 1434 | "def sentiment2label(sentiment):\n", 1435 | " if sentiment == \"positive\":\n", 1436 | " return 1\n", 1437 | " else :\n", 1438 | " return 0\n", 1439 | "\n", 1440 | "df['sentiment'] = df['sentiment'].apply(sentiment2label)" 1441 | ], 1442 | "execution_count": 0, 1443 | "outputs": [] 1444 | }, 1445 | { 1446 | "cell_type": "code", 1447 | "metadata": { 1448 | "id": "YK3jPP3i3lRw", 1449 | "colab_type": "code", 1450 | "outputId": "257a6439-6471-411c-8e48-1762ba3796b5", 1451 | "colab": { 1452 | "base_uri": "https://localhost:8080/", 1453 | "height": 67 1454 | } 1455 | }, 1456 | "source": [ 1457 | "df['sentiment'].value_counts()" 1458 | ], 1459 | "execution_count": 0, 1460 | "outputs": [ 1461 | { 1462 | "output_type": "execute_result", 1463 | "data": { 1464 | "text/plain": [ 1465 | "0 12006\n", 1466 | "1 11994\n", 1467 | "Name: sentiment, dtype: int64" 1468 | ] 1469 | }, 1470 | "metadata": { 1471 | "tags": [] 1472 | }, 1473 | "execution_count": 15 1474 | } 1475 | ] 1476 | }, 1477 | { 1478 | "cell_type": "code", 1479 | "metadata": { 1480 | "id": "StOb4mAa3rgo", 1481 | "colab_type": "code", 1482 | "colab": {} 1483 | }, 1484 | "source": [ 1485 | "class_names = ['negative', 'positive']" 1486 | ], 1487 | "execution_count": 0, 1488 | "outputs": [] 1489 | }, 1490 | { 1491 | "cell_type": "markdown", 1492 | "metadata": { 1493 | "id": "mmBGGgUVJBpT", 1494 | "colab_type": "text" 1495 | }, 1496 | "source": [ 1497 | "### Playing with XLNetTokenizer" 1498 | ] 1499 | }, 1500 | { 1501 | "cell_type": "code", 1502 | "metadata": { 1503 | "id": "hVWO_38_32jL", 1504 | "colab_type": "code", 1505 | "outputId": "81c0d90d-c134-4b43-815a-1eee3d29a947", 1506 | "colab": { 1507 | "base_uri": "https://localhost:8080/", 1508 | "height": 65, 1509 | "referenced_widgets": [ 1510 | "bd7d4d34bd6d46ae985741702b456aaf", 1511 | "e8135d40c9c4460d9ce1eb0885c562e4", 1512 | "0954f506d85d4723a3b32b6606db0015", 1513 | "297ea592ec1b44558448159860cd1aa0", 1514 | "ed27989647d140eca7d3bf745145a3a0", 1515 | "f97490f8dee84ccc8029e401abe1042e", 1516 | "8d146a11180d4d918cbfc302fc7d2971", 1517 | "73e86ec287c541d3a189620dd50c33b5" 1518 | ] 1519 | } 1520 | }, 1521 | "source": [ 1522 | "from transformers import XLNetTokenizer, XLNetModel\n", 1523 | "PRE_TRAINED_MODEL_NAME = 'xlnet-base-cased'\n", 1524 | "tokenizer = XLNetTokenizer.from_pretrained(PRE_TRAINED_MODEL_NAME)" 1525 | ], 1526 | "execution_count": 0, 1527 | "outputs": [ 1528 | { 1529 | "output_type": "display_data", 1530 | "data": { 1531 | "application/vnd.jupyter.widget-view+json": { 1532 | "model_id": "bd7d4d34bd6d46ae985741702b456aaf", 1533 | "version_minor": 0, 1534 | "version_major": 2 1535 | }, 1536 | "text/plain": [ 1537 | "HBox(children=(FloatProgress(value=0.0, description='Downloading', max=798011.0, style=ProgressStyle(descripti…" 1538 | ] 1539 | }, 1540 | "metadata": { 1541 | "tags": [] 1542 | } 1543 | }, 1544 | { 1545 | "output_type": "stream", 1546 | "text": [ 1547 | "\n" 1548 | ], 1549 | "name": "stdout" 1550 | } 1551 | ] 1552 | }, 1553 | { 1554 | "cell_type": "code", 1555 | "metadata": { 1556 | "id": "1ckpqWd_YWgZ", 1557 | "colab_type": "code", 1558 | "colab": {} 1559 | }, 1560 | "source": [ 1561 | "input_txt = \"India is my country. All Indians are my brothers and sisters\"\n", 1562 | "encodings = tokenizer.encode_plus(input_txt, add_special_tokens=True, max_length=16, return_tensors='pt', return_token_type_ids=False, return_attention_mask=True, pad_to_max_length=False)" 1563 | ], 1564 | "execution_count": 0, 1565 | "outputs": [] 1566 | }, 1567 | { 1568 | "cell_type": "code", 1569 | "metadata": { 1570 | "id": "Y_ew5njtYWc1", 1571 | "colab_type": "code", 1572 | "outputId": "dc94277d-2372-48bd-c9f7-2d367c8a3341", 1573 | "colab": { 1574 | "base_uri": "https://localhost:8080/", 1575 | "height": 50 1576 | } 1577 | }, 1578 | "source": [ 1579 | "print('input_ids : ',encodings['input_ids'])" 1580 | ], 1581 | "execution_count": 0, 1582 | "outputs": [ 1583 | { 1584 | "output_type": "stream", 1585 | "text": [ 1586 | "input_ids : tensor([[ 837, 27, 94, 234, 9, 394, 7056, 41, 94, 4194, 21, 8301,\n", 1587 | " 4, 3]])\n" 1588 | ], 1589 | "name": "stdout" 1590 | } 1591 | ] 1592 | }, 1593 | { 1594 | "cell_type": "code", 1595 | "metadata": { 1596 | "id": "eEXfe39mYWK7", 1597 | "colab_type": "code", 1598 | "outputId": "8953d12c-68ad-453c-8fd8-0cff386cf503", 1599 | "colab": { 1600 | "base_uri": "https://localhost:8080/", 1601 | "height": 251 1602 | } 1603 | }, 1604 | "source": [ 1605 | "tokenizer.convert_ids_to_tokens(encodings['input_ids'][0])" 1606 | ], 1607 | "execution_count": 0, 1608 | "outputs": [ 1609 | { 1610 | "output_type": "execute_result", 1611 | "data": { 1612 | "text/plain": [ 1613 | "['▁India',\n", 1614 | " '▁is',\n", 1615 | " '▁my',\n", 1616 | " '▁country',\n", 1617 | " '.',\n", 1618 | " '▁All',\n", 1619 | " '▁Indians',\n", 1620 | " '▁are',\n", 1621 | " '▁my',\n", 1622 | " '▁brothers',\n", 1623 | " '▁and',\n", 1624 | " '▁sisters',\n", 1625 | " '',\n", 1626 | " '']" 1627 | ] 1628 | }, 1629 | "metadata": { 1630 | "tags": [] 1631 | }, 1632 | "execution_count": 20 1633 | } 1634 | ] 1635 | }, 1636 | { 1637 | "cell_type": "code", 1638 | "metadata": { 1639 | "id": "XR1xkLYtTurv", 1640 | "colab_type": "code", 1641 | "outputId": "c86ef945-3963-453d-86f2-753cd7a45097", 1642 | "colab": { 1643 | "base_uri": "https://localhost:8080/", 1644 | "height": 33 1645 | } 1646 | }, 1647 | "source": [ 1648 | "type(encodings['attention_mask'])" 1649 | ], 1650 | "execution_count": 0, 1651 | "outputs": [ 1652 | { 1653 | "output_type": "execute_result", 1654 | "data": { 1655 | "text/plain": [ 1656 | "torch.Tensor" 1657 | ] 1658 | }, 1659 | "metadata": { 1660 | "tags": [] 1661 | }, 1662 | "execution_count": 21 1663 | } 1664 | ] 1665 | }, 1666 | { 1667 | "cell_type": "code", 1668 | "metadata": { 1669 | "id": "Pp97KX-9UtMK", 1670 | "colab_type": "code", 1671 | "colab": {} 1672 | }, 1673 | "source": [ 1674 | "attention_mask = pad_sequences(encodings['attention_mask'], maxlen=512, dtype=torch.Tensor ,truncating=\"post\",padding=\"post\")" 1675 | ], 1676 | "execution_count": 0, 1677 | "outputs": [] 1678 | }, 1679 | { 1680 | "cell_type": "code", 1681 | "metadata": { 1682 | "id": "6Pzeyv1_UvMT", 1683 | "colab_type": "code", 1684 | "outputId": "2acb94b0-943a-4273-bd71-32e62195a137", 1685 | "colab": { 1686 | "base_uri": "https://localhost:8080/", 1687 | "height": 385 1688 | } 1689 | }, 1690 | "source": [ 1691 | "attention_mask = attention_mask.astype(dtype = 'int64')\n", 1692 | "attention_mask = torch.tensor(attention_mask) \n", 1693 | "attention_mask.flatten()" 1694 | ], 1695 | "execution_count": 0, 1696 | "outputs": [ 1697 | { 1698 | "output_type": "execute_result", 1699 | "data": { 1700 | "text/plain": [ 1701 | "tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1702 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1703 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1704 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1705 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1706 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1707 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1708 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1709 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1710 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1711 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1712 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1713 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1714 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1715 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1716 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1717 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1718 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1719 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1720 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1721 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 1722 | " 0, 0, 0, 0, 0, 0, 0, 0])" 1723 | ] 1724 | }, 1725 | "metadata": { 1726 | "tags": [] 1727 | }, 1728 | "execution_count": 23 1729 | } 1730 | ] 1731 | }, 1732 | { 1733 | "cell_type": "code", 1734 | "metadata": { 1735 | "id": "kM7cxiA9RlnA", 1736 | "colab_type": "code", 1737 | "outputId": "78b39189-c841-4174-ec97-364f2327905e", 1738 | "colab": { 1739 | "base_uri": "https://localhost:8080/", 1740 | "height": 50 1741 | } 1742 | }, 1743 | "source": [ 1744 | "encodings['input_ids']" 1745 | ], 1746 | "execution_count": 0, 1747 | "outputs": [ 1748 | { 1749 | "output_type": "execute_result", 1750 | "data": { 1751 | "text/plain": [ 1752 | "tensor([[ 837, 27, 94, 234, 9, 394, 7056, 41, 94, 4194, 21, 8301,\n", 1753 | " 4, 3]])" 1754 | ] 1755 | }, 1756 | "metadata": { 1757 | "tags": [] 1758 | }, 1759 | "execution_count": 24 1760 | } 1761 | ] 1762 | }, 1763 | { 1764 | "cell_type": "markdown", 1765 | "metadata": { 1766 | "id": "M12PPghlJUbg", 1767 | "colab_type": "text" 1768 | }, 1769 | "source": [ 1770 | "### Checking the distribution of token lengths" 1771 | ] 1772 | }, 1773 | { 1774 | "cell_type": "code", 1775 | "metadata": { 1776 | "id": "zW4_SrOw4BDy", 1777 | "colab_type": "code", 1778 | "colab": {} 1779 | }, 1780 | "source": [ 1781 | "token_lens = []\n", 1782 | "\n", 1783 | "for txt in df['review']:\n", 1784 | " tokens = tokenizer.encode(txt, max_length=512)\n", 1785 | " token_lens.append(len(tokens))" 1786 | ], 1787 | "execution_count": 0, 1788 | "outputs": [] 1789 | }, 1790 | { 1791 | "cell_type": "code", 1792 | "metadata": { 1793 | "id": "aSxO20TU4dz5", 1794 | "colab_type": "code", 1795 | "outputId": "f8379514-5ae2-4e43-bb19-12e29d370386", 1796 | "colab": { 1797 | "base_uri": "https://localhost:8080/", 1798 | "height": 398 1799 | } 1800 | }, 1801 | "source": [ 1802 | "sns.distplot(token_lens)\n", 1803 | "plt.xlim([0, 1024]);\n", 1804 | "plt.xlabel('Token count');" 1805 | ], 1806 | "execution_count": 0, 1807 | "outputs": [ 1808 | { 1809 | "output_type": "display_data", 1810 | "data": { 1811 | "image/png": "iVBORw0KGgoAAAANSUhEUgAABAQAAAL6CAYAAAChL4S8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAgAElEQVR4nOzdfZTW9X0n/PfA8IwC4wjEIsY8MNGJ2kRzqhuSiCFtTJMYSNuV3GElBlPrJqTR3WO60Rqj91F31zb3FrW9wcSHNhK7YoxtzCGJEJUb15QYUCQYjUURGQfGIQICAzP3H+M8IDAwM9dwzfB7vc7hnO81v+98f5+L84Nzrvf1fahoaWlpCQAAAFAog8pdAAAAAHDkCQQAAACggAQCAAAAUEACAQAAACgggQAAAAAUkEAAAAAACkggAAAAAAUkEAAAAIACEggAAABAAQkEAAAAoIAEAgAAAFBAAgEAAAAooMpyF0D3PPPMM9m1a1cGDx6cYcOGlbscAAAASmjXrl3Zu3dvhg0bllNPPbVP7yUQGGB27dqV5ubmNDc3p6mpqdzlAAAA0Ad27drV5/cQCAwwgwcPTnNzcwYNGpSRI0eWuxw4LNu2bUuSjB49usyVQPd4dhmIPLcMRJ5bBqq+eHZ37NiR5ubmDB48uGRjHoxAYIAZNmxYmpqaMnLkyNTU1JS7HDgsK1euTBLPLAOOZ5eByHPLQOS5ZaDqi2d33bp12bZt2xFZIm5TQQAAACgggQAAAAAUkEAAAAAACkggAAAAAAUkEAAAAIACEggAAABAAQkEAAAAoIAEAgAAAFBAAgEAAAAoIIEAAAAAFJBAAAAAAApIIAAAAAAFJBAAAACAAhIIAAAAQAEJBAAAAKCABAIAAABQQAIBAAAAKCCBAAAAABSQQAAAAAAKSCAAAAAABSQQAAAAgAKqLPWAS5cuzaJFi7JmzZps3bo11dXVOeecc3LRRRelpqam1+OvW7cud955Z1asWJHNmzdnzJgxqa2tzYUXXphp06Yd9PdaWlry29/+NqtXr27/s27dujQ1NSVJfvazn2XSpEmHVcOePXuyaNGiPPjgg3nhhReye/funHDCCZk+fXrmzJmTqqqqXr9PAAAA6EslDQSuueaaLFq0aJ+fbdy4Mffdd18efPDBXHfddfnMZz7T4/Hvv//+XH311e0f4pOkvr4+y5Yty7JlyzJr1qx885vfPODvvvzyy/nEJz7R43u3ef311/PFL34xq1at2ufnzz//fJ5//vksXrw4CxYsyCmnnNLrewEAAEBfKdmSgQULFrSHAdOnT8/ixYuzYsWK3H777ZkyZUp2796db3zjG1m5cmWPxl+5cmWuuuqqNDU1ZcqUKbn99tuzYsWKLF68ONOnT0+S3HPPPVmwYMEhx5o4cWI+9rGP5ayzzup2HZdffnlWrVqVioqKXHrppfnJT36SRx99NDfccEOOOeaY1NfX58///M/T2NjY7bEBAADgSClJINDQ0JBbb701STJ16tTMnz8/tbW1qaqqytSpU3PXXXeluro6e/bsyU033dSje9x4443Zs2dPqqurc9ddd2Xq1KmpqqpKbW1t5s+fnw9+8INJkltvvTUNDQ37/f7YsWNzyy235LHHHsvPf/7zzJ8/P2effXa3avj5z3+eRx55JEny1a9+NV/72tcyefLkjB8/PjNnzszf//3fp6KiInV1dVm4cGGP3icAAAAcCSUJBO6///7s2LEjSes36BUVFftcHzduXObOnZskWbVqVdasWdOt8Z966qmsXr06STJ37tyMGzdun+sVFRW54oorkiQ7duzIAw88sN8Yo0ePzvTp03P88cd3696dfe9730vS+n6++MUv7nf9rLPOyrnnnpsk+ed//ufs2bOnx/cCAACAvlSSQGDp0qVJksmTJ6e2tvaAfc4///z29sMPP9yj8d86Tme1tbWZPHlyj8Y/HDt37syKFSuSJB/96EczdOjQA/Zrq6+xsbHHyyMAAACgr5UkEGj7xv+MM844aJ+JEydmwoQJ+/Tv7vgTJkzIxIkTD9qv7f7dHf9w/OY3v8muXbuSJL//+79/0H6dr/VFHQAAAFAKvT5loK6urn25wIknnthl30mTJqWuri4vvPBCt+7R1v9wxk+S7du3p66urj2AKIXONXd1POEJJ5yQQYMGpbm5udvvEwCK4pHGlsPu++GxFYfuBAB0W68Dgddee629fdxxx3XZt+16d3fgb7vH4Y7fdo9SBgKH+z6HDBmSY489No2NjU4aAIAu/HrHofu8Z2Tf1wEARdXrQKBtdkCSDBs2rMu+bde3b9/erXu88cYbSXLQdftthg8ffsC6SqGthuTw32epa+hs27Zt9ihgwPHMMlB5dkururo6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SWt8/vnn28d45zvfmc2bN+faa6/N1KlT8973vjfvfe97M2PGjCxYsCBvvPFGN94dAAAAHHm93lTwtddea28fd9xxXfZtu97Y2Nijexzu+G33aPu2vxQ1bty4sb29efPmfOpTn0pDQ0P7z5qamvLMM8/kmWeeyQMPPJCFCxd2OZsBAAAAyqnXgUDbt+ZJMmzYsC77tl3fvn17t+7R9o370KFDu+w3fPjwA9ZVihq3bdvW3v6bv/mb7NmzJ3/+53+eP/uzP8v48eOzYcOGfPe73829996b3/zmN5k3b14WLVqUQYNKdrLjfvX09AhHKBfPLAOVZ7e0qqur07BnVNa/uu2QfcePH531W7dn8+bNR6Cyo4vnloHIc8tANVCf3b75tHoUam5ubm83NTXl8ssvz+WXX55JkyZl6NChecc73pHrrrsus2bNStJ6UsFPf/rTcpULAAAAXer1DIGRI0e2t3ft2tVl37bro0aN6tY9RowYkaampuzevbvLfjt37jxgXaWosfMYY8aMyZw5cw74+1/5yldy7733Zu/evfnpT3+aP/zDP+zyfj01evTo1NTU9MnYUGptiemZZ55Z5kqgezy7fWd9Y0tOGtH1Mr4kqRqZnDS2OieddNIRqOro4LllIPLcMlD1xbO7bt26fWao96VezxAYN25ce3vLli1d9m27Pnbs2B7d43DHf+s9SlFj5zFOO+20gy5fOO6443LyyScnSZ577rku7wUAAADl0utAYPz48e3fnr/00ktd9t2wYUOStH9gPlxt/Q93/FGjRrVvKFiqGt/xjne0t8eMGdPlGMcee2yS7u+VAAAAAEdKrwOBioqK1NbWJklWr1590H6bNm1qPwqwrf/hautfV1e3z3GCb7Vq1aoDjl+KGseOHdt+ZOGhTklouz569Ogu+wEAAEC5lGRTwWnTpiVJ1q9fn7Vr1x6wz49//OP29nnnndej8ZPkoYceOmCfZ555Ji+++OJBxy9FjR/96EeTtIYKnfcr6OzVV1/Nv//7vydJTj311AP2AQAAgHIrSSAwY8aM9in5N998c1paWva53tjYmIULFyZJzjjjjG7PEDjttNNy+umnJ0kWLly43zf0LS0tufnmm5O0bv53wQUX9EmNs2bNSmVlZV5//fX2vm/1t3/7t+0nEnziE5/oztsEAACAI6YkgUBVVVUuu+yyJMmjjz6aefPmZe3atWloaMjy5csze/bs1NfXp7KyMldeeeV+v7948eLU1NSkpqYmixcvPuA9vv71r6eysjL19fWZPXt2li9fnoaGhqxduzbz5s3LY489liS57LLLUlVVVfIak+Ttb397LrrooiTJ3/3d3+X666/Pb37zm2zdujVr1qzJFVdc0V7/9OnTc84553TzbxIAAACOjF4fO9jmkksuyYYNG7Jo0aIsWbIkS5Ys2ef6kCFDcv311/f4OIYzzzwz119/fa6++uo8++yzufjii/frc+GFF+aSSy7p0xr/y3/5L9myZUt+8IMf5O67787dd9Civr0AACAASURBVN+9X5+pU6fmpptu6sa7AwAAgCOrZIFAklx77bU599xzc88992TNmjXZunVrjj/++Jx99tmZM2dOampqejX+jBkzcuqpp+aOO+7I448/nvr6+owZMya1tbWZNWvWPnsN9FWNgwYNyk033ZQ/+qM/yr333punn346jY2NOeaYY1JbW5uZM2fm4x//eAYNKsnkCwAAAOgTJQ0EktbN+w7ng3lnM2fOzMyZMw+rb01NTW644YaelNauJzW+1XnnndftzREBAACgv/A1NgAAABSQQAAAAAAKSCAAAAAABSQQAAAAgAISCAAAAEABCQQAAACggAQCAAAAUEACAQAAACgggQAAAAAUkEAAAAAACkggAAAAAAUkEAAAAIACEggAAABAAQkEAAAAoIAEAgAAAFBAAgEAAAAoIIEAAAAAFJBAAAAAAApIIAAAAAAFJBAAAACAAqosdwFA6T3S2HLYfT88tqIPKwEAAPorgQAcpX6949B93jOy7+sAAAD6J0sGAAAAoIAEAgAAAFBAAgEAAAAoIIEAAAAAFJBAAAAAAApIIAAAAAAFJBAAAACAAhIIAAAAQAEJBAAAAKCABAIAAABQQAIBAAAAKCCBAAAAABSQQAAAAAAKSCAAAAAABSQQAAAAgAISCAAAAEABCQQAAACggAQCAAAAUEACAQAAACgggQAAAAAUkEAAAAAACkggAAAAAAUkEAAAAIACqix3AcChPdLYcth9Jw49/HG70xcAADi6CARggPj1jsPr190P+d0JGz48tqJ7gwMAAP2WQAA4rLDhPSP7vg4AAODIsYcAAAAAFJBAAAAAAApIIAAAAAAFJBAAAACAAhIIAAAAQAEJBAAAAKCABAIAAABQQAIBAAAAKCCBAAAAABSQQAAAAAAKSCAAAAAABSQQAAAAgAISCAAAAEABCQQAAACggAQCAAAAUEACAQAAACgggQAAAAAUkEAAAAAACkggAAAAAAVUWe4CgCNvZ3MyuNxFAAAAZSUQgAKo35385o3k+TeS376RvLI7GfVmInDa6PLWBgAAlIdAAI5y/7o5+ZctSctbfr59b/KV3yQzj0+mjU2GWEAEAACF4iMAHMWefD158ABhQGeL65P/8WLy6u4jVhYAANAPmCEAR6n63cldmzpeTx6WvP+Y5J0jkuohyaJXk1XbWq+9uCv5v/89+fKk5N0jy1IuAABwhJkhAEehXc3Jgo3JG82tr48bknz1xOTjx7V+4B83JLn0hOQbJyVDKt78nZbku6+0bjgIAAAc/QQCcBS67eXWb/2T1tMELnlbxyaCbSoqktkTk1umdFxr2JPcX39ESwUAAMpEIABHmR9tSX6wueP1n4xP3j7i4P2njEz+4/iO1z9vTJ7d0Xf1AQAA/YNAAI4iu5qTa1/oeP3+Y5Jzxx769z5wTHL6qI7Xd29Kdls6AAAARzWBABxFfvG7ZOve1nZVZTJ7QuvSgEOpqEhmTUhGvPk/Qn1T8sPNXf8OAAAwsAkE4CjR0pI80tjx+rxxyYjBB+//VuOGtC4vaPOz15LfvlG6+gAAgP5FIABHifU7OzYSHFqRnDOm+2P8h2OTU948drAlyT11rUEDAABw9BEIwFGi8+yAaeP2P1XgcFRUJJ+f2BooJMlLu5Knt5emPgAAoH8RCMBRYPve5Bevd7y+oLrnYx03JJnaaSPCh7aYJQAAAEcjgQAcBR7/XdL05of2U0Z2TPvvqY+NS9omGPx2Z/KsvQQAAOCoIxCAAa6lJXm003KBCw/zZIGujBuy7x4ED23p3XgAAED/IxCAAe7ZN5JNu1vbwwclnzyuNOP+UVXSliv8ekey1l4CAABwVBEIwADXeTPBPzi2Z5sJHsjxQ5Ozjul4/Y91pRkXAADoHwQCMID9bk/yZKfNBD889uB9e+LjnWYbLN+aPL3N7oIAAHC0EAjAAPbUtqT5zfY7hie/N6y04//esOSM0R2vb3yxtOMDAADlIxCAAezpTuv633fMwfv1xserOtqL6pIXd5olAAAARwOBAAxQe1uStTs6XteO6pv7nDwiqXnzGMPmJAs39s19AACAI0sgAAPU828kO99cL1BVmbxtaN/dq/PeBLe/kjQ1myUAAAADnUAABqg1nZYL1I5KKioO3re3fn90a+iQJK/sTh7Y3Hf3AgAAjgyBAAxQnfcPeO/og/crhcEVyR93OnHgHywbAACAAU8gAAPQa03Jy7ta25UVHWv8+9Inqzv+w/jZa8mzOywbAACAgUwgAANQ5+UC7xqRDD8C/5InDDVLAAAAjiYCARiA3rp/wJFy6e91tO94JXljr1kCAAAwUAkEYIB563GD7z2CgcAfViVvH97afm1P8s/1R+7eAABAaQkEYIB563GDE/vwuMG3GlxRkS+d0PH6718+cvcGAABKSyAAA8w+pwv08XGDB3Lx25Ihb97z8d8lv3rdsgEAABiIBAIwwKzZ1tGu7ePjBg9k/NCKfPb4jtffeeXI1wAAAPSeQAAGkNeakpd3t7aP1HGDB3Lx2zra36tLdjWbJQAAAAONQAAGkGfKcNzggZw3Lpk8rLXdsCf54eby1AEAAPScQAAGkN+80dE+9QieLvBWgyoqMqfTLIHvWjYAAAADTmWpB1y6dGkWLVqUNWvWZOvWramurs4555yTiy66KDU1Nb0ef926dbnzzjuzYsWKbN68OWPGjEltbW0uvPDCTJs2rSw1rlixInPmzGl/fcMNN2TmzJndHgcO5flOgcC7RpSvjiSZMzH51r+3tpc0JBt2tmTS8CO8wyEAANBjJZ0hcM011+TSSy/NsmXLUl9fn927d2fjxo2577778id/8if5wQ9+0Kvx77///nz2s5/Nfffdl40bN2b37t2pr6/PsmXLcumll+ab3/zmEa9x165dueaaa3r4juDw/W5PUt/U2q6sSE4cVt563j6iIueNbW03J7lrU1nLAQAAuqlkgcCCBQuyaNGiJMn06dOzePHirFixIrfffnumTJmS3bt35xvf+EZWrlzZo/FXrlyZq666Kk1NTZkyZUpuv/32rFixIosXL8706dOTJPfcc08WLFhwRGu85ZZbsn79+px44ok9el9wuDrPDnj78GRIP1jw84XOywY2JS0tNhcEAICBoiQfKRoaGnLrrbcmSaZOnZr58+entrY2VVVVmTp1au66665UV1dnz549uemmm3p0jxtvvDF79uxJdXV17rrrrkydOjVVVVWpra3N/Pnz88EPfjBJcuutt6ahoeGI1Lhu3bp85zvfyTHH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0HkrvlRXV8f999/P22+/3WmfwYMH8/7775/yvM5d8YXVq1ezcOFC6uvrO+0zaNAgli1bxhlnnHHKPp234mmFhYXMmDGj0/3dCQj4y3m5evVqHnzwwdZgRntz585l0aJFnf8gbtCUAT+3bNmy1mDAzJkzWbVqFbm5uaxYsYKsrCwaGhq4//77ycvL8/FIJVhUV1cTERHBFVdcwZIlS1i7di2ffPIJb7/9Nrfccgs2m41jx44xf/58jh8/3uEx7rnnHvLz8zEMg9tuu413332XjRs3snjxYhISEiguLubWW29tvWvbXllZGbfddhvFxcUkJiayePFiNm7cyLvvvsttt92GYRhs2bKFe+65x5v/FBLgPvzwQ9asWcPQoUO71V/nrfiK3W7npz/9KW+//TYRERHccMMNvPbaa+Tm5vLRRx/xpz/9iZtvvpkBAwZ0+Hqdu9LXtm7dyn333Ud9fT2pqak89NBD/O1vfyM3N5fXX3+d2bNnA3DkyBFuv/12GhoaTjmGzlvxpoyMDC699FLOPvtst17nD+dlXl4eDzzwAI2NjWRlZbFixQpyc3NZtWoVM2fOBODVV19l2bJlbv1snTLFb504ccKcPHmymZWVZd58881mc3Nzm/2lpaXm+eefb2ZlZZnXXHONj0YpwWbRokVmUVFRp/vfeustMysry8zKyjIXLlx4yv7169e37l+6dOkp+z/99FMzOzvbzMrKMn/3u991+B5PPvmkmZWVZWZnZ5uffvrpKfuXLl3a+h4ffPBB9384CRk1NTXmjBkzzKysrDbn5L333tthf5234kt//OMfzaysLHPChAnm5s2b3Xqtzl3xhQULFphZWVnmmDFjzPz8/A77PPTQQ63nzbvvvttmn85b8YbKykrz3XffbfM99j//8z9bz4OCgoIuX+8v5+X3v/99Mysryzz//PPN0tLSNvuam5vNm266yczKyjInT55snjhxosufqTuUIeDHVq9eTU1NDWBFqwzDaLM/JSWF+fPnA5Cfn8/27dv7fIwSfBYuXEj//v073X/llVeSlZUFwIYNG07Z/8orrwDW+Tlv3rxT9p999tlMnz4dgNdffx273d5mv91u57XXXgNg+vTpHUZ2582bR3Jycpv3E3H19NNPU1BQwOWXX85FF1102v46b8VXysvLefbZZwG47bbbOPfcc916vc5d8YVdu3YB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j1e4zty5c9G3b98XkhAAgJCQEISGhqKqqkrpM7m7uyuMj4iI9BMTAkRERDrCzc0Nx44dw549e3Dy5Enk5OSgpqYG5ubmcHJygre3NyZNmgQTE5OnvsaAAQOQkJCAmTNn4sGDB/jiiy/Q0NCA9957T2gzefJkeHt748CBAzh//jyys7NRUVEBAwMDWFhYwNHREcOHD4eHhweGDRv2PD76MwsICMCECROwZ88enDt3Dnl5eaiqqoKpqSns7Ozg5uaGd955R21BwG3btuHkyZNITk7GlStXUF5eDhMTE/Tp0wejR4/GjBkzYGdnp3EMnp6eSExMxPbt25GWloaKigpYWFjgtddew4wZMzBq1CgcPHiwo26BEn9/f1hbW2Pv3r24fv06ysvLIZFIXtj1iYhI94mampqatD0IIiIiIiIiInqxWFSQiIiIiIiISA8xIUBERERERESkh5gQICIiIiIiItJDTAgQERERERER6SEmBIiIiIiIiIj0EBMCRERERERERHqICQEiIiIiIiIiPcSEABEREREREZEeYkKAiIiIiIiISA8xIUBERERERESkh5gQICIiIiIiItJDTAgQERERERER6SEmBIiIiIiIiIj0EBMCRERERERERHqICQEiIiIiIiIiPcSEABEREREREZEeYkKAiIiIiIiISA8xIUBERERERESkh5gQICIiIiIiItJD/wdN5mqRR76tHAAAAABJRU5ErkJggg==\n", 1812 | "text/plain": [ 1813 | "
" 1814 | ] 1815 | }, 1816 | "metadata": { 1817 | "tags": [], 1818 | "image/png": { 1819 | "width": 514, 1820 | "height": 381 1821 | } 1822 | } 1823 | } 1824 | ] 1825 | }, 1826 | { 1827 | "cell_type": "code", 1828 | "metadata": { 1829 | "id": "CR3rHUQR4pDE", 1830 | "colab_type": "code", 1831 | "colab": {} 1832 | }, 1833 | "source": [ 1834 | "MAX_LEN = 512" 1835 | ], 1836 | "execution_count": 0, 1837 | "outputs": [] 1838 | }, 1839 | { 1840 | "cell_type": "markdown", 1841 | "metadata": { 1842 | "id": "e6Kutw4dJyUG", 1843 | "colab_type": "text" 1844 | }, 1845 | "source": [ 1846 | "### Custom Dataset class" 1847 | ] 1848 | }, 1849 | { 1850 | "cell_type": "code", 1851 | "metadata": { 1852 | "id": "q2NOYXcjPK4z", 1853 | "colab_type": "code", 1854 | "colab": {} 1855 | }, 1856 | "source": [ 1857 | "class ImdbDataset(Dataset):\n", 1858 | "\n", 1859 | " def __init__(self, reviews, targets, tokenizer, max_len):\n", 1860 | " self.reviews = reviews\n", 1861 | " self.targets = targets\n", 1862 | " self.tokenizer = tokenizer\n", 1863 | " self.max_len = max_len\n", 1864 | " \n", 1865 | " def __len__(self):\n", 1866 | " return len(self.reviews)\n", 1867 | " \n", 1868 | " def __getitem__(self, item):\n", 1869 | " review = str(self.reviews[item])\n", 1870 | " target = self.targets[item]\n", 1871 | "\n", 1872 | " encoding = self.tokenizer.encode_plus(\n", 1873 | " review,\n", 1874 | " add_special_tokens=True,\n", 1875 | " max_length=self.max_len,\n", 1876 | " return_token_type_ids=False,\n", 1877 | " pad_to_max_length=False,\n", 1878 | " return_attention_mask=True,\n", 1879 | " return_tensors='pt',\n", 1880 | " )\n", 1881 | "\n", 1882 | " input_ids = pad_sequences(encoding['input_ids'], maxlen=MAX_LEN, dtype=torch.Tensor ,truncating=\"post\",padding=\"post\")\n", 1883 | " input_ids = input_ids.astype(dtype = 'int64')\n", 1884 | " input_ids = torch.tensor(input_ids) \n", 1885 | "\n", 1886 | " attention_mask = pad_sequences(encoding['attention_mask'], maxlen=MAX_LEN, dtype=torch.Tensor ,truncating=\"post\",padding=\"post\")\n", 1887 | " attention_mask = attention_mask.astype(dtype = 'int64')\n", 1888 | " attention_mask = torch.tensor(attention_mask) \n", 1889 | "\n", 1890 | " return {\n", 1891 | " 'review_text': review,\n", 1892 | " 'input_ids': input_ids,\n", 1893 | " 'attention_mask': attention_mask.flatten(),\n", 1894 | " 'targets': torch.tensor(target, dtype=torch.long)\n", 1895 | " }" 1896 | ], 1897 | "execution_count": 0, 1898 | "outputs": [] 1899 | }, 1900 | { 1901 | "cell_type": "code", 1902 | "metadata": { 1903 | "id": "wYXt2AtW6iaT", 1904 | "colab_type": "code", 1905 | "colab": {} 1906 | }, 1907 | "source": [ 1908 | "df_train, df_test = train_test_split(df, test_size=0.5, random_state=101)\n", 1909 | "df_val, df_test = train_test_split(df_test, test_size=0.5, random_state=101)" 1910 | ], 1911 | "execution_count": 0, 1912 | "outputs": [] 1913 | }, 1914 | { 1915 | "cell_type": "code", 1916 | "metadata": { 1917 | "id": "VmAsa9pg6oac", 1918 | "colab_type": "code", 1919 | "outputId": "7733a944-55b3-4181-f84a-be27f5eb3119", 1920 | "colab": { 1921 | "base_uri": "https://localhost:8080/", 1922 | "height": 33 1923 | } 1924 | }, 1925 | "source": [ 1926 | "df_train.shape, df_val.shape, df_test.shape" 1927 | ], 1928 | "execution_count": 0, 1929 | "outputs": [ 1930 | { 1931 | "output_type": "execute_result", 1932 | "data": { 1933 | "text/plain": [ 1934 | "((12000, 2), (6000, 2), (6000, 2))" 1935 | ] 1936 | }, 1937 | "metadata": { 1938 | "tags": [] 1939 | }, 1940 | "execution_count": 30 1941 | } 1942 | ] 1943 | }, 1944 | { 1945 | "cell_type": "markdown", 1946 | "metadata": { 1947 | "id": "iFw2z6ElMZMX", 1948 | "colab_type": "text" 1949 | }, 1950 | "source": [ 1951 | "### Custom Dataloader" 1952 | ] 1953 | }, 1954 | { 1955 | "cell_type": "code", 1956 | "metadata": { 1957 | "id": "3rd7890Z6zLr", 1958 | "colab_type": "code", 1959 | "colab": {} 1960 | }, 1961 | "source": [ 1962 | "def create_data_loader(df, tokenizer, max_len, batch_size):\n", 1963 | " ds = ImdbDataset(\n", 1964 | " reviews=df.review.to_numpy(),\n", 1965 | " targets=df.sentiment.to_numpy(),\n", 1966 | " tokenizer=tokenizer,\n", 1967 | " max_len=max_len\n", 1968 | " )\n", 1969 | "\n", 1970 | " return DataLoader(\n", 1971 | " ds,\n", 1972 | " batch_size=batch_size,\n", 1973 | " num_workers=4\n", 1974 | " )" 1975 | ], 1976 | "execution_count": 0, 1977 | "outputs": [] 1978 | }, 1979 | { 1980 | "cell_type": "code", 1981 | "metadata": { 1982 | "id": "tVU8o6i569ly", 1983 | "colab_type": "code", 1984 | "colab": {} 1985 | }, 1986 | "source": [ 1987 | "BATCH_SIZE = 4\n", 1988 | "\n", 1989 | "train_data_loader = create_data_loader(df_train, tokenizer, MAX_LEN, BATCH_SIZE)\n", 1990 | "val_data_loader = create_data_loader(df_val, tokenizer, MAX_LEN, BATCH_SIZE)\n", 1991 | "test_data_loader = create_data_loader(df_test, tokenizer, MAX_LEN, BATCH_SIZE)" 1992 | ], 1993 | "execution_count": 0, 1994 | "outputs": [] 1995 | }, 1996 | { 1997 | "cell_type": "markdown", 1998 | "metadata": { 1999 | "id": "aC5D5Dh8J5w9", 2000 | "colab_type": "text" 2001 | }, 2002 | "source": [ 2003 | "### Loading the Pre-trained XLNet model for sequence classification from huggingface transformers" 2004 | ] 2005 | }, 2006 | { 2007 | "cell_type": "code", 2008 | "metadata": { 2009 | "id": "H5mC8v6i7VH1", 2010 | "colab_type": "code", 2011 | "outputId": "0bc5d6fe-d14b-455b-cba5-00ce32812140", 2012 | "colab": { 2013 | "base_uri": "https://localhost:8080/", 2014 | "height": 114, 2015 | "referenced_widgets": [ 2016 | "c2b26508fa464328b2b30c851a0366fe", 2017 | "18e0ec87d07d4c0bb3930b5cef204963", 2018 | "bac82e5dc1974ef4ac18f743ecfb72b5", 2019 | "35d3d0c2b7004a6b87420e55a94ddcaf", 2020 | "d8893bea6edb4154b051b344cae1636c", 2021 | "d8c49d3421e843a6a2aadd20565ea5d2", 2022 | "3524b098b1944e5ba752f1fbfcb50aef", 2023 | "0cba445897514d4b98192e28890df304", 2024 | "62d0e9673815468ba407019771a0b2ba", 2025 | "6af011b92bd3462b937cea74a2094579", 2026 | "47a41f0a294f42cbb2c9ec3916ca100e", 2027 | "3d9a5c47f9fb44ffa41f91cc37b8ee6e", 2028 | "767ef584a8ed49b4ae8ee7835208fb44", 2029 | "769eba56a67d4d71b76f1240fd154a4e", 2030 | "f6cc72303ee14b548a2c4c1282a1784b", 2031 | "b9235fdb071742628781944bb3b6608d" 2032 | ] 2033 | } 2034 | }, 2035 | "source": [ 2036 | "from transformers import XLNetForSequenceClassification\n", 2037 | "model = XLNetForSequenceClassification.from_pretrained('xlnet-base-cased', num_labels = 2)\n", 2038 | "model = model.to(device)" 2039 | ], 2040 | "execution_count": 0, 2041 | "outputs": [ 2042 | { 2043 | "output_type": "display_data", 2044 | "data": { 2045 | "application/vnd.jupyter.widget-view+json": { 2046 | "model_id": "c2b26508fa464328b2b30c851a0366fe", 2047 | "version_minor": 0, 2048 | "version_major": 2 2049 | }, 2050 | "text/plain": [ 2051 | "HBox(children=(FloatProgress(value=0.0, description='Downloading', max=760.0, style=ProgressStyle(description_…" 2052 | ] 2053 | }, 2054 | "metadata": { 2055 | "tags": [] 2056 | } 2057 | }, 2058 | { 2059 | "output_type": "stream", 2060 | "text": [ 2061 | "\n" 2062 | ], 2063 | "name": "stdout" 2064 | }, 2065 | { 2066 | "output_type": "display_data", 2067 | "data": { 2068 | "application/vnd.jupyter.widget-view+json": { 2069 | "model_id": "62d0e9673815468ba407019771a0b2ba", 2070 | "version_minor": 0, 2071 | "version_major": 2 2072 | }, 2073 | "text/plain": [ 2074 | "HBox(children=(FloatProgress(value=0.0, description='Downloading', max=467042463.0, style=ProgressStyle(descri…" 2075 | ] 2076 | }, 2077 | "metadata": { 2078 | "tags": [] 2079 | } 2080 | }, 2081 | { 2082 | "output_type": "stream", 2083 | "text": [ 2084 | "\n" 2085 | ], 2086 | "name": "stdout" 2087 | } 2088 | ] 2089 | }, 2090 | { 2091 | "cell_type": "code", 2092 | "metadata": { 2093 | "id": "KYsVoULvfmvD", 2094 | "colab_type": "code", 2095 | "outputId": "f744743c-6554-4bc2-b3b0-1236164352fc", 2096 | "colab": { 2097 | "base_uri": "https://localhost:8080/", 2098 | "height": 1000 2099 | } 2100 | }, 2101 | "source": [ 2102 | "model" 2103 | ], 2104 | "execution_count": 0, 2105 | "outputs": [ 2106 | { 2107 | "output_type": "execute_result", 2108 | "data": { 2109 | "text/plain": [ 2110 | "XLNetForSequenceClassification(\n", 2111 | " (transformer): XLNetModel(\n", 2112 | " (word_embedding): Embedding(32000, 768)\n", 2113 | " (layer): ModuleList(\n", 2114 | " (0): XLNetLayer(\n", 2115 | " (rel_attn): XLNetRelativeAttention(\n", 2116 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2117 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2118 | " )\n", 2119 | " (ff): XLNetFeedForward(\n", 2120 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2121 | " (layer_1): Linear(in_features=768, out_features=3072, bias=True)\n", 2122 | " (layer_2): Linear(in_features=3072, out_features=768, bias=True)\n", 2123 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2124 | " )\n", 2125 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2126 | " )\n", 2127 | " (1): XLNetLayer(\n", 2128 | " (rel_attn): XLNetRelativeAttention(\n", 2129 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2130 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2131 | " )\n", 2132 | " (ff): XLNetFeedForward(\n", 2133 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2134 | " (layer_1): Linear(in_features=768, out_features=3072, bias=True)\n", 2135 | " (layer_2): Linear(in_features=3072, out_features=768, bias=True)\n", 2136 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2137 | " )\n", 2138 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2139 | " )\n", 2140 | " (2): XLNetLayer(\n", 2141 | " (rel_attn): XLNetRelativeAttention(\n", 2142 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2143 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2144 | " )\n", 2145 | " (ff): XLNetFeedForward(\n", 2146 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2147 | " (layer_1): Linear(in_features=768, out_features=3072, bias=True)\n", 2148 | " (layer_2): Linear(in_features=3072, out_features=768, bias=True)\n", 2149 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2150 | " )\n", 2151 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2152 | " )\n", 2153 | " (3): XLNetLayer(\n", 2154 | " (rel_attn): XLNetRelativeAttention(\n", 2155 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2156 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2157 | " )\n", 2158 | " (ff): XLNetFeedForward(\n", 2159 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2160 | " (layer_1): Linear(in_features=768, out_features=3072, bias=True)\n", 2161 | " (layer_2): Linear(in_features=3072, out_features=768, bias=True)\n", 2162 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2163 | " )\n", 2164 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2165 | " )\n", 2166 | " (4): XLNetLayer(\n", 2167 | " (rel_attn): XLNetRelativeAttention(\n", 2168 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2169 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2170 | " )\n", 2171 | " (ff): XLNetFeedForward(\n", 2172 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2173 | " (layer_1): Linear(in_features=768, out_features=3072, bias=True)\n", 2174 | " (layer_2): Linear(in_features=3072, out_features=768, bias=True)\n", 2175 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2176 | " )\n", 2177 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2178 | " )\n", 2179 | " (5): XLNetLayer(\n", 2180 | " (rel_attn): XLNetRelativeAttention(\n", 2181 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2182 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2183 | " )\n", 2184 | " (ff): XLNetFeedForward(\n", 2185 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2186 | " (layer_1): Linear(in_features=768, out_features=3072, bias=True)\n", 2187 | " (layer_2): Linear(in_features=3072, out_features=768, bias=True)\n", 2188 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2189 | " )\n", 2190 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2191 | " )\n", 2192 | " (6): XLNetLayer(\n", 2193 | " (rel_attn): XLNetRelativeAttention(\n", 2194 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2195 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2196 | " )\n", 2197 | " (ff): XLNetFeedForward(\n", 2198 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2199 | " (layer_1): Linear(in_features=768, out_features=3072, bias=True)\n", 2200 | " (layer_2): Linear(in_features=3072, out_features=768, bias=True)\n", 2201 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2202 | " )\n", 2203 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2204 | " )\n", 2205 | " (7): XLNetLayer(\n", 2206 | " (rel_attn): XLNetRelativeAttention(\n", 2207 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2208 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2209 | " )\n", 2210 | " (ff): XLNetFeedForward(\n", 2211 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2212 | " (layer_1): Linear(in_features=768, out_features=3072, bias=True)\n", 2213 | " (layer_2): Linear(in_features=3072, out_features=768, bias=True)\n", 2214 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2215 | " )\n", 2216 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2217 | " )\n", 2218 | " (8): XLNetLayer(\n", 2219 | " (rel_attn): XLNetRelativeAttention(\n", 2220 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2221 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2222 | " )\n", 2223 | " (ff): XLNetFeedForward(\n", 2224 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2225 | " (layer_1): Linear(in_features=768, out_features=3072, bias=True)\n", 2226 | " (layer_2): Linear(in_features=3072, out_features=768, bias=True)\n", 2227 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2228 | " )\n", 2229 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2230 | " )\n", 2231 | " (9): XLNetLayer(\n", 2232 | " (rel_attn): XLNetRelativeAttention(\n", 2233 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2234 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2235 | " )\n", 2236 | " (ff): XLNetFeedForward(\n", 2237 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2238 | " (layer_1): Linear(in_features=768, out_features=3072, bias=True)\n", 2239 | " (layer_2): Linear(in_features=3072, out_features=768, bias=True)\n", 2240 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2241 | " )\n", 2242 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2243 | " )\n", 2244 | " (10): XLNetLayer(\n", 2245 | " (rel_attn): XLNetRelativeAttention(\n", 2246 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2247 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2248 | " )\n", 2249 | " (ff): XLNetFeedForward(\n", 2250 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2251 | " (layer_1): Linear(in_features=768, out_features=3072, bias=True)\n", 2252 | " (layer_2): Linear(in_features=3072, out_features=768, bias=True)\n", 2253 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2254 | " )\n", 2255 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2256 | " )\n", 2257 | " (11): XLNetLayer(\n", 2258 | " (rel_attn): XLNetRelativeAttention(\n", 2259 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2260 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2261 | " )\n", 2262 | " (ff): XLNetFeedForward(\n", 2263 | " (layer_norm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n", 2264 | " (layer_1): Linear(in_features=768, out_features=3072, bias=True)\n", 2265 | " (layer_2): Linear(in_features=3072, out_features=768, bias=True)\n", 2266 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2267 | " )\n", 2268 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2269 | " )\n", 2270 | " )\n", 2271 | " (dropout): Dropout(p=0.1, inplace=False)\n", 2272 | " )\n", 2273 | " (sequence_summary): SequenceSummary(\n", 2274 | " (summary): Linear(in_features=768, out_features=768, bias=True)\n", 2275 | " (first_dropout): Identity()\n", 2276 | " (last_dropout): Dropout(p=0.1, inplace=False)\n", 2277 | " )\n", 2278 | " (logits_proj): Linear(in_features=768, out_features=2, bias=True)\n", 2279 | ")" 2280 | ] 2281 | }, 2282 | "metadata": { 2283 | "tags": [] 2284 | }, 2285 | "execution_count": 34 2286 | } 2287 | ] 2288 | }, 2289 | { 2290 | "cell_type": "markdown", 2291 | "metadata": { 2292 | "id": "vpn2sTTMK_zL", 2293 | "colab_type": "text" 2294 | }, 2295 | "source": [ 2296 | "### Setting Hyperparameters" 2297 | ] 2298 | }, 2299 | { 2300 | "cell_type": "code", 2301 | "metadata": { 2302 | "id": "aQ9Od31B9YJa", 2303 | "colab_type": "code", 2304 | "colab": {} 2305 | }, 2306 | "source": [ 2307 | "EPOCHS = 3\n", 2308 | "\n", 2309 | "param_optimizer = list(model.named_parameters())\n", 2310 | "no_decay = ['bias', 'LayerNorm.bias', 'LayerNorm.weight']\n", 2311 | "optimizer_grouped_parameters = [\n", 2312 | " {'params': [p for n, p in param_optimizer if not any(nd in n for nd in no_decay)], 'weight_decay': 0.01},\n", 2313 | " {'params': [p for n, p in param_optimizer if any(nd in n for nd in no_decay)], 'weight_decay':0.0}\n", 2314 | "]\n", 2315 | "optimizer = AdamW(optimizer_grouped_parameters, lr=3e-5)\n", 2316 | "\n", 2317 | "total_steps = len(train_data_loader) * EPOCHS\n", 2318 | "\n", 2319 | "scheduler = get_linear_schedule_with_warmup(\n", 2320 | " optimizer,\n", 2321 | " num_warmup_steps=0,\n", 2322 | " num_training_steps=total_steps\n", 2323 | ")" 2324 | ], 2325 | "execution_count": 0, 2326 | "outputs": [] 2327 | }, 2328 | { 2329 | "cell_type": "markdown", 2330 | "metadata": { 2331 | "id": "G2AtJcvwLV3x", 2332 | "colab_type": "text" 2333 | }, 2334 | "source": [ 2335 | "### Sanity check with one batch" 2336 | ] 2337 | }, 2338 | { 2339 | "cell_type": "code", 2340 | "metadata": { 2341 | "id": "rUoaMqjvKdym", 2342 | "colab_type": "code", 2343 | "outputId": "e9f8a354-bfd6-4ad9-f139-119e937d1a05", 2344 | "colab": { 2345 | "base_uri": "https://localhost:8080/", 2346 | "height": 33 2347 | } 2348 | }, 2349 | "source": [ 2350 | "data = next(iter(val_data_loader))\n", 2351 | "data.keys()" 2352 | ], 2353 | "execution_count": 0, 2354 | "outputs": [ 2355 | { 2356 | "output_type": "execute_result", 2357 | "data": { 2358 | "text/plain": [ 2359 | "dict_keys(['review_text', 'input_ids', 'attention_mask', 'targets'])" 2360 | ] 2361 | }, 2362 | "metadata": { 2363 | "tags": [] 2364 | }, 2365 | "execution_count": 36 2366 | } 2367 | ] 2368 | }, 2369 | { 2370 | "cell_type": "code", 2371 | "metadata": { 2372 | "id": "RIUB5WJNKhBs", 2373 | "colab_type": "code", 2374 | "outputId": "84dbb5d9-adb4-44a6-b8bb-1627fbf87592", 2375 | "colab": { 2376 | "base_uri": "https://localhost:8080/", 2377 | "height": 50 2378 | } 2379 | }, 2380 | "source": [ 2381 | "input_ids = data['input_ids'].to(device)\n", 2382 | "attention_mask = data['attention_mask'].to(device)\n", 2383 | "targets = data['targets'].to(device)\n", 2384 | "print(input_ids.reshape(4,512).shape) # batch size x seq length\n", 2385 | "print(attention_mask.shape) # batch size x seq length" 2386 | ], 2387 | "execution_count": 0, 2388 | "outputs": [ 2389 | { 2390 | "output_type": "stream", 2391 | "text": [ 2392 | "torch.Size([4, 512])\n", 2393 | "torch.Size([4, 512])\n" 2394 | ], 2395 | "name": "stdout" 2396 | } 2397 | ] 2398 | }, 2399 | { 2400 | "cell_type": "code", 2401 | "metadata": { 2402 | "id": "EYsDR9leYb4Z", 2403 | "colab_type": "code", 2404 | "outputId": "af950d9a-fad4-48a6-a49a-7b310f657794", 2405 | "colab": { 2406 | "base_uri": "https://localhost:8080/", 2407 | "height": 886 2408 | } 2409 | }, 2410 | "source": [ 2411 | "input_ids[0]" 2412 | ], 2413 | "execution_count": 0, 2414 | "outputs": [ 2415 | { 2416 | "output_type": "execute_result", 2417 | "data": { 2418 | "text/plain": [ 2419 | "tensor([[ 35, 26, 215, 435, 52, 1365, 21, 3353, 9, 4716,\n", 2420 | " 2537, 31, 58, 162, 192, 40, 24, 1288, 275, 2263,\n", 2421 | " 22, 182, 24, 17, 26, 16071, 778, 26, 29, 3469,\n", 2422 | " 107, 151, 24, 18041, 3401, 17, 16847, 939, 9, 1577,\n", 2423 | " 477, 805, 57, 195, 406, 1825, 22, 107, 21, 63,\n", 2424 | " 8008, 4623, 38, 58, 5754, 9, 17, 2369, 17, 2369,\n", 2425 | " 17, 29720, 63, 220, 26, 46, 9, 7174, 63, 26,\n", 2426 | " 88, 23064, 151, 37, 24, 321, 17785, 19167, 61, 51,\n", 2427 | " 106, 3404, 3728, 705, 21, 113, 30977, 23, 27, 2640,\n", 2428 | " 641, 20, 13943, 30436, 9, 17, 2369, 17, 2369, 35,\n", 2429 | " 937, 22, 287, 197, 124, 20, 166, 6454, 25, 124,\n", 2430 | " 1432, 545, 292, 9, 1988, 11247, 27288, 56, 9185, 675,\n", 2431 | " 110, 24, 16180, 21, 18, 4948, 30, 102, 10488, 1062,\n", 2432 | " 29, 36, 738, 24, 434, 20, 5632, 16055, 21, 555,\n", 2433 | " 15450, 4140, 30182, 11247, 9, 394, 25, 71, 65, 20,\n", 2434 | " 18, 2598, 3640, 6941, 17045, 23, 35, 26, 189, 545,\n", 2435 | " 566, 9, 9, 9, 443, 35, 26, 189, 566, 24,\n", 2436 | " 434, 9, 4, 3, 0, 0, 0, 0, 0, 0,\n", 2437 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2438 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2439 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2440 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2441 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2442 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2443 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2444 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2445 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2446 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2447 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2448 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2449 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2450 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2451 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2452 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2453 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2454 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2455 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2456 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2457 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2458 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2459 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2460 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2461 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2462 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2463 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2464 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2465 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2466 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2467 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2468 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2469 | " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", 2470 | " 0, 0]], device='cuda:0')" 2471 | ] 2472 | }, 2473 | "metadata": { 2474 | "tags": [] 2475 | }, 2476 | "execution_count": 38 2477 | } 2478 | ] 2479 | }, 2480 | { 2481 | "cell_type": "code", 2482 | "metadata": { 2483 | "id": "KCFLKXL0KmaA", 2484 | "colab_type": "code", 2485 | "outputId": "7e543f7e-a43d-4c30-91bf-0efe1d2d476c", 2486 | "colab": { 2487 | "base_uri": "https://localhost:8080/", 2488 | "height": 100 2489 | } 2490 | }, 2491 | "source": [ 2492 | "outputs = model(input_ids.reshape(4,512), token_type_ids=None, attention_mask=attention_mask, labels=targets)\n", 2493 | "outputs" 2494 | ], 2495 | "execution_count": 0, 2496 | "outputs": [ 2497 | { 2498 | "output_type": "execute_result", 2499 | "data": { 2500 | "text/plain": [ 2501 | "(tensor(0.7846, device='cuda:0', grad_fn=),\n", 2502 | " tensor([[-0.8857, -0.5108],\n", 2503 | " [-0.7872, -0.4824],\n", 2504 | " [-0.7139, -0.5388],\n", 2505 | " [-0.7889, -0.4051]], device='cuda:0', grad_fn=))" 2506 | ] 2507 | }, 2508 | "metadata": { 2509 | "tags": [] 2510 | }, 2511 | "execution_count": 39 2512 | } 2513 | ] 2514 | }, 2515 | { 2516 | "cell_type": "code", 2517 | "metadata": { 2518 | "id": "zbyJNtqVkg4Y", 2519 | "colab_type": "code", 2520 | "outputId": "207c8486-99f7-4ae7-d930-dde9419dd99f", 2521 | "colab": { 2522 | "base_uri": "https://localhost:8080/", 2523 | "height": 33 2524 | } 2525 | }, 2526 | "source": [ 2527 | "type(outputs[0])" 2528 | ], 2529 | "execution_count": 0, 2530 | "outputs": [ 2531 | { 2532 | "output_type": "execute_result", 2533 | "data": { 2534 | "text/plain": [ 2535 | "torch.Tensor" 2536 | ] 2537 | }, 2538 | "metadata": { 2539 | "tags": [] 2540 | }, 2541 | "execution_count": 42 2542 | } 2543 | ] 2544 | }, 2545 | { 2546 | "cell_type": "markdown", 2547 | "metadata": { 2548 | "id": "eg44cHnNLd3J", 2549 | "colab_type": "text" 2550 | }, 2551 | "source": [ 2552 | "### Defining the training step function" 2553 | ] 2554 | }, 2555 | { 2556 | "cell_type": "code", 2557 | "metadata": { 2558 | "id": "tPnWttRNMArt", 2559 | "colab_type": "code", 2560 | "colab": {} 2561 | }, 2562 | "source": [ 2563 | "from sklearn import metrics\n", 2564 | "def train_epoch(model, data_loader, optimizer, device, scheduler, n_examples):\n", 2565 | " model = model.train()\n", 2566 | " losses = []\n", 2567 | " acc = 0\n", 2568 | " counter = 0\n", 2569 | " \n", 2570 | " for d in data_loader:\n", 2571 | " input_ids = d[\"input_ids\"].reshape(4,512).to(device)\n", 2572 | " attention_mask = d[\"attention_mask\"].to(device)\n", 2573 | " targets = d[\"targets\"].to(device)\n", 2574 | " \n", 2575 | " outputs = model(input_ids=input_ids, token_type_ids=None, attention_mask=attention_mask, labels = targets)\n", 2576 | " loss = outputs[0]\n", 2577 | " logits = outputs[1]\n", 2578 | "\n", 2579 | " # preds = preds.cpu().detach().numpy()\n", 2580 | " _, prediction = torch.max(outputs[1], dim=1)\n", 2581 | " targets = targets.cpu().detach().numpy()\n", 2582 | " prediction = prediction.cpu().detach().numpy()\n", 2583 | " accuracy = metrics.accuracy_score(targets, prediction)\n", 2584 | "\n", 2585 | " acc += accuracy\n", 2586 | " losses.append(loss.item())\n", 2587 | " \n", 2588 | " loss.backward()\n", 2589 | "\n", 2590 | " nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)\n", 2591 | " optimizer.step()\n", 2592 | " scheduler.step()\n", 2593 | " optimizer.zero_grad()\n", 2594 | " counter = counter + 1\n", 2595 | "\n", 2596 | " return acc / counter, np.mean(losses)" 2597 | ], 2598 | "execution_count": 0, 2599 | "outputs": [] 2600 | }, 2601 | { 2602 | "cell_type": "markdown", 2603 | "metadata": { 2604 | "id": "4N2ktqT8LoDS", 2605 | "colab_type": "text" 2606 | }, 2607 | "source": [ 2608 | "### Defining the evaluation function" 2609 | ] 2610 | }, 2611 | { 2612 | "cell_type": "code", 2613 | "metadata": { 2614 | "id": "V_ZyoJ4qb-CB", 2615 | "colab_type": "code", 2616 | "colab": {} 2617 | }, 2618 | "source": [ 2619 | "def eval_model(model, data_loader, device, n_examples):\n", 2620 | " model = model.eval()\n", 2621 | " losses = []\n", 2622 | " acc = 0\n", 2623 | " counter = 0\n", 2624 | " \n", 2625 | " with torch.no_grad():\n", 2626 | " for d in data_loader:\n", 2627 | " input_ids = d[\"input_ids\"].reshape(4,512).to(device)\n", 2628 | " attention_mask = d[\"attention_mask\"].to(device)\n", 2629 | " targets = d[\"targets\"].to(device)\n", 2630 | " \n", 2631 | " outputs = model(input_ids=input_ids, token_type_ids=None, attention_mask=attention_mask, labels = targets)\n", 2632 | " loss = outputs[0]\n", 2633 | " logits = outputs[1]\n", 2634 | "\n", 2635 | " _, prediction = torch.max(outputs[1], dim=1)\n", 2636 | " targets = targets.cpu().detach().numpy()\n", 2637 | " prediction = prediction.cpu().detach().numpy()\n", 2638 | " accuracy = metrics.accuracy_score(targets, prediction)\n", 2639 | "\n", 2640 | " acc += accuracy\n", 2641 | " losses.append(loss.item())\n", 2642 | " counter += 1\n", 2643 | "\n", 2644 | " return acc / counter, np.mean(losses)" 2645 | ], 2646 | "execution_count": 0, 2647 | "outputs": [] 2648 | }, 2649 | { 2650 | "cell_type": "markdown", 2651 | "metadata": { 2652 | "id": "9AG1TE43LvkX", 2653 | "colab_type": "text" 2654 | }, 2655 | "source": [ 2656 | "### Fine-tuning the pre-trained model" 2657 | ] 2658 | }, 2659 | { 2660 | "cell_type": "code", 2661 | "metadata": { 2662 | "id": "eNSQSFkScp6f", 2663 | "colab_type": "code", 2664 | "outputId": "1970b1cb-c420-406d-d5e0-a7f490e45500", 2665 | "colab": { 2666 | "base_uri": "https://localhost:8080/", 2667 | "height": 301 2668 | } 2669 | }, 2670 | "source": [ 2671 | "%%time\n", 2672 | "history = defaultdict(list)\n", 2673 | "best_accuracy = 0\n", 2674 | "\n", 2675 | "for epoch in range(EPOCHS):\n", 2676 | " print(f'Epoch {epoch + 1}/{EPOCHS}')\n", 2677 | " print('-' * 10)\n", 2678 | "\n", 2679 | " train_acc, train_loss = train_epoch(\n", 2680 | " model,\n", 2681 | " train_data_loader, \n", 2682 | " optimizer, \n", 2683 | " device, \n", 2684 | " scheduler, \n", 2685 | " len(df_train)\n", 2686 | " )\n", 2687 | "\n", 2688 | " print(f'Train loss {train_loss} Train accuracy {train_acc}')\n", 2689 | "\n", 2690 | " val_acc, val_loss = eval_model(\n", 2691 | " model,\n", 2692 | " val_data_loader, \n", 2693 | " device, \n", 2694 | " len(df_val)\n", 2695 | " )\n", 2696 | "\n", 2697 | " print(f'Val loss {val_loss} Val accuracy {val_acc}')\n", 2698 | " print()\n", 2699 | "\n", 2700 | " history['train_acc'].append(train_acc)\n", 2701 | " history['train_loss'].append(train_loss)\n", 2702 | " history['val_acc'].append(val_acc)\n", 2703 | " history['val_loss'].append(val_loss)\n", 2704 | "\n", 2705 | " if val_acc > best_accuracy:\n", 2706 | " torch.save(model.state_dict(), '/content/drive/My Drive/NLP/Sentiment Analysis Series/models/xlnet_model.bin')\n", 2707 | " best_accuracy = val_acc" 2708 | ], 2709 | "execution_count": 0, 2710 | "outputs": [ 2711 | { 2712 | "output_type": "stream", 2713 | "text": [ 2714 | "Epoch 1/3\n", 2715 | "----------\n", 2716 | "Train loss 0.40229895541320243 Train accuracy 0.90525\n", 2717 | "Val loss 0.3111661048134168 Val accuracy 0.9308333333333333\n", 2718 | "\n", 2719 | "Epoch 2/3\n", 2720 | "----------\n", 2721 | "Train loss 0.2054168249045809 Train accuracy 0.9594166666666667\n", 2722 | "Val loss 0.3556234954794248 Val accuracy 0.9366666666666666\n", 2723 | "\n", 2724 | "Epoch 3/3\n", 2725 | "----------\n", 2726 | "Train loss 0.08638643393417199 Train accuracy 0.985\n", 2727 | "Val loss 0.3777355106075605 Val accuracy 0.9403333333333334\n", 2728 | "\n", 2729 | "CPU times: user 2h 31min 50s, sys: 1h 36min 22s, total: 4h 8min 12s\n", 2730 | "Wall time: 4h 8min 44s\n" 2731 | ], 2732 | "name": "stdout" 2733 | } 2734 | ] 2735 | }, 2736 | { 2737 | "cell_type": "markdown", 2738 | "metadata": { 2739 | "id": "qe08GjtNL-Sh", 2740 | "colab_type": "text" 2741 | }, 2742 | "source": [ 2743 | "### Evaluation of the fine-tuned model" 2744 | ] 2745 | }, 2746 | { 2747 | "cell_type": "code", 2748 | "metadata": { 2749 | "id": "XqtQkz2yrZE3", 2750 | "colab_type": "code", 2751 | "outputId": "b57d0042-0a00-4ae0-e177-3ebc889e29f8", 2752 | "colab": { 2753 | "base_uri": "https://localhost:8080/", 2754 | "height": 33 2755 | } 2756 | }, 2757 | "source": [ 2758 | "model.load_state_dict(torch.load('/content/drive/My Drive/NLP/Sentiment Analysis Series/models/xlnet_model.bin'))" 2759 | ], 2760 | "execution_count": 0, 2761 | "outputs": [ 2762 | { 2763 | "output_type": "execute_result", 2764 | "data": { 2765 | "text/plain": [ 2766 | "" 2767 | ] 2768 | }, 2769 | "metadata": { 2770 | "tags": [] 2771 | }, 2772 | "execution_count": 46 2773 | } 2774 | ] 2775 | }, 2776 | { 2777 | "cell_type": "code", 2778 | "metadata": { 2779 | "id": "26k0PMpdy1QT", 2780 | "colab_type": "code", 2781 | "colab": {} 2782 | }, 2783 | "source": [ 2784 | "model = model.to(device)" 2785 | ], 2786 | "execution_count": 0, 2787 | "outputs": [] 2788 | }, 2789 | { 2790 | "cell_type": "code", 2791 | "metadata": { 2792 | "id": "QHINzx6ezSD0", 2793 | "colab_type": "code", 2794 | "outputId": "48dd67b6-d26d-45cf-aeff-4c7eda62e5e5", 2795 | "colab": { 2796 | "base_uri": "https://localhost:8080/", 2797 | "height": 50 2798 | } 2799 | }, 2800 | "source": [ 2801 | "test_acc, test_loss = eval_model(\n", 2802 | " model,\n", 2803 | " test_data_loader,\n", 2804 | " device,\n", 2805 | " len(df_test)\n", 2806 | ")\n", 2807 | "\n", 2808 | "print('Test Accuracy :', test_acc)\n", 2809 | "print('Test Loss :', test_loss)" 2810 | ], 2811 | "execution_count": 0, 2812 | "outputs": [ 2813 | { 2814 | "output_type": "stream", 2815 | "text": [ 2816 | "Test Accuracy : 0.956\n", 2817 | "Test Loss : 0.2740427735249201\n" 2818 | ], 2819 | "name": "stdout" 2820 | } 2821 | ] 2822 | }, 2823 | { 2824 | "cell_type": "code", 2825 | "metadata": { 2826 | "id": "NBWsLq4yzubR", 2827 | "colab_type": "code", 2828 | "colab": {} 2829 | }, 2830 | "source": [ 2831 | "def get_predictions(model, data_loader):\n", 2832 | " model = model.eval()\n", 2833 | " \n", 2834 | " review_texts = []\n", 2835 | " predictions = []\n", 2836 | " prediction_probs = []\n", 2837 | " real_values = []\n", 2838 | "\n", 2839 | " with torch.no_grad():\n", 2840 | " for d in data_loader:\n", 2841 | "\n", 2842 | " texts = d[\"review_text\"]\n", 2843 | " input_ids = d[\"input_ids\"].reshape(4,512).to(device)\n", 2844 | " attention_mask = d[\"attention_mask\"].to(device)\n", 2845 | " targets = d[\"targets\"].to(device)\n", 2846 | " \n", 2847 | " outputs = model(input_ids=input_ids, token_type_ids=None, attention_mask=attention_mask, labels = targets)\n", 2848 | "\n", 2849 | " loss = outputs[0]\n", 2850 | " logits = outputs[1]\n", 2851 | " \n", 2852 | " _, preds = torch.max(outputs[1], dim=1)\n", 2853 | "\n", 2854 | " probs = F.softmax(outputs[1], dim=1)\n", 2855 | "\n", 2856 | " review_texts.extend(texts)\n", 2857 | " predictions.extend(preds)\n", 2858 | " prediction_probs.extend(probs)\n", 2859 | " real_values.extend(targets)\n", 2860 | "\n", 2861 | " predictions = torch.stack(predictions).cpu()\n", 2862 | " prediction_probs = torch.stack(prediction_probs).cpu()\n", 2863 | " real_values = torch.stack(real_values).cpu()\n", 2864 | " return review_texts, predictions, prediction_probs, real_values" 2865 | ], 2866 | "execution_count": 0, 2867 | "outputs": [] 2868 | }, 2869 | { 2870 | "cell_type": "code", 2871 | "metadata": { 2872 | "id": "hwCQaTFH5KWy", 2873 | "colab_type": "code", 2874 | "colab": {} 2875 | }, 2876 | "source": [ 2877 | "y_review_texts, y_pred, y_pred_probs, y_test = get_predictions(\n", 2878 | " model,\n", 2879 | " test_data_loader\n", 2880 | ")" 2881 | ], 2882 | "execution_count": 0, 2883 | "outputs": [] 2884 | }, 2885 | { 2886 | "cell_type": "code", 2887 | "metadata": { 2888 | "id": "wviSSrIP5Pvl", 2889 | "colab_type": "code", 2890 | "outputId": "87c89f11-e95b-4fdd-adf7-5601732d5080", 2891 | "colab": { 2892 | "base_uri": "https://localhost:8080/", 2893 | "height": 167 2894 | } 2895 | }, 2896 | "source": [ 2897 | "print(classification_report(y_test, y_pred, target_names=class_names))" 2898 | ], 2899 | "execution_count": 0, 2900 | "outputs": [ 2901 | { 2902 | "output_type": "stream", 2903 | "text": [ 2904 | " precision recall f1-score support\n", 2905 | "\n", 2906 | " negative 0.95 0.96 0.96 2976\n", 2907 | " positive 0.96 0.96 0.96 3024\n", 2908 | "\n", 2909 | " accuracy 0.96 6000\n", 2910 | " macro avg 0.96 0.96 0.96 6000\n", 2911 | "weighted avg 0.96 0.96 0.96 6000\n", 2912 | "\n" 2913 | ], 2914 | "name": "stdout" 2915 | } 2916 | ] 2917 | }, 2918 | { 2919 | "cell_type": "markdown", 2920 | "metadata": { 2921 | "id": "FdrnJkm-MGvv", 2922 | "colab_type": "text" 2923 | }, 2924 | "source": [ 2925 | "### Custom prediction function on raw text" 2926 | ] 2927 | }, 2928 | { 2929 | "cell_type": "code", 2930 | "metadata": { 2931 | "id": "lIxCoTjo6tWM", 2932 | "colab_type": "code", 2933 | "colab": {} 2934 | }, 2935 | "source": [ 2936 | "def predict_sentiment(text):\n", 2937 | " review_text = text\n", 2938 | "\n", 2939 | " encoded_review = tokenizer.encode_plus(\n", 2940 | " review_text,\n", 2941 | " max_length=MAX_LEN,\n", 2942 | " add_special_tokens=True,\n", 2943 | " return_token_type_ids=False,\n", 2944 | " pad_to_max_length=False,\n", 2945 | " return_attention_mask=True,\n", 2946 | " return_tensors='pt',\n", 2947 | " )\n", 2948 | "\n", 2949 | " input_ids = pad_sequences(encoded_review['input_ids'], maxlen=MAX_LEN, dtype=torch.Tensor ,truncating=\"post\",padding=\"post\")\n", 2950 | " input_ids = input_ids.astype(dtype = 'int64')\n", 2951 | " input_ids = torch.tensor(input_ids) \n", 2952 | "\n", 2953 | " attention_mask = pad_sequences(encoded_review['attention_mask'], maxlen=MAX_LEN, dtype=torch.Tensor ,truncating=\"post\",padding=\"post\")\n", 2954 | " attention_mask = attention_mask.astype(dtype = 'int64')\n", 2955 | " attention_mask = torch.tensor(attention_mask) \n", 2956 | "\n", 2957 | " input_ids = input_ids.reshape(1,512).to(device)\n", 2958 | " attention_mask = attention_mask.to(device)\n", 2959 | "\n", 2960 | " outputs = model(input_ids=input_ids, attention_mask=attention_mask)\n", 2961 | "\n", 2962 | " outputs = outputs[0][0].cpu().detach()\n", 2963 | "\n", 2964 | " probs = F.softmax(outputs, dim=-1).cpu().detach().numpy().tolist()\n", 2965 | " _, prediction = torch.max(outputs, dim =-1)\n", 2966 | "\n", 2967 | " print(\"Positive score:\", probs[1])\n", 2968 | " print(\"Negative score:\", probs[0])\n", 2969 | " print(f'Review text: {review_text}')\n", 2970 | " print(f'Sentiment : {class_names[prediction]}')" 2971 | ], 2972 | "execution_count": 0, 2973 | "outputs": [] 2974 | }, 2975 | { 2976 | "cell_type": "code", 2977 | "metadata": { 2978 | "id": "8UlPGZgNFV1j", 2979 | "colab_type": "code", 2980 | "outputId": "cd61d132-8ff8-4416-d4fe-7c6e16a55f04", 2981 | "colab": { 2982 | "base_uri": "https://localhost:8080/", 2983 | "height": 84 2984 | } 2985 | }, 2986 | "source": [ 2987 | "text = \"Movie is the worst one I have ever seen!! The story has no meaning at all\"\n", 2988 | "predict_sentiment(text)" 2989 | ], 2990 | "execution_count": 0, 2991 | "outputs": [ 2992 | { 2993 | "output_type": "stream", 2994 | "text": [ 2995 | "Positive score: 0.00017438380746170878\n", 2996 | "Negative score: 0.999825656414032\n", 2997 | "Review text: Movie is the worst one I have ever seen!! The story has no meaning at all\n", 2998 | "Sentiment : negative\n" 2999 | ], 3000 | "name": "stdout" 3001 | } 3002 | ] 3003 | }, 3004 | { 3005 | "cell_type": "code", 3006 | "metadata": { 3007 | "id": "2oO0OhNoF4wo", 3008 | "colab_type": "code", 3009 | "outputId": "bd7bd3c0-28c1-4df2-b86d-92327a7bac6d", 3010 | "colab": { 3011 | "base_uri": "https://localhost:8080/", 3012 | "height": 84 3013 | } 3014 | }, 3015 | "source": [ 3016 | "text = \"This is the best movie I have ever seen!! The story is such a motivation\"\n", 3017 | "predict_sentiment(text)" 3018 | ], 3019 | "execution_count": 0, 3020 | "outputs": [ 3021 | { 3022 | "output_type": "stream", 3023 | "text": [ 3024 | "Positive score: 0.9998512268066406\n", 3025 | "Negative score: 0.00014876725617796183\n", 3026 | "Review text: This is the best movie I have ever seen!! The story is such a motivation\n", 3027 | "Sentiment : positive\n" 3028 | ], 3029 | "name": "stdout" 3030 | } 3031 | ] 3032 | } 3033 | ] 3034 | } --------------------------------------------------------------------------------