{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"colab":{"provenance":[],"toc_visible":true,"machine_shape":"hm"},"accelerator":"GPU","widgets":{"application/vnd.jupyter.widget-state+json":{"2efb606ae85043d2aec636657b8dc23c":{"model_module":"@jupyter-widgets/controls","model_name":"HBoxModel","state":{"_view_name":"HBoxView","_dom_classes":[],"_model_name":"HBoxModel","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.5.0","box_style":"","layout":"IPY_MODEL_1b6366fa2570491f852ca70c8dd78a3b","_model_module":"@jupyter-widgets/controls","children":["IPY_MODEL_39b0a4ffae63427ba7e1b688e5a6d011","IPY_MODEL_12fcdc8b8f9c4c14836f67a8012d43f7"]},"model_module_version":"1.5.0"},"1b6366fa2570491f852ca70c8dd78a3b":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null},"model_module_version":"1.2.0"},"39b0a4ffae63427ba7e1b688e5a6d011":{"model_module":"@jupyter-widgets/controls","model_name":"FloatProgressModel","state":{"_view_name":"ProgressView","style":"IPY_MODEL_1fd362b69c9d44f58239aeb5080705c6","_dom_classes":[],"description":"Downloading: 100%","_model_name":"FloatProgressModel","bar_style":"success","max":425,"_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":425,"_view_count":null,"_view_module_version":"1.5.0","orientation":"horizontal","min":0,"description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_4a0ebf07f34641d5b059e0def5d92d41"},"model_module_version":"1.5.0"},"12fcdc8b8f9c4c14836f67a8012d43f7":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","state":{"_view_name":"HTMLView","style":"IPY_MODEL_d7ae2eb9cdf24069ad682092497e0bfe","_dom_classes":[],"description":"","_model_name":"HTMLModel","placeholder":"​","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":" 425/425 [00:23&lt;00:00, 18.1B/s]","_view_count":null,"_view_module_version":"1.5.0","description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_c6a703307fa84008a1a651a0bde9aff9"},"model_module_version":"1.5.0"},"1fd362b69c9d44f58239aeb5080705c6":{"model_module":"@jupyter-widgets/controls","model_name":"ProgressStyleModel","state":{"_view_name":"StyleView","_model_name":"ProgressStyleModel","description_width":"initial","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","bar_color":null,"_model_module":"@jupyter-widgets/controls"},"model_module_version":"1.5.0"},"4a0ebf07f34641d5b059e0def5d92d41":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null},"model_module_version":"1.2.0"},"d7ae2eb9cdf24069ad682092497e0bfe":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","state":{"_view_name":"StyleView","_model_name":"DescriptionStyleModel","description_width":"","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","_model_module":"@jupyter-widgets/controls"},"model_module_version":"1.5.0"},"c6a703307fa84008a1a651a0bde9aff9":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null},"model_module_version":"1.2.0"},"36a2eee270944e1ea01101031a0e430c":{"model_module":"@jupyter-widgets/controls","model_name":"HBoxModel","state":{"_view_name":"HBoxView","_dom_classes":[],"_model_name":"HBoxModel","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.5.0","box_style":"","layout":"IPY_MODEL_1ab261bd567b47f593bef7559d7140e5","_model_module":"@jupyter-widgets/controls","children":["IPY_MODEL_f60180a0cd674bb2b8842f6f174613b1","IPY_MODEL_6f521b76233846d8a09ee7ab98f7ea03"]},"model_module_version":"1.5.0"},"1ab261bd567b47f593bef7559d7140e5":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null},"model_module_version":"1.2.0"},"f60180a0cd674bb2b8842f6f174613b1":{"model_module":"@jupyter-widgets/controls","model_name":"FloatProgressModel","state":{"_view_name":"ProgressView","style":"IPY_MODEL_cf4f03a541d94ab29d4825910471cf27","_dom_classes":[],"description":"Downloading: 100%","_model_name":"FloatProgressModel","bar_style":"success","max":345636463,"_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":345636463,"_view_count":null,"_view_module_version":"1.5.0","orientation":"horizontal","min":0,"description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_6715a58a5d564ebf8bf64b705cf6f76c"},"model_module_version":"1.5.0"},"6f521b76233846d8a09ee7ab98f7ea03":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","state":{"_view_name":"HTMLView","style":"IPY_MODEL_495a2c6efc654ff29bbcbe1a7ba1e41e","_dom_classes":[],"description":"","_model_name":"HTMLModel","placeholder":"​","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":" 346M/346M [00:23&lt;00:00, 15.0MB/s]","_view_count":null,"_view_module_version":"1.5.0","description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_0b5c8cf671ca4cb09703ee9dde8766c9"},"model_module_version":"1.5.0"},"cf4f03a541d94ab29d4825910471cf27":{"model_module":"@jupyter-widgets/controls","model_name":"ProgressStyleModel","state":{"_view_name":"StyleView","_model_name":"ProgressStyleModel","description_width":"initial","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","bar_color":null,"_model_module":"@jupyter-widgets/controls"},"model_module_version":"1.5.0"},"6715a58a5d564ebf8bf64b705cf6f76c":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null},"model_module_version":"1.2.0"},"495a2c6efc654ff29bbcbe1a7ba1e41e":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","state":{"_view_name":"StyleView","_model_name":"DescriptionStyleModel","description_width":"","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","_model_module":"@jupyter-widgets/controls"},"model_module_version":"1.5.0"},"0b5c8cf671ca4cb09703ee9dde8766c9":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null},"model_module_version":"1.2.0"},"d54bd61599c740ce9afbd6dd0cdf3918":{"model_module":"@jupyter-widgets/controls","model_name":"HBoxModel","state":{"_view_name":"HBoxView","_dom_classes":[],"_model_name":"HBoxModel","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.5.0","box_style":"","layout":"IPY_MODEL_6373a61866e8427899a8c56ac463fc88","_model_module":"@jupyter-widgets/controls","children":["IPY_MODEL_892ab87763ca4569b1c14c7a864f0327","IPY_MODEL_f9ccf45eaeae49cd9ab55c8524fd06f7"]},"model_module_version":"1.5.0"},"6373a61866e8427899a8c56ac463fc88":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null},"model_module_version":"1.2.0"},"892ab87763ca4569b1c14c7a864f0327":{"model_module":"@jupyter-widgets/controls","model_name":"FloatProgressModel","state":{"_view_name":"ProgressView","style":"IPY_MODEL_598d0a9ff37e4051a77fe32e33c89d69","_dom_classes":[],"description":"Downloading: 100%","_model_name":"FloatProgressModel","bar_style":"success","max":160,"_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":160,"_view_count":null,"_view_module_version":"1.5.0","orientation":"horizontal","min":0,"description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_1de61920e64e41c8ba8da72e7ef9e27d"},"model_module_version":"1.5.0"},"f9ccf45eaeae49cd9ab55c8524fd06f7":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","state":{"_view_name":"HTMLView","style":"IPY_MODEL_f69783a89ebf4887aa55388c5f936d3b","_dom_classes":[],"description":"","_model_name":"HTMLModel","placeholder":"​","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":" 160/160 [00:07&lt;00:00, 20.7B/s]","_view_count":null,"_view_module_version":"1.5.0","description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_a6023bb8327044c4a6b478656261ef7d"},"model_module_version":"1.5.0"},"598d0a9ff37e4051a77fe32e33c89d69":{"model_module":"@jupyter-widgets/controls","model_name":"ProgressStyleModel","state":{"_view_name":"StyleView","_model_name":"ProgressStyleModel","description_width":"initial","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","bar_color":null,"_model_module":"@jupyter-widgets/controls"},"model_module_version":"1.5.0"},"1de61920e64e41c8ba8da72e7ef9e27d":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null},"model_module_version":"1.2.0"},"f69783a89ebf4887aa55388c5f936d3b":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","state":{"_view_name":"StyleView","_model_name":"DescriptionStyleModel","description_width":"","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","_model_module":"@jupyter-widgets/controls"},"model_module_version":"1.5.0"},"a6023bb8327044c4a6b478656261ef7d":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null},"model_module_version":"1.2.0"}}},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":5441,"databundleVersionId":38425,"sourceType":"competition"}],"dockerImageVersionId":30886,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Training the Vision Transformer on a Custom Dataset\n\nIn this notebook, we are going to fine-tune a pre-trained Vision Transformer (which can be found from [Huggingface](https://github.com/huggingface/transformers)) on a Custom Dataset. For this notebook we will be using the Rock, Paper, Scissors dataset which can be found [here](https://public.roboflow.com/classification/rock-paper-scissors/1). This dataset is a collection of 2925 images images in 3 different classes. This tutorial is based on Huggingface's [Fine tuning the Vision Transformer on CIFAR 10 notebook](https://colab.research.google.com/github/NielsRogge/Transformers-Tutorials/blob/master/VisionTransformer/Fine_tuning_the_Vision_Transformer_on_CIFAR_10_with_the_%F0%9F%A4%97_Trainer.ipynb).\n\n### Accompanying Blog Post\n\nWe recommend that you follow along in this notebook while reading the blog post on [How to Train the HuggingFace Vision Transformer On a Custom Dataset](blog.roboflow.com/how-to-train-the-huggingface-vision-transformer-on-a-custom-dataset/) concurrently.\n\n\nWe will prepare the data using [Roboflow's Preprocessing Tools](https://docs.roboflow.com/image-transformations/image-preprocessing), and train the model using this notebook. \n\n### Steps Covered in this Tutorial\n\nIn this tutorial, we will walk through the steps required to train a Vision Transformer on your custom classification data.\n\nTo train our image classifier we take the following steps:\n\n* Install Vision Transformer dependencies\n* Download custom Image Classification data using Roboflow\n* Use the Vision Transformer Feature Extractor\n* Run the Vision Transformer training procedure\n* Evaluate the Vision Transformer on a test image\n* Export the Vision Transformer model for future inference\n\n\n### **About**\n\n[Roboflow](https://roboflow.com) enables teams to deploy custom computer vision models quickly and accurately. Convert data from to annotation format, assess dataset health, preprocess, augment, and more. It's free for your first 1000 source images.\n\n**Looking for a vision model available via API without hassle? Try Roboflow Train.**\n\n![Roboflow Wordmark](https://i.imgur.com/dcLNMhV.png)\n\n","metadata":{"id":"szWwJmqPHZ-r"}},{"cell_type":"markdown","source":"Let's start by installing the relevant libraries.","metadata":{"id":"3_7rNZfIf301"}},{"cell_type":"code","source":"!pip install -q git+https://github.com/huggingface/transformers","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"6MCTZFkFw6i6","outputId":"a174e771-daae-47fc-c96b-be627e41b9b6","trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:04:27.833926Z","iopub.execute_input":"2025-02-10T11:04:27.834335Z","iopub.status.idle":"2025-02-10T11:05:10.027418Z","shell.execute_reply.started":"2025-02-10T11:04:27.834297Z","shell.execute_reply":"2025-02-10T11:05:10.025687Z"}},"outputs":[{"name":"stdout","text":"  Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n  Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n  Preparing metadata (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n  Building wheel for transformers (pyproject.toml) ... \u001b[?25l\u001b[?25hdone\n","output_type":"stream"}],"execution_count":1},{"cell_type":"markdown","source":"Next, convert the folder structure dataset into a PyTorch dataset format using PyTorch's ImageFolder dataset structure:","metadata":{"id":"1DSSAj4Os-Od"}},{"cell_type":"code","source":"# # importing required modules \n# from zipfile import ZipFile \n\n# # specifying the zip file name \n# file_name = \"/kaggle/input/dogs-vs-cats-redux-kernels-edition/test.zip\"\n\n# # opening the zip file in READ mode \n# with ZipFile(file_name, 'r') as zip: \n# \t# printing all the contents of the zip file \n# \tzip.printdir() \n\n# \t# extracting all the files \n# \tprint('Extracting all the files now...') \n# \tzip.extractall() \n# \tprint('Done!') \n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import os\n# import glob\n# import random\n# import shutil\n\n# # Define the source training directory from your extracted data.\n# original_train_dir = '/kaggle/working/train'\n\n# # Define the destination directories for training and validation sets.\n# # These directories will follow the ImageFolder structure.\n# new_train_dir = '/kaggle/working/train1'\n# new_valid_dir = '/kaggle/working/valid'\n\n# # Create the necessary subdirectories for each class in both train and valid folders.\n# for base_dir in [new_train_dir, new_valid_dir]:\n#     for class_name in ['cat', 'dog']:\n#         os.makedirs(os.path.join(base_dir, class_name), exist_ok=True)\n\n# # Get all image file paths from the original training folder.\n# all_images = glob.glob(os.path.join(original_train_dir, '*.jpg'))\n\n# # Shuffle the list to randomize the split.\n# random.shuffle(all_images)\n\n# # Define the split ratio (e.g., 80% training, 20% validation).\n# split_ratio = 0.8\n# split_index = int(len(all_images) * split_ratio)\n\n# # Split the images into training and validation sets.\n# train_images = all_images[:split_index]\n# valid_images = all_images[split_index:]\n\n# # Function to copy images into the appropriate folder based on filename.\n# def copy_images(image_list, destination_root):\n#     for file_path in image_list:\n#         filename = os.path.basename(file_path)\n#         if filename.startswith('cat'):\n#             class_name = 'cat'\n#         elif filename.startswith('dog'):\n#             class_name = 'dog'\n#         else:\n#             # If the filename doesn't match the expected pattern, skip it.\n#             continue\n\n#         # Define the destination folder and copy the file.\n#         dest_folder = os.path.join(destination_root, class_name)\n#         shutil.copy(file_path, dest_folder)\n\n# # Copy images to training and validation folders.\n# copy_images(train_images, new_train_dir)\n# copy_images(valid_images, new_valid_dir)\n\n# print(\"Training data successfully split into training and validation folders.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:27:05.106923Z","iopub.execute_input":"2025-02-10T11:27:05.107342Z","iopub.status.idle":"2025-02-10T11:27:09.089441Z","shell.execute_reply.started":"2025-02-10T11:27:05.107311Z","shell.execute_reply":"2025-02-10T11:27:09.08807Z"}},"outputs":[{"name":"stdout","text":"Training data successfully split into training and validation folders.\n","output_type":"stream"}],"execution_count":11},{"cell_type":"code","source":"import torchvision\nfrom torchvision.transforms import ToTensor\n\ntrain_ds = torchvision.datasets.ImageFolder('/kaggle/working/train1', transform=ToTensor())\nvalid_ds = torchvision.datasets.ImageFolder('/kaggle/working/valid', transform=ToTensor())\ntest_ds = torchvision.datasets.ImageFolder('/kaggle/working/test', transform=ToTensor())","metadata":{"id":"kgn-a3NiSjqR","trusted":true,"execution":{"iopub.status.busy":"2025-02-10T11:28:07.90149Z","iopub.execute_input":"2025-02-10T11:28:07.902616Z","iopub.status.idle":"2025-02-10T11:28:15.785417Z","shell.execute_reply.started":"2025-02-10T11:28:07.902563Z","shell.execute_reply":"2025-02-10T11:28:15.783804Z"}},"outputs":[{"traceback":["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m","\u001b[0;31mFileNotFoundError\u001b[0m                         Traceback (most recent call last)","\u001b[0;32m<ipython-input-12-e364c5f950d5>\u001b[0m in \u001b[0;36m<cell line: 6>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0mtrain_ds\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtorchvision\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdatasets\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mImageFolder\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'/kaggle/working/train1'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtransform\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mToTensor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0mvalid_ds\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtorchvision\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdatasets\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mImageFolder\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'/kaggle/working/valid'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtransform\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mToTensor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mtest_ds\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtorchvision\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdatasets\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mImageFolder\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'/kaggle/working/test'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtransform\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mToTensor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m","\u001b[0;32m/usr/local/lib/python3.10/dist-packages/torchvision/datasets/folder.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, root, transform, target_transform, loader, is_valid_file, allow_empty)\u001b[0m\n\u001b[1;32m    326\u001b[0m         \u001b[0mallow_empty\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mbool\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    327\u001b[0m     ):\n\u001b[0;32m--> 328\u001b[0;31m         super().__init__(\n\u001b[0m\u001b[1;32m    329\u001b[0m             \u001b[0mroot\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    330\u001b[0m             \u001b[0mloader\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/local/lib/python3.10/dist-packages/torchvision/datasets/folder.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, root, loader, extensions, transform, target_transform, is_valid_file, allow_empty)\u001b[0m\n\u001b[1;32m    147\u001b[0m     ) -> None:\n\u001b[1;32m    148\u001b[0m         \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mroot\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtransform\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtransform\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtarget_transform\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtarget_transform\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 149\u001b[0;31m         \u001b[0mclasses\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mclass_to_idx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfind_classes\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mroot\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    150\u001b[0m         samples = self.make_dataset(\n\u001b[1;32m    151\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mroot\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/local/lib/python3.10/dist-packages/torchvision/datasets/folder.py\u001b[0m in \u001b[0;36mfind_classes\u001b[0;34m(self, directory)\u001b[0m\n\u001b[1;32m    232\u001b[0m             \u001b[0;34m(\u001b[0m\u001b[0mTuple\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mList\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mstr\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mDict\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mstr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mList\u001b[0m \u001b[0mof\u001b[0m \u001b[0mall\u001b[0m \u001b[0mclasses\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mdictionary\u001b[0m \u001b[0mmapping\u001b[0m \u001b[0meach\u001b[0m \u001b[0;32mclass\u001b[0m \u001b[0mto\u001b[0m \u001b[0man\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    233\u001b[0m         \"\"\"\n\u001b[0;32m--> 234\u001b[0;31m         \u001b[0;32mreturn\u001b[0m \u001b[0mfind_classes\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdirectory\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    235\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    236\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0m__getitem__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0mTuple\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mAny\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mAny\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/local/lib/python3.10/dist-packages/torchvision/datasets/folder.py\u001b[0m in \u001b[0;36mfind_classes\u001b[0;34m(directory)\u001b[0m\n\u001b[1;32m     41\u001b[0m     \u001b[0mclasses\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msorted\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mentry\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mentry\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mos\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mscandir\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdirectory\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mentry\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_dir\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     42\u001b[0m     \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mclasses\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 43\u001b[0;31m         \u001b[0;32mraise\u001b[0m \u001b[0mFileNotFoundError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"Couldn't find any class folder in {directory}.\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     44\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     45\u001b[0m     \u001b[0mclass_to_idx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mcls_name\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcls_name\u001b[0m \u001b[0;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mclasses\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;31mFileNotFoundError\u001b[0m: Couldn't find any class folder in /kaggle/working/test."],"ename":"FileNotFoundError","evalue":"Couldn't find any class folder in /kaggle/working/test.","output_type":"error"}],"execution_count":12},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Define the Model\n\nHere we define the model.\n\nThe model itself uses a linear layer on top of a pre-trained `ViTModel`. We place a linear layer on top of the last hidden state of the [CLS] token, which serves as a good representation of an entire image. We also add dropout for regularization.\n\n**Note:** The Vision Transformer pretrained model can be used as a regular PyTorch layer.","metadata":{"id":"wyHJjDYLfoFy"}},{"cell_type":"code","source":"from transformers import ViTModel\nfrom transformers.modeling_outputs import SequenceClassifierOutput\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nclass ViTForImageClassification(nn.Module):\n    def __init__(self, num_labels=3):\n        super(ViTForImageClassification, self).__init__()\n        self.vit = ViTModel.from_pretrained('google/vit-base-patch16-224-in21k')\n        self.dropout = nn.Dropout(0.1)\n        self.classifier = nn.Linear(self.vit.config.hidden_size, num_labels)\n        self.num_labels = num_labels\n\n    def forward(self, pixel_values, labels):\n        outputs = self.vit(pixel_values=pixel_values)\n        output = self.dropout(outputs.last_hidden_state[:,0])\n        logits = self.classifier(output)\n\n        loss = None\n        if labels is not None:\n          loss_fct = nn.CrossEntropyLoss()\n          loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))\n        if loss is not None:\n          return logits, loss.item()\n        else:\n          return logits, None","metadata":{"id":"cGDrb1Q4ToLN"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Define the Model Parameters\n\nTo train this model, we will train in 3 epochs, with a batch size of 10 and a learning rate of 2e-5:","metadata":{"id":"BePiLK-LtXuG"}},{"cell_type":"code","source":"EPOCHS = 3\nBATCH_SIZE = 10\nLEARNING_RATE = 2e-5","metadata":{"id":"ntGvS0_wUAxc"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"We will use the pretrained Vision Transformer feature extractor, an Adam Optimizer, and a Cross Entropy Loss function.","metadata":{"id":"At9H-QOStt8_"}},{"cell_type":"code","source":"from transformers import ViTFeatureExtractor\nimport torch.nn as nn\nimport torch\n# Define Model\nmodel = ViTForImageClassification(len(train_ds.classes))    \n# Feature Extractor\nfeature_extractor = ViTFeatureExtractor.from_pretrained('google/vit-base-patch16-224-in21k')\n# Adam Optimizer\noptimizer = torch.optim.Adam(model.parameters(), lr=LEARNING_RATE)\n# Cross Entropy Loss\nloss_func = nn.CrossEntropyLoss()\n# Use GPU if available  \ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu') \nif torch.cuda.is_available():\n    model.cuda() ","metadata":{"colab":{"base_uri":"https://localhost:8080/","height":168,"referenced_widgets":["2efb606ae85043d2aec636657b8dc23c","1b6366fa2570491f852ca70c8dd78a3b","39b0a4ffae63427ba7e1b688e5a6d011","12fcdc8b8f9c4c14836f67a8012d43f7","1fd362b69c9d44f58239aeb5080705c6","4a0ebf07f34641d5b059e0def5d92d41","d7ae2eb9cdf24069ad682092497e0bfe","c6a703307fa84008a1a651a0bde9aff9","36a2eee270944e1ea01101031a0e430c","1ab261bd567b47f593bef7559d7140e5","f60180a0cd674bb2b8842f6f174613b1","6f521b76233846d8a09ee7ab98f7ea03","cf4f03a541d94ab29d4825910471cf27","6715a58a5d564ebf8bf64b705cf6f76c","495a2c6efc654ff29bbcbe1a7ba1e41e","0b5c8cf671ca4cb09703ee9dde8766c9","d54bd61599c740ce9afbd6dd0cdf3918","6373a61866e8427899a8c56ac463fc88","892ab87763ca4569b1c14c7a864f0327","f9ccf45eaeae49cd9ab55c8524fd06f7","598d0a9ff37e4051a77fe32e33c89d69","1de61920e64e41c8ba8da72e7ef9e27d","f69783a89ebf4887aa55388c5f936d3b","a6023bb8327044c4a6b478656261ef7d"]},"id":"RIyJr8EDtvlR","outputId":"1e4b58b2-ade2-4d6f-858b-8578ae8ea736"},"outputs":[{"output_type":"display_data","data":{"application/vnd.jupyter.widget-view+json":{"model_id":"2efb606ae85043d2aec636657b8dc23c","version_minor":0,"version_major":2},"text/plain":["HBox(children=(FloatProgress(value=0.0, description='Downloading', max=425.0, style=ProgressStyle(description_…"]},"metadata":{"tags":[]}},{"output_type":"stream","text":["\n"],"name":"stdout"},{"output_type":"display_data","data":{"application/vnd.jupyter.widget-view+json":{"model_id":"36a2eee270944e1ea01101031a0e430c","version_minor":0,"version_major":2},"text/plain":["HBox(children=(FloatProgress(value=0.0, description='Downloading', max=345636463.0, style=ProgressStyle(descri…"]},"metadata":{"tags":[]}},{"output_type":"stream","text":["\n"],"name":"stdout"},{"output_type":"display_data","data":{"application/vnd.jupyter.widget-view+json":{"model_id":"d54bd61599c740ce9afbd6dd0cdf3918","version_minor":0,"version_major":2},"text/plain":["HBox(children=(FloatProgress(value=0.0, description='Downloading', max=160.0, style=ProgressStyle(description_…"]},"metadata":{"tags":[]}},{"output_type":"stream","text":["\n"],"name":"stdout"}],"execution_count":null},{"cell_type":"markdown","source":"## Train the Model","metadata":{"id":"XTZ-BP1yu1Us"}},{"cell_type":"code","source":"import torch.utils.data as data\nfrom torch.autograd import Variable\nimport numpy as np\n\nprint(\"Number of train samples: \", len(train_ds))\nprint(\"Number of test samples: \", len(test_ds))\nprint(\"Detected Classes are: \", train_ds.class_to_idx) \n\ntrain_loader = data.DataLoader(train_ds, batch_size=BATCH_SIZE, shuffle=True,  num_workers=4)\ntest_loader  = data.DataLoader(test_ds, batch_size=BATCH_SIZE, shuffle=True, num_workers=4) \n\n# Train the model\nfor epoch in range(EPOCHS):        \n  for step, (x, y) in enumerate(train_loader):\n    # Change input array into list with each batch being one element\n    x = np.split(np.squeeze(np.array(x)), BATCH_SIZE)\n    # Remove unecessary dimension\n    for index, array in enumerate(x):\n      x[index] = np.squeeze(array)\n    # Apply feature extractor, stack back into 1 tensor and then convert to tensor\n    x = torch.tensor(np.stack(feature_extractor(x)['pixel_values'], axis=0))\n    # Send to GPU if available\n    x, y  = x.to(device), y.to(device)\n    b_x = Variable(x)   # batch x (image)\n    b_y = Variable(y)   # batch y (target)\n    # Feed through model\n    output, loss = model(b_x, None)\n    # Calculate loss\n    if loss is None: \n      loss = loss_func(output, b_y)   \n      optimizer.zero_grad()           \n      loss.backward()                 \n      optimizer.step()\n\n    if step % 50 == 0:\n      # Get the next batch for testing purposes\n      test = next(iter(test_loader))\n      test_x = test[0]\n      # Reshape and get feature matrices as needed\n      test_x = np.split(np.squeeze(np.array(test_x)), BATCH_SIZE)\n      for index, array in enumerate(test_x):\n        test_x[index] = np.squeeze(array)\n      test_x = torch.tensor(np.stack(feature_extractor(test_x)['pixel_values'], axis=0))\n      # Send to appropirate computing device\n      test_x = test_x.to(device)\n      test_y = test[1].to(device)\n      # Get output (+ respective class) and compare to target\n      test_output, loss = model(test_x, test_y)\n      test_output = test_output.argmax(1)\n      # Calculate Accuracy\n      accuracy = (test_output == test_y).sum().item() / BATCH_SIZE\n      print('Epoch: ', epoch, '| train loss: %.4f' % loss, '| test accuracy: %.2f' % accuracy)","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"5ql2T5PDUI1D","outputId":"ea0f05df-577b-4e15-f18a-5775824e838d"},"outputs":[{"output_type":"stream","text":["Number of train samples:  630\n","Number of test samples:  90\n","Detected Classes are:  {'paper': 0, 'rock': 1, 'scissors': 2}\n","Epoch:  0 | train loss: 1.1379 | test accuracy: 0.20\n","Epoch:  0 | train loss: 0.1694 | test accuracy: 1.00\n","Epoch:  1 | train loss: 0.1064 | test accuracy: 1.00\n","Epoch:  1 | train loss: 0.0560 | test accuracy: 1.00\n","Epoch:  2 | train loss: 0.0597 | test accuracy: 1.00\n","Epoch:  2 | train loss: 0.0905 | test accuracy: 1.00\n"],"name":"stdout"}],"execution_count":null},{"cell_type":"markdown","source":"## Evaluate on a Test Image\n\nFinally, let's evaluate the model on a test image:","metadata":{"id":"LWXvWiB-srBC"}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport numpy as np\n\nEVAL_BATCH = 1\neval_loader  = data.DataLoader(valid_ds, batch_size=EVAL_BATCH, shuffle=True, num_workers=4) \n# Disable grad\nwith torch.no_grad():\n    \n  inputs, target = next(iter(eval_loader))\n  # Reshape and get feature matrices as needed\n  print(inputs.shape)\n  inputs = inputs[0].permute(1, 2, 0)\n  # Save original Input\n  originalInput = inputs\n  for index, array in enumerate(inputs):\n    inputs[index] = np.squeeze(array)\n  inputs = torch.tensor(np.stack(feature_extractor(inputs)['pixel_values'], axis=0))\n\n  # Send to appropriate computing device\n  inputs = inputs.to(device)\n  target = target.to(device)\n \n  # Generate prediction\n  prediction, loss = model(inputs, target)\n    \n  # Predicted class value using argmax\n  predicted_class = np.argmax(prediction.cpu())\n  value_predicted = list(valid_ds.class_to_idx.keys())[list(valid_ds.class_to_idx.values()).index(predicted_class)]\n  value_target = list(valid_ds.class_to_idx.keys())[list(valid_ds.class_to_idx.values()).index(target)]\n        \n  # Show result\n  plt.imshow(originalInput)\n  plt.xlim(224,0)\n  plt.ylim(224,0)\n  plt.title(f'Prediction: {value_predicted} - Actual target: {value_target}')\n  plt.show()","metadata":{"colab":{"base_uri":"https://localhost:8080/","height":299},"id":"ZLv_xdYssuGO","outputId":"734efe1c-371c-4714-be8a-a79f0eceaefd"},"outputs":[{"output_type":"stream","text":["torch.Size([1, 3, 224, 224])\n"],"name":"stdout"},{"output_type":"display_data","data":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAARcAAAEICAYAAAB1U7CaAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOy9eZAtWV7f9/mdczLvUlWv39LLdM9MzzCLAIHMCE2AsEBCLDbCIEC2ESjEZoUwYWODTDiECEmBBcgSYpMtA4YQRiGxCEtgCIQtFhFiZ9Zepqdnprtfv+63L7VX3S3znJ//OCfvzbp1q+rWfut1/V7kq5vrOXny5Dd/+09UlXM6p3M6p6Mmc9odOKdzOqeHk87B5ZzO6ZyOhc7B5ZzO6ZyOhc7B5ZzO6ZyOhc7B5ZzO6ZyOhc7B5ZzO6ZyOhWYOXETkp0Xke9PvzxORjx/wOj8uIn/vaHt3NDTLfTsrJCLfKCK/d9r9OE2a9Xl0IHARkWsi0hWRDRG5mwBh/qg7p6q/q6qfPEV/tk00Vf0WVf2eo+7TUdAs921aSs+8FJEnpzz+80XkxnH3K7X1dhFREXEn0d5ptT/r8+gwnMuXq+o88JnAe4G/O37AaT3ccxrRcTwDEZkD/ktgFfjrR33906bzebudDjQmqrrvBbgGfFFt/Z8Av5p+K/DfAy8Br6ZtXwY8A6wAfwD8J7Vz/zTwIWAd+NfAzwPfm/Z9PnCjduxbgV8E7gOLwD8DPhXoAR7YAFbSsT9dXSet/03gZWAJ+BXgqdo+Bb4l9XkF+D8AmXIsPgv4ALAG3AV+qLbvc9P9rgDXgW8c7xvwKPCr6Zgl4HcBk/b9beBmGpuPA1+YtjeAHwFupeVHgEZ9zNK5d4B/uVsbB3z+X5/u59uAj4ztuwz8X6lfy8D/A8wBXSCkZ7QBPDXhGY0/7+8EXkn3/1Hgq2r7vhH4vR3693p6plVbnwO8E/gPad48AH4GuDg2p/828BzQB1y6z9fSOX+P2rwnfpir/i0CvwBc3qn9N+I8OjS4EF/4F4Dvqb2ov5EmWYsIHveAzwYs8A3p/AaQp4f3t4AM+K+Aggngks59Fvhh4mRtAp+700QbG/gvSBPqM1O7/zvwO2Pg8qvAReBpInh9Sdr3dBrMp3cYiz8Evi79ngf+bPr9tvQwvzbd2xXgPRP69r8CP56OyYDPAwT4ZOJEeiod93bgnen3PwD+CHgceIw48b6nNmYl8I/TvbZ2auMQ4PJbwPcDT6S2/kxt378jfiQupbb+wiTgGB+HHcDlvyaCkAH+KrAJPDkFuLw9PVNX2/Yu4IvTmDwG/A7wI2Nz+hnifG4Bf5IIDJ9LnKc/QJyb1bz/tvQM3pKu+X8CP7dL+2+4eXQYcNlIg/Ua8KNAq/aifkHt2B+rOlzb9nHgLwB/noiYUtv3B0wGl88hvvRuQn+2TbSxgf/nwPfX9s2nifL2Wp8/t7b/F4DvnHIsfgf4X4BHx7b/HeCXdjin3rd/APwy8K6xY95FBOUvArKxfa8AX1pb/8+Ba7UxGwDN2v6JbRzw2T9N5ECqCf7vgX+afj+Z9l2acN7wWU4LLhOu8QzwFTs989pxb2fs5Z5wzFcCHx6b0/9Nbf3vk8AirbfTuFbg8iKJA6jde0HkePZs/40wjw6jc/lKVb2oqm9T1f9OVbu1fddrv98GfIeIrFQL8evwVFpuaup5otd2aO+twGuqWh6gr0/Vr6uqG0RW9s21Y+7UfneIADQN/Q3gTwAfE5H3i8iX1fr7yhTn/xOiuPbrInJVRL4z9fFl4NuB7wbuicjPi8hTk+4n/X6qtn5fVXt7tTFOIvJdSUm/ISI/vkN/vw54UVWfSes/A/w1EcnSPS+p6vIU970nicjXi8gztXnz6UTW/CDXeiKN4U0RWQP+1YRr1eftU/V1Ve0Q50xFbwN+qda3F4mi+RMH6R8P0Tyq6LhM0XWwuA58XwKiammr6s8Bt4E3i4jUjn96h2teB57eQbGkE7bV6RZxMgBDheQVohx6KFLVl1T1a4ms5T8G/k26/nWinL/X+euq+h2q+g7gLwP/k4h8Ydr3s6r6uanvmq6/7X6IY3arftlp2xg77h+q6nxavmWHLn898A4RuSMid4AfIr6kX5ru+bKIXJx0qxO2bRI5goreVP0QkbcBPwl8K3BFVS8CHyGy+nvRpLb+Ydr+p1T1AlERPX6t+nm3iSJP1Z8Wcc5UdB34S2PzuqmqN3dof/cOP0TzqKKT8HP5SeBbROSzJdKciPwXIrJAlDNL4H8UkUxE/gpRsTWJ3kd84P8oXaMpIn8u7bsLvEVE8h3O/Tngm0TkPSLSIE60P1bVa4e9ORH56yLymKoGopgIUTT4GeCLROSrRcSJyBURec+E879MRN6VAHaV+PULIvLJIvIFqb89RgrR6n7+rog8JiKPEln4f7VLHye2cYB7rRSjnwW8Jy2fDvws8PWqehv4f4EfFZFL6Zn++XT6XeCKiDxSu+QzwJeKyGUReRPxC1vRHHFy309tf1Nqaxq6n+7vHbVtC0RRflVE3gz8z3tc498AXy4i/2maV9/NVjD6ceD7EgiSnsVX7NL+rvQwzqNjBxdV/QDRUvPPiNaDl4nyMqo6AP5KWl8iKu1+cYfreODLiTLk60RN9l9Nu/8DUal8R0QeTDj3N4na/n9LBKh3Al8zTf9F5OkkJuzEUX0J8IKIbAD/FPgaVe2q6uvEr/l3pHt7BviMCee/G/hN4sT/Q+BHVfW3iUq0f0RURN8hftH+Tjrne4mWheeA54nWtu/d5TZ2amO/9A3AL6vq86p6p1rSfX+ZiFwmik0F8DGirP/tAKr6MeJkvppEiaeIFohnifqOXycqgknHfxT4wdTfu8CfAn5/mk4mEeb7gN9Pbf1Zoj7jM4kvxb9jh3lWu8YLwP9AtF7eJo7dPaIliXTPv0IUEdaJitHP3qn9N+I8kq3qjnM6p3OaRBKdRFeAd6vqq6fdn7NAM+f+f07nNCskIl8uIu2k+/gB4tf92un26uzQsYGLiHyJiHxcRF7eS6t8Tuc0o/QVjBzM3k0UVc5Z/SnpWMQiEbHAJ4hOSzeA9wNfm+Toczqnc3oD0HFxLp8FvKyqV5PS9ueJX4FzOqdzeoPQcQVovZmtDkk3SJr0ikTkm4FvBpibm/szn/Ipn3JMXXmj0HYOtNoi1W8FkkuRqiIEBElHyJbzVDVtilcZuiJpvKJM421ynHQYhvu0+35K9MEPfvCBqj52Uu2dWvSnqv4E8BMA733ve/V973vfaXWl6s/oBZoR2qtP6T1PvxQqPKjWBTSAKhhjEDF4VXyI7tmZ9CFACAYxDVCDDwoiiA0Uvo914GwEH1UDahEsIooc6g2f7r4njoECoQaG9d0ydly1eYSuYPRMAUx9DA4zR40xO3m/HwsdF7jcJLotV/QWjsAb9jhJRGYSYA5GIy5DCQQNBB8QiVKwAcQI/W6P9dV11td7hGBRtSCGhQvzXLy8gLWKFUAD3ivWZBjjQBXvwdpj6v1uwEIdVCevjy5UO0C2HrTTU67a3LHtY5gje11zp/7s1dfTpuMCl/cD7xaRTyKCytcAf+2Y2joymvYBndTDnL6NukijaS3+b8Qghsi+SLzm+voay4uLfOyjz3L/3gPW1rqoZhhxWJdx5dHLPPHko3zSO9/KwkKL9lwTZ7IkXwVU7bF++Kvx3e3+wwg/9ybZ8mdXReNeHMJxPPdprjnpmKPgZo6TjgVcVLUUkW8lRsxa4KeSx+NDQSf5MPcUEUa9GipX4oe6CnsPgCImvqwbayt87IUXeP6557h/9xZF4XG2Sbt1gSxrUPrA+soy0KPfXeHNb3mCt33S22i1MxQY9HpY28S6Y2JbmGJ8ZavP+bTBRnUd1Gy+joenWeJijk3noqq/BvzacV3/YaOdJkV921STRmQIMKqKL0uMKFaF5aVlPvr8c3z4wx/k+vXXaTQbtNsLXLzwCAsLF8ldAxDEKMZ77t26gS865M7wlqffRt6YQ1TRoCMl8RHe67T7YcS5GK1JPTDUO9VFpaqfGocGu4+OV64as/LC7kWz1M/zdH570FG8CNPQoa6xg9LBGEGMRQyEos9rV1/ij37vd7h16zqPP/YYrtlmbm6BuXYbi6KhJHcZWe4QKTF5xtL9O7wU+mSZ461Pv4MsbxJKRUv2NXv2UkruT2mpUUNboUoCi+qsiTpdqQ3Tjkqa7XRcL+v0HOnZpTMDLqf1APZq8zREpOFYqCYuZWf9QAgeI8K9O3f40Pvfx+riA+YbGQ6PtQLqKYs+JoDNBCsOE0qgxFml4Qw3rr3KxQsXubhwmYVHn4xihd0f51Ifp50cN6d16FQixxKCxxgLKBoCzlrK4CmLAjGGEAIuyxEreA0YMYyDylHMq4NcYxqOtD4e+7n+rIDVmQGX0xqsWXlQMEmBt/1bPdIrRM1CCBDKPrevv87Na9fY3FhhvtnA+BJfFBTG4cyAoDaaf7wHUYLvE6QAP8AXA5YX77OytMTCo29CQwDNDqy4qADy4BTN4MEPGJSQWRutywEcGvVBCXTEgA8eXxaIERDBSBbRkaOZVyc1P6ZtZ1bm65kBl0l0Ei/+Qa9/cqBUBxap6R/iy5s5R29jk7u3b7G2toyWfSiFDM/AByQoEhTrFItiJWBVEQloKNBQ0m5kLC8+4P69O7z13Z+KFTk2jehU46YQygG5s1gxiMKg0+X+/Qf0e30ECCHQbLeZv7BAa2GeVh5T/ZShBFWUg3EFR3UfJzU/TvPjeKbBZVYQehKdZt+q18aXUSQSge7mBlYgdw5LiZZ9vPVo8BgCQsCIkkkEGa8a/Vk00Mgs95cecPf2LSQEwByT+9zu41ZxO9G7uMSR0dtc48a113j5Ey/x8RdeZG15hUae47KM1vwclx69zNvf+Q4+6V3v4uKVyxhnQewWRe1xKG1nRZw+zXl4ZsHlNJyZZttpabw/gvceSaaRfq+HCRFEfOHpdzt4O4f3DUIIiEY9hlEAD1piCBgNiAY66+vcv3eXYmMdk7Ux3oE7uYwdW/UPkKGsLj3g2Q9+iA994APcfv0Gq0tL4JVWq4V1DjFCEHj16svcvnWDT/m0T+Pt73oneaM548/y6Oicc0m0n4E4DWemgzgtHdXDPch1rLMYAlYMqgFVjy8HOAviy2GGdmsMuTXkmSVzFiOB0lvEOIIWdPsF1gj9Xof1tVUuPbow1Gkc9X1WVLek1NuIFCiLHi9/7AU+8Md/wNVPvIRV4crCAs08x1mLy3IarSadQY8w6HPj2qtkznDl0gUuPzEHJt+mMB2/h4fBonPOuSQ6iw+vTpPY66O6p4Ncx1qLBCVzhlYjJ3eWQc9jncH7Ad57QojBR6qauBZFFESjPkZ9SWdzE2eEsihZWVnh8uNPbxOLDuoqf5CXNoTA0r07fOyjH+HWjdcRDVixaCgIBVjX4tFLj/DIpYuoM6g1dMsBK8uLvHr1JRrzj9Gez3bs96R7mpW5eZZAbqbAZTfa7asyK3RS/dly73W30+EBpKBFJRQFRoS80STPMnohUA4CYdCn7zoYk5PbjAxLJoJRj6GkKLsgBZudTVaWl1Gb43s9lpeWKAd9rHFgdheLDuLWPs1zLYuS5595lueffY7lpWUev3yFtstZaLV5y1Nv5sqVKzSbTWzmkMwxd/EC3UGfB8vLEJTg/TauZNr+TqKTnIsHaee03pWZAZe9TJPjg3McX8STpoP2sTonCAxMjJWx6hMwhCHQGGPwTvBeaF16hK4vMQ7KYo2WM2QrdxisL7K4mLHeaNBo5DRyQ54pTgLiCxSPrq7RmH8UHwKL925gm6BSoLpTsYV9jMG4rkiixcuI0Ov1aDZzBp1N8lYLygI1htW7r3Prox+gXa5zMQ9kJtB6ZIHmI1fg0qP05y8ysIb5uTaN3NEjYLOcJx9/jBA8a6uLNObaNJttfOkjhycQwjjISL2jtT4eThw86HM/7Hw5aZoZcDlKOkpgOQxrP02066Fpgs9I5YQ6jKdRQ+ayCDbx1U2hSAG0BG8oiwFKSVkYBtaTm5JGbsmto9FokGWWwnu63U0G3Q5Zw8WosSOj7WNhEmdkrQUNUYTzBXfu3OHu3dv0+z0ajZy5+Tbz83M0GzmEEDmrLIscShCCKoonqCf4knIoDk7S7WxXjG+lsbHe59w4bb3iSdJDl6D7uBSLex0zifM6kckx1uw297r0oxITAlV/IXMZWZbhnMFaixWLtVHBKyJo6RERmnmONeDLAZ2NTTpr6xGYdurSvhzkdOJ9QASVcjDAZjHNg/qCfrfLq6+8zPLSEqqBVqtFq9Ekzxx5ZlEJlOUAQgmhRINHvSeUBWUxYDDoURaDaCGT0bOrlqN+ZvvluB8meijA5aBu0kdJpxKaUC0p1GbbN7aKoRFottu4rBETPiVwEQ0YdGgtajQcrUaDZrNBq9mMHEPwWAOiitFAOejQ3ViL7rA79WsfYyHbfkQKIb7opfdUeWgA1tdWuX49JjlsNnJajQaSrGAEjw0eCR6TXAojd+YJPnrplkWB9+GQHsLnNA2debFot6/NWdC7HCnVAvi0xsMohrm5BfIsj3vEoijeF9GBToTgBEKMvZF0duYsPhT4AjQMohLXl3Q7a6B+7+7sOv7bxZD66x6CYk19T0DUc+/OLZYW72NRGs6RWYOVCHyG6JNjjZI7S2YEixKSr46GkMBShiJXRRU3dxQ0Cz40szD3zyTnMi2nctqDeyKkW0WhUWhelYQyrrVaLVzeiFlzjUMVnIATgzHR/Kzq8d7jfcB7jzGGUHo0iRdWwJc9OmsrUAy2d2Vc97Pr+OvY36QjGtNP5BXChKgvef3aNXqb6/iyIISSzEaxrZU5cgOZCeQGGhYyo9gESqgHDSABlzmstRGyQgTXaqnEo4PSUaWkPCzNwtw/MLiIyFtF5LdF5KMi8oKIfFva/t0iclNEnknLlx5FRyc5PL1RactYMFkkigfGIwSh0WzhnCMmnI2puY0VxEiMz5F65rf4gpVlifceZwVnBEOg6HRYXV6i7HW2NbffCS1jwDL8XfVFBJNlqC8glPh+n9defYVQ9GnmLp6vJc4EnAVHIBOl6YTcCVniaEQLCAWiJSYoeZbhnENVo2I39f2g82oWxPJZpMOIRSXwHar6IYlF5T8oIr+R9v2wqv7A4bs3ojeyYmycto3FDsdFd5fIz1ibRbGm0tSooRyUWCeoRDFBfIxD8gLWQFlGL17nHB4QHyj6kXMp+z2yMf+QffmLVAmzq3PjiUOQMSIj8PEevKff7/Dg7i0InrlWE7ES95UDtOiBc+SmTdPFwEyjZUz76UvwJRpKROL9RAvU+LhyINHoJOfifl02pj3vOOjAnIuq3lbVD6Xf68CLxJIiB6I6azppmdD+QZt6aEgAGz/wURxKX3uqcUuwY51jMChotNoY6+j2BxQ+4IOvfbkNYFCVuCBgHc45Wu02/X6PzAjNhmNp8R697johRPNwpb/wPlqXTLI2GWN2XiZYiepPtAgaxbKigCxyGa++8hJLi/eRUODLAQbFiFIWA3y/i4QCqyUWj0vBmaHoI1oSij7rqys0Msdcuz1s0bn4fa3Goer7w0ancU9HonMRkbcDfxr447TpW0XkORH5KRG5dBRtTGjzOC579mhM5zKiyLGIGMRarMtwLsekDP4xyVI0KAeJ0pJHCGJQMQQxIBbFEEIFPkLwgX6/z9rKKsAWxeg0z6T+UaiiscduJ3riGBP1Hyk8wfc73LlxPcZKGcE5Q+4MzigGj/oBZb9Dv7POYHMN3+8gfoD4AWWvS7+ziZYFzTzD2jOpajxzdOhRFpF54N8C366qa8CPAe8E3gPcBn5wh/O+WUQ+ICIfuH///hZfg52WNzrVUw5UtFXnUmVzqSsUowhkbRazsjkHYhFjIJl4BUsgpSIQgxqDYqJ7v7GEoAmQYgBkv9fh/v27Q66l0l1U3Eq9v5OeYfy7Qza62o0Njwslm2urvHr1Jax6clNZiqJexWpIINKht7HK2tIDlu7dYW3pPmvLi6wsPWB1ZYli0KPVzHBHXBPlKOfmYa81S+/PoUzRIpIRgeVnVPUXAVT1bm3/TwK/OulcHSuKNkVbh+nqQ0G7WyF065tZwU3CG2MMxlpEKoHEoKIxulli5jY1BjWWYEDFxFSWqqgYXJ6BcRCEsii4f/8+vV6PRqMxFI9semkPOpHr9iPRKKo4a6EcsPjgHjeu38CiiOrQMmYAKyEmDi/7FD0lFH36XUfWaaHGMPCeMgTa83PMtVpHDi4n7bR5VujA4CJxFP458KKq/lBt+5OqejutfhXwkWmud1BF1cNOe/krbM0Ku9V3RDWW4DCqICYBSxJEJMbTiHVgYxCiiAXj4nYTYlYFCaixZLmlxGJ8VPyurKyyurrK/Pz8Fp+Oab+SO8Djlt+qCs4xWOtw/fp1NtfXaOcm+bMkE7laRA3WCFYUwSdoNfiih6ZKk84aGnlG1mohyQy9faxHHs170Sz4kYzTrHH3h+Fc/hzwdcDzIvJM2vZdwNeKyHuI8+Ma8N8eqocHpGkf/klPkv22N3Ucyk7bYkK5EVeQ1jGCMQ6xDjEWYzPEZrFagAVMAANGNIGNRXxUslocnW6HpaUlnnjiCbJslL6gEpHGndS2086i0fCIxHatrCzzyssvJX2LxUjSxaRFXHS4y6xgjGBtLAQXCIQhYEi6D9nRvLafaXCYOTOLwHQcdGBwUdXfY/JjmolaRdN6SI7vP+4Hf5KTKlqMGNVSHlrfDDYlezJiEGsQY8G6aN61BhGPx2PERHOuQFAICC5Zn5aXlymKgizLtpijp/uC6khFtHUrAEZG4LK4uMTVq6+SZVnyrq18ZKLnbgxhkLjYdM+qqbRKvP/KSzfGMpzui33QOXDWQOnMuP8fWI7fh+/FWXt4MHo/lXSPqqOI6KR6CRod01RMdFAzdrgehqbXaNY1mHQ9QwBilE7AqMQ1jflrrSq9jUW07CLaiCEECCGZsTUIo2L1OvS+rf6KkoqUVf8kHRX3iQRElDDoceP1a3TWVmiaAhMMmYlmcjUWNY4ghiBR3LNEb9xYa97hJUvioMU0L2Caj4DJGOmlRrY2rXxvto3wVhq6Gp7gfDmLc3OmwOU0B28WH940fYpRzhDd5QxVoVOF6PhmovkYa7FZhhoDzlHiEWsiAGnAhBIJNnrthviyYnM8gCiqAWsF40soO1iX4zfvQ7EOoY2YBqUXEIsRiwai6z2pVAlEfU8CApGY+S6kf5WSeXRjHiuB7uoSVz/xURomoIMuRmIKy2ByvHF46yisS6bygAkepwFjBEIMEQiZozAZdu5xTONRoIHgdvY+HD2BHbafrHv/tHNz1ubvzBj8T3tgTrt92G9szpTXJFqKnLUxvqgmwpBEmMra49PfkWiT9BSpL3UnOBFh0OvT73Yh+Kg8Vh0pRccZg9FdTdXrEAICLD1YZHl5maBh6PAWvWtrZu2qv6n9ihdKShYAjHXkjSbW5acuFu2XZmFuHoRmBlzO6XgmUQSGyMG0Wq2h8tXIZH+UUAeY6m/tWqbmy1IM+vQ6m0SRinh88uoTs5u6NqLOeGTRKHVEqkUdArdu3mRpaYkQNOl2okl9pD+SIVhEC1O93eilHBScy2jNzWHzswcuZ5VmDlxOwyFp1kx4R9Wf+jukQWk2Rz4eYraHV4y360PA+wQ2IWwBCxEh+IJetwvJ76SCi6l7P+RsEqoMDeUBZ6Ac9Ll58zqdzXUEcNZGzknqoQTRd2d4LyZ6wAQd6ZpAyPIGc3PzOJft2qXdxv405smszc390EzpXODkHZJOQ9eyV5tH2Z+hQUaEdjuKRaoav+kTmhkqwImxQipgiBYarUBE4rlaenqdzWgWRocvuIbJACPVPwXRpIZOYle8dgSYKsfM+voat27dQkNATGrXRO9iYyVmz7MxCNEaiQmiJKVYIERgEQFjabTatOcXYtjDBCvVNHSgAM1D0lkViWAGOZeTpmkf3lF+QfYTuXqYdoNGVxCIX/35+QXyPB85qNXaCGP6ljDBpBxf7sQxiBDKAZvr6zELXGVtMlvFk22915F1a6gYHf6KdZREQUPJg/t3eXD3TtS1SNTpxGJnBpfSJlRLBTTGOqxzWJvqQRuHzXKac/M05heixWyXMZ1WcboTt3caNAt9mEQzBS4nMUiT4nN268dxfqXG+zI+YQ/LVYUwAogsc8zPz5HnMRudD36irqW+1ClyOjJU7IoIvhjQ72zgiwFoZQ+qzOCToEW2/tyyqsNMckLADwYsLy6yurpEnhS5qiHl940AZ63FpEWsQ6zBWIOxGcZliLWIzTAuj/ls8lbyipmOJs2DcTpSLnOG5uZR0MyAS31gjyPoanvgHDtev/6wTsKhrnL4m7R9z2vUfm+9DxnWiQbwPiaznp+bi9yDbE+MFEIYFkpT1S2/wxh3IwhWlY3VVTob66gGvC+JcUypP1Iv+F5xKcnHpfIU1rRPYz2hEEqMKqEccO3Vl9EQKMsCAJu8iStwEbFDjbWk2ClrswQwDpc1CAo2y3nk0hXyZgsxGTG1xN7ewQedBwedr+NhFDsdc5A+nQbNDLi80enIJ4pU/8lwPc9zWu12/Nqb7Z6quwN79HUZbVPwUefS63RgnCeoxCO28i/jglCkqMSN3EtU6nY311l68IDgPaIB52wKjBw/V0BT7hox0bVXTApjcCCGvNGiPX8B5/IUO7U1R9CkF/kwz+Mozj0Ncf2o6aEFl1ke9J3oOPtsjcU5x8L8PJlzI8XIWNvjnNxIVGPLNgHwJf1el25nEyOxJEl1/vDVmPCOVEph0lK1ZwWciYLV0tIia6srDPpdrDXkzkYLlYYteXarKw5DHNQkT+SY+ArjaM7N02rPY2xGpTbecvaMcwC70Sz3/aEEl3GWdr8v7WmZI496otQvJybGBC0sLOCco/QlIWgSc8JEjmU8XmgLwAAGxQ/6dDbWkRAw1qCVvkYmjJNKzZelxoEkGSlyUyChZPnBfTbWVvBFEcMIRNJhI1OPSuRa4iVSIZHEsSngVcFa2vMLNOfmk0fy7L6MFR31/DutD+2ZA5dpBmr8Jd2vvHxSZuLjJkmSjya9hjGGhYULGB5IVXQAACAASURBVGMoimIIKpXid6+lrnMByJwBVXobG2gxQIRY1ZAQ3f3HAGaLfgiosttV++LQBkJZsrj4gF6nCwQIVbLwsMXKNHa3jLxtBJ+CpkUMzVabvNFENTrUncSrdpgXejdr4lmaf2cOXI57cE/74R2pyZsILNENJU7M+YV5suTrMgSLSmlbN0XXtlWK3krBW+2zCBICm+trDIbOdNFxRWuv8KQ7CskvxpgRuCAgpWfQ73Pvzm0GRZ/MOkATGCYOZuyKOv7IJJnXERBHo9nCZjlFgHAi0HI88+ig1zytOX3mwOUwdJLs4WEsBkfbjwoMAGNYWFig0WzgrNvGlezFsdSXypqEBjY3N+l0OoTgMUZimoZ0+9EszTZmI4TJXIj3Bf1+jzt37lAOCvI8R5JvijUxVUTQXUrJJoFtGAtlDZI3UGvxvnL2O6rR3Z2msUg9zHSmwOWwD+Okc6mcyuQZa3Kkp0giQrNFI2+Q5bUcLLWD69agSeJQfZtPpVH7vR79fj8liRpxI7HR7V2sPHKrF30USBlBpywHLC8vU5YlWZYNY5milcumc3eYupL0QSk0wBqLOBfTPdQVzcdI0z730+aSj5sO7f4vIteAdWKEf6mq7xWRy8C/Bt5OzEb31aq6vNt16k5bk8xxezkYHTbp0/j192sSnKZPh6FJ9yOqOAZoCkJUUqqE6hUKSiMm8UdQOt0ejQtXaDz2dhZfv8+8XyGzKQ+tKkYVGwqsV6zGkiROJTqupet5UfreYCyYZhsfoNfrsrm6yJv8myFYxGSUGAKp3pFEJa6VSs+rBHGUOMKgxGLInUN7HVzjAreuPsvavQc0xaJFiW1YslaLvh9gG4a82aKft8iMQQSsekR9zLtbCp0gqMnx1tFuX6LZvIiVPAKNTNbY7PdZ7EbTzJ2zpj85CB0V5/IXVfU9qvretP6dwG+p6ruB30rrJ0oHeXCzzKbuqmQeHVTTjNaOT/dljMG5jEazGTPPMe5cGNAwKucxdGzznhCqvyNdTFEUlGVBr9uhu7lJ8GU8p+Jy6n0Z9j/mcTHGDhNcCSYphxQksLT4IIpcW+6/Ont0Z5WieidSYvS3VF59RwAsR0UPO7DA8YlFXwH8i/T7XwBfedQNzLI8e5xtT3PtoU/slnACjfE3Wcbc/HyKjt6ucwkatilxy7KkKAqKohyWeA3B44sBwXu63S5rq6sMBv2oHPZ+gjdJRbFPJvmsSCoK74t+BIFej5u3btWsUmF4R8YYbJUqIpl9hpxm7eYrRTaAdXYoVj1Mr/MsfwgrOgpwUeDXReSDIvLNadsTOqoAcAd4YvwkGatbtF/aK/jvNL8MJxEysOsxw2Nh5FkbkyyJc1y4cCHVSt7qlRtCIPitoBKXgrIGLNUSWXsoyz5r6ysM+j1IznTG1Fx0GXd7iSshxPBpa01UthrD2soKd27fRjVmsBtVbxScTV66kkqDqKZMDSPtsRAVyhUTl2X5MMlUPffLWaezwPkcRcqFz1XVmyLyOPAbIvKx+k5VVZHtHlW6z7pF09JJDfpZkZkrpzMZZmZj6Ejn65xLJRolQBKN3IU1sZb0ELCCRJFFDBLKyCWUgZWlRZYXHzB/6VHI3dDJrmp9TCMGCCak2kmE+M4bZfH+PZZXFoEIOs5YXHLXtylsQURQH8AIahTV6ExntqIqCjGptxuJYLP/vT88zcIHFo6Ac1HVm+nvPeCXgM8C7orIkwDp773DtjOh3UPtPyztpaw7LtqPWBRCernNVh1Mu90eporcbmr2W7iToaK9ZtVRVTR41BeUxQDUs7z0gNu3btLpbICWaPDVaWxhYdJG1Wj9qUzSmXPgPTdv3WRzcz3GGQkYG116Y9LuCDLDPiXOpVoqkaiyRkXOJaZhGI3fwwEwu82D8dip06JDgYuIzInIQvUb+M+IRdB+BfiGdNg3AL98mHZ2aPtQ+4+TZkUsqtZEkrVHFbyn0WjsWHZ1C9DoyBs3mnZHkzakZDG+HGANrK+ucPf2LfqbHfAKodK7jL8E1VcVnCFyIApYQ9HrcvPmDXq9DkFLUL/dFF4GtCiRoENwMZXoVbv/6rezDmtNrIddpd58CNBlFsBjLzqsWPQE8EvpRh3ws6r6/4nI+4FfEJG/AbwGfPUh29mTpjUPHvV1D3Pt/fZjezt18/moNIdu2Z62SfoVojOamOjopoyH+KeXGRCxw3ajVUeoqgtUYo+EgDOGjX6fzfWo1B0qWDQW+xjyCtWbrdFiJKmqgIYoFvUHPZaWHlAM+mjww/Y1aIwZ8gFvPEENTmvNaCzxyjC73WicTMr/AnHzJLg7DTorYvVh6FDgoqpXgc+YsH0R+ML9XGunPBUn6Yx2GAA6tbAEjS/TEFjSOkp0ZlODqkckiiGUMYVklY82JCVtXq37uF+HOg4ZBTciiNGkVA0YLWg2copQkFnD8tISV1/+OFfe9BSuGXU6EUxgKAulnvqgFGXMMSN4KAtu3rzB3ds3CaGk3crjPYciJn2qiUPWGNTHgm0Gwcagpmh9EoNqSeEFlxsazQYGxZlYo0lLZsJs9EbQDc6kh24dTPZynjtJmtQvmDEWtSYbaNJTVJn+VRW1ZpgqMoSRTqVyl8+yjDzPaTQaQwWqTVaabYsoVgKZFZyJaS87mxsMel2iUjhll4utx22pi86mImQpgDp4z9rKCp3OBqEsU26YdI4Q60AnDioCSlTsWhnVyx6GQSYLUnVPYsxIHNri/jOF/qrmB7TXcSdJZ8ELeGbAZfwhjg/eaSbPmaR9H/ce3m05SFuHp7G2VVOYcASQmJc2+ZykF3Bk9h39Hr7QydJU35ZZiwEyIzQyiy8GrK+usLmxHl/uimuZkH6hKtkcUnpMXw64f/8O6+trhFCihChWqaJJ9xKTAkdQKosC70t8OTKLQ9W/BDYyuo84IltpKv3VlMrR45oP07Q3qzQz4FLRbgAzDR0mj8s01zxuOrq2oohU1XkmKUZBaTQatNttMpdF35cKPBJNyqFbV4RWlhhnGIocmbP4smRtdZW11WXU+3hCldNygqZDtNoXKw3cu3ePfq8Xk3yHgBKz+BPGYpyCUhYlfhD9b0Lp0dJDGFmPAIw1OOuGHrpVTaXjouPmXg56/dPi+mcGXHYCld3QfrdBO25Zsy6uHfdXaoreTLW3+ttoNLh48eIWfVb9CvXYmDoHU6+4GCsAxGz9xkDmLMYo/X701i3LQeJcEkexY5ej/OaLksXF+3hfkDdc5Gzq7SJbOKuGy8iMiz4wygh8qhAFFGss1tmkvK4luzqmaVGN52Hnw07HnVow7AFppuoW1QFhGnDYNd7mCIFlUl9miy2d3BdJit3KIlRRlmU8euUKn6hN1mElRdUUgxTTYlqJZUlEot2nUujaYbhOzH3rrKGRZaCBjY0NiqIga+38HoekD4rKWM+gKFhdXUNVsRKBygnDKOuh7idFOjcym1IwgEhUOHsfPZGj8cyNKgQYQ0nabpgNc9EudNTz+rTm6kyBC8ymie6w/Tmte4oeqVGsqCosorEs6qVLl8jznHLgtuhYhm5vE/RM4+uiIelOA0aELIsiSK/XoyiKnTsW3WCIpVmFsu8Z9Htsrm+g6qmy86tu98Gp0mj6EsQo3oCYlODbknLnxtsQE4uoMfTMnXFUechoZsBlP+zerIHPNLRfdnZr0OEOx6SUjtsFj9GWkfgGpLSSAeHCpSu0Fi6y0engMkcIHitAFRmtWTQZK6gmDmN0MwQVSnHRBR9BNJBbS9ASLbqEoo9oNDtXJVVVU01pwBMQK3j1oErR71P0+1gMGsBroNTItQRTEy2CJxTQLzzqLOIMYgURjUmqUkHFoABVRHT00VGNep6hB+8eXtbHNc+msTTO4kd2vzRT4DI+mIcVjU6CjoKr2el6k3RPdetFdB+xW88f7UnJm6ITWYwHinV/BqHk8pveytzjT/Py9VtcaeYUg3VyB0YCpS/JsiZBDMHEc8JQFAqIBDxKx7XJM4cVJfg+zloG/QH0Vgn9dUQ9ikONQdXgy4DNBA3KIPcYEwhFQSszdNfW0d6AtmniQlS8akr0ZPMGeebIrcMqmOAR6WEkx7oMm8zuZQATFDVCqQYVhzEZhJiRjhDL0soUz63Sb+xHTB9/fvuhLaEVu7R1kD6dFs2MQne3l2qcDmtR2g+dpgLtsHqenY631pJlGQvz8+RZttValMBLdeguUhMmaoXrEzcSQsAHP3S0iykYYi0jTSbi4JMytbIRE/U3kPKtAN1uN5mXfdL5OJzbqkAeKnetGZZwrZJ8x74qwUfOS4ZOgHbY9/0qcndyPThumlbnMsvAAjMELrv5uUzStu+0f1ot/bTbjpozOQ2qj0H10jWbTS5dukSWN5IVZRTQFz1wiT4mkMSphA01C45zqcBYCgyo6jx3Nztsrq8TQjRHV3WnjanEk+RMp+BMDKBcX1uLKR1KP/RPGS2x8dF6PUI66lYQUohD9NQ1RmKKTBfBZRpuZdZpFubSfmhmwKWik+JaJk204zD1neaEliEXslU5a60lz3MuXb6CsRlF6YdcR2UtqoBlq6l6a71oazMYmojjUSIw6PfY2Fin9AXWmmFyvGGZ1+QcJ4AVIZQFS0tL6DAYMWxhMlQVTHKOMwxBhgrYEmBaG83OkoI186GzYLyOkcq2tTPt5d5wklzzeBtnDRxnUucy/ruivfbvRPt5KGftAe5F48BSrTvnuPToFVzm6Pc9EgLeR3d6a0xUiGrSfaiCRGc7MTIEC1WiyCMMHfRQG8FlLSaPaswLRqMJW7SufA7END/C5vo6d+/cicBiBB9KrFrQrQGVGMEYm8zmkTuRtJgkqgUsPoFf1sgxKTk3lSS3B+3HDHwSc+Usz8eZ4lxOW9dykmznSbU1rgiur1+5fJlmoxEPFJPEFwCh9CFmktzSz/iGSioCH4IOrTIhBEIZ0ywEX7KxvkZvczNxIYEk2US8sgaTnN9C6Xlw/wE3rl8n+BJnaoAio1IgFXcSdTEZLsuw1g3rXldikqly1xiJx7ja93OmZvvDTzPDuVR0mibCWVHaHRVN0jfVt1145CKNZiuKNVi0Fo/kvUeyZEImySMy4loQQSVaoqyx+FjcFWsEG4Ret0t3Y53gi9Tu6M221uDFg0Ix6LO0+IC7t29RlgXtrJFSMAiIDnUqEUAMzsXsdFmauSbiyJBi9cgwBKNYwjVJRjI5w0x9bMatRLuN7VnmKk6CHgosn8bFehql77TK4JOgo2q7Hmg4vs25jMcffxP9QTE0C1mXMRgMyBvNoVUoaEyREBNIVdwKCAZrYy7ezDoyaxOnovS6m3Q212NellqEsxFFq0hpDZT9PtdeeYVup0PRH5BnLmWxi1HVoxAEjYGKwUfHwPpYpTQO0SBlEGsxSQdjjCWoUoYqCJIhuoyPcT3sYbfnsJPbxEGo7iC4W2G6WZ6rO9GBORcR+WRibaKK3gH8feAi8DeBKuv2d6nqr01zzfGHdlguZr9+M8f9NZp0/Ulfyp2OG7/WpO27nTO+zVrLlUevgELQlCvXWIrBgIYZJUuo2lMMoSr8HqOKMGJRLbDGgEbRSggU/R697ibBF4htDD15MSZmsdO4bGxscPPmTUIZqzeKkNItpPImtdAFrQVUBhSzPefeiMtxFuMsxhrKGqJsEfJ28SUZP6b+TPYa1+Oms8I1HRhcVPXjwHsARMQCN4k5dL8J+GFV/YH9XnMnhe1uILEftJ72gRzXw5t0zd2AZLd+HEX/XLMZRaNWCy06W/xZvPfR+S2ZmW1sNIURxPaTRoS6A4lJx4ayoLu5TtHv0sjbKIFYCD5yQxpiEbMH9+5y7+5dfDnAWYv6MKocMBql4T2rKEPZLIlpVSoITUZxI5Gjci4bKnwrba6ZIrZo1sHjLAALHJ1Y9IXAK6r62kEvsJuZbxLbdxwsYP3LdFIs5mlOInGORy5dpNlsxVSSqVYRMMyRkhiMCCTVejpfU26VaoOpFlE0FHQ21ul1OjFplIzGdXhf6rl54wZ3b90ieE/mHL4s465aPegKzDCMLESVuJc4FWSUGAqJmfZcKlk71LckX5jjpsPOnZ0+QmeNjgpcvgb4udr6t4rIcyLyUyJyadIJskPdotO2GNX6d2zXniW6ePEirVYTJRaWL0P0c/FDD90kTmiqQ5a2R8uSDMEnsRNRrBEgBLqdDbqdjWFUtrEVeIOzhqIouHHjOivLyxAUZx3el0ANsRKJqRS7lq1eu2YIMENTuYkWqcpSFEU6xVeS1jHTSXG9s06HBhcRyYG/DPzfadOPAe8kiky3gR+cdJ6q/oSqvldV3/vYY48dmGvZjyLrKMHoMAq8mSEfuHDhAu32XDJFJyuRdVQeu/Xx9yEBkA+UXgmMTNex9Eey3hChpt/t0ekkvQskX5QoTBmE7sYmt67fZDAYJIvVCL2Eaqyi5ccIQ9f/yKEkILHjOWaSBctFziX2LY75qIrjw0F7fXx3Ouak6Cg4l78EfEhV7wKo6l1V9Rr52p8k1jGaio6baxlXmh6GDvolmSmWV5ULFy4wNz+HcxkAZRJLKh1G1b8tJV7LktL7oVv/iB2oXOQiB9MfRHApi4KgfnQtjddZXl7m7t27qEZuKYpMSYNTyVsCWsufG61Hla9NAhkxW8SkocdulqV8msnHB5iUcnM0HNM/h1kAqWl0Q6fJ8RwFuHwtNZFIUjG0RF9FrGM0Ne3FiRzVQz2qQT+Kvp7mBGi327RaLbLkOFJZY4biEJLSLoxM0b6y2oTKDyZSpdpNulaC9xT9PmVZxuL2jECqLAesr62xuro6BAZlVL61uqBUaFMDl7hJGA5bZItiiEAtHMBYB7VMelBL4j2B3sie3MdBhy6KBnwx8Iu1zd8vIs+LyHPAXwT+1jTXquoQj1uCjmPZLx30WtNMwJEHSBgupEVVRyKDMSiGIhiCGMr022AgGMq+UA4UNIoGaCD4ASIeYxQjHsHHlAMKg16fnvV0beCtn/KpFJIRTIuseYHl1Q2sFULZJWgHdJOgXUrfx5cB9TnQwNsOpe3jnVJmhtJZgjOICTRMgN4avZU7lJ0lREsKFULWYF0yrAZuvPAMur6IH2yQNYRO2UWbGdrICDgMjixYbCGYAqymUq4qBHIUh8XgRIlnxBKv3ma4hcdozD1G0DZB2hAsTQyNUnZjXrY983H/k3Oang5bt2gTuDK27esO1aNE01hsjsJvZRpPzGOnehdqzYkIzWaTsvSUpUcxQ/HFmmhR6W96jLVkmSDWAhoLx5cDIDqeVe7xqoIv+jib0Ww2GZguwVoWFhYwziHWopqioqkUumEYyYyMIpzjsGgyL4+SQommGGlVgi/odTuUgwEaPD6UYLPIXfT7LN69SzEYgAa8LxERfAixr1JFW9crTdcHatzHheRMp4CNoQHGUnkYJ3VzdLQ7osd2GnSWOKaZc/+HnfUtB/WD2e/+3fp10g+3CgjMsliWVIGyjMpVa4RG00UUMIIQy6sSChp5BAtCiHlSSsVYR5ZlVAyrQUAcj1y8SKPRwBtDCCWNRoOyTAWFKmAZvro1zi1AEKXy7K9EkqrfPni6mx0G/X4EFo1ilbNCbzM6zxWDASKGsiyxVe1o3VrWZNzDGNIckdHvQJTSVGPwo0u1mRiee7iP0FGfu9t5pzHPjoNmBlzqE2gSuIz7SIz/nnTs+O9qfa/zd+tjncYnweEmRfz21tdVlaIoaDQao74GjZHLNn6NfdFn9f59lpYesNnt0O11MFZ45OIFHrl0kYuXLtNst6Mt1wMiBK9sdjZpLEQ/kEceucjCwiNsPriP955GK6MsS4yTmsJ2BC5RVCijE62pmaMFYvKmkTdst9ul3+siwWNUCUExVllbWeHu3TsEjcCpqmRZvuW5jQPLlt9owr6RMjloTKlgrMXlzWj12vJ8JkPMYV7ko1TsH/aas0YzBS4wGSjqdFCu46jO361vB7tWPU4m9QsSI69kLoOg9Ad9+v0+zWaTvNEgeM/9W7d4+blnePXaVW7evMHq+iqd7iYepT3X5k1PPsk73/Un+JOf9um89e3vIG+28UUBKsy1WpQSlbLtVpvHHn2U21dfJob1xLSY4twWcAkaCBJQiSCxtSRRLSgwmY4z4yiLPt3OZgRFk7RJCvcfPGB9fR0hpn+oZ5urrEe7cS5WBJGqbvUImBUw1pE38uhcR7QqRalOt2kZHxYuYRZpZsClot24lt1+V+vVNSaB1UG5lsNMvn1PXhFIjmrR8czEol/qaeYZee7ori/z/PPP88wH3s/VZz7AysoKm51NSvWUvmRQDChD4KX2HB943/t4+m2fxOd9/hfwWZ/9OVy6fAXEINYQtITEMTz51Ft4NrXpva+N7XaxKISABMFSlYkleusKiZMYBRyWRcnG2lp071ePM4GNbp/rr79Or9cb1X9OIlGe5xEIduNaJCbkrtqIfUv+wRKd57K8kcSi4cCiohiRLV6658ByfDQz4FIHikqmrz/4abiNnQBop/0nARoHamNMQlI8zWYDBHqrK3zgj9/Hf/yd3+aVFz8K64uIERrO0nI5SINBmdMvSzr9PjevL/Haa69x4+ZN7t29z+d93l/gLU+/DVMGaFbBh44nn3wyRjmbjLIsyHJXS8FQV5cqSlQuj0zBJuo7AB8qB7g4Rr4sWV9dod/vkbUKjDP0N1Z57dVXKYoiWsOsIM0mZVngXDs63Ykkh7jtEd3AqCibxLImlYeNIjD0cUmJoqrBTPmsTkOju5fu7yiueRxtHIZmBlz2oknAMIkD2W37UdIk0Jrm2ImUrC0jVBnZRwhKKEpcI6MsSq69/BLPfPCPuP3aq2QSaLUbWGfxePqDPmWIscxOlNwoj116hI1un488/yzLSytYMXzJl17g8qVHCdjhWF28cBHB4pwQfFSulqGsOrjlXqOoRLQMmaqvFcdVcTvxNO9LOpsblP0elH0QS39znXv37lGWnqIosC5yH2VZbuFOkO3i0HBMTSyqIpVrcOqDpnIiYl3qW71mkVLlAz6oFfCgnO602/ZDx/ZxOyKamXwuvirDuYOlaFofk3HuZzfaSQSrli0OXbuccyhKLyrJtDv0gNdoBg5axtrJRUHR3eAjz32I5z70QYreJg2ntJoOZ8GiZEawophQIsFD8JSDPloOuHzhAkv37vGzP/Mv+c1//+v0eh28Dwz6BYrh8cffRLvdptPp4pyj2+nGaOJqXCqTsAbKsqQ/6KbiZ+XQqS5U94IM0zU0Gzkbq6tsLi/irMEPurzw7If5xMc/RlEMmJ+fp91uU5ZlNI8nv576R2G8AoCIoD4QQqwUEELAWIuKoSw97fYC7bkFMJYg4EMAScmjqjGfkibpe2aVZq2fMwMu09L4y70TGB10/17nHs8DrLUpo7Xqi2vznEG/w7WPv8hrV6/iiy4tJzhCSlidHFSHpU9jfZ5Y8jQqPzMjGJTVpWVe/MhHuHH1KqpCnjdxLiPPm8zNXUg6l+i/EoFuxAFuA2zVFE0d39cQSBYbUmJuYdDvE4oCyXLILCvLi7z4/DOsr61Gx8naB2UL15Luffx5jPoQhpNXk8NhUEAsxmVIrPM6GseoGIqlHo/6A3EG6DQcAGcKXCZN4N24lXEuZS/Q2Gn/+PnTPIgje1gynlUt+mRUzExZxpeh1+ny4osvcOP1q2RGaViBpJuoFL/WplQD1pBZIc8sVogFxbKMRu7ob27y/LMf5rnnnqHX68YXWQ0uy7j4yEVQMwoBCNTAQ6nSIFRjVXmvBh8IfhQesEVP4z3FoE/nwV1WXn+VFz/0fj78vj9ifW1tyK3CdgXuTtxq1Y+Kq1P1EdiSjkecwTVybJaDmIqRSg6AnnoqhzcSnQZXMzM6l52AY7+ORpNMzbv5xxzUkemoHae2Xjx+XIWUVyUzbK6vcf/ObfrdTdp5hqWkCCVIfIRibaznIz5aQ0IAr1gXaBpDfxCtTa1mxt1bN/noc8/yGZ//xbTf0k6JoByPPHIxgUWMPq7rVzTlfgsaYknWYCjLgDUebwQvlegU/wYNBARrDGUx4IXnnuV973s/z7/4Ca5fe4XgPeKyLaJONUZ1d/ud0j8SQGX0QQiqeAzG5uR5MzoLmsojt7p2BKXxBFfndDw0M+ACWwFmJ633OOjsZGqu1qcBmPr5B1UGT6Op3/0642YMQdSQZRnqA8sri6wuL2E0kDkDocRZIYiJFlgUoxIrGYrEUiFa0sgyFMtgsEluLAtzcywvr/DxFz/Ka6+9zpve9BTNRgNR5cKFR/Be8cYjJqUoSDrmoTFao78LAuqVsoRSYmpKQ4x7sklR7H2JuJwQAq+9epWPv/IqL119laJf0MznYib/qt5QGvsQAqH2uw4yWwCG2jopmBIz4lxcPgpbqJ7tnk/xnI6SZkosGqe9xJVp9C/17dPqYg4i8hzKGlClbhxtGP7JsgyKgl6nw8bGRowZCiUaChqZS19hA2IRExNTm2GCakOe5zhrsCaKTc3c0W40uHvrNs8++ywry8soghpLe24O72M6hLIst4z/KKYoDP8G72MKBu/xIS6xiH3sfAgay41owJcFoRxQDvo0nCXL3MhFX7c+621AsmPiar8VZFRxzpHnDYyzBEmpOIeWJx4KnuU09CcHoZkBl2mBYq/9Bz3vNGj3vsRXIIQAJlZIFAkYDYgqviyg5vIeX55YcbDS8MowYBFarSbNRgNrDBcWLqDB84d/8Ie8eu0ag24PyjJySUknEULYGkc05BIgKlp9EqGiTiYETWU9Rh8DEROvETzWGh69fIVHL12k2cijb0oCDh/8FmvhuHPkUME91pdhe1V/VRFjsQm04nFxKEVG+Xb39xwO8wyPh/bjAHqaNDPgspdj3E7btsnibOVAdvo9fu5uNOmrOdy3bamtadoyPC8qHqsleWrgdQQSPoxeCA1QFCUYy/z8AnNzFzA2Bh5qkJgNziQLk5gY55M+z0Isi+wqHAAAIABJREFUXFZRnufkjQxrhfZcg1arySuf+ARXP/ESK0tLhLIEAa9RFPI6lmYgmcZ1qLQd6TCCrziWOhcRKyJaI2l/oN1ucvGRCzSzLJmE4zXqJUsqTiyOkSRFrQzLmWg1tKGK1gaqdJsBCDE5d+Xyr8n/Jrk8wwTx6ChDQHaaL9POtb1o0lyfdjlpmhlwgel1G9XfSXk2dgOTnfbv1c5uDyggFOLwEtnwaiYLHoMH9RACGqBUQ6mWAZY+lh6WEkfPK6UYvAi9QUHQFIejSp410MIzP3+Zx594moHP2ehZyC5R0sTagJgAEkME4jhaRCzOZhjjEtcTxYJmKwc88wsN5n3Bs7/7H3np+Q+jDrzxbPge62WfTijo+oIQAlbBBoUy+riUwcfMM6Gk9IO4lEVKgVlSlAOKoohpFnyBiKfpIJfA5QstFtqWhoPcGlxKTaliYilWHGWIS+Edhbd4bwnBEoJgggVv0DJgsRQ9jwSDH4AvLEUhGGkjtIAGIjleDWUAxG4Dlln/+u9EZ6HfU4GLxETb90TkI7Vtl0XkN0TkpfT3UtouIvK/icjLEpN0f+ZRd3pa3clB9u917jhtNRyPtTPh2PGtZdHDKGRAhjDfbqK+pChKcmcIZYltZCzMzZFnGcF7yrKISamtTeLEyKQLSQQYOp5tdUKz1mJd/Ds/P8fVqy/z+7//e9x77RqD/oD19XUWFxexYqKJOUx2Aag4Du9DzKlblpRFGf+mxF8+cTRVn1zmaLZazM/N0Ww2yLNUntVEnZBJReRHbcTFp3uuwgUGRTHUC1XtxkRjqfBZCEPxruZHPfn5zYDj2UFE+Vno9140Lefy08CXjG37Tv7/9t41RpYku+/7nYisR3ff19zH3Lk775kdrjQ0LHK9kAlYogXLsCTC8Er+IFMfLEomsCZAAhJswyZNA9IXAbINyYAgWwIFCSINmpQgSiY/UIDopUzagEh5Se6u9iFqd8ld7jx2dnYe996+3V1VGXH8ISIyI7Myq7L6datn+8zU7arMeGVkxj/PK86BT6rqK8An428IMXVfiZ9PEAJ2n4g6xZHOB/50zg/haHLqus0hBWrzbMWQxz+isDcZszcZU84OcfMjRigjq/j5Ec7VrvHOhTi01grjyQgEFuUimmrbuo6wKzkfmEhwbAspUQuKkeXa1T0ePnjAZ37rN/jkL3+SL3z+c+w/fMDBwSMODw9xpc90IfW4VdNHoh9MrdAty1p/kj5oiI07Kiy70ynXrl5lb3eX6WTCqAjWosIYrAghQUCt73HOVaAym4Wd4UdHR8wT0MTj5WJR626iGBa2BzT3Om2jyWjIXrmLSINM0ar6qyLyQuvwx4E/Er//JPB/A/9dPP5TGmbm10TkhojcU9U3T2PASeGXf+86dtzzq/qBvhudP7EhFmzl8SHpWKxPQHQXF+vi4BHjnR1Gojy8/x6PjDCfzXGLBaPJBKvKzmSMc3MEpfQlutCQpkMdNr3rtR5HBTQxF0jqXYSg7LXh2NgUXL92hYcPH/DLn/wl7t9/l/l8xmS8w/3795mMC4wB7wqsra9SUNTHrRHRJydwMRL8XhwISUSTysHNiDAeFezsTNmdwcwuKMugb5HoWSzJX0aC0tg5cAKLRbhe8R5nLVY8WgTwstbhxCLW4csFZbmISde03naUdj2dwjrtel5Og9rtrurjrMZwmnQSP5e7GWB8A7gbvz8NfD0r91o81gAXEfkEgbPhueeeW9vZaQLIqvP522LYmyNqX6uNcXG1ZWfISkjs08QC5dEBI6M8fOc9vvjFL/D1117j3XffZXZ0xHS6w9W9Xe7dfZKbT1zn/oP3ODg6xOAoCstkbDH40C31W1l9Bi4x7opJ7mQSNxuqYe4cV/amHB463nz9Ne4/eK8SLcqyDJsKjeALRU3O9VFdb+hGcQol8brizmgTFajeJ2VtANaRtexMx4gYZjKndC5atiLAkHSvYda8dzgXIu2lAJyLeYlhHERCVVTAFCXlYkY5nwU3f3zFuaTJV5r38jiL9KwW9SbtbjuwwCk50amqigwJe9yo8xPATwB87GMfG1T3tAEG+h3tNqO2zkWy33Vk+5A/RzBV3FlhpzC89qXf5tO/9Rk+9/nP8/obr7O/v89iPserMp2M2d3d5d7dO3zjzTd4dLDPld0dSl9inGaLMAfE2rksRWqryikxsZhgNaRYnYwL3HSMd7scHgVgmU52KBcOb4PYla4lSRZGEpiFkJtEACuJDn0SIuZVqVk1QIuRYEFK4II6QmyWmN85xmexMblZfu+JTnGqyqIsQ9KzpGsyEszai0XYrOk9ppLlMjO65DF5L8Yivah0EnB5K4k7EtKJfDMefx14Niv3TDx2KrQOADY5f1oPVh1NpHmk/jdyM4nDiG94RXnjd77Mr/zyL/OZz3yWw6ND5os54krGJizy/fuP+MYbv8fb33iNBw8e8ODBffTWTWxhETOpFnBYlLH3eCxZ1NJlmqiIUVXEw0QKXOmwxiBMmIyE4qFwcLiPNTZT6Ab9SuIkiP8aY0F9ZX7P4VVjjqMoHEZuRFEjFMYyGYfxudKieMQYiiKZz0NL1hC3B2TiTMxL5JLSVpPo5xEt8eUcX84DaDVH1OAkL+ns6STg8gvADwB/Nf79+ez4j4jIzwL/LnD/OPqW9IZaBxTQBIm8Xvo7RMQ5tmkv6gji1+oYGkAlcRImiktiDG6xwBYFb735Jr/yy5/kS//6i+zffzdyE4pqeP+bQijshPnsEbPDw8pi8s477yLGhgBSGhayQnCgi2SirsNEnY+IVOACoMbgjaBFgXqDNZ65Aed2gvghBVYsqERHOaUo6lgoGjkRxISFHbxOwjkf9hX5UnGqVQrWIKp5UB92atuwqZKkpUo7usXi1VGICQAjMW4LkeNTjzUW5zwjK4wKi8PgncOo4+gwZHk0RnDqo25IWpB/drTKunPSF9pF0LUkGgQuIvIzBOXtbRF5DfhLBFD5hyLyg8DXgD8di/8i8H3Al4ED4M+fZIDpRuVv5qH1hoBK2xu03e8qMBKJqUJbVqGsdYIzWfDlWPg5hRHQksXhEV/83Gf40m9/gfnskJ3piMViAd5RRBY/KWNH1jKfL5iMx0ymUw4ODnj06BHz69fYtaNgtane01pxGEINrtXbvxqrUIhG9/sCaxTUoeMRVvbAa52aI6pvQjzaoGgNc5CuMvSXckd71QCS3qAhKjhpb49oEFc8PmQvGFlE4s7rGH7TGIP4ECoigQtxPxMEW5I1Jog+xQhbWHDK3JUY7zk6eMR8PmNHiFYjk0WkO7mS9LhWnOOCwllw2+dBQ61Ff6bn1B/tKKvAD59kUNC/6FdRl3m5S++S2l9Xp6+PZptAUqamekG4Jy3MVN6XC7CCqOebb7zBZz/9mxwc7MdcymFDohrwvmSxCIpMVCkEvI0LzoT8Q0dHc/b3D7g6vtoLvCHYU7QUmRpkEk1sCl4tWArUTcApRuqwCwlgEtdgRGKdKGakgLRZTJlkUrZJvxFFFxvrhqeujmJnrIQk8UhMkRIcEq2VGBk3jUWqPNGeoNOp7MxRsa2+ZDE7YnF0iLpFdV8k9i31DVq6n0MX7nkv8IsEKDlt1a5oWLbSDAGYLkVtqj/kWFf/6+rW30G8VhJ9Yzt/VNqqgsfVnIN63nz9Nb76O1/GLGYkADBJnyAx+r4L4k5hDGoFDFg7QqTg8HDB/Qf73Lk6ZTwaB+WnV8SEcdZMiqm+18cCyBgbkptK9A5O+yetSd622kguVl2XGELkfUOKR5PyNRsBaySlaE4QiyEobY0NYRhQDVyMKSh8UAp7UgQ7wfsIJsT8SkgdECuJOSZPNRIsUeoc8wgulA5skQlCuaJ9+6jPIHFRaWvA5Xhm4JraTnL58T6gWNXHcN+XZJGIokGb7RaJ0fLLsAsYYTGb8c233mB28IhpikFbWXeo2hQJxh5rg9u6ehgVYwo75nB2xKP9A+azOYUt4piIVpvERNVm3bSogu4l/q22HglSCFBEJkAoxSNSYsVG4IhZliVpLYI+RrCVTkSMiSmbJca4hTp1ikbACVxW6YO4ZDx4YzAKLrOiJaANJvSQAqUCZ0nXkbyPo8ZHBIfHLeYsZhG0TRh3uvM+TnF+a0+ykE8TBIb6uFwU2hpwgeNxLauoLQoN7XM415KZOkOpcDxr3wYvtFDPBuVnOZ+F2CwGDFHE8C4OOsaiTboT1QpcnIY0IOPxhMOjBfN58F7Nk8fXWQ+zNiofnDBEMYnLCKAooqgYwIYYU2Vc0KQo+xnXkpTXYhBjo6Oar0Jt1msi+KWkGtUnBngy4oOyODAxQWRScGrCRswoTpoIL6EdJSnQRVIYCYsNJjNEA8CU5YL5/AivyVJWj19VQZKT4/AXSx89ThDYdu5mq8AFjse1QA0EfdzJut/r/F36WdYEMOGPNqoJznkKK+AN4kKK1PHIoOqZFCNcGaApJYhfYvfjG1p8WJijYsxkskNRzFE/b8RdaV5XPTatdBICBFOvSNTJRL2RkQAi6gU3Au8XMYhTvd8nbz9wFrYSZBBFO1ydwrKudS/qIrgEZI0cW+L9BBvZKY3cSeVOE9sKIGYw4mLMmhAnWIzBaNj86F3J0eEBvlxgxnErAbXYmZuou+71Ni/YRNsOLLBF4HLaXEsX9TnRHad+g0TjIlg+51zJyI4w1uDmC6wo4709dnZ3GI9G7M+Dm7pJCwQFky+nqndAsGIZjUYUxQi3KGMw7QxYtQ2KoClhj0LgSJIOI+iIJLz4QS2FFYzxMap+bW2q5yzlK0oLtYKOzF4VO87K5XPovccURXZMcKmcAYna4QQuXrUSHQMmhR7rzZjhu8NiYwzgo6MjXLnA+JAhslbqNufocS3QkzpubjuwwBaBCxwfVPrqtI/3WYvWWYf6gCiYVy1eRySzcXKUqzIC2hB3FhQZj5mXC1SFl179A/zab36OnYfxjexD2gvnwZeCEvw/pABxCtZFI4tj6uDankHdGDs2lOop1QXFL0rpgmNcGD8gNihUFcQbjA0+LCPvaz8YFNU5Ih4dO0bGM184vA+u/cnaYkRBLOBQF2LAWBNMxoWFwgiF+Gjh0aAXsYIxtQgZlM/E8WgMgEVIaK82ckYWQwECXmzlMxTGAIUEU7aKBGW0DRsfC+c4OnyPo/deh9n7mJ0pYoWSKaXC3BtG4h7Lg99lmew6fhrA0SXSnzdtFbicNW3CufSBTqfIlOR3mpqJpCNAtWLzNWgj2d27QjGZoNVbPxez6pZCX8ERzNrAZfhJgfc7OBfCWbY6bTxYSQ+TyiQ1kSCYpIaJSmWNHMzIgBQG56M+JnnYx42FIbxk7ZRWS0NR4Ru7kwqU0rXkXrxh60Eads1ZRXtb1OUIIUWIrziPpDQ22b2sdSloiNI3O3xEOTtk6kvUeHwwXkd/l6CHOk3R4iS+KBdBxDkObS24nJVoBN36k1VcTle99Fs3eCjSQjPGMJlMuHLlCo+MqWKetMua6M+R6gAYU1Qig3dF5AiW6yoakaQeazXm9IkgYFBIpmQFa8O5ogghD7QFWDVCta89AkRcwCK0FlztZxOKKcu3OCmZ8x3SZNcfY9SoiQCTXZ/XuDu75PDwgNnBI66k1CVeKz+8CotPcUGfpK0PIrDAFoLLJrqXdefWcR5ttrSt1O0a21I7lW5BV447P2eMYTqdcu3aNQ5MAVqCRD4gnjdxoap6RBSbbC8CBRYZg3eCNSH1aloxkq/eFXOTj0dEqq0DNjVkogldBI05iRo7CfP2qjZzziWZwfPMlfn9iGXx4LNNhZKNKf420WkvHbNReZuUzSl3UQhgFYJnHR0ecbD/kBveBdN49B5u5KY/R/qgcieraGvApQ9U2gu663tfe6voOIDSrtc4pvVDq5o8d7spcC5Trl+/zjeMAd8qbIIJFjzexT1BcedxAJjQvi1M9EPpA9GMc4iiQPvaKm6KYI62BlQN3kf/Ggl7nUqa/iJV/ez649F4jgZQJM7Dt8oZY/CELQFJZGzWq1PDVhH1JHAuUWEUlcSBk9IYwHwxn/Fo/xGudNH5LkZGS1a5s2GKK2qDyabi9weBtgZcYD3X0j52XKXVKmBZ931JLIJOziUfV/BDaV7LaFSwt7eHiQrJ1IxEs3N62yvJclNHdiuTKRlDUUgVHrIxNoIbf1rUkuK+ZDoQG0MdtOcwgI2vOKjwtyYfHVEqzi32ly6xDSx1n7UZWIxtcFBBTLPZGLL6rXsXauQJ5YN4VdU1wqJc8PDhAxaLOWPSPYYOa/mZ0NDn8YMKLLBl4AL9XAt0cyurkH+IJQio2P9V4+gClkq8goovyLkXyEAiC0WpGhzjptMpWIP43C+luf/H2rSsTdQnKMY5vAQHMWN73pCZGAGJc6G12BWDR9KiVh84i2TdykCmQCsOQlQrgCHNQKWPrRXSbYBpjMOEXyFHvM2AOmZgNMkjN/WTNkwKGrMahDqxY1PrU4wJO6QPH+3jZkdQOqTwoFG/9cFdz1tFWwMum+ha2vWOc24dbQRaGt6cpnG+v11VjfFLihAaQTJoarVtGyKFYowLoSd9nCPxlW6ii9qLOj9ei0TRwa7VSNrTHMoH97tKREHJ9dA551K1vyR71OOsOZRcRpEo8pmqz8p3psGxOhyK6UCJJOJ5dczmM9xiDloi6sE5wgYtzgRgPsgiznFoa8AF6geuSweyDmy6fAZyNn/V+XXUVn7m3xVBjWkspHqxh4BP1tpKDEhkxHDlyhWK0YTDwyMg6Dic9xjxWGtCEnpoJGsvrMRYJlA6h6sc3Uxj/mgrbTO9RSpXuhLBRrHK47zEyPlhUTufXPWBtHlR6wRkoR4Yje78EhS/ZRm2OpjCNMumMXbMe5jLMHbn5hTjkJ8pKYjTNokkXhU2efK6oNCmTqoWBqk8evCA99/5FjfuPgdjwRaGEEKqy93x5HQJLE3aGnBpA0tOmyhaT0pdZup2H41FXIkh4e3dHlclFkWdQBU1TurfEL1QU7R8W4cXqBYLNWARnfSMKJpScmT9ptCSbXFp6eGPWRV9UpQSgjtJVK6KgJXErQSzu436Hk26mspaVk1DtNyEoFEkEG5xcylwVfMlEs3FEt36bdi/5IkAq0LwEA4cjsYgVaBx60IAVQEQmM/nHBweUM5njKYO1GA6+Z3zpbMCoZP42pwFbQ24JNpEqbtOL5KOD6E+UOnjdLrKtBWPtfojcRERTHI9hDU4QnJ3UapyQPBn8fXCE5HKLJsWUS7uNM3dtiH6BMmryQlqFOfwbslfRyQ47dWbeyRkddTkfawsXHtumu2n7QOwHOxLkBhvRmowIsqWWpuvjYBSA20QldJ1SwUu7bGLKrPZIY8ePGB+eMjoSpizx2WKPg/aBkDJaW14N+lOiPY/i8i/lpD07J+IyI14/AURORSRT8fP3x46kE6lJMsKwb7zp0FDxbDOcj11wyLzMWlXXVaQuDFQqjLEXb6pXm5OFgmBrU38hBxENuNamgrjxBlBl9UmkGTnklWoMLXJ16ZkZbEtK0SOwmJsnWitarvybQlcnG8psSM7FTmPej6TpJQOGbsMGA2S6p/q+sKXyNWFGaRcLNjff8BsdggatiQs64HOlk6Lo76INCR25N9nOSHaLwH/lqr+28C/AX4sO/cVVf2u+PmhTQbTByBDzneBzFDgaZtE28cb5tIOEFl1PgFH0gek7yIwmUwqMEkikhQWIuCouorrCL4aMamZFUZW4ibDZG5ucVqVWViWPmlcJvP+TZ6v1oYsiCOb+ZRICpIt2ThsVs802sl1PH33q9aPLN8DkbQfKbWbRaFL12FaYFnpc6JymaD4PXx0wNHhYTTppzGc34Lve/6GvrwuMq0FF1X9VeDd1rF/piGKNMCvESL8nwqdlGvpqjOUugCmfa6vbLtGbubORaSU5tQWBbt7e4wmU+yoqEMMSHD5r6+FGLg6LJ7CBGWmzT7GmCVOYt2cJE6iDiEZfFkSZ1RzPcRySSzLdyMvj0OMZKlkTatvqRTN2gUujeuWKmVtygBgTMwauSTyJSEpbCgX1Rh/1/Lo4BEPHzzAzReBA8uNUz33+jxo1fO5beLNcek0EtH/F8A/zX6/KCK/JSK/IiJ/uK+SiHxCRD4lIp96++23T8y19NU7C+p+IFeLVHn6D1VFrOXK3h67uzsUxRigEp+S303gajKTsaljkqTvFadRjEKa1qLoBBlBlkAm6TryMasSzLY9VxcWsjZApurPmBhrxSydWyLREK3OLL886t++Q09U++C0uaN8tCmTwKNHD3nvvXeZHx1W2ysaw/iALORtpBMpdEXkx4ES+Ol46E3gOVV9R0T+HeD/FJHvVNUH7brakRQtZ9l7+hvEVQyl4/glLClyReoFkJSm+XlSNLf4IGfnJtMpO7t7VAGvvUe9wwoInsKG3EE1RSWm0bBXBrAExzBNjEF6+ycv3kqXodmH+khS6Jp8d7VEy4xW/wFB6UzNKVgTy/mg5zAkccVXICSxvUpkkaSTSbFkTLSyGVAf64cwFcGl3+OquUwbLhVjRhnAhN5DHIc4ttjP0fyIR/sPmM0OmHoXTOqPGU/WPa8fFMA7NriIyJ8D/mPgj2qcLVWdAbP4/TdE5CvAdwCf2rDtTitNfsxaWytCO6j9Rm7fsHXn+9rMAVBEQF22M7laOXHh1DoOj7AoQ0BqVWU2d+xevcFTL34H//LTn2ZsLVYXjNwht65d4f79+9jRFLFTvCnABo5ETfApsQKFKoVboNG/RKUDmBXw0rl728sYh0W0oNCCFN5AAUcIt+lFAn6giDhKFGssRgwTn6CnrOdQBDUWL4qPHI41ghoJbisSd2zbMaUYXAq7MCoCGy0SsjZK0D3VTnz5+BX1s7DZ0lhgHFDSl4zMgrEuUF2wWDzAmCkH77/G/sM3md66himuYWRUZy24pDOjY4lFIvLHgf8W+E9U9SA7fkdCyjxE5CXgFeB3jtnHoHN95Y6L/m3l7Cql7lCFbt95gBtP3GA63QkZBOOxkKlQKgBt1ltW0K7TMS23sXy9kDiZmruplaWr5lOren2K8VXU9RIZojPLvVVyjjCN12fc5Oxoxv7DfXxZcm6bi86QLooyeIgp+meAfwF8RERek5AE7W8CV4FfkqbJ+XuBz4rIp4F/BPyQqr7b2XB/fyu/r3vohgDPOhoKLF1lus616+bju3n7Nrs7e8wXLmyRMYbFIqTtCOJSU+8gleK3ttCkv10WnPaYkoK5Pba29aYxztZC7tLb5GrttLArUSg00mijj/K2+0C0UuDmZbPfisRkaEEvdXR0wHvvvsN8NoM4n133b+jntGnTNi+KMnitWKTdCdH+bk/ZnwN+7jgDyUWh9vfYdm+ddpmu+ielVQ9Alxg3dPxXr15nuruLcx7BIqag9I6UkL1LQSCScvekMjV45H3nWQHa15KLd9776NVb2a87wXzdXFZAo1RhakWSs1znpdRl1nBhTeU0iMS9RZliV+KcVKlQIuC6csF7773DwcE+u0/com9e87k5TzqN/h7HuNfRVnno9ils07kcTPLvfaBynLfMEGXbEOBYdz6dm0ymTHf30GD+IezcDftlytIhZtQwc4sJyt74fo6Rtbu5JegGmGoBKw2AER85oWBWiWWSZWZ5/GEsUu37CSfiPEoNMECMntfkgrrmJL+3+Tw1/2qmM8m4qKjcrUJNGIOPSeEe3r/Pw/ff5+bdD2GK6YlEi21bxLCdYzoNU/SpUh9L3D7fVafre1f5vodnlcizTjRa9bvrXBrbeDLh6tVrjEYjEAkBsb1iRyNKF6K/tR3Gqm0CwpIYlESkruPtee29xhX3ptFWZYKu/VLIy0hUJKd7EMWkLnxZJfZ2cTYGgrlZsvPZPBkT5TF1FFY4PNjnvXfeDmleO0ztm1CfXumkIlNbtL7otDXgMoT9bh9fp58Z0tcm1HXzux60VbJ5+/hkd4+r128wnuzgEeZlGRK5R2VudGiJiya2kczDSgUmnQuw5WfSBph8rF3gt26uEoAgEnM816BSIUhc41U7UuthunRQq/psgltlzM7ajXoqiXyderxzFNawmB1y//13KGeHDR1W170Zyrmseh6PQ/k92UZOZFPaGnCB9QDRx8kMWQhD+j1pO32cSlskyct7FW7deRKxIxSDUwixaKPuwBgk7QSmXsBd4kUXwORA01W2a6xDFJddoFblkZUIgKmdSqmbcTatMfT10R5npXiujFqaJjOhWCYmhUIGEO/Zf/99Dh89RGMGzK57s8nCPisFb972WSqSz5q2SucC3QDTNbFdb9g+NnXIw5I/WKsesCEANEQHk3Qhi0XJk0/dwxQFWhqITmXOK8YWYdHkc0KEGAFY9vNpg1fDKzgThUJZKr2L9x5xqY8QdiH0sMxd1IuXmJbEQIe/keZ1WiKTaL0fKo1vlZjRuL+qhHQrdYKTeEXRc7jAe4eoxxrDwoc8TgePHvDowfvcvOvIsbY9Z+1jfXTW3EWupL+InMxWcS6b0FDRadP666hLn9J1vl22r46xlt3dPaY7u8xLhy1GiLXM54tQp1EvWmLUh8U8kI2H7uttV+tqJXEenfWJwklU3mrjeOq4/iIizXN5H3TPXfsa0sdGvUq9fcBUgpJmuqgAZIqoR8s586NHaLSOdeme2tf5uLmGrvFcFLoQ4LJOt7KJDLyJbqaP1okRXfqXvmMilunuHntXrjJfLLC2ADEBXIypACCUD8Di1Ye/Ld+UvuvvEifXst2qnVxLL2UiT6W0lXScWgXT08Y6JXhbEW6zfUyV3icDuKAGksiB+ZAp0pccHewHrqZDLIRmpL68v8dFfXqpi0BbIxatEzNytrjre1ss6hJv+uqvoz4xqd1GXq4tYvWx+A4oRhOuX7+B8ymPMziFkZioVojsfwQUIw4fdzOL6VbAdomNXfoLk5dPgEdTnUElhtXXrUGbXClVK0Agec/M9TFEAAAgAElEQVQqGaJQ7SsKzWV7guo5yWmVqJJ0NiGlYzRLi1ZtarKmoYHLU48Vg/Oe2cEBZbnonKttpIsEJm26UJzLOg4mfR8iMm1y0/re+Pnv/Hz7+ypOxyuIMdy8dZvRaEzpNQTiTtairHwVfMlr5F6WFZJ93Fon50K/xy5kXEBH+xpPqGThlzIOouZgqtr1MaQRlqHL2tXnYZw4OJ8pjCvlcezHK1UK2uThbEVAHYeHj5jPZs3gXWw3wPTRto95a8Cl/XB1LYhUrl2n61y7zSH129SnYBwiCuXf++qpKrYoEGO4fecOOzu7lN7hVBmNRmHhU+tdiIvIqw8A45sAswpUh4hGS9ecvlfiTt7+ckoTicxI2iTZOZ4IMClkQxtM8t/9AFPncMrjwqS5EsnurdbKX/WO2cEjZrMZZVlWXGWXeLSKOueq4/emtGn9bedqtgZc1tE6rmOdvuU0dC3raNXD0Qc4xWiEMZbrN24w3d3Fx9Sp1lqccw3dR83ukx3rl8nzhdN5zauAhW4Fb9fJpbleVS+VMd2g0gWEnZyfC0ptn3EzUd5qgFO6ThS8K5nNjljM5w3OZVPxqG9OT/pcbTtYbEpbo3NJtIpVbesu+ijXdaTvXbqPVfX69CxDx9+lJ+h6mEezGXsifOj2ba7sXOG+g1FRUGrKdFhi1CFOELFByWvGOBPSmZhkNYqfmHuRjOUBBFEo1GJFqgWJrTkTlcx3JqgysJqZrpPEk7xijYBzIUdQTDVbTwKIKTBiY4hMAxg0Bp0JHI5pWpQkc8KDoH9qi30awn0KgjNjfBUHZx6yJ6RrgZCdQBVvgg7GugVXjMHuv8viwduMnn2OkVEWqmAtpYQs2R4odIEQY+4qwf9ICjwhJGlBv4fv0Ofz24G2lnPZhEVcpWdol1n3lmyXOyl1cQUNbmExxwrs7e5x586dEKNETAUAQWfpCVqGOiUZFKjYKB5FfUzUyaBhAUr6S1i/Ju4Dim55wUEviR4V4FEDE8S2Kt0p4rX6iwaxBK0zEdS91R+NKUHqj611NpWr2/K8Lb1cYh8oqLFVNoKktFUNqVJC/BmqHVihQU+BQjlnfriPlAvwPoCYxMwGJnr3Ctkk1KOrPX+7dWjbrgM5b9pacFlHQwClXW6oaLQOVDYFnb4HUFUpvQOB6XSH559/nmIyJobEGdRW/vHxU/WRD3NJZ9IsMERpfZqLJyioa51Rngu7yzGweW+HcQft5yG1fXRwwOLoCOdLUFcBcqrXTT5+NrvGvuNnCUTbAnJbJxZ1iSRti0guXnR972tzXZ2uc0PqbiKqtSmw84ZiPObp555nOp0ye/SQhPs+fYu6F0UxqoAjeddCtvtZopcq8S0fDTRJtEljiU02lbXpeBpXGrNqbViOvwM3sww660C7qd+o50+iuNbgHPP2NlwvbT1KPs6Dw0fMZodM9Fq4xqj3TRzaaq3RemBYqedacfy0aFvEruPmLfrLIvK61PmJvi8792Mi8mUR+W0R+WPHGVRbXOlybGqX7avfV6evbJ8ota6dPup6+zc+EsUHY7l16xZXrl4PQbpVo4gU28nacNGE7OOib5hl8wc/SSY5me5rr/RTLHMVlYS0oSjQd77rxdHZZj42s3yfh1D7OVBVZoeHlIsZgmIlZAwIYJ36bvazHXzAxaPj5i0C+F+0zk/0iwAi8irw/cB3xjr/m6zi8TekdQt7FdAMqb+qn1V118ngq0QMr4KPmQfHkyl37j6J8+DUQ1RGOqUCkqRjSBxFG3ziACtdSuBKWnNjak6lS+80ZPzQzRV0UX6+ms+uMnQDVuJiNqFVIsnR0QGL+RFGQ/4oNKWCbfRaxYy5COF22+L2NtCx8hatoI8DP6uqM1X9XeDLwB88zsC6Hvp0vF2m63j72Kr6fW2s09/0iW45rdK3qCpOJezbFYOxI5760DMBVHxTrxq0n9rgYBpxSSQuglzMqQe7vECke467AGbV+NvXvUpP0+ij4952UXV+A64l57y66OjggKPDfbyfhx3ScZd0UjvXYXZr1i/Mn8cbXZq3vmf1PGlTjvo86CQK3R+RkM7174nIE/HY08DXszKvxWNLJK28Ra1z1d8hnMM6EFlXv93nqrbai29Vm13UrudRvIA3Bqzh1q07YCyO4L1bx5xLnrBh63IAHl2ao7D7OOp4opiTECqBTz3oeMxIiMdi6o2FmvWhsW7KAuCjRYas7XRtQylVby7Kfh1FJbat4ZLysfSVm88OmM8OcWWJqEO8x2iKGBEgxmhaGtkLJCidBl7hJR0XXP4W8DLwXYRcRX9t0wZU9SdU9WOq+rE7d+4scQF9b751INCOvJaXHVK/fW5V+a6xrvss1UEonXIwm8egUROeuHUTjGXhfMwKkLSNVKbQODoW3lGqD4s+WVtUcSlmCU2dDNAAk0aclyhCpY9XX5mM22/mSifD6utN9wTqbJM+mn+X3viqOOcoyzKUyectDd2EjIsay3alhQWqNLlVf9nz4X3Jwf5DyvkRRWEo/QIrQmFhMS+jpvv0aIh+amg7F4mOBS6q+paqOg18+d+hFn1eB57Nij4Tjw2idXqQ9kJfemuvON8+np8f0vYmtMlDUCK45Ncilr1r17h69XplnXHqKauFTLaPJmQeTBTqZ2PIzlZQlMAj/83yPOXn+s43OuqhLhEr50DaZdsvh3bTq8TY9jhXiXKo4/DgASIe9SVWKtdDihjHOLaYtZ5M0cPN4Cel0xK1HhcoHTdv0b3s558CkiXpF4DvF5GJiLxIyFv0L082xOPROtFpU9Fo1fHjllPVIOSIDUpblJu37nDrzh0Qi5dcN6OZq3sCmMgJpfbo2NCXzok0loaIVByMVknLBKxBrKnPCUFsk9iGxGVWyTXrrULrRMhqEWU5qGPTWaG8XDOlStcizOep2odU/S55cP89nCiuXGCNYg04RyM+TOc9W5H3aKiCu11+ExrCGbfpcelg1vq5SMhb9EeA2yLyGvCXgD8iIt9FeFa/CvyXAKr6eRH5h8AXCGlef1hVXVe7J6EuNjgbb3Usfe86tu58399UJvXd9RbuGk+vWIUBa/ELw8J5rt24wZ27T2EKy2KhjFPU/Ly+6X+jJUc629KtZKhSiSAKVdsVsMYyqIbcP+12sr99ylxoxkXJF12ak3xQfXPUKB9ZuTBWMJV37vJ2jXWLTr3j/v33KcsFzpWMJgbvQXxsv1JSwbIaqPNgdl2t0iuekce16M+LTjVvUSz/V4C/cpJBraOuhZ7137n428e6zg8BmFSvXa6P8vPtN2s4GP4YY5gvHLvjCbeffJKd3V2O9u8j1tZpOZKoILkiN44p68ujoB5LiMyf8j43+s/+zee1/Xsdx7eKIzkJtbmAsM/K9M5l17i6xCIAg+foYB/3aB+z+wSm6iOWg2gxMiQFeuDe+oGl3Uei44rWQ9pu07aB1YV1/++jLl1B+1jf+aHn2ueHfroHbCmdYuyIxaLEOceTTz7F7dt3srqhaA5qnW9JskVF5p8hJBalOQ+tBdi3MFb12UXthd2eg1yky/vtFmH80rF1ffYBej4G7xc8uP9eqgxesRZ8kE+plkauyDphKthN5vA41DU3j0vfAh8gcOkDkKHnh9ZdV39TUlVK5yiKgtKXzBZzbt26xVNPPUUxGePWWGOW2svabTAmUo89fdqWnqoey2X7xt7+3aV3aLfRV09bQNLeb9QX2KpvTvrAPXgWCe+//z6aWdkAynIzKX7o4n1cXMXj5Ga2bm/RSWiV/mOdfmSoHmWdjmUI5fWDCdmBmeC9xznlypU9bt66xXg8YXG4wBsJmVu9Rl2JgDqMrVO+5s+Qas2khL4k/d9r66ikNAlewZXepSrQ/JJ8ZmsACUc7rzMHtCSCVAPOuJY2SOScCEGhrGoqbqL/PiTORcmL5CBjjHB48Ii03zxxe847wJI8fhStd4Tr8vxtws0NpZMAwuPkVNq0deAyRH+RZPC+823Kd9nmD3mq09V+F7fSV6d9vE8P0XXjpzjUCPNH++xNd9DFHO8NL7zynVz/1G/x5te/hjVhM+Lh4X0m4xGTYsRidoSdTCqlLBJd/qOTindQqiISFpIRUymCq7FED98gTlG7uIhUmx7RNpdQzSpVotlK91P71SCCtYI3isZNloIgxmIEJhquSWK+a+9dhXCBq3JVPxDyO5WuxOsCZwwjLSqRUSRYjcI4o8ilincOxDeA16uiCzAUHD06YHGwz/TKLY68UgrYvTFzr1g8RoNzHQrGCcalYOBLt3HpWWlT+5lap6sb2u66fh4nXSixaJ1y7LQmdV07Jz3fLmuMqXYuKyDGsLe3x1N3n8JaG4IxERzDxFgCpyLZ279Jq5SZbXFl3dgaehLNXN9rOavde1W+7eSW6uYvhlWcJh3nlkWi1vWtKJ+3q6q4xYJ5FZXOEU7VvtDNyWAtqKRrHHL8NDjgTfp/HHShwOW41KVv6VP49ZVb9X3o+Z7BhbzGLbp65QrPv/ACk8kkxtJVTDECli1eq/QPSXeR/x2qV1nFddUg0y43TA+St9k4T3a+Z8qabfaLUl31wpcQ5Go2mzE7OERdCUQeSUObJ9TdDqKhnMhFpQsLLptO+jrLz6rvq84vKQs3BBjvQ/BECfw9IoL3ntF4zFP3nubq9Rs4FcrS1ToLX4szifoApg9YVnEM68BnqNWjUzxYoZgNlZZa6eyv75qac9IsX48rdDOfH3FweIBqSLGiUYzsoyghnSsNVaZvI10YcOl6cx6HcsAYAgrrAGZd/XVUAYUqEMJOzkuHU+Ha9es8+eST2KKgdHW5tG/I+6ZlYxWwdJlzh1qCurmbzOTdcW/q6P2mAsW07ykfS7uvRjutvlc55nWBa87V5NcVJBxlfnTE0cEj1DusBfGKrQW+wfQ4Fvo2iT99dGHA5SSTuWoR9XE0XXWOw9WsHVtUqlab62wR/F087Ozt8aFnnmMymcZ4LlFpGTWw6uIO6R5xqA0sS2EI1uiw2hv+0uIO7dbm4zQGoBHUKV/gy+Nc5pIa85L12ZXbqKudLjEsp2qMAOpZzI6Cxci7qPNy1LzJ+Vh3jkMXgWuBCwQup0Gr9C3tMn3HjsPVDKF6966Q/LgmO3vcvfc0k909fLxVAnFvTZ5ZsEldIseQxddVP+l30p6ffGH3cUJpDgKgNc+nfEW54reLcm6lC2D6xp3LQr2XqR7xjvn8iNnhIVqWCB7vXLYhtFVZIQZlWDl3p00XBUi66NsGXDaxjPQByBBQai/oRH0PSQCJIOsHsYEY1V4wdsSNm7fY3buGGItXhWhZoqUf6FOe5rR0fsW89ClhV30PbXZ74lbz0jFH6wByNSB2n09cU9f1oCFKjlssqrguhKkFrzG/dJvqndKrOMXTBoOhL8BtpK3zc2lTenMOpS4AWPd2zB/29LsNFn3n1/WxlhTKcsFoVKCqlKVjNBrj1TFbOK5cu87tO3d48+u/S1kusNbg3AKjnpG1+I7x5zuGO7tMiyBeQts03I6+n19v1a6EtEciEn1tIqhk02Ki301j4WncJyRNnQo0eYLExYW+tZdr0WTdScdFSKASjjUDTIkIqMca0IXj6OiQ2dEhk2vKZDxmvqhFo9piZNKtWhrnadKQZ33T9fA4aevB5awm8iQ3MQekrjb7zuUPeP09Ay8MiEc1BeZ2THZ2eeLmLaQYIX6BkbD4xyMbwjNKP/PZpWhtgmVYi+1rzUWfdjv1Ag9J2Za4l/TpGUvS0XgROizwlSwTNipK/L68T8s33PTb19k7JeF8lZxe8GWJW8xDv96BxkBW1CDiodpidJZCyiAdXeuluc1A820jFnXRKm5jqO6ly5LSXgjrRIq6HkDwAlUMKobxZMrtJ+9SjMYgAXS89xTFKESp6xEpun4vi2yr2fi2yTiNt6EDacdVoT0vzfZ8ikany+ZoGiAW5qENLO3rWrqmQaKJItH87MoZ8/ks6Fy8H+ortxW0zcAC3+bgMvTmrFPopu+5qXQIsKTF1xiGpIDdAjEV6o0nbjGd7obzGsyohZFqIQ1V6raPD9EJtduoFa1R2doBpM15lUY7bRAYoqtol2uLbZuSxO0BhRFcGfQuwVqUtgr0jeX8FbptukgK3uPmLfoHUucs+qqIfDoef0FEDrNzf/ssB3+etApU8gXVF8O3l5tp6wdCRKQo7gilh929Pa5eu06Kn2uNBPOpNBd/3m6XorHNiSgsLew+kOgrQ0e55nhac9bDEfaDU005MJ2ETBTJisLgypL5bBYULBFcoq2ru/JjXtvbzq3kNETn8veBvwn8VDqgqv9Z+i4ifw24n5X/iqp+16YDOU358TTb6teV1Iu4Sw7uU/ou10u5lNO6y4R7MXh1TKYTbt28yTd+z8S4I5b5fL5yEa66loYYsmKeusZfn+s+nmw0fWJlpZdpHRNpOq+JyRWqresJqJr1kSt0az1SH6W0TYW1OFdSlovQoYI1Bu+6gUVj+/l1b/qc9dXZdv3JcWhIJLpfFZEXus5JmI0/DfwHJx3IeQHLqpu7amxdAJN+5/VXLfguQEpGm9wS0RiJCEUx5saNG2Hnrw8bGBeHRxTjcS+YdY1nWQzqGKtS74heQdrjY7PcV1PvQsXZLYuK6frjZS9tzJT8eqSHm1wp1tRlBcVaQ6lhg2UM1ocRgx+YE7rrpbJJnbzeBw1Y4OTWoj8MvKWqX8qOvSgivwU8AP4HVf1/uiqKyCeATwA899xznY2v4gL6aAhwDLHmdI2jPaa+Nvrqd+lAHBaCwINRhyGYQlWJ8Uug2LnCjSc/hEyuMJ8dMjKWhXOMJdudTC02tMWj9iJI4pGJPilFUdR14ls/mZD72jYidZDuDsrBIoV7QOu9P1KJN1oDgmhtqcmc74xRjMSd4z7EfaEaS6tP1SoIVvu+VmRNyA2lWsGIOofHxHguPddEDVvtee0D8VVz00frXnQXhU6q0P0zwM9kv98EnlPV7wb+K+D/EJFrXRW1lbeoi9pvtbOmXr1I1xu29bZZdX4lJyW1klDC441RhyWYRZ1XbDHm6o2b7Fy5TonFIxhjo46gu+328TSePh1M+/rrAfaMO8Zs6fp09Z08c01L/GkqeTOGKSiEKv2K5OUbuqOetvquJ82NhLQtnhikKu489wP1OZtyv5u080GhY4OLiBTAfwr8g3RMQxrXd+L33wC+AnzHSQd5WnRamvZ1D0TfG62b/W3qHILapV6kzjkUuHbtGrdv30JEKlN0ucZq0ruwIq2ajWquei41iUXrLD2prVXlahDOxr2yxc1o+YVhABO4oGrf1WqxNlzIKQ4qNdniZE/azjbRSTiX/xD416r6WjogInckJp4XkZcIeYt+Z5NGN5mkoWVPiwNaxamsOt/F5fR9kligLXFn79p1bj95F2Mti9IHfYtff/19b+/QcN1+FyeTn8sXgeqyj8wq8BgCQGF83XM0hLoArM091vuTEgcUAnLn+qO6v45+e4F2ADD10Fk8m9tCQ0zRPwP8C+AjIvKaiPxgPPX9NEUigO8FPivBNP2PgB9S1aFJ7FN/Z1a2d0EPqNfV51CASd+7/GAqV/2k4Axnq3rB1d4wmU64c+dJpjt7lM5Vx4dec99428CyKhRC1+9cpOmivExDZOmI0yLC0vzkx3p6WAK+rvHn7aoKIati0kuBSMi0KNWcns1zeFLaRg6lj46btwhV/XMdx34O+LmTD6t3LOd+I5sPZbdJun3D2+fz9kKu4jpMQQUw6rK3d4qEJhhbAIoxBbdu3+HmrVu8/v438SqILQZx6uvmLAeYXDeTznW1E8beFJ+SErjdX18by8cyYKnqQjI1r1pYOUe1Sn5JQKgoKoKIxRhbcY1Q34Nl8qwCnfN4Pvt0PReSczlPOq6WfUi943Auq/QVfaJO1+9VHERbJKoe8CQiZb9v3b7N3afuYYsRpdfsLbv6uvt+QzdnsTSfHUrT9vd1tNR2pl/J/2aD3Ug0qsZE0yLWeV0azPBGDMYUGGMxplgtEg2gNvieF20jsMCWgctxJynVO6sb2ifqDDnft8DTxxJ2/SKZQrcuHd7YYkAsV69d58at29i4r0h6dj139b9qbvtApQ0EjfMtP5eu+onb6LovSSzqGm/WJZs8EhqtS6sAU1WjPssg2AAwUkSgzpPQn4z6OIxvJ9qaXdHH5VradddZJI5Dq8aWFlAOcH0sfLss1EyBkBaSkGIpqRhKDM6VFALWFty7d4/xdAd/tGDhSlRdFcSp3deqcYTyzXnLx9dXN1+oNluHuf6ozaV1poFBewNK1nXDfCiuARJ99zJxf3lOJNXaopbG7RbKaGKZzxdcvbnLlStXmM/mjPemLBZh53nafxQadiQvOx3wGPWJxOlvny4oL3dc2iYuZqs4l01oE3Z8XflNRaauBdQn8uR1us9nD1p1vhaLrLXYYoQZjRlNp1y7/gRPPnUPY0fYomhcW97nIJElu7xNRJzQ1/KxVdxCe3wDBJ2uYfb2mR1Yex2VagZDYceMRmOstaiaKE5Jpbmp3G1CNqbGuPqo69kZKt59kOjCgsvQG9Ur058hreur+7zUK1YC16IIvnpTh93Su1eu8qFnnsMjMQHjMHPwca9jqL4qVwp3xexdBtVhSuawmJtc0Lr5zXUu7bEGpbVBo7WoGBWMx1OMKUCVynWok0VJITAvaQhdWHDpo8cp167iVFadFwST7WdJ73bBBADBVFHzp9MpTz/9NEVR4Fztqj5ENFwab2uBt7mOlcDSAQ5tgOman1p5vXpsq8SHlF1x1SeAyzKXqapYYzFiQQ2FHTEajaLoZjIRrmOA316Mx4npAwcuZ63c7epvCID0nZfM571asGnxCRRFgS0KrLF4TAja/dSHuHn7LmKbYlGXKAKr37VtLmAouJxkoQ3iIhuiZl1vSN1Vli+RYN4XCUBSFGMKO0bVROB5/DFbToO2QXn8gQOXROct354MYJJ/SW4tiUrV5KJOiD0iIly7do1nn3uO0WjUDSbtBTXwGjotK32Wl45nNy3+VaLLqvpdbbVFqGXA6DZhd40/tYuGDZTWFkynU8ajERDm2VjbqU86TTrrhb9K6X2e9IEFl/OkPgDpUup1nW+LGJKFPKjEDNUQ1hLDZGeHF196iZ3dK1WZdbTJ4zxEd5PvPM6vpysVSN5mup51IzI5SGVzscxVtXRDrVHm+p80zrIM6VyLomBnZ4disoMqMWc0p2aO7pvHs1742wAssEWm6POgs0L0oWb0XjN1bjSS8CO9r4vCIipYa/C+YCzCaLTHM888y9WrV3n/7az9+G/ylK2vN+1U6tKTZN1WZVL95rnlssvX2aXwbQJtPcruEVEHm5J6PCFSXAZJK+5jxfXVZqHGfXfOIdZji4LJZIKMRkGvFblEae7sao5SBR0Y76WqMgT8T4mb2QZxKNHWgMumiz4Hik0tR6c5rvQm7tJd9HEu+fHwRrVINCsHu6diNObP0QXGexazRVikkx3mfsLD0S1e+O5/n2+89TbqS9QvQF0I22A8Bo9RwVBQ7QIWQSlC8G8MRhctUEl/E8AkYDCthWpSiVgj/Wcyf514JpuCxnTYECfYp/kwUm33EWCOr+LNAOE8hCRrEXiSWlmzeQtYUCBGUedRrzGIuMGogFecVcpC2Zkarj55A6+HjKYTzKxkPJlQzudUlqFoslYKnFoUwTJf+Uzkz8Cqe3+W1PZbehz0gRCLzvPN0EVDgOW4VJYlQBXQKZlYd3Z2uHHjCfZ2r1CWjkWZ3qZSR+U3iaNJbu/U7EdrOs5iftqi0iBTslJxTTmgNdqNe6+SN0riNKpWI8jkxyS7dpXQ9mgUfIWMaYN9z/UMv/RBdB7P5OMUkS4suPQpSIeUP2vapK8+3Uz6eO+jVSOASzI/7+7u8tRTT/Hs889TjMY470FsZA9MZcb2caEtK2qbeaZz6te5bOJk11RQ52130bLyNY21r4M87aq2gKb528QMiySP3QguO7u7TMaTwJnFMTfApaPvoQtmCHBsi27krOjCgss20SqT7bpPVzs5Jb+L9LCmh380GnHz1i0+8uqr3Lh5K6R7BZAg/jjVKgBSrnzVKD70AcjqRTF8MazzQ+mp1W+papU0moS78JHgVgh4EMWIYqUGGdRVYmPyKtq9coXxZALWRhCLHrqN6z0eAHzQgWMIXYLLllDXwygijEYjIFkymgrh6c4Ozz7/Anfufgg7nrIofYzAKziv1Q7h5sdXXAt0+8jkx49LlZWr5a27CtS6QahbjKPFqVRzBpjkOqTL54k6GDBc2bvGeDKF6AmtUQfURbnKPI33ItDjHOeQYFHPisg/F5EviMjnReQvxOM3ReSXRORL8e8T8biIyN8QkS+LyGdF5KObDuokE3Lek3kSrqXPqpJ/rLWNvpqcjHDl2k2ee+FFrt24hcPg1eB8OKetLQKJawk/XPN4RqdnuaATsPoBhg5ArM5WcxD+y7mSwLkY9YgGDsagVQoRyTkb8YgNitmdK3sUxSic9QngTX+KXIGUz+hxciab3J9O6+Q50RDOpQT+a1V9Ffge4IdF5FXgR4FPquorwCfjb4A/QQhv+Qohuv/f2nRQJ7lx28qOHucG1z4hIZ1I0rtAXGTGUEx3eOHD38G9Z55lNNnBI8xLhyec99SLPF+MfcqM03oQu0S/9LVL/Iu9k+taKqGuBwSrKlDlOJLs2FLRCFhiLGoMk8kOphijUTclsry7fKmjM6BN53xTwNhaa5Gqvqmqvxm/PwS+CDwNfBz4yVjsJ4E/Gb9/HPgpDfRrwA0RuTd0QJtMWq98vuHnOLSJhWrVOPvazBW6iYPJQysEcLHY8Q637z3NM8+/yJXrT6BSUKrgkGCyrRpMf6KOQoIRt08UysfYZUFR+ucgHU8K3S6g6RLDVGvlczxYAWNSuC4DU0vs6boW6rzX6bctxhSjCZjAqXiVsFexaru9NLQCsJM8S311jvPMntazfOdE/NEAABKKSURBVFa0kc5FRF4Avhv4deCuqr4ZT30DuBu/Pw18Pav2Wjw2tI9NxrO2zNAJH6Jw3bTv47KkbbEo36iXHxNjUCmwdsyHP/L7ef6llynGE8QEq5HX6I1ScQw1x2OlfjjbupE8nq6LieOXdD5rHvCutp2rF7hzrhHuM3yhNpuTAKy5s9oYg7Hh+pLWJapxw+90XINoCFL1nTYzzuYLrl27wWgyxaliR6PoK2Ma7nPV/cj+yprb2fWCOAvOYduApIsGg4uIXCHEx/2LqvogP6fhSje6WhH5hIh8SkQ+9fbbb29SdSNad2OPwymdNh2XxfUKXgpG0z2uXr/Jh1/5fdy8/STz0uN8LlrkXIoCjZO9Y+gSR/K3fxpPYwFlos8QGnrtSwAmFk3OgfETXAeTdsXE84JqfT4apxFbYEcjjCmiWCS46I0bytWXU3NGSgf2nAu152moif9x0iBwEZERAVh+WlX/cTz8VhJ34t9vxuOvA89m1Z+JxxqkA5KinQelmzSEzT0r2bWv3aa+Yvm7Al4Mphgz3bvCcy++zDPPvcB0dy/smBZTixUJWNSDj1Yj+sWzdSx417grZesx50nRta+oICIpKjZ+InBoBBU1ESgEB7h0HIllQtYEUxQUo3EMci7RbB+5vMSZVaJaAmPf4KzOk9oi5arz20JDrEUC/F3gi6r617NTvwD8QPz+A8DPZ8f/bLQafQ9wPxOfHjudN8IPtQqtsiDlbTXbNXgxLBRMMeHKteu89PKHufehZ8BYSq/ZOlFicJha1OjSj/boXZbA5RSAtw1cbbGobxyhXLIBRY5FpPqrxiLWgrEQ/6ox2V8TI/mNwxwqeCF67tZq5YxfocK9x8AhnNdL7rRpyN6ifw/4z4F/JSEfEcB/D/xV4B9KyGP0NUJCeoBfBL4P+DJwAPz5IQNJ8vxZU1cf6wDnNMe1qU6poefIjsUfOGdQPEUxZjSZ8vxLL/ONN77Ou998k9n8KCwYwqLV3DdEYngqZal9YKnf9piCXqM+no+Jqq3+a8vb72Lxl+apBTyuSoObRBVLtblRgwNhYkJ8FI0ATBSRgl6qFqMS1+W9x+acSz6AMFn9F3VK1L7+iwImbRqSt+j/pV/S/KMd5RX44U0H0n6oHwedRd+btNfuv60cXBJHVKJYoIi1jMYTbt2+w8uvfJjXf+8rvP7VQ3Qxqxal4kFjYnj1QNg82NVvG9i6QCcHl7RNAa+x2WNwMmhgHzqqKnVA7wAeAVik2jVNtfa9eJx3AWsUvK+BUH0EGyGGsXCo1RhASkLCuQqQq2arORQ9e71L3wtwG9bIJrQ1u6K3iR7XzesCll6uJf4uCot6pVzMGVuDlYJnnnmWV199lYfvvc3733qrbi+zpPRd3zqgqY7TBL98zOp1cKzbpbqSACMt7bpDjSZ0BZzGzYoiFehINCVbYymKcWq4tnQBIobSGPDgvA8Oh5bgtRsBJzbUHGyPmeisn5Wu9ofM6zaAz9aBy+OclC49x0npuDqefEHnb6ycDEJBCCLlnaKmQEXYuXqHD//+j/LaG2/z9rsPmS9m7IwM3i+C/USCtiL6msb262tPwlO1aBFMtMTU/wFS80RJDxMWey2GiUBylRWJPICGYFDWGIwkUBHAImIQsZTeYzC4FHjKWkRsDJ8gFDFDpUhIbpbrqoxI2BEexaMi7hdK5xwF2CJwOmWJsWUsX1AYiYpwwYuJu689RoE4Az53H9rwWRnyPHSJRINEx6z9bbAebR24fLvQkLdLFwfROK+BTVcFMTGxlymQAq7ffpqXPvIH+Prrb/HNN77G3JcYL4yM4tRhRJrKU1nmFOr+YlADTSAk8S3v00CDqiVBkghePa70GEOIK2MkprYOfVoMooaQoin04zUsbEdIAudlFEDFjLCjMdaOoyMhFDrrVJDn2yNUFXUOVAPgxM/IJJd/jzXBSF1qidGgIA9WI4PHRuO1i1sLgr5Kpd6S8bhoGziTdbT14HJWLN6m7Z72OE6lLQlcRci5E7mEGI93PB7z0ksv8623vpPZwQPee/tNxgamxYhyXiK23b9mrL8AIX9PTUFHk4tmPkoQ4WMCgFT6IIJOKNN5GIXkYu81iCKGaNlBMBosYIhlNJkS8jjHdKvFCGuKKsZtUNb2pxBJlBwQ05ynz3w+5/DgEbdsEbiRssRMJu3pfSy0qX5lW8SgNm09uJz2pLVFjfMYx5kBZPwrRqKhJLytjTHY8Zjbd27z4Q+/wttvvsbBg/fQ8ghrRyxkhlfBSsWHVLuIQ6vJQ8GBmqxQHZAKAV/pR6KlJYGRauRUioZuRn0IYGVCjLmQn7kYMxpNotdtiBgn1jAaTREMapJoZvECHk8QoGruJG2RyIGkbb5u6K4UZrMZ9++/z4c0uMy50mFHAVCDaNclViSx7myDCayyFK3SwWwbyGw9uJwVx3CSdjete2Y3XBWNeoDAbMTFJkphDMVozN2n7vHKRz7Ct775Dd564/dYlB5JQaXU03w/NxdhUIK2Hu6UVIxo2Emnk8gUxTTjA+iFtoKuQ43FRsc3KUbY8YhiMmE0nmBt4FCCD0oSTQAf2vAEZaviq+tUTVsLFGOSFTyKaMm3B4NIFB3TeQDnefD+fcqjGZO9UWKFAmglZXLUs9Rm6LO4iZvRqmepz7T/uGjrweWsJuok7W7bmyJTq8ZlER4yI8KNJ57g5Vc+wmu/9zW++Y03eHR0xGRkGRUF4mbLbbVMzGTcUH4MqKwqqoJHkci5JI9ZwWDExE2XBUVRUNigRymKgtFoRDEeBW9iIzhJSljw3kWrtFTKWJV6A6OWPrmiRE40AFK6H8ZIQ6xrWtlgNCp4+OABjx4+ZLJ7hUncX2StpWzboTO3ui4r2aZ0ls/MNjyPibYeXBKd10LepJ+zeFP0OZX1DKACkvRmNRJUpD5aU2wx5sk7d3np5Vf43a98mXfeeiPsAMZCDKjd7AuSRSceybiZik2JZU1lOQoWGoORYNVJgGKMpShGFHYUEryljZg2brw0Nrjqe0ghKMXHqCmJMxJtBOsOf11DgZvmyTlXxeztm1/vPaPJhP0HD3j/3Xd54tYdismYWVliR6OIWNVlxrmur3xbXirr6HGP88KAy0m5haH1NlWenfbN62qv7d9SHQfExIj4mofEDKKCeo+fL5hMpjz7/At86JnnePjgAW5xxMLDJMkPrV0gwaycuJAmqNT3wUTtR9KhFGCKoHi1BUVUwFpT1CJP8oh1ILZAJABLLX4YjBBEo8pqE3dOS23b8l6xLfEtHA9ljTFVkK22mKeqeKeYCezv73P//XdZzBdMJ7CYzxE7QjSF/G758SRHuktgGUQXBlwSHXfCTovLOO0blsdKaYNWn5NaXSb8zUMyVOeMDdaX8YSynPPkk/f4yO97la9/9Ws82ldKVcQFeDAmJWeP7YkJ0dqqRGJBRyNxXw4S8iiNdqYYE0UeG0FEbLT4mOpv2mRIivAmAhicgvGRIzGBA3Lq0ZhZUqru6hdLmDPFuNpnJjZK7a8T2q+tQ805nFjhYH+f6XTKO996h8VixjSavpwrMSZkYFQfQoJ6PEaUQtoaqM1plW9KOt/+nVPX89L3QnrcdOHAJaehlp8lt/kWbcONgPVvm+6HSGu1gEjmQi9hgWORIogkt598ijt373F0dERZLnA+cgppA1IaRzQLGzuK5mBTBasyElNxGIMWoxhXJmwQ9DE4eNJ9Cml7gmQ2qGSNoeFZazCBO9FQRivLeAKWwEnkFqBsFqq/fc9D/nKxgHgfrEaHhxzu77N37QkKiUGlcm/cjIFpcnHHpzZY5rQNHMdp0YUCl7Yr+lCvxQ80RSuHRktI7akSwMWrY2THWAt37n6I5194mTdef5PZvAyiRwSKsOCDD0rSi4xGYddwcOW3jTStCJTWRt+WCCBJ7xmFCpM298SPRh8cVKLXb4jEH5S20ZUugV2lPM2EsmhuRz1DaNVLRYygruTwYJ/33n2XJ+7cw9pRECdNeo6CNa2urtGv+fjLZh032lX+oj7TFwpcVrGBq45vMzX8L7LxD7NIKKqOECwpvuqrjX+hrdIF/YT3cO3GEzz7wot8+jOf4dHhIaaYYm3IiZRAI8TqHdd6C22y6YrgEkcRdSiiNvEgmWla4z6djI2vFMiKUfBqQDRsBkwsgkAKgh2KZkrkxM14QX2Tc2mKRIL6/BhNjsgoI1NQemV2eMQ73/oWz744Z3p1ymIR0o9UviySdj3WIti6mC6rRJ8+/Vlf2fT7Ij7bFwpcPqh04gen7a8iYRFp1JN4hYXzjMc73Ll7jyefusf+o0dMGVFYU8XmTVxK4lxqoIqOYxp3DGlkUEwUbkSj5YZOjhKiJSgZyivxLaSyrTTTcdd2XSn+oxJQJcXB7TCXr5rHZK5Oi9YgFBa8A+8c77//HkdHR0yvXIv6K9+SfhK4RGP/MW5XWxQacs/bnroXjS4kuHTt1L2o6N5FqxR6jXKhcFpaVXmN+heAYjQKizJaaG48cYsXXnyZt9/6Fizu1y77avDRx8SprxcZEJSjtaiVhrSISlURwVjBElJ2mKhTCX51gXsxYZNRNW4TQ1AGyUmRam9T3MagGjcNRqEpcSyqMUrn+jnq4xZEUp3gJLj/4CEH+w/ZvX4DsaPal0VqHEleLsL6hT4UOLrKf1C4FrigSdG6xKOLegPab/rjv6GiyZZg9RAJoRutKaLlJSymnekOzz33AjtXruBVKJ3ifAhh4BSchj1DzmtMB1tnCApJUSUGwZZKneJ92KSYgmCHrIUaF3HEuZR+NUoqqh6jmnE0EajyuSFjEqICxniiGLWa+uYx+Lko6gJ4WWs4PDhkf3+fxdFRpedpm6HTIE7KQbS3JfSNtSGKXkCuBS4o57KKthnpV41tiCw+jJJWAxauxJgisRCULnja3njiCUajMbN5iUiMBJmUuhI2EqbNkJAizwUrUFA/pB3VyZQSXfS9j1xN7TGbACU3CQfrkKK4iCAphEOsU1mKwpUkDk00y32diUIbb8dA8c6hClZGHM7nzGYzFvMFo51ao1LpbESqLQenZDAaRNv8LA8h2QZU/NjHPqaf+tSnHvcwLumSPtAkIr+hqh87t/62AVxE5G1CHN6zotvAt86w/bOmiz5+uPjXcNHHD/ARVb16Xp1thVikqmeaW0REPnWeiH3adNHHDxf/Gi76+CFcw3n2dyEVupd0SZe0/XQJLpd0SZd0JvTtAi4/8bgHcEK66OOHi38NF338cM7XsBUK3Uu6pEv64NG3C+dySZd0SedMl+BySZd0SWdCFx5cRORZEfnnIvIFEfm8iPyFePymiPySiHwp/n0iHhcR+Rsi8mUR+ayIfPTxXgGIyN8TkW+KyOeyY39ZRF4XkU/Hz/dl534sjv+3ReSPPZ5R19Qz/gsz/10kIl8VkX8V5/5T8VjnNW07icgfj8/Kl0XkR8+t4/Zeh4v2Ae4BH43frwL/BngV+J+AH43HfxT4H+P37wP+KcGJ+3uAX9+Ca/he4KPA57Jjfxn4bzrKvgp8BpgALwJfAewWjv/CzH/PNX0VuN061nlN2/whZGH5CvASMI7Pzqvn0feF51xU9U1V/c34/SHwReBp4OPAT8ZiPwn8yfj948BPaaBfA26IyL1zHnaDVPVXgXcHFv848LOqOlPV3wW+DPzBMxvcAOoZ/4WZ/w2o75q2mf4g8GVV/R1VnQM/S7iOM6cLDy45icgLwHcDvw7cVdU346lvAHfj96eBr2fVXovHtpF+JIoOfy9jwS/K+C/6/Cvwz0TkN0TkE/FY3zVtMz22+f7AgIuIXAF+DviLqvogP6eBP7xoNve/BbwMfBfwJvDXHu9wjk8XdP7/kKp+FPgTwA+LyPfmJy/oNZ0rfSDARURGBGD5aVX9x/HwW4ndjn+/GY+/DjybVX8mHtsqUtW3VNVpCHjyd6hFnwsxfi7+/L8e/34T+CeE+e+7pm2mxzbfFx5cJAS8+LvAF1X1r2enfgH4gfj9B4Cfz47/2Wi1+B7gfsbqbg219BB/CkiWmF8Avl9EJiLyIvAK8C/Pe3wD6MLOv4jsicjV9B34jwjz33dN20z/H/CKiLwoImPg+wnXcfb0uLXZp6AN/0ME9vSzwKfj5/uAW8AngS8B/xdwM5YX4H8laND/FfCxLbiGnyGIPguCTPyDwP8ex/fZ+DDcy8r/eBz/bwN/YkvHf2Hmv+N6XiJYVT4DfB748Xi885q2/RPXw7+Jc/7j59Xvpfv/JV3SJZ0JXXix6JIu6ZK2ky7B5ZIu6ZLOhC7B5ZIu6ZLOhC7B5ZIu6ZLOhC7B5ZIu6ZLOhC7B5ZIu6ZLOhC7B5ZIu6ZLOhP5/HMe6/VmY2SEAAAAASUVORK5CYII=\n","text/plain":["<Figure size 432x288 with 1 Axes>"]},"metadata":{"tags":[],"needs_background":"light"}}],"execution_count":null},{"cell_type":"markdown","source":"## Save the Entire Model\n\nWe can save the entire model as follows:","metadata":{"id":"gGVIM5jX2Z5b"}},{"cell_type":"code","source":"torch.save(model, '/content/model.pt')","metadata":{"id":"x4S-BcSI2v88"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Export Trained Model\n\nNow that you have trained your custom vision transformer, you can export the trained model you have made here for inference on your device elsewhere","metadata":{"id":"aeJ99BfV9QRo"}},{"cell_type":"code","source":"from google.colab import drive\ndrive.mount('/content/gdrive')\n\n%cp /content/model.pt /content/gdrive/My\\ Drive","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"gFmfiH0Z3QJb","outputId":"2351b3dd-4ced-4300-f13c-18c740b12a11"},"outputs":[{"output_type":"stream","text":["Mounted at /content/gdrive\n"],"name":"stdout"}],"execution_count":null},{"cell_type":"markdown","source":"## Use your Exported Model","metadata":{"id":"ORZKpeH1REHP"}},{"cell_type":"code","source":"MODEL_PATH = '/content/model.pt'\nmodel = torch.load(MODEL_PATH)\nmodel.eval()","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"rS706FbORDiO","outputId":"74fb0815-f1dd-463c-b012-3cfa546cbd08"},"outputs":[{"output_type":"execute_result","data":{"text/plain":["ViTForImageClassification(\n","  (vit): ViTModel(\n","    (embeddings): ViTEmbeddings(\n","      (patch_embeddings): PatchEmbeddings(\n","        (projection): Conv2d(3, 768, kernel_size=(16, 16), stride=(16, 16))\n","      )\n","      (dropout): Dropout(p=0.0, inplace=False)\n","    )\n","    (encoder): ViTEncoder(\n","      (layer): ModuleList(\n","        (0): ViTLayer(\n","          (attention): ViTAttention(\n","            (attention): ViTSelfAttention(\n","              (query): Linear(in_features=768, out_features=768, bias=True)\n","              (key): Linear(in_features=768, out_features=768, bias=True)\n","              (value): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","            (output): ViTSelfOutput(\n","              (dense): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","          )\n","          (intermediate): ViTIntermediate(\n","            (dense): Linear(in_features=768, out_features=3072, bias=True)\n","          )\n","          (output): ViTOutput(\n","            (dense): Linear(in_features=3072, out_features=768, bias=True)\n","            (dropout): Dropout(p=0.0, inplace=False)\n","          )\n","          (layernorm_before): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","          (layernorm_after): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","        )\n","        (1): ViTLayer(\n","          (attention): ViTAttention(\n","            (attention): ViTSelfAttention(\n","              (query): Linear(in_features=768, out_features=768, bias=True)\n","              (key): Linear(in_features=768, out_features=768, bias=True)\n","              (value): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","            (output): ViTSelfOutput(\n","              (dense): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","          )\n","          (intermediate): ViTIntermediate(\n","            (dense): Linear(in_features=768, out_features=3072, bias=True)\n","          )\n","          (output): ViTOutput(\n","            (dense): Linear(in_features=3072, out_features=768, bias=True)\n","            (dropout): Dropout(p=0.0, inplace=False)\n","          )\n","          (layernorm_before): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","          (layernorm_after): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","        )\n","        (2): ViTLayer(\n","          (attention): ViTAttention(\n","            (attention): ViTSelfAttention(\n","              (query): Linear(in_features=768, out_features=768, bias=True)\n","              (key): Linear(in_features=768, out_features=768, bias=True)\n","              (value): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","            (output): ViTSelfOutput(\n","              (dense): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","          )\n","          (intermediate): ViTIntermediate(\n","            (dense): Linear(in_features=768, out_features=3072, bias=True)\n","          )\n","          (output): ViTOutput(\n","            (dense): Linear(in_features=3072, out_features=768, bias=True)\n","            (dropout): Dropout(p=0.0, inplace=False)\n","          )\n","          (layernorm_before): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","          (layernorm_after): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","        )\n","        (3): ViTLayer(\n","          (attention): ViTAttention(\n","            (attention): ViTSelfAttention(\n","              (query): Linear(in_features=768, out_features=768, bias=True)\n","              (key): Linear(in_features=768, out_features=768, bias=True)\n","              (value): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","            (output): ViTSelfOutput(\n","              (dense): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","          )\n","          (intermediate): ViTIntermediate(\n","            (dense): Linear(in_features=768, out_features=3072, bias=True)\n","          )\n","          (output): ViTOutput(\n","            (dense): Linear(in_features=3072, out_features=768, bias=True)\n","            (dropout): Dropout(p=0.0, inplace=False)\n","          )\n","          (layernorm_before): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","          (layernorm_after): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","        )\n","        (4): ViTLayer(\n","          (attention): ViTAttention(\n","            (attention): ViTSelfAttention(\n","              (query): Linear(in_features=768, out_features=768, bias=True)\n","              (key): Linear(in_features=768, out_features=768, bias=True)\n","              (value): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","            (output): ViTSelfOutput(\n","              (dense): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","          )\n","          (intermediate): ViTIntermediate(\n","            (dense): Linear(in_features=768, out_features=3072, bias=True)\n","          )\n","          (output): ViTOutput(\n","            (dense): Linear(in_features=3072, out_features=768, bias=True)\n","            (dropout): Dropout(p=0.0, inplace=False)\n","          )\n","          (layernorm_before): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","          (layernorm_after): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","        )\n","        (5): ViTLayer(\n","          (attention): ViTAttention(\n","            (attention): ViTSelfAttention(\n","              (query): Linear(in_features=768, out_features=768, bias=True)\n","              (key): Linear(in_features=768, out_features=768, bias=True)\n","              (value): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","            (output): ViTSelfOutput(\n","              (dense): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","          )\n","          (intermediate): ViTIntermediate(\n","            (dense): Linear(in_features=768, out_features=3072, bias=True)\n","          )\n","          (output): ViTOutput(\n","            (dense): Linear(in_features=3072, out_features=768, bias=True)\n","            (dropout): Dropout(p=0.0, inplace=False)\n","          )\n","          (layernorm_before): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","          (layernorm_after): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","        )\n","        (6): ViTLayer(\n","          (attention): ViTAttention(\n","            (attention): ViTSelfAttention(\n","              (query): Linear(in_features=768, out_features=768, bias=True)\n","              (key): Linear(in_features=768, out_features=768, bias=True)\n","              (value): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","            (output): ViTSelfOutput(\n","              (dense): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","          )\n","          (intermediate): ViTIntermediate(\n","            (dense): Linear(in_features=768, out_features=3072, bias=True)\n","          )\n","          (output): ViTOutput(\n","            (dense): Linear(in_features=3072, out_features=768, bias=True)\n","            (dropout): Dropout(p=0.0, inplace=False)\n","          )\n","          (layernorm_before): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","          (layernorm_after): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","        )\n","        (7): ViTLayer(\n","          (attention): ViTAttention(\n","            (attention): ViTSelfAttention(\n","              (query): Linear(in_features=768, out_features=768, bias=True)\n","              (key): Linear(in_features=768, out_features=768, bias=True)\n","              (value): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","            (output): ViTSelfOutput(\n","              (dense): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","          )\n","          (intermediate): ViTIntermediate(\n","            (dense): Linear(in_features=768, out_features=3072, bias=True)\n","          )\n","          (output): ViTOutput(\n","            (dense): Linear(in_features=3072, out_features=768, bias=True)\n","            (dropout): Dropout(p=0.0, inplace=False)\n","          )\n","          (layernorm_before): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","          (layernorm_after): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","        )\n","        (8): ViTLayer(\n","          (attention): ViTAttention(\n","            (attention): ViTSelfAttention(\n","              (query): Linear(in_features=768, out_features=768, bias=True)\n","              (key): Linear(in_features=768, out_features=768, bias=True)\n","              (value): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","            (output): ViTSelfOutput(\n","              (dense): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","          )\n","          (intermediate): ViTIntermediate(\n","            (dense): Linear(in_features=768, out_features=3072, bias=True)\n","          )\n","          (output): ViTOutput(\n","            (dense): Linear(in_features=3072, out_features=768, bias=True)\n","            (dropout): Dropout(p=0.0, inplace=False)\n","          )\n","          (layernorm_before): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","          (layernorm_after): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","        )\n","        (9): ViTLayer(\n","          (attention): ViTAttention(\n","            (attention): ViTSelfAttention(\n","              (query): Linear(in_features=768, out_features=768, bias=True)\n","              (key): Linear(in_features=768, out_features=768, bias=True)\n","              (value): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","            (output): ViTSelfOutput(\n","              (dense): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","          )\n","          (intermediate): ViTIntermediate(\n","            (dense): Linear(in_features=768, out_features=3072, bias=True)\n","          )\n","          (output): ViTOutput(\n","            (dense): Linear(in_features=3072, out_features=768, bias=True)\n","            (dropout): Dropout(p=0.0, inplace=False)\n","          )\n","          (layernorm_before): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","          (layernorm_after): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","        )\n","        (10): ViTLayer(\n","          (attention): ViTAttention(\n","            (attention): ViTSelfAttention(\n","              (query): Linear(in_features=768, out_features=768, bias=True)\n","              (key): Linear(in_features=768, out_features=768, bias=True)\n","              (value): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","            (output): ViTSelfOutput(\n","              (dense): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","          )\n","          (intermediate): ViTIntermediate(\n","            (dense): Linear(in_features=768, out_features=3072, bias=True)\n","          )\n","          (output): ViTOutput(\n","            (dense): Linear(in_features=3072, out_features=768, bias=True)\n","            (dropout): Dropout(p=0.0, inplace=False)\n","          )\n","          (layernorm_before): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","          (layernorm_after): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","        )\n","        (11): ViTLayer(\n","          (attention): ViTAttention(\n","            (attention): ViTSelfAttention(\n","              (query): Linear(in_features=768, out_features=768, bias=True)\n","              (key): Linear(in_features=768, out_features=768, bias=True)\n","              (value): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","            (output): ViTSelfOutput(\n","              (dense): Linear(in_features=768, out_features=768, bias=True)\n","              (dropout): Dropout(p=0.0, inplace=False)\n","            )\n","          )\n","          (intermediate): ViTIntermediate(\n","            (dense): Linear(in_features=768, out_features=3072, bias=True)\n","          )\n","          (output): ViTOutput(\n","            (dense): Linear(in_features=3072, out_features=768, bias=True)\n","            (dropout): Dropout(p=0.0, inplace=False)\n","          )\n","          (layernorm_before): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","          (layernorm_after): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","        )\n","      )\n","    )\n","    (layernorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n","    (pooler): ViTPooler(\n","      (dense): Linear(in_features=768, out_features=768, bias=True)\n","      (activation): Tanh()\n","    )\n","  )\n","  (dropout): Dropout(p=0.1, inplace=False)\n","  (classifier): Linear(in_features=768, out_features=3, bias=True)\n",")"]},"metadata":{"tags":[]},"execution_count":11}],"execution_count":null}]}