{"metadata":{"accelerator":"GPU","colab":{"provenance":[]},"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"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":1789966,"sourceType":"datasetVersion","datasetId":1063627},{"sourceId":6041428,"sourceType":"datasetVersion","datasetId":3454349},{"sourceId":7494590,"sourceType":"datasetVersion","datasetId":4363922}],"dockerImageVersionId":30636,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Importing the important libraries","metadata":{"id":"6ab2e043-e257-4956-b4b8-58dcc4d77fd3"}},{"cell_type":"markdown","source":"**tensorFlow (tf):**\ntensorFlow is a powerful open-source library for numerical computation and machine learning. It provides a symbolic math library and tools for building and training neural networks. TensorFlow is particularly useful for building and deploying large-scale machine learning models.\n**pandas (pd):**\npandas is a popular library for data analysis and manipulation in Python. It provides data structures and operations for manipulating numerical tables and time series. pandas is particularly useful for cleaning, transforming, and analyzing data.\n**matplotlib (plt):**\nmatplotlib is a comprehensive library for creating static, animated, and interactive visualizations in Python. It provides a variety of plotting options, including line plots, scatter plots, histograms, and bar charts. Matplotlib is commonly used for data visualization and exploration.\n**numpy (np):**\nnumpy is a fundamental library for scientific computing in Python. It provides a powerful N-dimensional array object and useful linear algebra, Fourier transform, and random number capabilities. NumPy is often used for numerical operations and data manipulation.\n**json:**\njson (JavaScript Object Notation) is a popular data interchange format. It is often used to represent structured data in a human-readable format. In Python, the JSON module provides functions for encoding and decoding JSON data.\n**platform:**\nThe platform module provides information about the underlying platform on which the Python interpreter is running. It provides functions for getting system-specific information such as the operating system name, version, and architecture.\n**time:**\nThe time module provides various functions for working with time. It allows you to get the current time, measure execution time, and create delays.\n**pathlib:**\nThe pathlib module provides an object-oriented interface for working with file paths. It simplifies working with file and directory paths, making it easier to manipulate and navigate the file system.\n**os:**\nThe os module provides a portable way to use operating system-dependent functionality. It provides functions for creating and removing directories, listing files, and interacting with the file system.\nBy importing these libraries, the code snippet gains access to a wide range of functionalities for numerical computation, data analysis, visualization, and system interaction.\n**re:**\nThe re module is a powerful tool for working with regular expressions in Python. It can be used to perform a variety of tasks, including matching, searching, and replacing strings based on regular expression patterns.","metadata":{"id":"5ad3632a-2e01-492c-925e-8254490246e5"}},{"cell_type":"code","source":"# Packages for training the model and working with the dataset.\nimport tensorflow as tf\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport json\n\n# Utility/helper packages.\nimport platform\nimport time\nimport pathlib\nimport os\nimport re","metadata":{"id":"a8292b09-5a39-46aa-8d69-cfecbac3a418","execution":{"iopub.status.busy":"2024-04-27T15:54:00.988869Z","iopub.execute_input":"2024-04-27T15:54:00.989222Z","iopub.status.idle":"2024-04-27T15:54:13.024830Z","shell.execute_reply.started":"2024-04-27T15:54:00.989195Z","shell.execute_reply":"2024-04-27T15:54:13.023870Z"},"trusted":true},"execution_count":1,"outputs":[{"name":"stderr","text":"/opt/conda/lib/python3.10/site-packages/scipy/__init__.py:146: UserWarning: A NumPy version >=1.16.5 and <1.23.0 is required for this version of SciPy (detected version 1.24.3\n warnings.warn(f\"A NumPy version >={np_minversion} and <{np_maxversion}\"\n","output_type":"stream"}]},{"cell_type":"markdown","source":"# Read The Dataset","metadata":{"id":"0be1eef6-c94a-4a5f-a4bc-0e8f38100062"}},{"cell_type":"markdown","source":"1. **Defining the Data Directory**:\n - The code defines a variable called `data_dir` and assigns it the value `r'G:/College/Graduation Project/Dataset'`. This variable specifies the directory where the data file is locat\n2. **Constructing the File Path**:\n - The code constructs the full path to the data file by concatenating the `data_dir` variable with the file name `'Recipes.xlsx'`. This results in the variable `file_name` containing the complete path to the Excel e.\n3. **Reading the Excel File**:\n - The code uses the `pd.read_excel()` function to read the Excel file specified by the `file_name` variable. This function loads the data from the Excel file into a Pandas DataFrame, which is a tabular data structure. The resulting DataFrame is stored in the variable `dataseaw`.\n4. **Displaying the First 25 Rows**:\n - Finally, the code uses the `head()` method on the `dataset_raw` DataFrame to display the first 25 rows of the data. This provides a preview of the data contained in the Exf the data.","metadata":{"id":"fad5dc45-89eb-4c44-b57e-d76085254c20"}},{"cell_type":"code","source":"dataset_raw = pd.read_csv(r'/kaggle/input/recipe-dataset-over-2m/recipes_data.csv')\ndataset_raw = dataset_raw [:75000]\ndataset_raw.head(25)","metadata":{"id":"8152512b-7b74-4d10-8e6e-3e4c49fea001","outputId":"cf416071-8877-47dc-9970-7d7e1f1fcdee","execution":{"iopub.status.busy":"2024-04-27T15:54:13.027132Z","iopub.execute_input":"2024-04-27T15:54:13.028164Z","iopub.status.idle":"2024-04-27T15:55:01.910031Z","shell.execute_reply.started":"2024-04-27T15:54:13.028126Z","shell.execute_reply":"2024-04-27T15:55:01.908970Z"},"trusted":true},"execution_count":2,"outputs":[{"execution_count":2,"output_type":"execute_result","data":{"text/plain":" title \\\n0 No-Bake Nut Cookies \n1 Jewell Ball'S Chicken \n2 Creamy Corn \n3 Chicken Funny \n4 Reeses Cups(Candy) \n5 Cheeseburger Potato Soup \n6 Rhubarb Coffee Cake \n7 Scalloped Corn \n8 Nolan'S Pepper Steak \n9 Millionaire Pie \n10 Double Cherry Delight \n11 Buckeye Candy \n12 Quick Barbecue Wings \n13 Taco Salad Chip Dip \n14 Pink Stuff(Frozen Dessert) \n15 Fresh Strawberry Pie \n16 Easy German Chocolate Cake \n17 Broccoli Salad \n18 Strawberry Whatever \n19 Eggless Milkless Applesauce Cake \n20 Grandma Hanrath'S Banana Breadfort Collins, Co... \n21 Chocolate Frango Mints \n22 Cuddy Farms Marinated Turkey \n23 Spaghetti Sauce To Can \n24 Prize-Winning Meat Loaf \n\n ingredients \\\n0 [\"1 c. firmly packed brown sugar\", \"1/2 c. eva... \n1 [\"1 small jar chipped beef, cut up\", \"4 boned ... \n2 [\"2 (16 oz.) pkg. frozen corn\", \"1 (8 oz.) pkg... \n3 [\"1 large whole chicken\", \"2 (10 1/2 oz.) cans... \n4 [\"1 c. peanut butter\", \"3/4 c. graham cracker ... \n5 [\"6 baking potatoes\", \"1 lb. of extra lean gro... \n6 [\"1 1/2 c. sugar\", \"1/2 c. butter\", \"1 egg\", \"... \n7 [\"1 can cream-style corn\", \"1 can whole kernel... \n8 [\"1 1/2 lb. round steak (1-inch thick), cut in... \n9 [\"1 large container Cool Whip\", \"1 large can c... \n10 [\"1 (17 oz.) can dark sweet pitted cherries\", ... \n11 [\"1 box powdered sugar\", \"8 oz. soft butter\", ... \n12 [\"chicken wings (as many as you need for dinne... \n13 [\"8 oz. Ortega taco sauce\", \"8 oz. sour cream\"... \n14 [\"1 can pie filling (cherry or strawberry)\", \"... \n15 [\"1 baked pie shell\", \"1 qt. cleaned strawberr... \n16 [\"1/2 pkg. chocolate fudge cake mix without pu... \n17 [\"1 large head broccoli (about 1 1/2 lb.)\", \"1... \n18 [\"1 lb. frozen strawberries in juice\", \"1 smal... \n19 [\"3/4 c. sugar\", \"1/2 c. shortening\", \"1 1/2 c... \n20 [\"1 c. sugar\", \"1/2 c. shortening\", \"2 eggs (a... \n21 [\"1 pkg. devil's food cake mix\", \"1 pkg. choco... \n22 [\"2 c. 7-Up or Sprite\", \"1 c. vegetable oil\", ... \n23 [\"1/2 bushel tomatoes\", \"1 c. oil\", \"1/4 c. mi... \n24 [\"1 1/2 lb. ground beef\", \"1 c. tomato juice\",... \n\n directions \\\n0 [\"In a heavy 2-quart saucepan, mix brown sugar... \n1 [\"Place chipped beef on bottom of baking dish.... \n2 [\"In a slow cooker, combine all ingredients. C... \n3 [\"Boil and debone chicken.\", \"Put bite size pi... \n4 [\"Combine first four ingredients and press in ... \n5 [\"Wash potatoes; prick several times with a fo... \n6 [\"Cream sugar and butter.\", \"Add egg and beat ... \n7 [\"Mix together both cans of corn, crackers, eg... \n8 [\"Roll steak strips in flour.\", \"Brown in skil... \n9 [\"Empty Cool Whip into a bowl.\", \"Drain juice ... \n10 [\"Drain cherries, measuring syrup.\", \"Cut cher... \n11 [\"Mix sugar, butter and peanut butter.\", \"Roll... \n12 [\"Clean wings.\", \"Flour and fry until done.\", ... \n13 [\"Mix taco sauce, sour cream and cream cheese.... \n14 [\"Mix all ingredients together.\", \"Pour into a... \n15 [\"Mix water, cornstarch, sugar and salt in sau... \n16 [\"Mix according to directions and add oil.\", \"... \n17 [\"Trim off large leaves of broccoli and remove... \n18 [\"Mix Jell-O in boiling water.\", \"Add strawber... \n19 [\"Mix Crisco with applesauce, nuts and raisins... \n20 [\"Cream sugar and shortening.\", \"Add eggs, sal... \n21 [\"Mix ingredients together for 5 minutes.\", \"S... \n22 [\"Buy whole turkey breast; remove all skin and... \n23 [\"Cook ground or chopped peppers and onions in... \n24 [\"Mix well.\", \"Press firmly into an 8 1/2 x 4 ... \n\n link source \\\n0 www.cookbooks.com/Recipe-Details.aspx?id=44874 Gathered \n1 www.cookbooks.com/Recipe-Details.aspx?id=699419 Gathered \n2 www.cookbooks.com/Recipe-Details.aspx?id=10570 Gathered \n3 www.cookbooks.com/Recipe-Details.aspx?id=897570 Gathered \n4 www.cookbooks.com/Recipe-Details.aspx?id=659239 Gathered \n5 www.cookbooks.com/Recipe-Details.aspx?id=20115 Gathered \n6 www.cookbooks.com/Recipe-Details.aspx?id=210288 Gathered \n7 www.cookbooks.com/Recipe-Details.aspx?id=876969 Gathered \n8 www.cookbooks.com/Recipe-Details.aspx?id=375254 Gathered \n9 www.cookbooks.com/Recipe-Details.aspx?id=794547 Gathered \n10 www.cookbooks.com/Recipe-Details.aspx?id=703381 Gathered \n11 www.cookbooks.com/Recipe-Details.aspx?id=886785 Gathered \n12 www.cookbooks.com/Recipe-Details.aspx?id=768311 Gathered \n13 www.cookbooks.com/Recipe-Details.aspx?id=806409 Gathered \n14 www.cookbooks.com/Recipe-Details.aspx?id=982483 Gathered \n15 www.cookbooks.com/Recipe-Details.aspx?id=161321 Gathered \n16 www.cookbooks.com/Recipe-Details.aspx?id=983179 Gathered \n17 www.cookbooks.com/Recipe-Details.aspx?id=50992 Gathered \n18 www.cookbooks.com/Recipe-Details.aspx?id=718063 Gathered \n19 www.cookbooks.com/Recipe-Details.aspx?id=343158 Gathered \n20 www.cookbooks.com/Recipe-Details.aspx?id=1072247 Gathered \n21 www.cookbooks.com/Recipe-Details.aspx?id=958474 Gathered \n22 www.cookbooks.com/Recipe-Details.aspx?id=9449 Gathered \n23 www.cookbooks.com/Recipe-Details.aspx?id=1059279 Gathered \n24 www.cookbooks.com/Recipe-Details.aspx?id=923674 Gathered \n\n NER site \n0 [\"bite size shredded rice biscuits\", \"vanilla\"... www.cookbooks.com \n1 [\"cream of mushroom soup\", \"beef\", \"sour cream... www.cookbooks.com \n2 [\"frozen corn\", \"pepper\", \"cream cheese\", \"gar... www.cookbooks.com \n3 [\"chicken gravy\", \"cream of mushroom soup\", \"c... www.cookbooks.com \n4 [\"graham cracker crumbs\", \"powdered sugar\", \"p... www.cookbooks.com \n5 [\"sour cream\", \"bacon\", \"pepper\", \"extra lean ... www.cookbooks.com \n6 [\"buttermilk\", \"egg\", \"sugar\", \"vanilla\", \"sod... www.cookbooks.com \n7 [\"egg\", \"pepper\", \"crackers\", \"cream-style cor... www.cookbooks.com \n8 [\"oil\", \"tomatoes\", \"green peppers\", \"water\", ... www.cookbooks.com \n9 [\"condensed milk\", \"lemons\", \"graham cracker c... www.cookbooks.com \n10 [\"flavor gelatin\", \"dark sweet pitted cherries... www.cookbooks.com \n11 [\"paraffin\", \"powdered sugar\", \"peanut butter\"... www.cookbooks.com \n12 [\"flour\", \"chicken\", \"barbecue sauce\"] www.cookbooks.com \n13 [\"sour cream\", \"tomato\", \"shredded lettuce\", \"... www.cookbooks.com \n14 [\"condensed milk\", \"pie filling\", \"pineapple\",... www.cookbooks.com \n15 [\"sugar\", \"shell\", \"water\", \"cleaned strawberr... www.cookbooks.com \n16 [\"chocolate fudge cake\", \"white cake\", \"wesson... www.cookbooks.com \n17 [\"bacon\", \"vinegar\", \"sugar\", \"green onions\", ... www.cookbooks.com \n18 [\"sour cream\", \"frozen strawberries\", \"strawbe... www.cookbooks.com \n19 [\"sugar\", \"shortening\", \"cinnamon\", \"soda\", \"a... www.cookbooks.com \n20 [\"sugar\", \"shortening\", \"eggs\", \"soda\", \"banan... www.cookbooks.com \n21 [\"sour cream\", \"frango\", \"cake mix\", \"eggs\", \"... www.cookbooks.com \n22 [\"garlic\", \"vegetable oil\", \"soy sauce\"] www.cookbooks.com \n23 [\"oil\", \"oregano\", \"sugar\", \"tomatoes\", \"tomat... www.cookbooks.com \n24 [\"egg\", \"tomato juice\", \"pepper\", \"oats\", \"oni... www.cookbooks.com ","text/html":"
\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
titleingredientsdirectionslinksourceNERsite
0No-Bake Nut Cookies[\"1 c. firmly packed brown sugar\", \"1/2 c. eva...[\"In a heavy 2-quart saucepan, mix brown sugar...www.cookbooks.com/Recipe-Details.aspx?id=44874Gathered[\"bite size shredded rice biscuits\", \"vanilla\"...www.cookbooks.com
1Jewell Ball'S Chicken[\"1 small jar chipped beef, cut up\", \"4 boned ...[\"Place chipped beef on bottom of baking dish....www.cookbooks.com/Recipe-Details.aspx?id=699419Gathered[\"cream of mushroom soup\", \"beef\", \"sour cream...www.cookbooks.com
2Creamy Corn[\"2 (16 oz.) pkg. frozen corn\", \"1 (8 oz.) pkg...[\"In a slow cooker, combine all ingredients. C...www.cookbooks.com/Recipe-Details.aspx?id=10570Gathered[\"frozen corn\", \"pepper\", \"cream cheese\", \"gar...www.cookbooks.com
3Chicken Funny[\"1 large whole chicken\", \"2 (10 1/2 oz.) cans...[\"Boil and debone chicken.\", \"Put bite size pi...www.cookbooks.com/Recipe-Details.aspx?id=897570Gathered[\"chicken gravy\", \"cream of mushroom soup\", \"c...www.cookbooks.com
4Reeses Cups(Candy)[\"1 c. peanut butter\", \"3/4 c. graham cracker ...[\"Combine first four ingredients and press in ...www.cookbooks.com/Recipe-Details.aspx?id=659239Gathered[\"graham cracker crumbs\", \"powdered sugar\", \"p...www.cookbooks.com
5Cheeseburger Potato Soup[\"6 baking potatoes\", \"1 lb. of extra lean gro...[\"Wash potatoes; prick several times with a fo...www.cookbooks.com/Recipe-Details.aspx?id=20115Gathered[\"sour cream\", \"bacon\", \"pepper\", \"extra lean ...www.cookbooks.com
6Rhubarb Coffee Cake[\"1 1/2 c. sugar\", \"1/2 c. butter\", \"1 egg\", \"...[\"Cream sugar and butter.\", \"Add egg and beat ...www.cookbooks.com/Recipe-Details.aspx?id=210288Gathered[\"buttermilk\", \"egg\", \"sugar\", \"vanilla\", \"sod...www.cookbooks.com
7Scalloped Corn[\"1 can cream-style corn\", \"1 can whole kernel...[\"Mix together both cans of corn, crackers, eg...www.cookbooks.com/Recipe-Details.aspx?id=876969Gathered[\"egg\", \"pepper\", \"crackers\", \"cream-style cor...www.cookbooks.com
8Nolan'S Pepper Steak[\"1 1/2 lb. round steak (1-inch thick), cut in...[\"Roll steak strips in flour.\", \"Brown in skil...www.cookbooks.com/Recipe-Details.aspx?id=375254Gathered[\"oil\", \"tomatoes\", \"green peppers\", \"water\", ...www.cookbooks.com
9Millionaire Pie[\"1 large container Cool Whip\", \"1 large can c...[\"Empty Cool Whip into a bowl.\", \"Drain juice ...www.cookbooks.com/Recipe-Details.aspx?id=794547Gathered[\"condensed milk\", \"lemons\", \"graham cracker c...www.cookbooks.com
10Double Cherry Delight[\"1 (17 oz.) can dark sweet pitted cherries\", ...[\"Drain cherries, measuring syrup.\", \"Cut cher...www.cookbooks.com/Recipe-Details.aspx?id=703381Gathered[\"flavor gelatin\", \"dark sweet pitted cherries...www.cookbooks.com
11Buckeye Candy[\"1 box powdered sugar\", \"8 oz. soft butter\", ...[\"Mix sugar, butter and peanut butter.\", \"Roll...www.cookbooks.com/Recipe-Details.aspx?id=886785Gathered[\"paraffin\", \"powdered sugar\", \"peanut butter\"...www.cookbooks.com
12Quick Barbecue Wings[\"chicken wings (as many as you need for dinne...[\"Clean wings.\", \"Flour and fry until done.\", ...www.cookbooks.com/Recipe-Details.aspx?id=768311Gathered[\"flour\", \"chicken\", \"barbecue sauce\"]www.cookbooks.com
13Taco Salad Chip Dip[\"8 oz. Ortega taco sauce\", \"8 oz. sour cream\"...[\"Mix taco sauce, sour cream and cream cheese....www.cookbooks.com/Recipe-Details.aspx?id=806409Gathered[\"sour cream\", \"tomato\", \"shredded lettuce\", \"...www.cookbooks.com
14Pink Stuff(Frozen Dessert)[\"1 can pie filling (cherry or strawberry)\", \"...[\"Mix all ingredients together.\", \"Pour into a...www.cookbooks.com/Recipe-Details.aspx?id=982483Gathered[\"condensed milk\", \"pie filling\", \"pineapple\",...www.cookbooks.com
15Fresh Strawberry Pie[\"1 baked pie shell\", \"1 qt. cleaned strawberr...[\"Mix water, cornstarch, sugar and salt in sau...www.cookbooks.com/Recipe-Details.aspx?id=161321Gathered[\"sugar\", \"shell\", \"water\", \"cleaned strawberr...www.cookbooks.com
16Easy German Chocolate Cake[\"1/2 pkg. chocolate fudge cake mix without pu...[\"Mix according to directions and add oil.\", \"...www.cookbooks.com/Recipe-Details.aspx?id=983179Gathered[\"chocolate fudge cake\", \"white cake\", \"wesson...www.cookbooks.com
17Broccoli Salad[\"1 large head broccoli (about 1 1/2 lb.)\", \"1...[\"Trim off large leaves of broccoli and remove...www.cookbooks.com/Recipe-Details.aspx?id=50992Gathered[\"bacon\", \"vinegar\", \"sugar\", \"green onions\", ...www.cookbooks.com
18Strawberry Whatever[\"1 lb. frozen strawberries in juice\", \"1 smal...[\"Mix Jell-O in boiling water.\", \"Add strawber...www.cookbooks.com/Recipe-Details.aspx?id=718063Gathered[\"sour cream\", \"frozen strawberries\", \"strawbe...www.cookbooks.com
19Eggless Milkless Applesauce Cake[\"3/4 c. sugar\", \"1/2 c. shortening\", \"1 1/2 c...[\"Mix Crisco with applesauce, nuts and raisins...www.cookbooks.com/Recipe-Details.aspx?id=343158Gathered[\"sugar\", \"shortening\", \"cinnamon\", \"soda\", \"a...www.cookbooks.com
20Grandma Hanrath'S Banana Breadfort Collins, Co...[\"1 c. sugar\", \"1/2 c. shortening\", \"2 eggs (a...[\"Cream sugar and shortening.\", \"Add eggs, sal...www.cookbooks.com/Recipe-Details.aspx?id=1072247Gathered[\"sugar\", \"shortening\", \"eggs\", \"soda\", \"banan...www.cookbooks.com
21Chocolate Frango Mints[\"1 pkg. devil's food cake mix\", \"1 pkg. choco...[\"Mix ingredients together for 5 minutes.\", \"S...www.cookbooks.com/Recipe-Details.aspx?id=958474Gathered[\"sour cream\", \"frango\", \"cake mix\", \"eggs\", \"...www.cookbooks.com
22Cuddy Farms Marinated Turkey[\"2 c. 7-Up or Sprite\", \"1 c. vegetable oil\", ...[\"Buy whole turkey breast; remove all skin and...www.cookbooks.com/Recipe-Details.aspx?id=9449Gathered[\"garlic\", \"vegetable oil\", \"soy sauce\"]www.cookbooks.com
23Spaghetti Sauce To Can[\"1/2 bushel tomatoes\", \"1 c. oil\", \"1/4 c. mi...[\"Cook ground or chopped peppers and onions in...www.cookbooks.com/Recipe-Details.aspx?id=1059279Gathered[\"oil\", \"oregano\", \"sugar\", \"tomatoes\", \"tomat...www.cookbooks.com
24Prize-Winning Meat Loaf[\"1 1/2 lb. ground beef\", \"1 c. tomato juice\",...[\"Mix well.\", \"Press firmly into an 8 1/2 x 4 ...www.cookbooks.com/Recipe-Details.aspx?id=923674Gathered[\"egg\", \"tomato juice\", \"pepper\", \"oats\", \"oni...www.cookbooks.com
\n
"},"metadata":{}}]},{"cell_type":"markdown","source":"**Calling the `info()` Method**:\n - The `info()` method is called on the `dataset_raw` DataFrame. This method provides concise summary information about the DataFrame, including the number of rows, columns, data types, and memory usa\n**Displaying the DataFrame Information**:\n - The output of the `info()` method is displayed, providing insights into the structure and contents of the DataFrame. This information can be useful for understanding the data and making informed decisions about further processing or ana","metadata":{"id":"defbfb93-7eae-4f5a-b9e3-d6f779f1ee35"}},{"cell_type":"code","source":"dataset_raw.info()","metadata":{"id":"5ce82336-c095-4d95-9cc9-ec58914cea3c","outputId":"623fffc3-4b80-453c-8945-29be282101cb","execution":{"iopub.status.busy":"2024-04-27T15:55:01.911201Z","iopub.execute_input":"2024-04-27T15:55:01.911482Z","iopub.status.idle":"2024-04-27T15:55:01.988408Z","shell.execute_reply.started":"2024-04-27T15:55:01.911457Z","shell.execute_reply":"2024-04-27T15:55:01.987465Z"},"trusted":true},"execution_count":3,"outputs":[{"name":"stdout","text":"\nRangeIndex: 75000 entries, 0 to 74999\nData columns (total 7 columns):\n # Column Non-Null Count Dtype \n--- ------ -------------- ----- \n 0 title 75000 non-null object\n 1 ingredients 75000 non-null object\n 2 directions 75000 non-null object\n 3 link 75000 non-null object\n 4 source 75000 non-null object\n 5 NER 75000 non-null object\n 6 site 75000 non-null object\ndtypes: object(7)\nmemory usage: 4.0+ MB\n","output_type":"stream"}]},{"cell_type":"markdown","source":"## Preprocessing The Data","metadata":{"id":"a50ee7a0-6b81-4ded-b6e9-bd4d0c3c6345"}},{"cell_type":"markdown","source":"### Converting recipes objects into strings","metadata":{"id":"37781ca1-e88d-4d1e-9998-91b372b75593"}},{"cell_type":"markdown","source":"\nThe code dataset_validated = [recipe for recipe in dataset_raw.iterrows()] is using a list comprehension to create a new list called dataset_validated from the dataset_raw DataFrame.\n\ndataset_raw.iterrows() returns an iterator that generates a tuple for each row in the DataFrame, where the first element of the tuple is the index of the row and the second element is the row itself as a Series object.\n\nThe list comprehension then iterates over each tuple in the iterator and extracts the row Series object, which is assigned to the variable recipe. This variable is then used in the list comprehension to create a new list dataset_validated.\n\nSo, dataset_validated will be a list of Series objects, where each Series object corresponds to a row in the original dataset_raw DataFrame.\n","metadata":{"id":"iFU9H2RERKzU"}},{"cell_type":"code","source":"dataset_validated = [recipe for recipe in dataset_raw.iterrows()]\n","metadata":{"id":"SSWY6cWiPokz","execution":{"iopub.status.busy":"2024-04-27T15:55:01.991258Z","iopub.execute_input":"2024-04-27T15:55:01.991860Z","iopub.status.idle":"2024-04-27T15:55:07.401887Z","shell.execute_reply.started":"2024-04-27T15:55:01.991831Z","shell.execute_reply":"2024-04-27T15:55:07.401075Z"},"trusted":true},"execution_count":4,"outputs":[]},{"cell_type":"markdown","source":" The code defines three constants. Each constant is assigned a string value. The first constant, `STOP_WORD_TITLE`, is assigned the string value `'📕 '`. The second constant, `STOP_WORD_INGREDIENTS`, is assigned the string value `'\\n🥩\\n\\n'`. The third constant, `STOP_WORD_INSTRUCTIONS`, is assigned the string value `'\\n✍️\\n\\n'`.\nThe purpose of these constants is not immediately clear from the code itself. However, it is possible that they are used as delimiters in a larger program. For example, they could be used to separate different sections of a recipe, such as the title, ingredients, and instructions.\nWithout more context, it is difficult to say for sure what these constants are used for. However, the names of the constants suggest that they are related to a recipe or cooking instructions.","metadata":{"id":"428250f5-c4a9-43ae-bf27-cd3f8f2db9ba"}},{"cell_type":"code","source":"STOP_WORD_TITLE = '📕 '\nSTOP_WORD_INGREDIENTS = '\\n🥩\\n\\n'\nSTOP_WORD_INSTRUCTIONS = '\\n✍️\\n\\n'","metadata":{"id":"2cec2569-9c70-4c7d-b1c3-6c11d202446b","execution":{"iopub.status.busy":"2024-04-27T15:55:07.403247Z","iopub.execute_input":"2024-04-27T15:55:07.403542Z","iopub.status.idle":"2024-04-27T15:55:07.407838Z","shell.execute_reply.started":"2024-04-27T15:55:07.403516Z","shell.execute_reply":"2024-04-27T15:55:07.406946Z"},"trusted":true},"execution_count":5,"outputs":[]},{"cell_type":"markdown","source":"The function called `recipe_to_string` that takes a recipe as input and converts it into a string representation.\nThe function first extracts the recipe name, ingredients, and directions from the recipe dictionary.\nNext, the function creates two empty strings, `ingredients_string` and `instructions_string`, which will be used to store the formatted ingredients and instructions.\nThe function then iterates over the ingredients and instructions lists, formatting each item and adding it to the respective string.\nFinally, the function returns a string that combines the formatted title, ingredients, and instructions, using the `STOP_WORD_TITLE`, `STOP_WORD_INGREDIENTS`, and `STOP_WORD_INSTRUCTIONS` constants as delimiters.\nThe code then uses the `recipe_to_string` function to convert each recipe in the `dataset_validated` list into a string representation.\nThe resulting list of strings is stored in the `dataset_stringified` variable.\nFinally, the code prints the first five recipes in the `dataset_stringified` list, along with their recipe numbers and a separator line.","metadata":{"id":"a5fffb24-8bc6-4a4e-89d6-7965e4a293df"}},{"cell_type":"code","source":"def recipe_to_string(recipe):\n recipe = recipe[1]\n \n title = recipe['title']\n ingredients = recipe['ingredients']\n instructions = recipe['directions']\n\n ingredients_string = ''\n\n for ingredient in ingredients.strip(\"[]\").split(', '):\n if ingredient:\n ingredient = ingredient.replace(\"'\", \"\")\n ingredients_string += f'• {ingredient}\\n'\n\n instructions_string = ''\n for instruction in instructions.strip('][').split(', '):\n if instruction:\n instruction = instruction.replace(\"'\", \"\")\n instructions_string += f'▪︎ {instruction}\\n'\n\n return f'{STOP_WORD_TITLE}{title}\\n{STOP_WORD_INGREDIENTS}{ingredients_string}{STOP_WORD_INSTRUCTIONS}{instructions_string}'\n\ndataset_stringified = [recipe_to_string(recipe) for recipe in dataset_validated]\n\nfor recipe_index, recipe_string in enumerate(dataset_stringified[:5]):\n print('Recipe #{}\\n---------'.format(recipe_index + 1))\n print(recipe_string)\n print('\\n')","metadata":{"id":"df7e335d-29fe-4002-bc13-ed22a920aea3","outputId":"b18f9225-92fe-4376-b87b-c855cc204606","execution":{"iopub.status.busy":"2024-04-27T15:55:07.409177Z","iopub.execute_input":"2024-04-27T15:55:07.409443Z","iopub.status.idle":"2024-04-27T15:55:09.548465Z","shell.execute_reply.started":"2024-04-27T15:55:07.409420Z","shell.execute_reply":"2024-04-27T15:55:09.547485Z"},"trusted":true},"execution_count":6,"outputs":[{"name":"stdout","text":"Recipe #1\n---------\n📕 No-Bake Nut Cookies\n\n🥩\n\n• \"1 c. firmly packed brown sugar\"\n• \"1/2 c. evaporated milk\"\n• \"1/2 tsp. vanilla\"\n• \"1/2 c. broken nuts (pecans)\"\n• \"2 Tbsp. butter or margarine\"\n• \"3 1/2 c. bite size shredded rice biscuits\"\n\n✍️\n\n▪︎ \"In a heavy 2-quart saucepan\n▪︎ mix brown sugar\n▪︎ nuts\n▪︎ evaporated milk and butter or margarine.\"\n▪︎ \"Stir over medium heat until mixture bubbles all over top.\"\n▪︎ \"Boil and stir 5 minutes more. Take off heat.\"\n▪︎ \"Stir in vanilla and cereal; mix well.\"\n▪︎ \"Using 2 teaspoons\n▪︎ drop and shape into 30 clusters on wax paper.\"\n▪︎ \"Let stand until firm\n▪︎ about 30 minutes.\"\n\n\n\nRecipe #2\n---------\n📕 Jewell Ball'S Chicken\n\n🥩\n\n• \"1 small jar chipped beef\n• cut up\"\n• \"4 boned chicken breasts\"\n• \"1 can cream of mushroom soup\"\n• \"1 carton sour cream\"\n\n✍️\n\n▪︎ \"Place chipped beef on bottom of baking dish.\"\n▪︎ \"Place chicken on top of beef.\"\n▪︎ \"Mix soup and cream together; pour over chicken. Bake\n▪︎ uncovered\n▪︎ at 275\\u00b0 for 3 hours.\"\n\n\n\nRecipe #3\n---------\n📕 Creamy Corn\n\n🥩\n\n• \"2 (16 oz.) pkg. frozen corn\"\n• \"1 (8 oz.) pkg. cream cheese\n• cubed\"\n• \"1/3 c. butter\n• cubed\"\n• \"1/2 tsp. garlic powder\"\n• \"1/2 tsp. salt\"\n• \"1/4 tsp. pepper\"\n\n✍️\n\n▪︎ \"In a slow cooker\n▪︎ combine all ingredients. Cover and cook on low for 4 hours or until heated through and cheese is melted. Stir well before serving. Yields 6 servings.\"\n\n\n\nRecipe #4\n---------\n📕 Chicken Funny\n\n🥩\n\n• \"1 large whole chicken\"\n• \"2 (10 1/2 oz.) cans chicken gravy\"\n• \"1 (10 1/2 oz.) can cream of mushroom soup\"\n• \"1 (6 oz.) box Stove Top stuffing\"\n• \"4 oz. shredded cheese\"\n\n✍️\n\n▪︎ \"Boil and debone chicken.\"\n▪︎ \"Put bite size pieces in average size square casserole dish.\"\n▪︎ \"Pour gravy and cream of mushroom soup over chicken; level.\"\n▪︎ \"Make stuffing according to instructions on box (do not make too moist).\"\n▪︎ \"Put stuffing on top of chicken and gravy; level.\"\n▪︎ \"Sprinkle shredded cheese on top and bake at 350\\u00b0 for approximately 20 minutes or until golden and bubbly.\"\n\n\n\nRecipe #5\n---------\n📕 Reeses Cups(Candy) \n\n🥩\n\n• \"1 c. peanut butter\"\n• \"3/4 c. graham cracker crumbs\"\n• \"1 c. melted butter\"\n• \"1 lb. (3 1/2 c.) powdered sugar\"\n• \"1 large pkg. chocolate chips\"\n\n✍️\n\n▪︎ \"Combine first four ingredients and press in 13 x 9-inch ungreased pan.\"\n▪︎ \"Melt chocolate chips and spread over mixture. Refrigerate for about 20 minutes and cut into pieces before chocolate gets hard.\"\n▪︎ \"Keep in refrigerator.\"\n\n\n\n","output_type":"stream"}]},{"cell_type":"markdown","source":"This line prints the value of the 801st element of the `dataset_stringified` list to the console.","metadata":{"id":"76dfcf54-199a-4af7-a52c-4ab12e39ba9d"}},{"cell_type":"code","source":"print(dataset_stringified[800])","metadata":{"id":"7cdfa2b8-0508-4a2e-8781-be225541c070","outputId":"1e438362-e944-4f7e-b86b-b2e28ad870a3","execution":{"iopub.status.busy":"2024-04-27T15:55:09.550026Z","iopub.execute_input":"2024-04-27T15:55:09.550405Z","iopub.status.idle":"2024-04-27T15:55:09.555631Z","shell.execute_reply.started":"2024-04-27T15:55:09.550370Z","shell.execute_reply":"2024-04-27T15:55:09.554559Z"},"trusted":true},"execution_count":7,"outputs":[{"name":"stdout","text":"📕 Finger Jello\n\n🥩\n\n• \"4 boxes of small jello\"\n• \"4 pkg. gelatin\"\n\n✍️\n\n▪︎ \"Mix together and add 5 c. boiling water. Dissolve completely. Let set in refrigerator.\"\n\n","output_type":"stream"}]},{"cell_type":"markdown","source":"### Filtering out large & small receipes","metadata":{"id":"b9261b9b-1eb2-47a5-b8ac-08a418ebbe7d"}},{"cell_type":"markdown","source":"\n1. **recipes_lengths = []**: This line initializes an empty list called `recipes_lengths`. This list will be used to store the lengths of the recipes.\n2. **for recipe_text in dataset_stringified**: This line starts a `for` loop that iterates over each element in the `dataset_stringified` list. Each element in this list is a string that represents a recipe.\n3. **len(recipe_text)**: Inside the loop, this expression calculates the length of the current recipe string. The `len()` function returns the number of characters in a string.\n4. **recipes_lengths.append(len(recipe_text))**: This line appends the length of the current recipe to the `recipes_lengths` list. The `append()` method adds an element to the end of a list.","metadata":{"id":"3764488d-93b4-4de2-b9df-8ad218f0ff64"}},{"cell_type":"code","source":"recipes_lengths = []\nfor recipe_text in dataset_stringified:\n recipes_lengths.append(len(recipe_text))","metadata":{"id":"c8e3a3e3-ebf6-4a30-b108-4751ba20dd57","execution":{"iopub.status.busy":"2024-04-27T15:55:09.556968Z","iopub.execute_input":"2024-04-27T15:55:09.557556Z","iopub.status.idle":"2024-04-27T15:55:09.594651Z","shell.execute_reply.started":"2024-04-27T15:55:09.557521Z","shell.execute_reply":"2024-04-27T15:55:09.593709Z"},"trusted":true},"execution_count":8,"outputs":[]},{"cell_type":"markdown","source":"1. **plt.hist(recipes_lengths, bins=50)**: This line creates a histogram of the recipe lengths. The `plt.hist()` function takes two main arguments: the data to be plotted (in this case, `recipes_lengths`) and the number of bins to use (in this case, 50). The number of bins determines how many bars will be used in the histogram.\n2. **plt.show()**: This line displays the histogram on the screen.","metadata":{"id":"a7e8007b-f254-4543-9fe1-67007b40a114"}},{"cell_type":"code","source":"plt.hist(recipes_lengths, bins=50)\nplt.show()","metadata":{"id":"0b7bb5df-461a-4030-8e51-0455e6d036ef","outputId":"f0ee1fd8-32df-421a-feca-ee873cf61562","execution":{"iopub.status.busy":"2024-04-27T15:55:09.595860Z","iopub.execute_input":"2024-04-27T15:55:09.596212Z","iopub.status.idle":"2024-04-27T15:55:10.253593Z","shell.execute_reply.started":"2024-04-27T15:55:09.596178Z","shell.execute_reply":"2024-04-27T15:55:10.252645Z"},"trusted":true},"execution_count":9,"outputs":[{"output_type":"display_data","data":{"text/plain":"
","image/png":"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IgcAAFiJyAEAAFYicgAAgJXC23oBt7I+WfltvQQAAKzFOzkAAMBKRA4AALASkQMAAKxE5AAAACsROQAAwEpEDgAAsBKRAwAArETkAAAAKxE5AADASkQOAACwEpEDAACsROQAAAArETkAAMBKRA4AALASkQMAAKxE5AAAACsROQAAwEpEDgAAsBKRAwAArETkAAAAKxE5AADASkQOAACwEpEDAACsROQAAAArETkAAMBKRA4AALASkQMAAKxE5AAAACsROQAAwEpEDgAAsBKRAwAArETkAAAAKxE5AADASkQOAACwEpEDAACsROQAAAArETkAAMBKRA4AALASkQMAAKzUrMjJycnRqFGj1KlTJ8XExGjSpEmqrKwMmvn666+Vnp6url27qmPHjpo8ebKqq6uDZqqqqpSSkqIOHTooJiZGCxcu1MWLF4NmduzYoeHDh8vlcqlfv37Kzc29bD2rV69Wnz59FBkZqaSkJO3bt685hwMAACzWrMgpLi5Wenq69uzZo8LCQl24cEHjx4/XuXPnnJkFCxbozTff1ObNm1VcXKzjx4/rkUcecbY3NDQoJSVF9fX12r17t1577TXl5uYqOzvbmTly5IhSUlL04IMPqqysTPPnz9fjjz+ubdu2OTMbN25UZmamnnnmGb377rsaMmSIfD6fTp48eT2vBwAAsESIMca09MGnTp1STEyMiouLNXbsWNXW1qp79+5av369fv7zn0uSKioqNHDgQJWUlGjMmDF6++239fDDD+v48eOKjY2VJK1du1aLFy/WqVOnFBERocWLFys/P1/l5eXOc02dOlU1NTUqKCiQJCUlJWnUqFFatWqVJKmxsVEJCQl68sknlZWVdU3rDwQC8ng8qq2tldvtbunL0GJ9svJbZT9Hl6e0yn4AAGgPrvX393V9Jqe2tlaS1KVLF0lSaWmpLly4oOTkZGdmwIAB6tWrl0pKSiRJJSUlSkxMdAJHknw+nwKBgA4fPuzMXLqPppmmfdTX16u0tDRoJjQ0VMnJyc7MldTV1SkQCATdAACAnVocOY2NjZo/f77uu+8+DR48WJLk9/sVERGh6OjooNnY2Fj5/X5n5tLAadretO3bZgKBgM6fP6/PP/9cDQ0NV5xp2seV5OTkyOPxOLeEhITmHzgAAGgXWhw56enpKi8v14YNG1pzPTfUkiVLVFtb69yOHTvW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ExMTtD08PFxdunQJmrnSPi59jqvNNG2/kpycHHk8HueWkJDQ3EMEAADtxC11ddWSJUtUW1vr3I4dO9bWSwIAADdIq0ZOXFycJKm6ujro/urqamdbXFycTp48GbT94sWLOn36dNDMlfZx6XNcbaZp+5W4XC653e6gGwAAsFOrRk7fvn0VFxenoqIi575AIKC9e/fK6/VKkrxer2pqalRaWurMbN++XY2NjUpKSnJmdu7cqQsXLjgzhYWF6t+/vzp37uzMXPo8TTNNzwMAAG5tzY6cs2fPqqysTGVlZZK++bBxWVmZqqqqFBISovnz5+uf//mf9Yc//EGHDh3S3//93ys+Pt65AmvgwIGaMGGCnnjiCe3bt09//vOflZGRoalTpyo+Pl6S9OijjyoiIkJpaWk6fPiwNm7cqJUrVyozM9NZx7x581RQUKDf/OY3qqio0LJly3TgwAFlZGRc/6sCAADavfDmPuDAgQN68MEHnZ+bwmPGjBnKzc3VokWLdO7cOc2ePVs1NTW6//77VVBQoMjISOcx69atU0ZGhsaNG6fQ0FBNnjxZL774orPd4/Hoj3/8o9LT0zVixAh169ZN2dnZQd+lc++992r9+vVaunSpfvnLX+quu+7S1q1bNXjw4Ba9EAAAwC7X9T057R3fkwMAQPvTJt+TAwAAcLMgcgAAgJWIHAAAYCUiBwAAWInIAQAAViJyAACAlYgcAABgJSIHAABYicgBAABWInIAAICViBwAAGAlIgcAAFiJyAEAAFYicgAAgJWIHAAAYCUiBwAAWInIAQAAViJyAACAlYgcAABgJSIHAABYicgBAABWInIAAICViBwAAGAlIgcAAFiJyAEAAFYicgAAgJWIHAAAYCUiBwAAWInIAQAAViJyAACAlYgcAABgJSIHAABYicgBAABWInIAAICViBwAAGAlIgcAAFiJyAEAAFYicgAAgJWIHAAAYCUiBwAAWInIAQAAViJyAACAlYgcAABgJSIHAABYicgBAABWInIAAICViBwAAGAlIgcAAFiJyAEAAFYicgAAgJWIHAAAYCUiBwAAWInIAQAAViJyAACAlYgcAABgJSIHAABYqdUjZ9myZQoJCQm6DRgwwNn+9ddfKz09XV27dlXHjh01efJkVVdXB+2jqqpKKSkp6tChg2JiYrRw4UJdvHgxaGbHjh0aPny4XC6X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3Rw4cMB4vV7j9Xqd7U2XIo8fP96UlZWZgoIC07179yteirxw4ULz4YcfmtWrV3Mpciu79OoqYzhvN6N9+/aZ8PBw89xzz5mPPvrIrFu3znTo0MH813/9lzOzfPlyEx0dbd544w1z8OBB89Of/vSKlyIPGzbM7N271+zatcvcddddQZci19TUmNjYWDN9+nRTXl5uNmzYYDp06NDmlyK3VzNmzDA/+MEPnEvIf//735tu3bqZRYsWOTM2nzci5zr97ne/M7169TIRERFm9OjRZs+ePW29pFuGpCveXn31VWfm/Pnz5h/+4R9M586dTYcOHczPfvYzc+LEiaD9HD161Dz00EMmKirKdOvWzTz11FPmwoULQTPvvPOOGTp0qImIiDB33HFH0HPg+v3/yOG83ZzefPNNM3jwYONyucyAAQPMyy+/HLS9sbHR/OpXvzKxsbHG5XKZcePGmcrKyqCZL774wkybNs107NjRuN1uM2vWLHPmzJmgmffff9/cf//9xuVymR/84Adm+fLlN/zYbBUIBMy8efNMr169TGRkpLnjjjvM008/HXSpt83nLcSYS772EAAAwBJ8JgcAAFiJyAEAAFYicgAAgJWIHAAAYCUiBwAAWInIAQAAViJyAACAlYgcAABgJSIHAABYicgBAABWInIAAICViBwAAGCl/wUmlpz0CqLJ2wAAAABJRU5ErkJggg=="},"metadata":{}}]},{"cell_type":"markdown","source":"1. **plt.hist(recipes_lengths,range=(0,2000), bins=50)**: This line creates a histogram of the recipe lengths. The `plt.hist()` function takes three main arguments: the data to be plotted (in this case, `recipes_lengths`), the range of values to be plotted (in this case, 0 to 2000), and the number of bins to use (in this case, 50). The number of bins determines how many bars will be used in the histogram.\n2. **plt.show()**: This line displays the histogram on the screen.","metadata":{"id":"6481bb84-181b-4f64-ae27-fb782e5080ed"}},{"cell_type":"code","source":"plt.hist(recipes_lengths,range=(0,2000), bins=50)\nplt.show()","metadata":{"id":"0d46e90b-7345-4555-ba86-66b269dbcd3d","outputId":"919075b7-71cd-45b3-cae5-85958cbeacef","execution":{"iopub.status.busy":"2024-04-27T15:55:10.256939Z","iopub.execute_input":"2024-04-27T15:55:10.257297Z","iopub.status.idle":"2024-04-27T15:55:10.835336Z","shell.execute_reply.started":"2024-04-27T15:55:10.257272Z","shell.execute_reply":"2024-04-27T15:55:10.834263Z"},"trusted":true},"execution_count":10,"outputs":[{"output_type":"display_data","data":{"text/plain":"
","image/png":"iVBORw0KGgoAAAANSUhEUgAAAjAAAAGdCAYAAAAMm0nCAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8WgzjOAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAw5UlEQVR4nO3df3RU9Z3/8VcCZAg/ZiI/MkNKgFhaIAoqUcOsSqtmGWlstcSuKFVUlIUNVhKFmNVFpd2Gg8ciVoG2WsI5ShXOUVSiYAQBlQE0a5QfkkUFg4VJqJgZUEgC+Xz/6Dd3GQmQhEDyCc/HOfcccj/ve+fz8ULuy8/9MTHGGCMAAACLxLZ2BwAAAJqKAAMAAKxDgAEAANYhwAAAAOsQYAAAgHUIMAAAwDoEGAAAYB0CDAAAsE7H1u7AmVJXV6c9e/aoe/fuiomJae3uAACARjDG6MCBA0pKSlJs7InnWdptgNmzZ4+Sk5NbuxsAAKAZdu/erb59+56wvd0GmO7du0v6538At9vdyr0BAACNEYlElJyc7JzHT6TdBpj6y0Zut5sAAwCAZU51+wc38QIAAOsQYAAAgHUIMAAAwDoEGAAAYB0CDAAAsA4BBgAAWIcAAwAArEOAAQAA1iHAAAAA6xBgAACAdQgwAADAOgQYAABgHQIMAACwDgEGAABYp2NrdwA4mQEPFp2yZteszLPQEwBAW8IMDAAAsA4BBgAAWIcAAwAArEOAAQAA1iHAAAAA6zQpwAwYMEAxMTHHLdnZ2ZKkw4cPKzs7Wz179lS3bt2UlZWlioqKqH2Ul5crMzNTXbp0UWJioqZNm6YjR45E1axZs0bDhw+Xy+XSwIEDVVhYeHqjBAAA7UqTAswHH3ygvXv3OktxcbEk6Ve/+pUkKScnR6+//rqWLl2qtWvXas+ePRozZoyz/dGjR5WZmamamhqtX79eixYtUmFhoWbMmOHU7Ny5U5mZmbr66qtVWlqqqVOn6u6779bKlStbYrwAAKAdiDHGmOZuPHXqVC1fvlw7duxQJBJR7969tXjxYt10002SpO3bt2vIkCEKBoMaMWKE3nzzTV1//fXas2ePvF6vJGnBggXKy8vTvn37FBcXp7y8PBUVFWnLli3O54wdO1ZVVVVasWJFo/sWiUTk8XgUDofldrubO0S0Mt4DAwDnlsaev5t9D0xNTY2ef/553XXXXYqJiVFJSYlqa2uVkZHh1AwePFj9+vVTMBiUJAWDQQ0dOtQJL5IUCAQUiUS0detWp+bYfdTX1O/jRKqrqxWJRKIWAADQPjU7wCxbtkxVVVW64447JEmhUEhxcXFKSEiIqvN6vQqFQk7NseGlvr2+7WQ1kUhEhw4dOmF/CgoK5PF4nCU5Obm5QwMAAG1cs79K4LnnntPo0aOVlJTUkv1ptvz8fOXm5jo/RyIRQsw5gstMAHDuaVaA+fLLL/X222/r5Zdfdtb5fD7V1NSoqqoqahamoqJCPp/Pqdm0aVPUvuqfUjq25vtPLlVUVMjtdis+Pv6EfXK5XHK5XM0ZDgAAsEyzLiEtXLhQiYmJysz8v/+rTUtLU6dOnbRq1SpnXVlZmcrLy+X3+yVJfr9fmzdvVmVlpVNTXFwst9ut1NRUp+bYfdTX1O8DAACgyQGmrq5OCxcu1Pjx49Wx4/9N4Hg8Hk2YMEG5ubl65513VFJSojvvvFN+v18jRoyQJI0aNUqpqam67bbb9PHHH2vlypV6+OGHlZ2d7cyeTJo0SV988YWmT5+u7du3a968eVqyZIlycnJaaMgAAMB2Tb6E9Pbbb6u8vFx33XXXcW1z5sxRbGyssrKyVF1drUAgoHnz5jntHTp00PLlyzV58mT5/X517dpV48eP18yZM52alJQUFRUVKScnR3PnzlXfvn317LPPKhAINHOIAACgvTmt98C0ZbwHpu1rzM23LYWbeAHADmf8PTAAAACthQADAACsQ4ABAADWIcAAAADrEGAAAIB1CDAAAMA6BBgAAGAdAgwAALAOAQYAAFiHAAMAAKxDgAEAANYhwAAAAOsQYAAAgHUIMAAAwDodW7sDwNkw4MGiU9bsmpV5FnoCAGgJzMAAAADrEGAAAIB1CDAAAMA6BBgAAGAdAgwAALAOAQYAAFiHAAMAAKxDgAEAANYhwAAAAOsQYAAAgHUIMAAAwDoEGAAAYB0CDAAAsA4BBgAAWIcAAwAArNOxtTuA9mnAg0Wt3QUAQDvGDAwAALAOAQYAAFiHAAMAAKxDgAEAANYhwAAAAOsQYAAAgHUIMAAAwDpNDjB///vf9etf/1o9e/ZUfHy8hg4dqg8//NBpN8ZoxowZ6tOnj+Lj45WRkaEdO3ZE7WP//v0aN26c3G63EhISNGHCBB08eDCq5pNPPtFVV12lzp07Kzk5WbNnz27mEAEAQHvTpADzzTff6IorrlCnTp305ptvatu2bXriiSd03nnnOTWzZ8/WU089pQULFmjjxo3q2rWrAoGADh8+7NSMGzdOW7duVXFxsZYvX65169Zp4sSJTnskEtGoUaPUv39/lZSU6PHHH9ejjz6qP//5zy0wZAAAYLsYY4xpbPGDDz6o999/X++++26D7cYYJSUl6f7779cDDzwgSQqHw/J6vSosLNTYsWP16aefKjU1VR988IEuvfRSSdKKFSv0s5/9TF999ZWSkpI0f/58PfTQQwqFQoqLi3M+e9myZdq+fXuj+hqJROTxeBQOh+V2uxs7RLQQG9/Eu2tWZmt3AQDOeY09fzdpBua1117TpZdeql/96ldKTEzUJZdcor/85S9O+86dOxUKhZSRkeGs83g8Sk9PVzAYlCQFg0ElJCQ44UWSMjIyFBsbq40bNzo1I0eOdMKLJAUCAZWVlembb75psG/V1dWKRCJRCwAAaJ+aFGC++OILzZ8/Xz/60Y+0cuVKTZ48Wb/5zW+0aNEiSVIoFJIkeb3eqO28Xq/TFgqFlJiYGNXesWNH9ejRI6qmoX0c+xnfV1BQII/H4yzJyclNGRoAALBIkwJMXV2dhg8frt///ve65JJLNHHiRN1zzz1asGDBmepfo+Xn5yscDjvL7t27W7tLAADgDGlSgOnTp49SU1Oj1g0ZMkTl5eWSJJ/PJ0mqqKiIqqmoqHDafD6fKisro9qPHDmi/fv3R9U0tI9jP+P7XC6X3G531AIAANqnJgWYK664QmVlZVHr/vd//1f9+/eXJKWkpMjn82nVqlVOeyQS0caNG+X3+yVJfr9fVVVVKikpcWpWr16turo6paenOzXr1q1TbW2tU1NcXKxBgwZFPfEEAADOTU0KMDk5OdqwYYN+//vf67PPPtPixYv15z//WdnZ2ZKkmJgYTZ06Vb/73e/02muvafPmzbr99tuVlJSkG2+8UdI/Z2yuu+463XPPPdq0aZPef/99TZkyRWPHjlVSUpIk6dZbb1VcXJwmTJigrVu36qWXXtLcuXOVm5vbsqMHAABW6tiU4ssuu0yvvPKK8vPzNXPmTKWkpOjJJ5/UuHHjnJrp06fr22+/1cSJE1VVVaUrr7xSK1asUOfOnZ2aF154QVOmTNG1116r2NhYZWVl6amnnnLaPR6P3nrrLWVnZystLU29evXSjBkzot4VAwAAzl1Neg+MTXgPTOviPTAAgOY4I++BAQAAaAsIMAAAwDpNugcGaM8ac9mLy0wA0DYwAwMAAKxDgAEAANYhwAAAAOsQYAAAgHUIMAAAwDoEGAAAYB0CDAAAsA4BBgAAWIcAAwAArEOAAQAA1iHAAAAA6xBgAACAdQgwAADAOgQYAABgHQIMAACwDgEGAABYhwADAACsQ4ABAADWIcAAAADrEGAAAIB1CDAAAMA6BBgAAGAdAgwAALAOAQYAAFiHAAMAAKxDgAEAANYhwAAAAOsQYAAAgHUIMAAAwDoEGAAAYB0CDAAAsA4BBgAAWIcAAwAArEOAAQAA1mlSgHn00UcVExMTtQwePNhpP3z4sLKzs9WzZ09169ZNWVlZqqioiNpHeXm5MjMz1aVLFyUmJmratGk6cuRIVM2aNWs0fPhwuVwuDRw4UIWFhc0fIQAAaHeaPANzwQUXaO/evc7y3nvvOW05OTl6/fXXtXTpUq1du1Z79uzRmDFjnPajR48qMzNTNTU1Wr9+vRYtWqTCwkLNmDHDqdm5c6cyMzN19dVXq7S0VFOnTtXdd9+tlStXnuZQAQBAe9GxyRt07Cifz3fc+nA4rOeee06LFy/WNddcI0lauHChhgwZog0bNmjEiBF66623tG3bNr399tvyer26+OKL9dvf/lZ5eXl69NFHFRcXpwULFiglJUVPPPGEJGnIkCF67733NGfOHAUCgdMcLgAAaA+aPAOzY8cOJSUl6fzzz9e4ceNUXl4uSSopKVFtba0yMjKc2sGDB6tfv34KBoOSpGAwqKFDh8rr9To1gUBAkUhEW7dudWqO3Ud9Tf0+AAAAmjQDk56ersLCQg0aNEh79+7VY489pquuukpbtmxRKBRSXFycEhISorbxer0KhUKSpFAoFBVe6tvr205WE4lEdOjQIcXHxzfYt+rqalVXVzs/RyKRpgwNAABYpEkBZvTo0c6fhw0bpvT0dPXv319Lliw5YbA4WwoKCvTYY4+1ah8AAMDZcVqPUSckJOjHP/6xPvvsM/l8PtXU1KiqqiqqpqKiwrlnxufzHfdUUv3Pp6pxu90nDUn5+fkKh8POsnv37tMZGgAAaMNOK8AcPHhQn3/+ufr06aO0tDR16tRJq1atctrLyspUXl4uv98vSfL7/dq8ebMqKyudmuLiYrndbqWmpjo1x+6jvqZ+HyficrnkdrujFgAA0D41KcA88MADWrt2rXbt2qX169frl7/8pTp06KBbbrlFHo9HEyZMUG5urt555x2VlJTozjvvlN/v14gRIyRJo0aNUmpqqm677TZ9/PHHWrlypR5++GFlZ2fL5XJJkiZNmqQvvvhC06dP1/bt2zVv3jwtWbJEOTk5LT96AABgpSbdA/PVV1/plltu0ddff63evXvryiuv1IYNG9S7d29J0pw5cxQbG6usrCxVV1crEAho3rx5zvYdOnTQ8uXLNXnyZPn9fnXt2lXjx4/XzJkznZqUlBQVFRUpJydHc+fOVd++ffXss8/yCDUAAHDEGGNMa3fiTIhEIvJ4PAqHw1xOagUDHixq7S6cEbtmZbZ2FwCgXWvs+ZvvQgIAANYhwAAAAOs0+asEgPZ6eQgAYA9mYAAAgHUIMAAAwDoEGAAAYB0CDAAAsA438QJN0JgbmHlXDACceczAAAAA6xBgAACAdQgwAADAOgQYAABgHQIMAACwDgEGAABYhwADAACsQ4ABAADWIcAAAADrEGAAAIB1CDAAAMA6BBgAAGAdAgwAALAOAQYAAFiHAAMAAKxDgAEAANYhwAAAAOsQYAAAgHUIMAAAwDoEGAAAYB0CDAAAsA4BBgAAWIcAAwAArEOAAQAA1iHAAAAA6xBgAACAdQgwAADAOgQYAABgHQIMAACwDgEGAABY57QCzKxZsxQTE6OpU6c66w4fPqzs7Gz17NlT3bp1U1ZWlioqKqK2Ky8vV2Zmprp06aLExERNmzZNR44ciapZs2aNhg8fLpfLpYEDB6qwsPB0ugoAANqRZgeYDz74QH/60580bNiwqPU5OTl6/fXXtXTpUq1du1Z79uzRmDFjnPajR48qMzNTNTU1Wr9+vRYtWqTCwkLNmDHDqdm5c6cyMzN19dVXq7S0VFOnTtXdd9+tlStXNre7AACgHWlWgDl48KDGjRunv/zlLzrvvPOc9eFwWM8995z+8Ic/6JprrlFaWpoWLlyo9evXa8OGDZKkt956S9u2bdPzzz+viy++WKNHj9Zvf/tbPfPMM6qpqZEkLViwQCkpKXriiSc0ZMgQTZkyRTfddJPmzJnTAkMGAAC2a1aAyc7OVmZmpjIyMqLWl5SUqLa2Nmr94MGD1a9fPwWDQUlSMBjU0KFD5fV6nZpAIKBIJKKtW7c6Nd/fdyAQcPYBAADObR2busGLL76o//mf/9EHH3xwXFsoFFJcXJwSEhKi1nu9XoVCIafm2PBS317fdrKaSCSiQ4cOKT4+/rjPrq6uVnV1tfNzJBJp6tAAAIAlmjQDs3v3bt1333164YUX1Llz5zPVp2YpKCiQx+NxluTk5NbuEgAAOEOaFGBKSkpUWVmp4cOHq2PHjurYsaPWrl2rp556Sh07dpTX61VNTY2qqqqitquoqJDP55Mk+Xy+455Kqv/5VDVut7vB2RdJys/PVzgcdpbdu3c3ZWgAAMAiTbqEdO2112rz5s1R6+68804NHjxYeXl5Sk5OVqdOnbRq1SplZWVJksrKylReXi6/3y9J8vv9+u///m9VVlYqMTFRklRcXCy3263U1FSn5o033oj6nOLiYmcfDXG5XHK5XE0ZDnBGDHiw6JQ1u2ZlnoWeAED71aQA0717d1144YVR67p27aqePXs66ydMmKDc3Fz16NFDbrdb9957r/x+v0aMGCFJGjVqlFJTU3Xbbbdp9uzZCoVCevjhh5Wdne0EkEmTJunpp5/W9OnTddddd2n16tVasmSJiopOfWIAAADtX5Nv4j2VOXPmKDY2VllZWaqurlYgENC8efOc9g4dOmj58uWaPHmy/H6/unbtqvHjx2vmzJlOTUpKioqKipSTk6O5c+eqb9++evbZZxUIBFq6uwAAwEIxxhjT2p04EyKRiDwej8LhsNxud2t3p11pzCUSnByXkACgYY09f/NdSAAAwDoEGAAAYB0CDAAAsA4BBgAAWIcAAwAArEOAAQAA1iHAAAAA6xBgAACAdQgwAADAOgQYAABgHQIMAACwDgEGAABYhwADAACsQ4ABAADWIcAAAADrdGztDqBtGfBgUWt3AQCAU2IGBgAAWIcAAwAArEOAAQAA1iHAAAAA6xBgAACAdXgKCWgFjXnaa9eszLPQEwCwEzMwAADAOgQYAABgHQIMAACwDgEGAABYhwADAACsQ4ABAADWIcAAAADrEGAAAIB1CDAAAMA6BBgAAGAdAgwAALAOAQYAAFiHAAMAAKxDgAEAANYhwAAAAOsQYAAAgHWaFGDmz5+vYcOGye12y+12y+/3680333TaDx8+rOzsbPXs2VPdunVTVlaWKioqovZRXl6uzMxMdenSRYmJiZo2bZqOHDkSVbNmzRoNHz5cLpdLAwcOVGFhYfNHCAAA2p0mBZi+fftq1qxZKikp0YcffqhrrrlGN9xwg7Zu3SpJysnJ0euvv66lS5dq7dq12rNnj8aMGeNsf/ToUWVmZqqmpkbr16/XokWLVFhYqBkzZjg1O3fuVGZmpq6++mqVlpZq6tSpuvvuu7Vy5coWGjIAALBdjDHGnM4OevTooccff1w33XSTevfurcWLF+umm26SJG3fvl1DhgxRMBjUiBEj9Oabb+r666/Xnj175PV6JUkLFixQXl6e9u3bp7i4OOXl5amoqEhbtmxxPmPs2LGqqqrSihUrGt2vSCQij8ejcDgst9t9OkM8pwx4sKi1u4D/b9eszNbuAgCcdY09fzf7HpijR4/qxRdf1Lfffiu/36+SkhLV1tYqIyPDqRk8eLD69eunYDAoSQoGgxo6dKgTXiQpEAgoEok4szjBYDBqH/U19fsAAADo2NQNNm/eLL/fr8OHD6tbt2565ZVXlJqaqtLSUsXFxSkhISGq3uv1KhQKSZJCoVBUeKlvr287WU0kEtGhQ4cUHx/fYL+qq6tVXV3t/ByJRJo6NAAAYIkmz8AMGjRIpaWl2rhxoyZPnqzx48dr27ZtZ6JvTVJQUCCPx+MsycnJrd0lAABwhjQ5wMTFxWngwIFKS0tTQUGBLrroIs2dO1c+n081NTWqqqqKqq+oqJDP55Mk+Xy+455Kqv/5VDVut/uEsy+SlJ+fr3A47Cy7d+9u6tAAAIAlTvs9MHV1daqurlZaWpo6deqkVatWOW1lZWUqLy+X3++XJPn9fm3evFmVlZVOTXFxsdxut1JTU52aY/dRX1O/jxNxuVzO4931CwAAaJ+adA9Mfn6+Ro8erX79+unAgQNavHix1qxZo5UrV8rj8WjChAnKzc1Vjx495Ha7de+998rv92vEiBGSpFGjRik1NVW33XabZs+erVAopIcffljZ2dlyuVySpEmTJunpp5/W9OnTddddd2n16tVasmSJiop4OgYAAPxTkwJMZWWlbr/9du3du1cej0fDhg3TypUr9a//+q+SpDlz5ig2NlZZWVmqrq5WIBDQvHnznO07dOig5cuXa/LkyfL7/eratavGjx+vmTNnOjUpKSkqKipSTk6O5s6dq759++rZZ59VIBBooSEDAADbnfZ7YNoq3gPTPLwHpu3gPTAAzkVn/D0wAAAArYUAAwAArEOAAQAA1iHAAAAA6xBgAACAdQgwAADAOgQYAABgHQIMAACwDgEGAABYhwADAACs06TvQgJw9jTmax34ugEA5ypmYAAAgHUIMAAAwDoEGAAAYB0CDAAAsA4BBgAAWIcAAwAArEOAAQAA1iHAAAAA6xBgAACAdQgwAADAOgQYAABgHQIMAACwDgEGAABYhwADAACsQ4ABAADWIcAAAADrEGAAAIB1CDAAAMA6BBgAAGAdAgwAALAOAQYAAFiHAAMAAKxDgAEAANYhwAAAAOsQYAAAgHU6tnYHADTfgAeLTlmza1bmWegJAJxdBJhzRGNOdAAA2KJJl5AKCgp02WWXqXv37kpMTNSNN96osrKyqJrDhw8rOztbPXv2VLdu3ZSVlaWKioqomvLycmVmZqpLly5KTEzUtGnTdOTIkaiaNWvWaPjw4XK5XBo4cKAKCwubN0IAANDuNCnArF27VtnZ2dqwYYOKi4tVW1urUaNG6dtvv3VqcnJy9Prrr2vp0qVau3at9uzZozFjxjjtR48eVWZmpmpqarR+/XotWrRIhYWFmjFjhlOzc+dOZWZm6uqrr1ZpaammTp2qu+++WytXrmyBIQMAANvFGGNMczfet2+fEhMTtXbtWo0cOVLhcFi9e/fW4sWLddNNN0mStm/friFDhigYDGrEiBF68803df3112vPnj3yer2SpAULFigvL0/79u1TXFyc8vLyVFRUpC1btjifNXbsWFVVVWnFihWN6lskEpHH41E4HJbb7W7uENsNLiGdu7gHBoBNGnv+Pq2nkMLhsCSpR48ekqSSkhLV1tYqIyPDqRk8eLD69eunYDAoSQoGgxo6dKgTXiQpEAgoEolo69atTs2x+6ivqd9HQ6qrqxWJRKIWAADQPjU7wNTV1Wnq1Km64oordOGFF0qSQqGQ4uLilJCQEFXr9XoVCoWcmmPDS317fdvJaiKRiA4dOtRgfwoKCuTxeJwlOTm5uUMDAABtXLMDTHZ2trZs2aIXX3yxJfvTbPn5+QqHw86ye/fu1u4SAAA4Q5r1GPWUKVO0fPlyrVu3Tn379nXW+3w+1dTUqKqqKmoWpqKiQj6fz6nZtGlT1P7qn1I6tub7Ty5VVFTI7XYrPj6+wT65XC65XK7mDAcAAFimSTMwxhhNmTJFr7zyilavXq2UlJSo9rS0NHXq1EmrVq1y1pWVlam8vFx+v1+S5Pf7tXnzZlVWVjo1xcXFcrvdSk1NdWqO3Ud9Tf0+AADAua1JMzDZ2dlavHixXn31VXXv3t25Z8Xj8Sg+Pl4ej0cTJkxQbm6uevToIbfbrXvvvVd+v18jRoyQJI0aNUqpqam67bbbNHv2bIVCIT388MPKzs52ZlAmTZqkp59+WtOnT9ddd92l1atXa8mSJSoq4kkaAADQxBmY+fPnKxwO66c//an69OnjLC+99JJTM2fOHF1//fXKysrSyJEj5fP59PLLLzvtHTp00PLly9WhQwf5/X79+te/1u23366ZM2c6NSkpKSoqKlJxcbEuuugiPfHEE3r22WcVCARaYMgAAMB2p/UemLaM98BE4z0w5y7eAwPAJmflPTAAAACtgQADAACsQ4ABAADWIcAAAADrEGAAAIB1CDAAAMA6BBgAAGAdAgwAALAOAQYAAFiHAAMAAKxDgAEAANYhwAAAAOt0bO0OADizGvNFnnzhIwDbMAMDAACsQ4ABAADWIcAAAADrEGAAAIB1CDAAAMA6BBgAAGAdAgwAALAOAQYAAFiHAAMAAKxDgAEAANYhwAAAAOsQYAAAgHUIMAAAwDoEGAAAYB0CDAAAsA4BBgAAWIcAAwAArEOAAQAA1iHAAAAA63Rs7Q4AaH0DHiw6Zc2uWZlnoScA0DjMwAAAAOsQYAAAgHUIMAAAwDoEGAAAYB0CDAAAsE6TA8y6dev085//XElJSYqJidGyZcui2o0xmjFjhvr06aP4+HhlZGRox44dUTX79+/XuHHj5Ha7lZCQoAkTJujgwYNRNZ988omuuuoqde7cWcnJyZo9e3bTRwcAANqlJgeYb7/9VhdddJGeeeaZBttnz56tp556SgsWLNDGjRvVtWtXBQIBHT582KkZN26ctm7dquLiYi1fvlzr1q3TxIkTnfZIJKJRo0apf//+Kikp0eOPP65HH31Uf/7zn5sxRAAA0N7EGGNMszeOidErr7yiG2+8UdI/Z1+SkpJ0//3364EHHpAkhcNheb1eFRYWauzYsfr000+VmpqqDz74QJdeeqkkacWKFfrZz36mr776SklJSZo/f74eeughhUIhxcXFSZIefPBBLVu2TNu3b29U3yKRiDwej8LhsNxud3OH2G405j0fwMnwHhgAZ0Njz98teg/Mzp07FQqFlJGR4azzeDxKT09XMBiUJAWDQSUkJDjhRZIyMjIUGxurjRs3OjUjR450woskBQIBlZWV6Ztvvmnws6urqxWJRKIWAADQPrVogAmFQpIkr9cbtd7r9TptoVBIiYmJUe0dO3ZUjx49omoa2sexn/F9BQUF8ng8zpKcnHz6AwIAAG1Su3kKKT8/X+Fw2Fl2797d2l0CAABnSIt+F5LP55MkVVRUqE+fPs76iooKXXzxxU5NZWVl1HZHjhzR/v37ne19Pp8qKiqiaup/rq/5PpfLJZfL1SLjAHA8vi8JQFvSogEmJSVFPp9Pq1atcgJLJBLRxo0bNXnyZEmS3+9XVVWVSkpKlJaWJklavXq16urqlJ6e7tQ89NBDqq2tVadOnSRJxcXFGjRokM4777yW7HK7wA26AIBzTZMvIR08eFClpaUqLS2V9M8bd0tLS1VeXq6YmBhNnTpVv/vd7/Taa69p8+bNuv3225WUlOQ8qTRkyBBdd911uueee7Rp0ya9//77mjJlisaOHaukpCRJ0q233qq4uDhNmDBBW7du1UsvvaS5c+cqNze3xQYOAADs1eQZmA8//FBXX32183N9qBg/frwKCws1ffp0ffvtt5o4caKqqqp05ZVXasWKFercubOzzQsvvKApU6bo2muvVWxsrLKysvTUU0857R6PR2+99Zays7OVlpamXr16acaMGVHvigEAAOeu03oPTFt2Lr0HhktIaCu4BwbA6WqV98AAAACcDQQYAABgHQIMAACwDgEGAABYhwADAACsQ4ABAADWIcAAAADrEGAAAIB1WvS7kACc2/jCRwBnCzMwAADAOgQYAABgHQIMAACwDgEGAABYhwADAACsQ4ABAADWIcAAAADr8B4YAGcV74oB0BKYgQEAANYhwAAAAOsQYAAAgHUIMAAAwDrcxAugzeFGXwCnwgwMAACwDgEGAABYhwADAACsQ4ABAADWIcAAAADr8BQSACvxpBJwbmMGBgAAWIcAAwAArMMlpDauMdPkAACcawgwANot7pMB2i8uIQEAAOswAwPgnMYsDWAnZmAAAIB1CDAAAMA6XEICgFPgMhPQ9hBgAKAFEHKAs6tNX0J65plnNGDAAHXu3Fnp6enatGlTa3cJAAC0AW12Buall15Sbm6uFixYoPT0dD355JMKBAIqKytTYmJia3cPAJqspV5MyUwOIMUYY0xrd6Ih6enpuuyyy/T0009Lkurq6pScnKx7771XDz744Cm3j0Qi8ng8CofDcrvdZ7q7Zwxv4gXQHIQc2Kqx5+82OQNTU1OjkpIS5efnO+tiY2OVkZGhYDDY4DbV1dWqrq52fg6Hw5L++R+irbrwkZWt3QUA7VS/nKVn7bO2PBY4a5+F9q/+vH2q+ZU2GWD+8Y9/6OjRo/J6vVHrvV6vtm/f3uA2BQUFeuyxx45bn5ycfEb6CAD4J8+Trd0DtEcHDhyQx+M5YXubDDDNkZ+fr9zcXOfnuro67d+/Xz179lRMTEyLfU4kElFycrJ2795t9aWpk2nvY2R89mvvY2zv45Pa/xgZX/MZY3TgwAElJSWdtK5NBphevXqpQ4cOqqioiFpfUVEhn8/X4DYul0sulytqXUJCwpnqotxud7v8S3ms9j5Gxme/9j7G9j4+qf2PkfE1z8lmXuq1yceo4+LilJaWplWrVjnr6urqtGrVKvn9/lbsGQAAaAva5AyMJOXm5mr8+PG69NJLdfnll+vJJ5/Ut99+qzvvvLO1uwYAAFpZmw0wN998s/bt26cZM2YoFArp4osv1ooVK467sfdsc7lceuSRR467XNWetPcxMj77tfcxtvfxSe1/jIzvzGuz74EBAAA4kTZ5DwwAAMDJEGAAAIB1CDAAAMA6BBgAAGAdAkwTPfPMMxowYIA6d+6s9PR0bdq0qbW71CgFBQW67LLL1L17dyUmJurGG29UWVlZVM1Pf/pTxcTERC2TJk2KqikvL1dmZqa6dOmixMRETZs2TUeOHDmbQ2nQo48+elzfBw8e7LQfPnxY2dnZ6tmzp7p166asrKzjXpTYVscmSQMGDDhufDExMcrOzpZk57Fbt26dfv7znyspKUkxMTFatmxZVLsxRjNmzFCfPn0UHx+vjIwM7dixI6pm//79GjdunNxutxISEjRhwgQdPHgwquaTTz7RVVddpc6dOys5OVmzZ88+00OTdPLx1dbWKi8vT0OHDlXXrl2VlJSk22+/XXv27InaR0PHfdasWVE1rTU+6dTH8I477jiu/9ddd11Uja3HUFKD/yZjYmL0+OOPOzVt+Rg25rzQUr8716xZo+HDh8vlcmngwIEqLCw8/QEYNNqLL75o4uLizF//+lezdetWc88995iEhARTUVHR2l07pUAgYBYuXGi2bNliSktLzc9+9jPTr18/c/DgQafmJz/5ibnnnnvM3r17nSUcDjvtR44cMRdeeKHJyMgwH330kXnjjTdMr169TH5+fmsMKcojjzxiLrjggqi+79u3z2mfNGmSSU5ONqtWrTIffvihGTFihPmXf/kXp70tj80YYyorK6PGVlxcbCSZd955xxhj57F74403zEMPPWRefvllI8m88sorUe2zZs0yHo/HLFu2zHz88cfmF7/4hUlJSTGHDh1yaq677jpz0UUXmQ0bNph3333XDBw40Nxyyy1OezgcNl6v14wbN85s2bLF/O1vfzPx8fHmT3/6U6uOr6qqymRkZJiXXnrJbN++3QSDQXP55ZebtLS0qH3079/fzJw5M+q4HvtvtjXHd6oxGmPM+PHjzXXXXRfV//3790fV2HoMjTFR49q7d6/561//amJiYsznn3/u1LTlY9iY80JL/O784osvTJcuXUxubq7Ztm2b+eMf/2g6dOhgVqxYcVr9J8A0weWXX26ys7Odn48ePWqSkpJMQUFBK/aqeSorK40ks3btWmfdT37yE3PfffedcJs33njDxMbGmlAo5KybP3++cbvdprq6+kx295QeeeQRc9FFFzXYVlVVZTp16mSWLl3qrPv000+NJBMMBo0xbXtsDbnvvvvMD3/4Q1NXV2eMsfvYGWOOOznU1dUZn89nHn/8cWddVVWVcblc5m9/+5sxxpht27YZSeaDDz5wat58800TExNj/v73vxtjjJk3b54577zzosaYl5dnBg0adIZHFK2hk9/3bdq0yUgyX375pbOuf//+Zs6cOSfcpq2Mz5iGxzh+/Hhzww03nHCb9nYMb7jhBnPNNddErbPpGH7/vNBSvzunT59uLrjggqjPuvnmm00gEDit/nIJqZFqampUUlKijIwMZ11sbKwyMjIUDAZbsWfNEw6HJUk9evSIWv/CCy+oV69euvDCC5Wfn6/vvvvOaQsGgxo6dGjUywQDgYAikYi2bt16djp+Ejt27FBSUpLOP/98jRs3TuXl5ZKkkpIS1dbWRh27wYMHq1+/fs6xa+tjO1ZNTY2ef/553XXXXVFfVGrzsfu+nTt3KhQKRR0zj8ej9PT0qGOWkJCgSy+91KnJyMhQbGysNm7c6NSMHDlScXFxTk0gEFBZWZm++eabszSaxgmHw4qJiTnuO9xmzZqlnj176pJLLtHjjz8eNTVvw/jWrFmjxMREDRo0SJMnT9bXX3/ttLWn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"},"metadata":{}}]},{"cell_type":"markdown","source":"**This is a constant named `MAX_RECIPE_LENGTH` and assigns it the value 750.\nThis constant is likely used to specify the maximum length of a recipe in some context**","metadata":{"id":"7224a27e-832d-4ca3-80a7-65631a79bef0"}},{"cell_type":"code","source":"MAX_RECIPE_LENGTH = 750","metadata":{"id":"67ec05aa-c770-49ad-b669-22649a150b85","execution":{"iopub.status.busy":"2024-04-27T15:55:10.836879Z","iopub.execute_input":"2024-04-27T15:55:10.837354Z","iopub.status.idle":"2024-04-27T15:55:10.843753Z","shell.execute_reply.started":"2024-04-27T15:55:10.837317Z","shell.execute_reply":"2024-04-27T15:55:10.842922Z"},"trusted":true},"execution_count":11,"outputs":[]},{"cell_type":"markdown","source":"This a function called `filter_max_recipes_by_length()` that takes a recipe text as input and returns `True` if the length of the recipe text is less than or equal to the `MAX_RECIPE_LENGTH` constant, and `False` otherwise.\nThe code then uses this function to filter a list of recipe texts (`dataset_stringified`) and create a new list (`dataset_max_filtered`) that contains only the recipe texts that are less than or equal to `MAX_RECIPE_LENGTH`.\nFinally, the code prints the sizes of the original dataset (`dataset_stringified`) and the filtered dataset (`dataset_max_filtered`), as well as the number of recipes that were eliminated due to not meeting the maximum length requirement.","metadata":{"id":"f3ec3c0c-3f11-4ff7-9a28-31ff27a5af34"}},{"cell_type":"code","source":"def filter_max_recipes_by_length(recipe_test):\n return (len(recipe_test) <= MAX_RECIPE_LENGTH)\n\ndataset_max_filtered = [recipe_text for recipe_text in dataset_stringified if filter_max_recipes_by_length(recipe_text)]\n\nprint('Dataset size BEFORE filtering length: ', len(dataset_stringified))\nprint('Dataset size AFTER filtering length: ', len(dataset_max_filtered))\nprint('Number of eliminated recipes length: ', len(dataset_stringified) - len(dataset_max_filtered))","metadata":{"id":"6aa21610-b7d7-431a-8d18-3f62ab9ab853","outputId":"d29812ae-b733-4c25-c885-bc89fbf7ac94","execution":{"iopub.status.busy":"2024-04-27T15:55:10.844868Z","iopub.execute_input":"2024-04-27T15:55:10.845139Z","iopub.status.idle":"2024-04-27T15:55:10.883941Z","shell.execute_reply.started":"2024-04-27T15:55:10.845116Z","shell.execute_reply":"2024-04-27T15:55:10.883006Z"},"trusted":true},"execution_count":12,"outputs":[{"name":"stdout","text":"Dataset size BEFORE filtering length: 75000\nDataset size AFTER filtering length: 67857\nNumber of eliminated recipes length: 7143\n","output_type":"stream"}]},{"cell_type":"markdown","source":"1. **plt.hist(recipes_lengths,range=(0,750), bins=50)**: This line creates a histogram of the recipe lengths. The `plt.hist()` function takes three main arguments: the data to be plotted (in this case, `recipes_lengths`), the range of values to be plotted (in this case, 0 to 2000), and the number of bins to use (in this case, 50). The number of bins determines how many bars will be used in the histogram.\n2. **plt.show()**: This line displays the histogram on the screen.","metadata":{"id":"Zgd3WC7TSSsz"}},{"cell_type":"code","source":"plt.hist(recipes_lengths,range=(0,750), bins=50)\nplt.show()","metadata":{"id":"7sfxqNpiSFWg","outputId":"c1e782e0-aa99-4266-9b23-d83b59649dba","execution":{"iopub.status.busy":"2024-04-27T15:55:10.885272Z","iopub.execute_input":"2024-04-27T15:55:10.886167Z","iopub.status.idle":"2024-04-27T15:55:11.444848Z","shell.execute_reply.started":"2024-04-27T15:55:10.886099Z","shell.execute_reply":"2024-04-27T15:55:11.443973Z"},"trusted":true},"execution_count":13,"outputs":[{"output_type":"display_data","data":{"text/plain":"
","image/png":"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"},"metadata":{}}]},{"cell_type":"markdown","source":"**This is a constant named MIN_RECIPE_LENGTH and assigns it the value 250.\nThis constant is likely used to specify the minimum length of a recipe in some context**","metadata":{"id":"613c4034-fba8-4aad-81d1-3795b073a52d"}},{"cell_type":"code","source":"MIN_RECIPE_LENGTH = 250","metadata":{"id":"8e0e0791-76d7-49ae-bbc8-83e858dc7ea2","execution":{"iopub.status.busy":"2024-04-27T15:55:11.446136Z","iopub.execute_input":"2024-04-27T15:55:11.446434Z","iopub.status.idle":"2024-04-27T15:55:11.450829Z","shell.execute_reply.started":"2024-04-27T15:55:11.446408Z","shell.execute_reply":"2024-04-27T15:55:11.449845Z"},"trusted":true},"execution_count":14,"outputs":[]},{"cell_type":"markdown","source":"This is a function called `filter_min_recipes_by_length()` that takes a recipe text as input and returns `True` if the length is greater than or equal to the (`MIN_RECIPE_LENGTH`), and `False` otherwise.\nThe code then uses this function to filter a list of recipe texts (`dataset_max_filtered`) and create a new list called (`dataset_filtered`) that contains only the recipe texts that are greater than or equal to `MIN_RECIPE_LENGTH`.\nFinally, the code prints the sizes of the original dataset (`dataset_max_filtered`) and the filtered dataset (`dataset_filtered`), as well as the number of recipes that were eliminated due to not meeting the minimum length requirement.","metadata":{"id":"0a045459-9831-4cbe-b698-9b035ad0c438"}},{"cell_type":"code","source":"def filter_min_recipes_by_length(recipe_test):\n return (len(recipe_test) >= MIN_RECIPE_LENGTH)\n\ndataset_filtered = [recipe_text for recipe_text in dataset_max_filtered if filter_min_recipes_by_length(recipe_text)]\n\nprint('Dataset size BEFORE filtering length: ', len(dataset_max_filtered))\nprint('Dataset size AFTER filtering length: ', len(dataset_filtered))\nprint('Number of eliminated recipes length: ', len(dataset_max_filtered) - len(dataset_filtered))","metadata":{"id":"bbe8e2b9-a82b-4792-b515-360b41fd74c2","outputId":"9f158793-2e43-4fb8-b82c-d833d65f2035","execution":{"iopub.status.busy":"2024-04-27T15:55:11.452105Z","iopub.execute_input":"2024-04-27T15:55:11.452441Z","iopub.status.idle":"2024-04-27T15:55:11.489135Z","shell.execute_reply.started":"2024-04-27T15:55:11.452410Z","shell.execute_reply":"2024-04-27T15:55:11.488197Z"},"trusted":true},"execution_count":15,"outputs":[{"name":"stdout","text":"Dataset size BEFORE filtering length: 67857\nDataset size AFTER filtering length: 63766\nNumber of eliminated recipes length: 4091\n","output_type":"stream"}]},{"cell_type":"markdown","source":"1. **plt.hist(recipes_lengths,range=(250,750), bins=50)**: This line creates a histogram of the recipe lengths. The `plt.hist()` function takes three main arguments: the data to be plotted (in this case, `recipes_lengths`), the range of values to be plotted (in this case, 0 to 2000), and the number of bins to use (in this case, 50). The number of bins determines how many bars will be used in the histogram.\n2. **plt.show()**: This line displays the histogram on the screen to show the range of samples.","metadata":{"id":"eUQQARNeSrTV"}},{"cell_type":"code","source":"plt.hist(recipes_lengths,range=(250,750), bins=50)\nplt.show()","metadata":{"id":"6FkPGLYySeu3","outputId":"0fa8785e-0fe4-4732-f9c8-280fdcbbb600","execution":{"iopub.status.busy":"2024-04-27T15:55:11.490273Z","iopub.execute_input":"2024-04-27T15:55:11.490628Z","iopub.status.idle":"2024-04-27T15:55:12.079258Z","shell.execute_reply.started":"2024-04-27T15:55:11.490593Z","shell.execute_reply":"2024-04-27T15:55:12.078272Z"},"trusted":true},"execution_count":16,"outputs":[{"output_type":"display_data","data":{"text/plain":"
","image/png":"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WZZlvfnmm1ZERITl9/vtOuvWrbPcbrfV0tJyxdve050+fdq6/vrrrZKSEus73/mOHWDo69BZtmyZNW7cuE7L6OfQyc/Pt2699dYLlre3t1sej8datWqVva2xsdFyuVzWz3/+c8uyLOvIkSOWJGvfvn12nV/96leWw+Gwfve734Wv8QZ75JFHrOHDh1vt7e38nkOES0i9wLlz5/TSSy/pzJkz8vl8qqioUGtrq9LT0+06I0eO1NChQ1VWViZJKisr05gxY4IeDJiZmalAIKDDhw9f8XPo6XJzc5WdnR3Up5Lo6xA7evSovF6vrr32Ws2ZM0e1tbWS6OdQev311zVx4kR9//vfV3x8vMaPH6///M//tMtramrk9/uD+jo6OlppaWlBfR0TE6OJEyfaddLT0xUREaHy8vIrdzKGOHv2rF544QXdf//9cjgc/J5DhABjsIMHD+qaa66Ry+XSAw88oFdffVWpqany+/1yOp0dXmaZkJAgv98vSfL7/R2eanx+/XwdfOmll17SgQMHVFRU1KGMvg6dtLQ0bdy4Udu2bdO6detUU1OjSZMm6fTp0/RzCP32t7/VunXrdP311+utt97Sgw8+qIcfflg/+9nPJP2xrzrry6/2dXx8fFB5ZGSkYmNj6etObNmyRY2Njbr33nsl8e9GqPTYVwng4kaMGKHKyko1NTXpv//7vzVv3jzt2rWru5vVq5w8eVKPPPKISkpK1K9fv+5uTq+WlZVlfx47dqzS0tKUnJysX/ziF+rfv383tqx3aW9v18SJE/XUU09JksaPH69Dhw7p2Wef1bx587q5db3Tc889p6ysLHm93u5uSq/CCIzBnE6nrrvuOk2YMEFFRUUaN26c1qxZI4/Ho7Nnz6qxsTGofn19vTwejyTJ4/F0mPF+fv18HXx56aKhoUE333yzIiMjFRkZqV27dumZZ55RZGSkEhIS6OswiYmJ0Q033KBjx47xmw6hxMREpaamBm278cYb7ct15/uqs778al83NDQElbe1tenUqVP09Z/46KOPVFpaqr//+7+3t/F7Dg0CTC/S3t6ulpYWTZgwQX379tWOHTvssurqatXW1srn80mSfD6fDh48GPSPUElJidxud4d/3K5mU6dO1cGDB1VZWWkvEydO1Jw5c+zP9HV4NDc36/jx40pMTOQ3HULf/va3VV1dHbTtN7/5jZKTkyVJKSkp8ng8QX0dCARUXl4e1NeNjY2qqKiw6+zcuVPt7e1KS0u7Amdhjueff17x8fHKzs62t/F7DpHunkWMy/PYY49Zu3btsmpqaqyqqirrsccesxwOh7V9+3bLsr68RW/o0KHWzp07rf3791s+n8/y+Xz298/fopeRkWFVVlZa27Zts4YMGcItepfgq3chWRZ9HSqLFy+23nnnHaumpsZ67733rPT0dCsuLs5qaGiwLIt+DpW9e/dakZGR1j/90z9ZR48etTZt2mRFRUVZL7zwgl2nuLjYiomJsV577TWrqqrK+u53v9vpbdTjx4+3ysvLrV//+tfW9ddfz23Uf+LcuXPW0KFDrfz8/A5l/J7/fAQYQ91///1WcnKy5XQ6rSFDhlhTp061w4tlWdYf/vAH64c//KE1aNAgKyoqyvqbv/kbq66uLmgfJ06csLKysqz+/ftbcXFx1uLFi63W1tYrfSrG+dMAQ1+Hxp133mklJiZaTqfT+ou/+AvrzjvvDHo2Cf0cOr/85S+t0aNHWy6Xyxo5cqS1fv36oPL29nbrJz/5iZWQkGC5XC5r6tSpVnV1dVCdTz/91Jo1a5Z1zTXXWG6327rvvvus06dPX8nT6PHeeustS1KHvrMsfs+h4LAsy+ruUSAAAICuYA4MAAAwDgEGAAAYhwADAACMQ4ABAADGIcAAAADjEGAAAIBxCDAAAMA4BBgAAGAcAgwAADAOAQYAABiHAAMAAIxDgAEAAMb5f+mc7ZWP1IUIAAAAAElFTkSuQmCC"},"metadata":{}}]},{"cell_type":"markdown","source":"## Tokenizing Characters","metadata":{"id":"f517437c-1211-46f0-abf4-ae0426d19b26"}},{"cell_type":"markdown","source":"The code defines a constant named `STOP_SIGN` and assigns it the value `␣`. This constant is likely used as an indicator to mark the end of a recipe.","metadata":{"id":"3301638d-aacc-4d14-9304-ca2b5db1b448"}},{"cell_type":"code","source":"# Indicator of the end of the recipe.\nSTOP_SIGN = '␣'","metadata":{"id":"c2b39050-db4d-4f87-9c1d-5ee64433b178","execution":{"iopub.status.busy":"2024-04-27T15:55:12.080308Z","iopub.execute_input":"2024-04-27T15:55:12.080586Z","iopub.status.idle":"2024-04-27T15:55:12.084997Z","shell.execute_reply.started":"2024-04-27T15:55:12.080563Z","shell.execute_reply":"2024-04-27T15:55:12.084058Z"},"trusted":true},"execution_count":17,"outputs":[]},{"cell_type":"markdown","source":" This code is an instantiation of the `Tokenizer` class from the `tf.keras.preprocessing.text` module in TensorFlow. This class is used to vectorize text data, which is a necessary step before training a machine learning model on text data.\nHere's a breakdown of what each line of code does:\n1. `tokenizer = tf.keras.preprocessing.text.Tokenizer(`: This line creates an instance of the `Tokenizer` class.\n2. `char_level=True`: This argument specifies that the tokenizer should tokenize the text at the character level instead of the word level. This means that each character in the text will be considered a separate token.\n3. `filters=''`: This argument specifies the characters that should be removed from the text before tokenization. In this case, no characters will be removed.\n4. `lower=False`: This argument specifies whether the text should be converted to lowercase before tokenization. In this case, the text will not be converted to lowercase.\n5. `split=''`: This argument specifies the delimiter that should be used to split the text into tokens. In this case, no delimiter will be used, which means that the entire text will be considered a single token.\nOnce the tokenizer has been instantiated, it can be used to tokenize text data by calling the `tokenize()` method. The `tokenize()` method takes a list of strings as input and returns a list of lists of integers, where each integer represents the index of a token in the tokenizer's vocabulary.","metadata":{"id":"2d0f0d01-6d38-407c-ab06-8685c6c64bb7"}},{"cell_type":"code","source":"tokenizer = tf.keras.preprocessing.text.Tokenizer(\n char_level=True,\n filters='',\n lower=False,\n split=''\n)","metadata":{"id":"28cba549-2212-4734-80f0-331c125c0950","execution":{"iopub.status.busy":"2024-04-27T15:55:12.086209Z","iopub.execute_input":"2024-04-27T15:55:12.086547Z","iopub.status.idle":"2024-04-27T15:55:12.205760Z","shell.execute_reply.started":"2024-04-27T15:55:12.086515Z","shell.execute_reply":"2024-04-27T15:55:12.204694Z"},"trusted":true},"execution_count":18,"outputs":[]},{"cell_type":"markdown","source":"This code is used to train the tokenizer to recognize the stop sign symbol as a separate token.","metadata":{"id":"a489ba06-a3e8-4a00-9fec-2fde02d852ea"}},{"cell_type":"code","source":"# Stop word is not a part of recipes, but tokenizer must know about it as well.\ntokenizer.fit_on_texts([STOP_SIGN])","metadata":{"id":"dcd428e7-018b-409b-bcb3-cab4db71e7ab","execution":{"iopub.status.busy":"2024-04-27T15:55:12.207277Z","iopub.execute_input":"2024-04-27T15:55:12.207960Z","iopub.status.idle":"2024-04-27T15:55:12.212411Z","shell.execute_reply.started":"2024-04-27T15:55:12.207924Z","shell.execute_reply":"2024-04-27T15:55:12.211497Z"},"trusted":true},"execution_count":19,"outputs":[]},{"cell_type":"markdown","source":"This code is used to train the tokenizer on the `dataset_filtered`. This means that the tokenizer will learn to recognize the words and patterns that appear in these texts and will be able to use this knowledge to tokenize new texts in the future.","metadata":{"id":"a90bfde0-52a7-44cb-a8e5-b5d1f33b452e"}},{"cell_type":"code","source":"tokenizer.fit_on_texts(dataset_filtered)","metadata":{"id":"084a2ef7-f319-434f-b9db-8118bc899960","execution":{"iopub.status.busy":"2024-04-27T15:55:12.213557Z","iopub.execute_input":"2024-04-27T15:55:12.213849Z","iopub.status.idle":"2024-04-27T15:55:21.437039Z","shell.execute_reply.started":"2024-04-27T15:55:12.213824Z","shell.execute_reply":"2024-04-27T15:55:21.436160Z"},"trusted":true},"execution_count":20,"outputs":[]},{"cell_type":"markdown","source":"This function returns the tokenizer configuration as Python dictionary.","metadata":{"id":"b669a1c4-4880-42ed-9a04-f9640644880e"}},{"cell_type":"code","source":"tokenizer.get_config()","metadata":{"id":"20ef8d4a-a623-40d6-801c-9396e24f1d00","outputId":"37f3c399-e8fb-4825-ec1b-faaa596bd7c8","execution":{"iopub.status.busy":"2024-04-27T15:55:21.438218Z","iopub.execute_input":"2024-04-27T15:55:21.438496Z","iopub.status.idle":"2024-04-27T15:55:21.445670Z","shell.execute_reply.started":"2024-04-27T15:55:21.438473Z","shell.execute_reply":"2024-04-27T15:55:21.444641Z"},"trusted":true},"execution_count":21,"outputs":[{"execution_count":21,"output_type":"execute_result","data":{"text/plain":"{'num_words': None,\n 'filters': '',\n 'lower': False,\n 'split': '',\n 'char_level': True,\n 'oov_token': None,\n 'document_count': 63767,\n 'word_counts': '{\"\\\\u2423\": 1, \"\\\\ud83d\\\\udcd5\": 63766, \" \": 4649638, \"N\": 4456, \"o\": 1359407, \"-\": 38957, \"B\": 70103, \"a\": 1489465, \"k\": 283515, \"e\": 2098978, \"u\": 657374, \"t\": 1255684, \"C\": 105566, \"i\": 1212724, \"s\": 1158374, \"\\\\n\": 1391649, \"\\\\ud83e\\\\udd69\": 63766, \"\\\\u2022\": 529389, \"\\\\\"\": 1546526, \"1\": 395131, \"c\": 861788, \".\": 691178, \"f\": 259520, \"r\": 1273815, \"m\": 447692, \"l\": 910392, \"y\": 141222, \"p\": 668438, \"d\": 786658, \"b\": 398291, \"w\": 218181, \"n\": 1281435, \"g\": 491696, \"/\": 147775, \"2\": 207739, \"v\": 150239, \"(\": 58295, \")\": 58285, \"T\": 58103, \"3\": 103176, \"z\": 59824, \"h\": 527464, \"\\\\u270d\": 63766, \"\\\\ufe0f\": 63766, \"\\\\u25aa\": 415898, \"\\\\ufe0e\": 415898, \"I\": 14140, \"q\": 17575, \"x\": 96837, \"S\": 81053, \"5\": 58008, \";\": 23748, \"U\": 2959, \"0\": 154088, \"L\": 12847, \"J\": 5169, \"\\'\": 3882, \"j\": 25952, \"4\": 82881, \"P\": 65337, \"M\": 52964, \"7\": 7394, \"\\\\\\\\\": 33418, \"6\": 19829, \"8\": 23684, \"Y\": 3255, \"F\": 17968, \"R\": 23387, \"9\": 10808, \"K\": 4625, \"A\": 49256, \"D\": 22115, \"W\": 18975, \"E\": 5607, \"O\": 8151, \"Q\": 1314, \"H\": 11563, \"G\": 9997, \":\": 2296, \",\": 1050, \"Z\": 987, \"V\": 3873, \"*\": 1047, \"!\": 1474, \"&\": 446, \"+\": 99, \"X\": 95, \"?\": 102, \"]\": 6, \"#\": 75, \"%\": 235, \"~\": 88, \"`\": 19, \"=\": 12, \"_\": 25, \"|\": 4, \"$\": 7, \"\\\\u00e9\": 2, \"@\": 1, \">\": 1}',\n 'word_docs': '{\"\\\\u2423\": 1, \"g\": 63352, \"a\": 63766, \"-\": 26996, \"1\": 63149, \"T\": 34313, \"h\": 63449, \"\\\\\"\": 63766, \"S\": 45137, \"p\": 63632, \"C\": 51626, \";\": 17538, \"2\": 58787, \"x\": 46208, \"\\\\ufe0f\": 63766, \"t\": 63765, \"\\\\ufe0e\": 63766, \"n\": 63766, \"\\\\u2022\": 63766, \"c\": 63758, \"d\": 63745, \"b\": 62911, \"(\": 33841, \"I\": 11829, \"L\": 10964, \"3\": 48330, \"\\\\u270d\": 63766, \"r\": 63766, \"N\": 4097, \"U\": 2681, \"o\": 63764, \"w\": 59633, \"/\": 51553, \"\\\\u25aa\": 63766, \"l\": 63755, \"s\": 63764, \"u\": 63692, \"i\": 63766, \"e\": 63766, \"y\": 51761, \"f\": 60734, \"q\": 12807, \"\\\\n\": 63766, \"B\": 43158, \")\": 33835, \"\\\\ud83d\\\\udcd5\": 63766, \"z\": 29788, \"v\": 54312, \"k\": 61293, \"\\\\ud83e\\\\udd69\": 63766, \"0\": 37880, \"m\": 63272, \".\": 63765, \" \": 63766, \"5\": 36238, \"7\": 6694, \"j\": 15471, \"J\": 3627, \"M\": 37130, \"\\\\\\\\\": 29898, \"P\": 39552, \"4\": 42598, \"\\'\": 3818, \"6\": 15770, \"8\": 18484, \"Y\": 3112, \"F\": 14655, \"R\": 18038, \"9\": 9958, \"K\": 3590, \"A\": 32792, \"D\": 18309, \"W\": 13663, \"E\": 4926, \"O\": 6314, \"Q\": 1266, \"H\": 9993, \"G\": 8864, \":\": 1916, \",\": 832, \"Z\": 950, \"V\": 3214, \"*\": 605, \"!\": 1256, \"&\": 320, \"+\": 89, \"X\": 87, \"?\": 45, \"]\": 6, \"#\": 70, \"%\": 211, \"~\": 50, \"`\": 19, \"=\": 11, \"_\": 6, \"|\": 3, \"$\": 5, \"\\\\u00e9\": 2, \"@\": 1, \">\": 1}',\n 'index_docs': '{\"1\": 63766, \"98\": 1, \"20\": 63352, \"4\": 63766, \"52\": 26996, \"25\": 63149, \"48\": 34313, \"19\": 63449, \"3\": 63766, \"38\": 45137, \"16\": 63632, \"34\": 51626, \"55\": 17538, \"29\": 58787, \"36\": 46208, \"44\": 63766, \"9\": 63765, \"23\": 63766, \"7\": 63766, \"18\": 63766, \"13\": 63758, \"14\": 63745, \"24\": 62911, \"46\": 33841, \"63\": 11829, \"64\": 10964, \"35\": 48330, \"43\": 63766, \"8\": 63766, \"73\": 4097, \"77\": 2681, \"6\": 63764, \"28\": 59633, \"32\": 51553, \"22\": 63766, \"12\": 63755, \"11\": 63764, \"17\": 63692, \"10\": 63766, \"2\": 63766, \"33\": 51761, \"27\": 60734, \"62\": 12807, \"5\": 63766, \"39\": 43158, \"47\": 33835, \"41\": 63766, \"45\": 29788, \"31\": 54312, \"26\": 61293, \"42\": 63766, \"30\": 37880, \"21\": 63272, \"15\": 63765, \"49\": 36238, \"69\": 6694, \"54\": 15471, \"71\": 3627, \"50\": 37130, \"53\": 29898, \"40\": 39552, \"37\": 42598, \"74\": 3818, \"59\": 15770, \"56\": 18484, \"76\": 3112, \"61\": 14655, \"57\": 18038, \"66\": 9958, \"72\": 3590, \"51\": 32792, \"58\": 18309, \"60\": 13663, \"70\": 4926, \"68\": 6314, \"80\": 1266, \"65\": 9993, \"67\": 8864, \"78\": 1916, \"81\": 832, \"83\": 950, \"75\": 3214, \"82\": 605, \"79\": 1256, \"84\": 320, \"87\": 89, \"88\": 87, \"86\": 45, \"95\": 6, \"90\": 70, \"85\": 211, \"89\": 50, \"92\": 19, \"93\": 11, \"91\": 6, \"96\": 3, \"94\": 5, \"97\": 2, \"99\": 1, \"100\": 1}',\n 'index_word': '{\"1\": \" \", \"2\": \"e\", \"3\": \"\\\\\"\", \"4\": \"a\", \"5\": \"\\\\n\", \"6\": \"o\", \"7\": \"n\", \"8\": \"r\", \"9\": \"t\", \"10\": \"i\", \"11\": \"s\", \"12\": \"l\", \"13\": \"c\", \"14\": \"d\", \"15\": \".\", \"16\": \"p\", \"17\": \"u\", \"18\": \"\\\\u2022\", \"19\": \"h\", \"20\": \"g\", \"21\": \"m\", \"22\": \"\\\\u25aa\", \"23\": \"\\\\ufe0e\", \"24\": \"b\", \"25\": \"1\", \"26\": \"k\", \"27\": \"f\", \"28\": \"w\", \"29\": \"2\", \"30\": \"0\", \"31\": \"v\", \"32\": \"/\", \"33\": \"y\", \"34\": \"C\", \"35\": \"3\", \"36\": \"x\", \"37\": \"4\", \"38\": \"S\", \"39\": \"B\", \"40\": \"P\", \"41\": \"\\\\ud83d\\\\udcd5\", \"42\": \"\\\\ud83e\\\\udd69\", \"43\": \"\\\\u270d\", \"44\": \"\\\\ufe0f\", \"45\": \"z\", \"46\": \"(\", \"47\": \")\", \"48\": \"T\", \"49\": \"5\", \"50\": \"M\", \"51\": \"A\", \"52\": \"-\", \"53\": \"\\\\\\\\\", \"54\": \"j\", \"55\": \";\", \"56\": \"8\", \"57\": \"R\", \"58\": \"D\", \"59\": \"6\", \"60\": \"W\", \"61\": \"F\", \"62\": \"q\", \"63\": \"I\", \"64\": \"L\", \"65\": \"H\", \"66\": \"9\", \"67\": \"G\", \"68\": \"O\", \"69\": \"7\", \"70\": \"E\", \"71\": \"J\", \"72\": \"K\", \"73\": \"N\", \"74\": \"\\'\", \"75\": \"V\", \"76\": \"Y\", \"77\": \"U\", \"78\": \":\", \"79\": \"!\", \"80\": \"Q\", \"81\": \",\", \"82\": \"*\", \"83\": \"Z\", \"84\": \"&\", \"85\": \"%\", \"86\": \"?\", \"87\": \"+\", \"88\": \"X\", \"89\": \"~\", \"90\": \"#\", \"91\": \"_\", \"92\": \"`\", \"93\": \"=\", \"94\": \"$\", \"95\": \"]\", \"96\": \"|\", \"97\": \"\\\\u00e9\", \"98\": \"\\\\u2423\", \"99\": \"@\", \"100\": \">\"}',\n 'word_index': '{\" \": 1, \"e\": 2, \"\\\\\"\": 3, \"a\": 4, \"\\\\n\": 5, \"o\": 6, \"n\": 7, \"r\": 8, \"t\": 9, \"i\": 10, \"s\": 11, \"l\": 12, \"c\": 13, \"d\": 14, \".\": 15, \"p\": 16, \"u\": 17, \"\\\\u2022\": 18, \"h\": 19, \"g\": 20, \"m\": 21, \"\\\\u25aa\": 22, \"\\\\ufe0e\": 23, \"b\": 24, \"1\": 25, \"k\": 26, \"f\": 27, \"w\": 28, \"2\": 29, \"0\": 30, \"v\": 31, \"/\": 32, \"y\": 33, \"C\": 34, \"3\": 35, \"x\": 36, \"4\": 37, \"S\": 38, \"B\": 39, \"P\": 40, \"\\\\ud83d\\\\udcd5\": 41, \"\\\\ud83e\\\\udd69\": 42, \"\\\\u270d\": 43, \"\\\\ufe0f\": 44, \"z\": 45, \"(\": 46, \")\": 47, \"T\": 48, \"5\": 49, \"M\": 50, \"A\": 51, \"-\": 52, \"\\\\\\\\\": 53, \"j\": 54, \";\": 55, \"8\": 56, \"R\": 57, \"D\": 58, \"6\": 59, \"W\": 60, \"F\": 61, \"q\": 62, \"I\": 63, \"L\": 64, \"H\": 65, \"9\": 66, \"G\": 67, \"O\": 68, \"7\": 69, \"E\": 70, \"J\": 71, \"K\": 72, \"N\": 73, \"\\'\": 74, \"V\": 75, \"Y\": 76, \"U\": 77, \":\": 78, \"!\": 79, \"Q\": 80, \",\": 81, \"*\": 82, \"Z\": 83, \"&\": 84, \"%\": 85, \"?\": 86, \"+\": 87, \"X\": 88, \"~\": 89, \"#\": 90, \"_\": 91, \"`\": 92, \"=\": 93, \"$\": 94, \"]\": 95, \"|\": 96, \"\\\\u00e9\": 97, \"\\\\u2423\": 98, \"@\": 99, \">\": 100}'}"},"metadata":{}}]},{"cell_type":"markdown","source":"\nThe `VOCABULARY_SIZE` variable is used to specify the number of unique tokens that the tokenizer can recognize.Tthe vocabulary size is calculated by taking the length of the `tokenizer.word_counts` dictionary, which contains the frequency of each word in the training data, and adding 1..\nThe `print` statement is used to display the value of the `VOCABULARY_SIZE` varia.le.\n","metadata":{"id":"dc3bfb5b-570a-4c62-bee7-d1ecc71b23af"}},{"cell_type":"code","source":"# Adding +1 to take into account a special unassigned 0 index.\nVOCABULARY_SIZE = len(tokenizer.word_counts) + 1\n\nprint('VOCABULARY_SIZE: ', VOCABULARY_SIZE)","metadata":{"id":"1fd50226-2b26-472b-a529-0fe57abf2139","outputId":"afcd9a6f-bf4e-4021-b586-12a913b9c51c","execution":{"iopub.status.busy":"2024-04-27T15:55:21.446773Z","iopub.execute_input":"2024-04-27T15:55:21.447072Z","iopub.status.idle":"2024-04-27T15:55:21.457531Z","shell.execute_reply.started":"2024-04-27T15:55:21.447039Z","shell.execute_reply":"2024-04-27T15:55:21.456705Z"},"trusted":true},"execution_count":22,"outputs":[{"name":"stdout","text":"VOCABULARY_SIZE: 101\n","output_type":"stream"}]},{"cell_type":"markdown","source":"This code is printing the word that corresponds to the index 21 in the tokenizer's vocabulary","metadata":{"id":"3582caab-849b-4cdf-b961-21f96ef56fa0"}},{"cell_type":"code","source":"print(tokenizer.index_word[21])","metadata":{"id":"d86125d9-d3b2-4f33-9bc0-66d5ef851e03","outputId":"2c5dea4e-ce4f-4497-afde-56361d0e7d6a","execution":{"iopub.status.busy":"2024-04-27T15:55:21.459634Z","iopub.execute_input":"2024-04-27T15:55:21.460004Z","iopub.status.idle":"2024-04-27T15:55:21.468894Z","shell.execute_reply.started":"2024-04-27T15:55:21.459971Z","shell.execute_reply":"2024-04-27T15:55:21.468132Z"},"trusted":true},"execution_count":23,"outputs":[{"name":"stdout","text":"m\n","output_type":"stream"}]},{"cell_type":"markdown","source":"This code is printing the index of the word m in the tokenizer's vocabulary","metadata":{"id":"da001dde-0a75-4d7d-805e-01bc0704284d"}},{"cell_type":"code","source":"tokenizer.word_index['m']","metadata":{"id":"ddbd0283-e0ba-42f0-89dc-59f7719fd871","outputId":"2705de20-a257-4eb1-a564-efb3ec33bb75","execution":{"iopub.status.busy":"2024-04-27T15:55:21.470042Z","iopub.execute_input":"2024-04-27T15:55:21.470388Z","iopub.status.idle":"2024-04-27T15:55:21.480562Z","shell.execute_reply.started":"2024-04-27T15:55:21.470356Z","shell.execute_reply":"2024-04-27T15:55:21.479685Z"},"trusted":true},"execution_count":24,"outputs":[{"execution_count":24,"output_type":"execute_result","data":{"text/plain":"21"},"metadata":{}}]},{"cell_type":"markdown","source":"The `tokenizer.sequences_to_texts` method converts a list of token sequences into a list of text strings. In this case, the list of token sequences is created by iterating over the range of indices in the tokenizer's vocabulary and creating a list of lists, each containing a single token index.\nThe `print` statement is used to display the list of characters that correspond to the list of token indices.\nThe code creates an array of characters that represent the vocabulary of the tokenizer.","metadata":{"id":"9935ac2a-2790-4549-8c76-6d2998be596e"}},{"cell_type":"code","source":"# For demo application we need to have an array of characters as vocabulary.\narray_vocabulary = tokenizer.sequences_to_texts([[word_index] for word_index in range(VOCABULARY_SIZE)])\nprint([char for char in array_vocabulary])","metadata":{"id":"85a6b042-68aa-4733-9b83-c69080f15853","outputId":"9767e1e1-c5dc-4259-bb8e-ce2b9e47c776","execution":{"iopub.status.busy":"2024-04-27T15:55:21.481529Z","iopub.execute_input":"2024-04-27T15:55:21.481786Z","iopub.status.idle":"2024-04-27T15:55:21.491113Z","shell.execute_reply.started":"2024-04-27T15:55:21.481763Z","shell.execute_reply":"2024-04-27T15:55:21.490325Z"},"trusted":true},"execution_count":25,"outputs":[{"name":"stdout","text":"['', ' ', 'e', '\"', 'a', '\\n', 'o', 'n', 'r', 't', 'i', 's', 'l', 'c', 'd', '.', 'p', 'u', '•', 'h', 'g', 'm', '▪', '︎', 'b', '1', 'k', 'f', 'w', '2', '0', 'v', '/', 'y', 'C', '3', 'x', '4', 'S', 'B', 'P', '📕', '🥩', '✍', '️', 'z', '(', ')', 'T', '5', 'M', 'A', '-', '\\\\', 'j', ';', '8', 'R', 'D', '6', 'W', 'F', 'q', 'I', 'L', 'H', '9', 'G', 'O', '7', 'E', 'J', 'K', 'N', \"'\", 'V', 'Y', 'U', ':', '!', 'Q', ',', '*', 'Z', '&', '%', '?', '+', 'X', '~', '#', '_', '`', '=', '$', ']', '|', 'é', '␣', '@', '>']\n","output_type":"stream"}]},{"cell_type":"markdown","source":"The `tokenizer.texts_to_sequences` method converts a list of text strings into a list of token sequences.\nThe tokenizer will break down the text string into a sequence of tokens. The specific tokens that are produced will depend on the tokenizer's vocabulary and the rules that it uses to tokenize text.","metadata":{"id":"fad22343-31d7-4b02-823a-de2994ebb516"}},{"cell_type":"code","source":"tokenizer.texts_to_sequences(['🥩 meat'])","metadata":{"id":"f62fdada-f44d-45be-ab3a-d4fd673fca7d","outputId":"02f8c3ea-457e-4682-9266-0699a368cb61","execution":{"iopub.status.busy":"2024-04-27T15:55:21.492688Z","iopub.execute_input":"2024-04-27T15:55:21.493122Z","iopub.status.idle":"2024-04-27T15:55:21.503005Z","shell.execute_reply.started":"2024-04-27T15:55:21.493090Z","shell.execute_reply":"2024-04-27T15:55:21.502097Z"},"trusted":true},"execution_count":26,"outputs":[{"execution_count":26,"output_type":"execute_result","data":{"text/plain":"[[42, 1, 21, 2, 4, 9]]"},"metadata":{}}]},{"cell_type":"markdown","source":"## Vectorization","metadata":{"id":"dbcc0122-540f-484a-91c8-fff8ebf0c7be"}},{"cell_type":"markdown","source":"\nThe texts_to_sequences method of the tokenizer takes a list of text strings as input and returns a list of lists of integers, where each inner list represents the sequence of token IDs for the corresponding text strin The method of vectorization used in this function is word-level tokenization, where each word in the text string is converted into a unique integer ID.g.\nThe resulting dataset_vectorized is a list of lists of integers, where each inner list represents a sequence of token IDs for a text string in the original dataset.\nThe print statement simply outputs the size of the vectorized dataset, which is the number of text strings in the original dataset.","metadata":{"id":"e8da5722-4b3a-407d-86de-7cdaaa5bf92a"}},{"cell_type":"code","source":"dataset_vectorized = tokenizer.texts_to_sequences(dataset_filtered)\n\nprint('Vectorized dataset size', len(dataset_vectorized))","metadata":{"id":"8d79c158-a292-462a-b0f8-a42f1980f9c8","outputId":"9f939127-ae33-442c-ce72-0d0c175530b8","execution":{"iopub.status.busy":"2024-04-27T15:55:21.504180Z","iopub.execute_input":"2024-04-27T15:55:21.504532Z","iopub.status.idle":"2024-04-27T15:55:30.355707Z","shell.execute_reply.started":"2024-04-27T15:55:21.504501Z","shell.execute_reply":"2024-04-27T15:55:30.354797Z"},"trusted":true},"execution_count":27,"outputs":[{"name":"stdout","text":"Vectorized dataset size 63766\n","output_type":"stream"}]},{"cell_type":"markdown","source":"The function recipe_sequence_to_string takes a recipe sequence as input and converts it back into a text string.\nThe function first uses the tokenizer to convert the recipe sequence back into a list of text strings.\nThen, it uses a regular expression to remove any HTML tags from the text string and replaces any triple spaces with a single space.\nFinally, it prints the resulting text string.\nThe code then calls the recipe_sequence_to_string function with the first recipe sequence in the dataset_vectorized list as input.","metadata":{"id":"597e9ba2-a272-4e44-9f32-24b43a659d34"}},{"cell_type":"code","source":"def recipe_sequence_to_string(recipe_sequence):\n recipe_stringified = tokenizer.sequences_to_texts([recipe_sequence])[0] ## msh fahma awi leh 7atena 0\n recipe_stringified = re.sub(r'(?<=\\S)\\s(?=\\S)', '', recipe_stringified).replace(\" \", \" \")\n print(recipe_stringified)","metadata":{"id":"c581f957-335f-440c-8b99-da5f41c78691","execution":{"iopub.status.busy":"2024-04-27T15:55:30.364028Z","iopub.execute_input":"2024-04-27T15:55:30.364313Z","iopub.status.idle":"2024-04-27T15:55:30.369630Z","shell.execute_reply.started":"2024-04-27T15:55:30.364290Z","shell.execute_reply":"2024-04-27T15:55:30.368692Z"},"trusted":true},"execution_count":28,"outputs":[]},{"cell_type":"markdown","source":"This will convert the 100th recipe sequence back into a text string and print it.","metadata":{"id":"683ef3b6-7055-4849-9552-9cbbee56aa87"}},{"cell_type":"code","source":"recipe_sequence_to_string(dataset_vectorized[99])","metadata":{"id":"f8be5f8e-5ec1-42b5-b2db-a8f6b9a9dcc9","outputId":"debb1873-34a1-456e-c63c-f4252f4a38bc","execution":{"iopub.status.busy":"2024-04-27T15:55:30.370673Z","iopub.execute_input":"2024-04-27T15:55:30.371285Z","iopub.status.idle":"2024-04-27T15:55:30.382074Z","shell.execute_reply.started":"2024-04-27T15:55:30.371258Z","shell.execute_reply":"2024-04-27T15:55:30.381152Z"},"trusted":true},"execution_count":29,"outputs":[{"name":"stdout","text":"📕 Crisp Oatmeal Cookies \n \n 🥩 \n \n • \"4 c. quick cooking oats\" \n • \"2 c. brown sugar \n • packed\" \n • \"1 c. salad oil\" \n • \"2 eggs \n • well beaten\" \n • \"1/2 tsp. salt\" \n • \"1 tsp. almond extract\" \n \n ✍️ \n \n ▪︎ \"Mix oats \n ▪︎ brown sugar and oil; let stand overnight or 8 hours. Preheat oven to 325\\u00b0.\" \n ▪︎ \"Mix rest of ingredients into oat mixture. Drop by teaspoon onto greased baking sheet.\" \n ▪︎ \"Bake 15 minutes. Cool completely before removing from baking sheet.\" \n\n","output_type":"stream"}]},{"cell_type":"markdown","source":"### Add padding to sequences","metadata":{"id":"f61a079f-2a3e-497f-bc83-c935d806f56e"}},{"cell_type":"markdown","source":"This code iterates over the first 20 elements of the list `dataset_vectorized` and print the length of it","metadata":{"id":"1837316c-cbdc-4395-a703-fa9229146f3f"}},{"cell_type":"code","source":"for recipe_index, recipe in enumerate(dataset_vectorized[:20]):\n print('Recipe #{} length: {}'.format(recipe_index + 1, len(recipe)))","metadata":{"id":"74fe03c5-747c-435e-967e-fa57cc971969","outputId":"0168f309-a483-4155-dc25-cfee081f49c3","execution":{"iopub.status.busy":"2024-04-27T15:55:30.383104Z","iopub.execute_input":"2024-04-27T15:55:30.383387Z","iopub.status.idle":"2024-04-27T15:55:30.392329Z","shell.execute_reply.started":"2024-04-27T15:55:30.383363Z","shell.execute_reply":"2024-04-27T15:55:30.391418Z"},"trusted":true},"execution_count":30,"outputs":[{"name":"stdout","text":"Recipe #1 length: 603\nRecipe #2 length: 341\nRecipe #3 length: 361\nRecipe #4 length: 604\nRecipe #5 length: 415\nRecipe #6 length: 484\nRecipe #7 length: 424\nRecipe #8 length: 588\nRecipe #9 length: 600\nRecipe #10 length: 639\nRecipe #11 length: 450\nRecipe #12 length: 304\nRecipe #13 length: 532\nRecipe #14 length: 380\nRecipe #15 length: 548\nRecipe #16 length: 264\nRecipe #17 length: 619\nRecipe #18 length: 500\nRecipe #19 length: 534\nRecipe #20 length: 399\n","output_type":"stream"}]},{"cell_type":"markdown","source":"This code prints the variable `MAX_RECIPE_LENGTH` which assigns the maximum length of the recipes","metadata":{"id":"78618d7f-3e6b-4be8-add9-7dd8ee519d34"}},{"cell_type":"code","source":"MAX_RECIPE_LENGTH","metadata":{"id":"24af5bba-f8ae-4c66-8d18-6c945351e902","outputId":"e76555c5-65f7-4a37-f441-cd3869f750b2","execution":{"iopub.status.busy":"2024-04-27T15:55:30.393447Z","iopub.execute_input":"2024-04-27T15:55:30.393720Z","iopub.status.idle":"2024-04-27T15:55:30.403761Z","shell.execute_reply.started":"2024-04-27T15:55:30.393696Z","shell.execute_reply":"2024-04-27T15:55:30.402901Z"},"trusted":true},"execution_count":31,"outputs":[{"execution_count":31,"output_type":"execute_result","data":{"text/plain":"750"},"metadata":{}}]},{"cell_type":"markdown","source":"This code uses the `pad_sequences` function from the `tf.keras.preprocessing.sequence` module to pad the sequences in the `dataset_vectorized` variable. Padding is a technique used to ensure that all sequences have the same length, which is necessary for certain NLP tasks.\n - The `padding='post'` argument specifies that the padding should be added at the end of the sequences.\n - The `truncating='post'` argument specifies that if a sequence is longer than the specified `maxlen`, it should be truncated at the end.\n - The `maxlen` argument specifies the maximum length of the padded sequences, which is set to `MAX_RECIPE_LENGTH-1`.\n - The `value` argument specifies the value to use for padding. In this case, it is set to the numerical representation of the `STOP_SIGN` token, which is obtained by converting the string `STOP_SIGN` into a numerical sequence using the `tokenizer.texts_to_","metadata":{"id":"1d23ad32-e34d-4c0e-943c-c1f8fd353e6d"}},{"cell_type":"code","source":"dataset_vectorized_padded_without_stops = tf.keras.preprocessing.sequence.pad_sequences(\n dataset_vectorized,\n padding='post',\n truncating='post',\n maxlen=MAX_RECIPE_LENGTH-1,\n value=tokenizer.texts_to_sequences([STOP_SIGN])[0] # 0 is the index of '␣'\n)","metadata":{"id":"8e133d61-298d-4219-85d0-3c12f3b0d5b8","execution":{"iopub.status.busy":"2024-04-27T15:55:30.404884Z","iopub.execute_input":"2024-04-27T15:55:30.405148Z","iopub.status.idle":"2024-04-27T15:55:32.783707Z","shell.execute_reply.started":"2024-04-27T15:55:30.405126Z","shell.execute_reply":"2024-04-27T15:55:32.782919Z"},"trusted":true},"execution_count":32,"outputs":[]},{"cell_type":"markdown","source":"We repeat the function using -1 above and +1 below to make sure that all recipes will have at least 1 stop sign at the end,","metadata":{"id":"8d190ffb-d144-4a78-b579-751191fd3aef"}},{"cell_type":"code","source":"dataset_vectorized_padded = tf.keras.preprocessing.sequence.pad_sequences(\n dataset_vectorized_padded_without_stops,\n padding='post',\n truncating='post',\n maxlen=MAX_RECIPE_LENGTH+1,\n value=tokenizer.texts_to_sequences([STOP_SIGN])[0]\n)","metadata":{"id":"9391ed7a-7188-45e4-8433-6f74b762f66b","execution":{"iopub.status.busy":"2024-04-27T15:55:32.784749Z","iopub.execute_input":"2024-04-27T15:55:32.785016Z","iopub.status.idle":"2024-04-27T15:55:33.064118Z","shell.execute_reply.started":"2024-04-27T15:55:32.784993Z","shell.execute_reply":"2024-04-27T15:55:33.063326Z"},"trusted":true},"execution_count":33,"outputs":[]},{"cell_type":"markdown","source":"This code iterates over the first 20 elements of the list `dataset_vectorized_padded` and print the length of it","metadata":{"id":"99b5cc36-16a8-4df5-9a77-c7cd02c8ea27"}},{"cell_type":"code","source":"for recipe_index, recipe in enumerate(dataset_vectorized_padded[:20]):\n print('Recipe #{} length: {}'.format(recipe_index, len(recipe)))","metadata":{"id":"c4c01fa8-3a82-4cb8-923a-f964128284ca","outputId":"951ec5d1-b5fa-458e-9e08-5d725bb9ceb0","execution":{"iopub.status.busy":"2024-04-27T15:55:33.065292Z","iopub.execute_input":"2024-04-27T15:55:33.065641Z","iopub.status.idle":"2024-04-27T15:55:33.071662Z","shell.execute_reply.started":"2024-04-27T15:55:33.065610Z","shell.execute_reply":"2024-04-27T15:55:33.070805Z"},"trusted":true},"execution_count":34,"outputs":[{"name":"stdout","text":"Recipe #0 length: 751\nRecipe #1 length: 751\nRecipe #2 length: 751\nRecipe #3 length: 751\nRecipe #4 length: 751\nRecipe #5 length: 751\nRecipe #6 length: 751\nRecipe #7 length: 751\nRecipe #8 length: 751\nRecipe #9 length: 751\nRecipe #10 length: 751\nRecipe #11 length: 751\nRecipe #12 length: 751\nRecipe #13 length: 751\nRecipe #14 length: 751\nRecipe #15 length: 751\nRecipe #16 length: 751\nRecipe #17 length: 751\nRecipe #18 length: 751\nRecipe #19 length: 751\n","output_type":"stream"}]},{"cell_type":"markdown","source":"### Create TensorFlow dataset","metadata":{"id":"ZoZqCOjRzoBH"}},{"cell_type":"markdown","source":"The function `tf.data.Dataset.from_tensor_slices()` takes a NumPy array as input and creates a dataset that exports each element of the array as a separate element.\nIn this case, the `dataset_vectorized_padded` variable is a NumPy array that contains the padded vectors of the input text sequences.","metadata":{"id":"IvxncxYPrzml"}},{"cell_type":"code","source":"dataset = tf.data.Dataset.from_tensor_slices(dataset_vectorized_padded)","metadata":{"id":"fpDdBfO_mD9X","execution":{"iopub.status.busy":"2024-04-27T15:55:33.072793Z","iopub.execute_input":"2024-04-27T15:55:33.073102Z","iopub.status.idle":"2024-04-27T15:55:34.164643Z","shell.execute_reply.started":"2024-04-27T15:55:33.073077Z","shell.execute_reply":"2024-04-27T15:55:34.163774Z"},"trusted":true},"execution_count":35,"outputs":[]},{"cell_type":"markdown","source":"This line displays information about the dataset, such as the number of elements, the data types of the elements.","metadata":{"id":"ErxoBVX11HDb"}},{"cell_type":"code","source":"print(dataset)","metadata":{"id":"DrRaSXTsmC6J","outputId":"968fa48e-c17e-462b-82f4-f72dad4f1de7","execution":{"iopub.status.busy":"2024-04-27T15:55:34.165980Z","iopub.execute_input":"2024-04-27T15:55:34.166376Z","iopub.status.idle":"2024-04-27T15:55:34.172290Z","shell.execute_reply.started":"2024-04-27T15:55:34.166340Z","shell.execute_reply":"2024-04-27T15:55:34.171277Z"},"trusted":true},"execution_count":36,"outputs":[{"name":"stdout","text":"<_TensorSliceDataset element_spec=TensorSpec(shape=(751,), dtype=tf.int32, name=None)>\n","output_type":"stream"}]},{"cell_type":"markdown","source":"1. `dataset.take(1)`: This line of code takes the first element from the `dataset` object. It assumes that `dataset` is a collection of recipes, and it selects the 101 recipe from that collection.\n2. `print('Recipe in tensorflow:\\n', dataset.take(1), '\\n\\n\\n')`: This line prints the first recipe data from tensorflow dataset\n3. `print('Raw recipe:\\n', recipe.numpy(), '\\n\\n\\n')`: This line prints the raw recipe data in a human-readable format. The `recipe` variable is likely a NumPy array that contains the recipe data, and the `numpy()` method converts it into a Python list.\n4. `recipe_sequence_to_string(recipe.numpy())`: This line calls a function named `recipe_sequence_to_string` and passes the NumPy array containing the recipe data as an argument. The `recipe_sequence_to_string` function is likely responsible for converting the recipe data into a human-readable string format.\nIn summary, this code snippet appears to be part of a program that processes recipes. It takes the first recipe from a dataset, prints the raw recipe data, and then prints a stringified version of the recipe. The `recipe_sequence_to_string` function is responsible for converting the recipe data into a human-readable string format.","metadata":{"id":"ZMQrrZ-2D3yt"}},{"cell_type":"code","source":"print('Recipe in tensorflow:\\n', dataset.take(1), '\\n\\n\\n')\nfor recipe in dataset.take(1):\n print('Raw recipe:\\n', recipe.numpy(), '\\n\\n\\n')\n print('Stringified recipe:\\n')\n recipe_sequence_to_string(recipe.numpy())\n","metadata":{"id":"724530bd-3768-461d-9742-c282e10a6c89","outputId":"45bdcb89-0140-4e83-9885-23c424a671e8","execution":{"iopub.status.busy":"2024-04-27T15:55:34.173601Z","iopub.execute_input":"2024-04-27T15:55:34.173929Z","iopub.status.idle":"2024-04-27T15:55:34.374003Z","shell.execute_reply.started":"2024-04-27T15:55:34.173880Z","shell.execute_reply":"2024-04-27T15:55:34.373031Z"},"trusted":true},"execution_count":37,"outputs":[{"name":"stdout","text":"Recipe in tensorflow:\n <_TakeDataset element_spec=TensorSpec(shape=(751,), dtype=tf.int32, name=None)> \n\n\n\nRaw recipe:\n [41 1 73 6 52 39 4 26 2 1 73 17 9 1 34 6 6 26 10 2 11 5 5 42\n 5 5 18 1 3 25 1 13 15 1 27 10 8 21 12 33 1 16 4 13 26 2 14 1\n 24 8 6 28 7 1 11 17 20 4 8 3 5 18 1 3 25 32 29 1 13 15 1 2\n 31 4 16 6 8 4 9 2 14 1 21 10 12 26 3 5 18 1 3 25 32 29 1 9\n 11 16 15 1 31 4 7 10 12 12 4 3 5 18 1 3 25 32 29 1 13 15 1 24\n 8 6 26 2 7 1 7 17 9 11 1 46 16 2 13 4 7 11 47 3 5 18 1 3\n 29 1 48 24 11 16 15 1 24 17 9 9 2 8 1 6 8 1 21 4 8 20 4 8\n 10 7 2 3 5 18 1 3 35 1 25 32 29 1 13 15 1 24 10 9 2 1 11 10\n 45 2 1 11 19 8 2 14 14 2 14 1 8 10 13 2 1 24 10 11 13 17 10 9\n 11 3 5 5 43 44 5 5 22 23 1 3 63 7 1 4 1 19 2 4 31 33 1 29\n 52 62 17 4 8 9 1 11 4 17 13 2 16 4 7 5 22 23 1 21 10 36 1 24\n 8 6 28 7 1 11 17 20 4 8 5 22 23 1 7 17 9 11 5 22 23 1 2 31\n 4 16 6 8 4 9 2 14 1 21 10 12 26 1 4 7 14 1 24 17 9 9 2 8\n 1 6 8 1 21 4 8 20 4 8 10 7 2 15 3 5 22 23 1 3 38 9 10 8\n 1 6 31 2 8 1 21 2 14 10 17 21 1 19 2 4 9 1 17 7 9 10 12 1\n 21 10 36 9 17 8 2 1 24 17 24 24 12 2 11 1 4 12 12 1 6 31 2 8\n 1 9 6 16 15 3 5 22 23 1 3 39 6 10 12 1 4 7 14 1 11 9 10 8\n 1 49 1 21 10 7 17 9 2 11 1 21 6 8 2 15 1 48 4 26 2 1 6 27\n 27 1 19 2 4 9 15 3 5 22 23 1 3 38 9 10 8 1 10 7 1 31 4 7\n 10 12 12 4 1 4 7 14 1 13 2 8 2 4 12 55 1 21 10 36 1 28 2 12\n 12 15 3 5 22 23 1 3 77 11 10 7 20 1 29 1 9 2 4 11 16 6 6 7\n 11 5 22 23 1 14 8 6 16 1 4 7 14 1 11 19 4 16 2 1 10 7 9 6\n 1 35 30 1 13 12 17 11 9 2 8 11 1 6 7 1 28 4 36 1 16 4 16 2\n 8 15 3 5 22 23 1 3 64 2 9 1 11 9 4 7 14 1 17 7 9 10 12 1\n 27 10 8 21 5 22 23 1 4 24 6 17 9 1 35 30 1 21 10 7 17 9 2 11\n 15 3 5 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98\n 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98\n 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98\n 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98\n 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98\n 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98 98\n 98 98 98 98 98 98 98] \n\n\n\nStringified recipe:\n\n📕 No-Bake Nut Cookies \n \n 🥩 \n \n • \"1 c. firmly packed brown sugar\" \n • \"1/2 c. evaporated milk\" \n • \"1/2 tsp. vanilla\" \n • \"1/2 c. broken nuts (pecans)\" \n • \"2 Tbsp. butter or margarine\" \n • \"3 1/2 c. bite size shredded rice biscuits\" \n \n ✍️ \n \n ▪︎ \"In a heavy 2-quart saucepan \n ▪︎ mix brown sugar \n ▪︎ nuts \n ▪︎ evaporated milk and butter or margarine.\" \n ▪︎ \"Stir over medium heat until mixture bubbles all over top.\" \n ▪︎ \"Boil and stir 5 minutes more. Take off heat.\" \n ▪︎ \"Stir in vanilla and cereal; mix well.\" \n ▪︎ \"Using 2 teaspoons \n ▪︎ drop and shape into 30 clusters on wax paper.\" \n ▪︎ \"Let stand until firm \n ▪︎ about 30 minutes.\" \n ␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣\n","output_type":"stream"}]},{"cell_type":"markdown","source":"The function `split_input_target` takes a string as input and splits it into two parts: the input text and the target text. The input text is the string without the last character, and the target text is the string with the last character removed.","metadata":{"id":"T43kNUBRUNK4"}},{"cell_type":"code","source":"def split_input_target(recipe):\n input_text = recipe[:-1]\n target_text = recipe[1:]\n\n return input_text, target_text","metadata":{"id":"IKVCLNETTuLp","execution":{"iopub.status.busy":"2024-04-27T15:55:34.375117Z","iopub.execute_input":"2024-04-27T15:55:34.375387Z","iopub.status.idle":"2024-04-27T15:55:34.380139Z","shell.execute_reply.started":"2024-04-27T15:55:34.375363Z","shell.execute_reply":"2024-04-27T15:55:34.379199Z"},"trusted":true},"execution_count":38,"outputs":[]},{"cell_type":"markdown","source":" This code is using the `map` method of a dataset object to apply a function to each element of the dataset. In this case, the function being applied is `split_input_target`, which is presumably a function that takes a single input and splits it into two parts, an input and a target.\nThe `map` method returns a new dataset object that contains the results of applying the function to each element of the original dataset. In this case, the new dataset object will contain pairs of inputs and targets.","metadata":{"id":"fJpJLuOGsiN-"}},{"cell_type":"code","source":"dataset_targeted = dataset.map(split_input_target)\n\nprint(dataset_targeted)","metadata":{"id":"tPzv04iuqQN3","outputId":"82e50429-d1e0-4b74-b769-0bd44b0bc8cd","execution":{"iopub.status.busy":"2024-04-27T15:55:34.381601Z","iopub.execute_input":"2024-04-27T15:55:34.382251Z","iopub.status.idle":"2024-04-27T15:55:34.446443Z","shell.execute_reply.started":"2024-04-27T15:55:34.382216Z","shell.execute_reply":"2024-04-27T15:55:34.445576Z"},"trusted":true},"execution_count":39,"outputs":[{"name":"stdout","text":"<_MapDataset element_spec=(TensorSpec(shape=(750,), dtype=tf.int32, name=None), TensorSpec(shape=(750,), dtype=tf.int32, name=None))>\n","output_type":"stream"}]},{"cell_type":"markdown","source":"The function `split_train_test_data` takes two arguments: `dataset` and `train_ratio`.\n\n`num_samples` is set to the length of the dataset.\n`num_train_samples` is calculated as the integer portion of num_samples multiplied by train_ratio.\n`data_train` is created by taking the first num_train_samples from the dataset.\n`data_test` is created by skipping the first num_train_samples from the dataset.\nBoth `data_train` and `data_test` are converted to numpy arrays by calling `as_numpy_iterator()` and then converted to lists.\nFinally, `data_train` and `data_test` are returned as a tuple.","metadata":{}},{"cell_type":"code","source":"def split_train_test_data(dataset, train_ratio):\n num_samples = len(dataset)\n num_train_samples = int(num_samples * train_ratio)\n data_train = dataset.take(num_train_samples)\n data_test = dataset.skip(num_train_samples)\n data_train = list(data_train.as_numpy_iterator())\n data_test = list(data_test.as_numpy_iterator())\n return data_train, data_test","metadata":{"execution":{"iopub.status.busy":"2024-04-27T15:55:34.447463Z","iopub.execute_input":"2024-04-27T15:55:34.447757Z","iopub.status.idle":"2024-04-27T15:55:34.453193Z","shell.execute_reply.started":"2024-04-27T15:55:34.447730Z","shell.execute_reply":"2024-04-27T15:55:34.452279Z"},"trusted":true},"execution_count":40,"outputs":[]},{"cell_type":"markdown","source":"The first line `data_text_list = list(dataset_targeted)` converts the `dataset_targeted` object to a Python list as it is being iterated over. The result of the iteration is assigned to the variable `data_text_list`.\n\nThe second line `data_train, data_test = split_train_test_data(dataset_targeted, 0.7)` splits the `dataset_targeted` object into a training set and a testing set using the `split_train_test_da`ta function that was defined earlier. The train_ratio argument is set to 0.7, which means that 70% of the `dataset_targeted` object will be used for training, and the remaining 30% will be used for testing. The function returns two objects, `data_train` and `data_test`, which represent the training and testing sets, respectively.","metadata":{}},{"cell_type":"code","source":"data_text_list = list(dataset_targeted)\n\ndata_train, data_test = split_train_test_data(dataset_targeted, 0.7)","metadata":{"execution":{"iopub.status.busy":"2024-04-27T15:55:34.454427Z","iopub.execute_input":"2024-04-27T15:55:34.454789Z","iopub.status.idle":"2024-04-27T15:56:10.476493Z","shell.execute_reply.started":"2024-04-27T15:55:34.454765Z","shell.execute_reply":"2024-04-27T15:56:10.475464Z"},"trusted":true},"execution_count":41,"outputs":[]},{"cell_type":"markdown","source":"`data_train_subset = data_train[:1]`: This line takes the first element of the `data_train `list. The `[:1]` slice notation means \"get the first element of the list\".\n\n`for input_example, target_example in data_train_subset:`: This line starts a loop that iterates over each tuple in the `data_train_subset` list. The loop variable `input_example` will hold the input sequence, and `target_example` will hold the target sequence.\n\n`print('Input sequence size:', repr(len(input_example)))`: This line prints the length of the input sequence. The `repr()` function is used to convert the length to a string.\n\n`print('Target sequence size:', repr(len(target_example)))`: This line prints the length of the target sequence. The `repr()` function is used to convert the length to a string.\n\n`print()`: This line prints an empty line to separate the output for each tuple.\n\n`input_stringified = tokenizer.sequences_to_texts([input_example[:50]])[0]`: This line converts the first 50 tokens of the input sequence to a string. The `sequences_to_texts()` function is used for this conversion. The `[0]` at the end is used to get the first (and only) element of the list returned by `sequences_to_texts()`.\n\n`target_stringified = tokenizer.sequences_to_texts([target_example[:50]])[0]`: This line converts the first 50 tokens of the target sequence to a string. The `sequences_to_texts()` function is used for this conversion. The `[0]` at the end is used to get the first (and only) element of the list returned by `sequences_to_texts()`.","metadata":{}},{"cell_type":"code","source":"data_train_subset = data_train[:1] # Take the first element from the list\n\nfor input_example, target_example in data_train_subset:\n print('Input sequence size:', repr(len(input_example)))\n print('Target sequence size:', repr(len(target_example)))\n print()\n\n input_stringified = tokenizer.sequences_to_texts([input_example[:50]])[0]\n target_stringified = tokenizer.sequences_to_texts([target_example[:50]])[0]\n\n print('Input: ', repr(''.join(input_stringified)))\n print('Target: ', repr(''.join(target_stringified)))","metadata":{"execution":{"iopub.status.busy":"2024-04-27T15:56:10.478182Z","iopub.execute_input":"2024-04-27T15:56:10.478478Z","iopub.status.idle":"2024-04-27T15:56:10.485811Z","shell.execute_reply.started":"2024-04-27T15:56:10.478454Z","shell.execute_reply":"2024-04-27T15:56:10.484876Z"},"trusted":true},"execution_count":42,"outputs":[{"name":"stdout","text":"Input sequence size: 750\nTarget sequence size: 750\n\nInput: '📕 N o - B a k e N u t C o o k i e s \\n \\n 🥩 \\n \\n • \" 1 c . f i r m l y p a c k e d b r'\nTarget: ' N o - B a k e N u t C o o k i e s \\n \\n 🥩 \\n \\n • \" 1 c . f i r m l y p a c k e d b r o'\n","output_type":"stream"}]},{"cell_type":"markdown","source":"`len(data_test)` returns the number of elements in the `data_test` list.","metadata":{}},{"cell_type":"code","source":"len( data_test)","metadata":{"execution":{"iopub.status.busy":"2024-04-27T15:56:10.486976Z","iopub.execute_input":"2024-04-27T15:56:10.487275Z","iopub.status.idle":"2024-04-27T15:56:10.499520Z","shell.execute_reply.started":"2024-04-27T15:56:10.487251Z","shell.execute_reply":"2024-04-27T15:56:10.498662Z"},"trusted":true},"execution_count":43,"outputs":[{"execution_count":43,"output_type":"execute_result","data":{"text/plain":"19130"},"metadata":{}}]},{"cell_type":"markdown","source":"`len(data_train)` returns the number of elements in the `data_train` list.","metadata":{}},{"cell_type":"code","source":"len( data_train)","metadata":{"execution":{"iopub.status.busy":"2024-04-27T15:56:10.500593Z","iopub.execute_input":"2024-04-27T15:56:10.500869Z","iopub.status.idle":"2024-04-27T15:56:10.509951Z","shell.execute_reply.started":"2024-04-27T15:56:10.500845Z","shell.execute_reply":"2024-04-27T15:56:10.508965Z"},"trusted":true},"execution_count":44,"outputs":[{"execution_count":44,"output_type":"execute_result","data":{"text/plain":"44636"},"metadata":{}}]},{"cell_type":"markdown","source":"This code is used to print out the first element of the `data_train list`, which is a subset of the training data. The first line `data_train_subset = data_train[:1]` creates a new list `data_train_subset` that contains only the first element of `data_train`.\n\nThe for loop then iterates over this subset, which contains a single element that is a tuple of input and target sequences. The `input_example` and `target_example` variables are used to refer to the input and target sequences, respectively.\n\nThe code then prints out the size of the input and target sequences using the `len()` function. This is followed by converting the input and target sequences to strings using the tokenizer.sequences_to_texts() function. The `[:50]` slice is used to limit the length of the input and target sequences to the first 50 characters.\n\nFinally, the input and target sequences are printed out using the `repr()` function to display the strings in a readable format. The `join()` function is used to concatenate the individual characters in the input and target sequences into strings.","metadata":{}},{"cell_type":"code","source":"def transform_element(input_target):\n input_sequence, target_sequence = input_target[0], input_target[1]\n\n # Apply tf.squeeze() only if the shape is compatible\n if input_sequence.shape[-1] == 1:\n input_sequence = tf.squeeze(input_sequence, axis=-1)\n if target_sequence.shape[-1] == 1:\n target_sequence = tf.squeeze(target_sequence, axis=-1)\n\n return input_sequence, target_sequence","metadata":{"execution":{"iopub.status.busy":"2024-04-27T15:56:10.511310Z","iopub.execute_input":"2024-04-27T15:56:10.511602Z","iopub.status.idle":"2024-04-27T15:56:10.520441Z","shell.execute_reply.started":"2024-04-27T15:56:10.511578Z","shell.execute_reply":"2024-04-27T15:56:10.519641Z"},"trusted":true},"execution_count":45,"outputs":[]},{"cell_type":"markdown","source":"### Split up the dataset into batches","metadata":{"id":"FvQSGO7y5hHH"}},{"cell_type":"markdown","source":" This display information about the targeted dataset, such as the number of elements.","metadata":{"id":"G-NeJSZvHRwF"}},{"cell_type":"code","source":"print(dataset_targeted)","metadata":{"id":"-vAzNdYP2eXl","outputId":"b56d890e-c205-4f96-b8a9-05d5eade0cc3","execution":{"iopub.status.busy":"2024-04-27T15:56:10.521521Z","iopub.execute_input":"2024-04-27T15:56:10.521945Z","iopub.status.idle":"2024-04-27T15:56:10.531565Z","shell.execute_reply.started":"2024-04-27T15:56:10.521913Z","shell.execute_reply":"2024-04-27T15:56:10.530588Z"},"trusted":true},"execution_count":46,"outputs":[{"name":"stdout","text":"<_MapDataset element_spec=(TensorSpec(shape=(750,), dtype=tf.int32, name=None), TensorSpec(shape=(750,), dtype=tf.int32, name=None))>\n","output_type":"stream"}]},{"cell_type":"markdown","source":"This code sets the batch size to 64 and the shuffle buffer size to 1000. The shuffle buffer size determines how many elements are shuffled at a time when creating batches from the dataset. In this case, it means that the dataset will be shuffled in chunks of 1000 elements.\nThe `shuffle()` method in TensorFlow creates a dataset that shuffles its elements randomly. The `batch()` method creates a dataset that batches its elements into fixed-size batches. The `drop_remainder=True` argument specifies that any remaining elements that don't fit into a complete batch should be dropped. The `repeat()` method creates a dataset that repeats itself indefinitely.","metadata":{"id":"TRfDMZDtEFFq"}},{"cell_type":"code","source":"# Batch size.\n\n\n\nBATCH_SIZE = 64\n\n# Buffer size to shuffle the dataset (TF data is designed to work\n# with possibly infinite sequences, so it doesn't attempt to shuffle\n# the entire sequence in memory. Instead, it maintains a buffer in\n# which it shuffles elements).\nSHUFFLE_BUFFER_SIZE = 1000\n\ndataset_train = dataset_targeted.shuffle(SHUFFLE_BUFFER_SIZE).batch(BATCH_SIZE, drop_remainder=True).repeat()\n\nprint(dataset_train)","metadata":{"id":"JG06vo8o5pXg","outputId":"3616f116-1bbf-4081-9e7f-29c4cf03135d","execution":{"iopub.status.busy":"2024-04-27T15:56:10.532811Z","iopub.execute_input":"2024-04-27T15:56:10.533318Z","iopub.status.idle":"2024-04-27T15:56:10.550842Z","shell.execute_reply.started":"2024-04-27T15:56:10.533292Z","shell.execute_reply":"2024-04-27T15:56:10.549971Z"},"trusted":true},"execution_count":47,"outputs":[{"name":"stdout","text":"<_RepeatDataset element_spec=(TensorSpec(shape=(64, 750), dtype=tf.int32, name=None), TensorSpec(shape=(64, 750), dtype=tf.int32, name=None))>\n","output_type":"stream"}]},{"cell_type":"markdown","source":"This code uses the `take()` to retrie the first batch of data from the dataset_train.\nThe code then prints the input text and target text for the first batch of data. The input text is the text that is fed into the language model, and the target text is the text that the language model is expected to produce.","metadata":{"id":"2l6_3cRUF8fM"}},{"cell_type":"code","source":"for input_text, target_text in dataset_train.take(1):\n print('1st batch: input_text:', input_text,'\\n')\n print('1st batch: target_text:', target_text,'\\n')","metadata":{"id":"1BssYJXnD1s0","outputId":"4e890f6a-37ee-468f-e812-e7b479616076","execution":{"iopub.status.busy":"2024-04-27T15:56:10.551833Z","iopub.execute_input":"2024-04-27T15:56:10.552133Z","iopub.status.idle":"2024-04-27T15:56:10.744870Z","shell.execute_reply.started":"2024-04-27T15:56:10.552100Z","shell.execute_reply":"2024-04-27T15:56:10.743936Z"},"trusted":true},"execution_count":48,"outputs":[{"name":"stdout","text":"1st batch: input_text: tf.Tensor(\n[[41 1 57 ... 98 98 98]\n [41 1 57 ... 98 98 98]\n [41 1 40 ... 98 98 98]\n ...\n [41 1 39 ... 98 98 98]\n [41 1 39 ... 98 98 98]\n [41 1 61 ... 98 98 98]], shape=(64, 750), dtype=int32) \n\n1st batch: target_text: tf.Tensor(\n[[ 1 57 19 ... 98 98 98]\n [ 1 57 4 ... 98 98 98]\n [ 1 40 6 ... 98 98 98]\n ...\n [ 1 39 6 ... 98 98 98]\n [ 1 39 8 ... 98 98 98]\n [ 1 61 8 ... 98 98 98]], shape=(64, 750), dtype=int32) \n\n","output_type":"stream"}]},{"cell_type":"markdown","source":"## Build the model","metadata":{"id":"qMFCFS7UXBkV"}},{"cell_type":"markdown","source":"This print the size of vocabulary","metadata":{"id":"6dOlyLKPW4HM"}},{"cell_type":"code","source":"print(VOCABULARY_SIZE)","metadata":{"id":"o3OSe2LqMXsn","outputId":"d109c9ee-ae19-4bee-85a7-96f92d61ab5c","execution":{"iopub.status.busy":"2024-04-27T15:56:10.746167Z","iopub.execute_input":"2024-04-27T15:56:10.746485Z","iopub.status.idle":"2024-04-27T15:56:10.751271Z","shell.execute_reply.started":"2024-04-27T15:56:10.746461Z","shell.execute_reply":"2024-04-27T15:56:10.750325Z"},"trusted":true},"execution_count":49,"outputs":[{"name":"stdout","text":"101\n","output_type":"stream"}]},{"cell_type":"markdown","source":"First line assign the length of `vocab_size` to the actual size of the dataset (`VOCABULARY_SIZE`)\n\nSecond Line assign the embedding dimension (`embedding_dim`) to 256\n\nThird line assign `rnn units` to 1024","metadata":{"id":"cYmpya_5XKUq"}},{"cell_type":"code","source":"vocab_size = VOCABULARY_SIZE\nembedding_dim = 256\nrnn_units = 1024","metadata":{"id":"Fet_96XbTjLd","execution":{"iopub.status.busy":"2024-04-27T15:56:10.752446Z","iopub.execute_input":"2024-04-27T15:56:10.752732Z","iopub.status.idle":"2024-04-27T15:56:10.761401Z","shell.execute_reply.started":"2024-04-27T15:56:10.752709Z","shell.execute_reply":"2024-04-27T15:56:10.760500Z"},"trusted":true},"execution_count":50,"outputs":[]},{"cell_type":"markdown","source":" This function called `build_model` that takes four arguments: `vocab_size`, `embedding_dim`, `rnn_units`, and `batch_size`. This function creates a sequential neural network model for natural language processing tasks.\nThe code creates a `tf.keras.models.Sequential` model, which is a linear stack of layers.\n\n\n\nThe first layer in the model is an `Embedding` layer, which converts categorical variables (in this case, word indices) into dense vectors.\nThe `input_dim` parameter specifies the size of the vocabulary (the number of unique words in the text data), and the `output_dim` parameter specifies the dimensionality of the dense vectors.\nThe `batch_input_shape` parameter specifies the shape of the input data, which is a batch of sequences of variable length.\nThe `output_dim` parameter of the `Embedding` layer specifies the dimensionality of the dense vectors that will be used to represent each word in the vocabulary.\nThis dimensionality is also referred to as the \"embedding size\" or \"embedding dimension\".\nThe embedding size determines the number of features that will be used to represent each word, and it has a significant impact on the performance of the model.\nA larger embedding size can capture more complex relationships between words, but it also increases the computational cost of the model.\nThe optimal embedding size depends on the specific task and dataset, and it is often determined through experimentation.\nIn general, a good rule of thumb is to start with an embedding size of 300 and adjust it as needed.\nThe `Embedding` layer will output a 3D tensor of shape `(batch_size, sequence_length, embedding_dim)`.\nThis means that the output of the `Embedding` layer will be a 3-dimensional tensor, where the first dimension corresponds to the batch size, the second dimension corresponds to the sequence length, and the third dimension corresponds to the embedding dimension.\n\n\n\nThe second layer in the model is an `LSTM` layer\nThe code creates an LSTM layer with `rnn_units` number of units.We want the output to be a sequence of vectors, so we set `return_sequences` to True.We want the LSTM layer to maintain its internal state, so we set `stateful` to True.\nThe `recurrent_initializer` argument specifies the initializer to use for the recurrent weights of the LSTM layer. In this case, we are using the Glorot Normal initializer, which is a commonly used initializer for recurrent neural networks.\n\n\nThe Third layer in the model is an `Dense` layer with `vocab_size` number of units. The dense layer is used to convert the output of the LSTM layer into a probability distribution over the vocabulary of the language model.\nThe number `vocab_size` refers to the number of neurons in the dense layer that is being added to the neural network model.\nIn a dense layer, each neuron in the previous layer is connected to each neuron in the current layer, and the weights of these connections are learned during the training process. The number of neurons in a dense layer determines the dimensionality of the output of that layer.\n`vocab_size` = 98, which means that the dense layer has 98 neurons, and the output of the previous layer will be flattened into a one-dimensional array of 98 values, and each of these values will be connected to each of the 98 neurons in the dense layer.\n\nThen the function `build_model` return model","metadata":{"id":"glN5Dt2ITuOg"}},{"cell_type":"code","source":"def build_model(vocab_size, embedding_dim, rnn_units, batch_size):\n model = tf.keras.models.Sequential()\n\n model.add(tf.keras.layers.Embedding(\n input_dim=vocab_size,\n output_dim=embedding_dim,\n batch_input_shape=[batch_size, None]\n ))\n\n model.add(tf.keras.layers.LSTM(\n units=rnn_units,\n return_sequences=True,\n stateful=True,\n recurrent_initializer=tf.keras.initializers.GlorotNormal()\n ))\n\n model.add(tf.keras.layers.Dense(vocab_size))\n\n return model","metadata":{"id":"UgE9V7eATmRA","execution":{"iopub.status.busy":"2024-04-27T15:56:10.762466Z","iopub.execute_input":"2024-04-27T15:56:10.762749Z","iopub.status.idle":"2024-04-27T15:56:10.771615Z","shell.execute_reply.started":"2024-04-27T15:56:10.762724Z","shell.execute_reply":"2024-04-27T15:56:10.770892Z"},"trusted":true},"execution_count":51,"outputs":[]},{"cell_type":"markdown","source":"First we build `model` using `build_model` function\n\n`model.summary()`method to obtain a summary of the model's architecture. This method prints the following information:\n - **Layer Name**: The name of each layer in the network.\n - **Input Shape**: The shape of the input data that the layer expects.\n - **Output Shape**: The shape of the output data that the layer produces.\n - **Parameters**: The number of trainable parameters in the layer.\n - **Total Params**: The total number of trainable parameters in the entire model.\n\n The output shape of (64, None, 256) indicates the following:\n- **Batch Size**: The first dimension of the output shape, 64, represents the batch size. This means that the model is processing 64 samples at a time.\n- **Sequence Length**: The second dimension of the output shape, None, represents the sequence length. This means that the model can process sequences of varying lengths. The actual sequence length will depend on the input data.\n- **Feature Dimension**: The third dimension of the output shape, 256, represents the feature dimension. This means that each sequence element is represented as a 256-dimensional vector.\n\nThe input shape for the \"sequential\" model is (64, None, 256), which is the shape of the output of the embedding layer.","metadata":{"id":"OA6jP4qqmPkc"}},{"cell_type":"code","source":"model = build_model(vocab_size, embedding_dim, rnn_units, BATCH_SIZE)\n\nmodel.summary()","metadata":{"id":"T1Y6QELJJolf","outputId":"1b17dc64-729e-4887-8a0b-dcf50debdf18","execution":{"iopub.status.busy":"2024-04-27T15:56:10.772701Z","iopub.execute_input":"2024-04-27T15:56:10.773021Z","iopub.status.idle":"2024-04-27T15:56:11.155079Z","shell.execute_reply.started":"2024-04-27T15:56:10.772983Z","shell.execute_reply":"2024-04-27T15:56:11.154139Z"},"trusted":true},"execution_count":52,"outputs":[{"name":"stdout","text":"Model: \"sequential\"\n_________________________________________________________________\n Layer (type) Output Shape Param # \n=================================================================\n embedding (Embedding) (64, None, 256) 25856 \n \n lstm (LSTM) (64, None, 1024) 5246976 \n \n dense (Dense) (64, None, 101) 103525 \n \n=================================================================\nTotal params: 5376357 (20.51 MB)\nTrainable params: 5376357 (20.51 MB)\nNon-trainable params: 0 (0.00 Byte)\n_________________________________________________________________\n","output_type":"stream"}]},{"cell_type":"markdown","source":" The `tf.keras.utils.plot_model()` function is used to visualize the architecture of a Keras model. It creates a graphical representation of the model, showing the different layers and their connections.\nThe `show_shapes` argument controls whether to display the shape of each layer. The `show_layer_names` argument controls whether to display the name of each layer. The `to_file` argument specifies the path to the file where the plot should be saved.","metadata":{"id":"W_HXguzzPsIz"}},{"cell_type":"code","source":"tf.keras.utils.plot_model(\n model,\n show_shapes=True,\n show_layer_names=True,\n to_file='model.png'\n)","metadata":{"id":"T2eIH2w4PGKM","outputId":"13b9bc0d-f750-4a48-ab7e-5b437f2adf2a","execution":{"iopub.status.busy":"2024-04-27T15:56:11.156302Z","iopub.execute_input":"2024-04-27T15:56:11.156580Z","iopub.status.idle":"2024-04-27T15:56:11.356199Z","shell.execute_reply.started":"2024-04-27T15:56:11.156546Z","shell.execute_reply":"2024-04-27T15:56:11.355201Z"},"trusted":true},"execution_count":53,"outputs":[{"execution_count":53,"output_type":"execute_result","data":{"image/png":"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0QL/+9//5LZ54MABHDhwABs3blRJzEZGRvj555+hp6eHzz//HAkJCSrpR11MmzYNDg4OgvJmzZoBALS0tOrVfl32s6urK/r164evvvqqUZ6fqnbfnLZt2waxWIyOHTtyZdevX8dPP/3E/b1gwQJcv34dhw8fhra2NgYPHoy2bdsCAC5cuIC4uDgYGBhgwIABcHJyqra/xMREnDx5EmVlZejevTukUqncerm5uTh8+DBycnJgbGyM3r17w8PDQ27dlJQUHD9+HOXl5ejcufNrx4dqUl/eNtDU1JRbnpaWhqNHj0JDQwM9evRA165dq+23rKwMrq6uGDx4MKKiopCRkQEA6Ny5M/7v//6v2tjrq7S0FIcPH0ZaWhpEIhFcXFwwcOBA7s2YmZmJbdu2cfUXLlwIsViM8vJyLF26lCufMmUKLC0tkZOTg82bN+Off/4BACxZsoT75jJp0iRoampi8+bN3OumTZuGhw8f4tixYygqKkLbtm0xdOhQSCQSlfSvjDGZ2jp69CgKCwvRu3dvwbL4+HgAgIuLC65evYo///wTJSUlaN26NXx8fKCvry94zePHj/HRRx9h/fr1aN68ucridnNzw/fff48JEyYgICAAKSkpcicHyHP9+nXExcUhPz8fFhYW6NevH+9ccOjQIZw9exYA0KpVK4SEhODYsWNISkqCqakpBg4cCDs7O7ltX7lyBfHx8SgsLESLFi0wcOBAQdJXlsTERABQOK726NEjHDx4ENnZ2TA2NkavXr3knpfqsp8BoE+fPjh27BjOnz+v8DyiKo36zen69etYvHgx719mZqbC+j/99BPCwsIQHh6O+fPn4969e9i6dSs6dOiA6OhoLF68GEuXLkVubi7Cw8Ph6uqKP//8U2F7M2bMwLx583D37l2cOHECffv2xdChQ/Hs2TNevVWrVsHe3h4bN25Efn4+4uLi0LlzZ4wdOxbPnz/n6hERJk+ejE6dOuHnn3/G/fv3sWHDBowcORIVFRWC/mtbv+o2KC8vl1v+zTff4NNPP8Xdu3cRExODbt26YeXKldX2++DBA/zwww/w9vbGhg0beCddVfrrr7/g4OCA6dOn486dO7hx4waCg4PRtm1b7k0ps3v3boSFhaGyspJXfuTIEYSFheHBgwe16vvQoUMICwvD4sWLMXbsWNy8eROpqakYN24c3NzcuAStqv7T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","text/plain":""},"metadata":{}}]},{"cell_type":"markdown","source":"## Trying The Model","metadata":{"id":"--FxwjIiSA9a"}},{"cell_type":"markdown","source":"dataset_train.take(1): This takes the first batch from the dataset_train dataset. The take() method returns a dataset that yields only the specified number of elements (in this case, 1) and then completes.\n\nfor input_example_batch, target_example_batch in dataset_train.take(1):: This iterates over the first batch of data in dataset_train. The batch contains two components: input_example_batch and target_example_batch. The input_example_batch contains the input data for the model, and target_example_batch contains the corresponding target values.\n\nexample_batch_predictions = model(input_example_batch): This line feeds the input_example_batch to the model and generates predictions. The model is a neural network or another machine learning model that you have defined and trained previously.\n\nSo, this code fetches the first batch of data from the dataset_train dataset and generates predictions for the input data using the defined model.","metadata":{"id":"myHJqxpzUAAk"}},{"cell_type":"code","source":"for input_example_batch, target_example_batch in dataset_train.take(1):\n example_batch_predictions = model(input_example_batch)\n print(example_batch_predictions.shape, \"# (batch_size, sequence_length, vocab_size)\")","metadata":{"id":"cutwkVoxSLMb","outputId":"0343f09d-4138-43a4-e170-3808c08c6943","execution":{"iopub.status.busy":"2024-04-27T15:56:11.357614Z","iopub.execute_input":"2024-04-27T15:56:11.358231Z","iopub.status.idle":"2024-04-27T15:56:12.035288Z","shell.execute_reply.started":"2024-04-27T15:56:11.358193Z","shell.execute_reply":"2024-04-27T15:56:12.034305Z"},"trusted":true},"execution_count":54,"outputs":[{"name":"stdout","text":"(64, 750, 101) # (batch_size, sequence_length, vocab_size)\n","output_type":"stream"}]},{"cell_type":"markdown","source":"1. logits=example_batch_predictions[0]: This line selects the 1st element (index 0) from the example_batch_predictions tensor. The example_batch_predictions tensor likely contains a batch of predictions made by the machine learning model for multiple examples. By selecting the 1st element, the code focuses on the predictions for a specific example.\n2. num_samples=1: This line specifies that we want to generate one sample from the categorical distribution. In other words, we want to select one predicted class for the given example.\n3. sampled_indices = tf.random.categorical(...): This line uses the tf.random.categorical function from TensorFlow to randomly sample one index from the categorical distribution defined by the logits. The logits represent the log probabilities of different classes, and the function will select the class with the highest probability. The result of this operation is stored in the sampled_indices tensor.\n4. sampled_indices.shape: This line prints the shape of the sampled_indices tensor. Since we specified num_samples=1, the shape of the tensor will be (1,), indicating that it contains a single index.\n","metadata":{"id":"AcddrE4je18a"}},{"cell_type":"code","source":"sampled_indices = tf.random.categorical(\n logits=example_batch_predictions[0],\n num_samples=1\n)\n\nsampled_indices.shape","metadata":{"id":"98agimVpV1Uu","outputId":"3474fdd3-bbc1-4a09-a149-00611ed16229","execution":{"iopub.status.busy":"2024-04-27T15:56:12.036654Z","iopub.execute_input":"2024-04-27T15:56:12.037002Z","iopub.status.idle":"2024-04-27T15:56:12.063695Z","shell.execute_reply.started":"2024-04-27T15:56:12.036974Z","shell.execute_reply":"2024-04-27T15:56:12.062762Z"},"trusted":true},"execution_count":55,"outputs":[{"execution_count":55,"output_type":"execute_result","data":{"text/plain":"TensorShape([750, 1])"},"metadata":{}}]},{"cell_type":"markdown","source":" This code prints the first 10 elements of a list `sampled_indices`","metadata":{"id":"1mndpGRjL5aY"}},{"cell_type":"code","source":"sampled_indices[:10]","metadata":{"id":"WGbwYEDfLJvQ","outputId":"09631417-9087-44c4-b8b3-cf741c69d828","execution":{"iopub.status.busy":"2024-04-27T15:56:12.064831Z","iopub.execute_input":"2024-04-27T15:56:12.065234Z","iopub.status.idle":"2024-04-27T15:56:12.076551Z","shell.execute_reply.started":"2024-04-27T15:56:12.065184Z","shell.execute_reply":"2024-04-27T15:56:12.075612Z"},"trusted":true},"execution_count":56,"outputs":[{"execution_count":56,"output_type":"execute_result","data":{"text/plain":""},"metadata":{}}]},{"cell_type":"markdown","source":"We use `tf.squeeze` to remove any dimensions of size 1 from the `sampled_indices` tensor, converts it into a NumPy array, and then prints the shape of the resulting array.\n\nThe purpose of this step is to make code simpler","metadata":{"id":"h37xkna1I_I2"}},{"cell_type":"code","source":"sampled_indices = tf.squeeze(sampled_indices).numpy()\nsampled_indices.shape","metadata":{"id":"0NxqPSJlIQbT","outputId":"1f3a6d42-e347-4b00-8d66-31531ac84224","execution":{"iopub.status.busy":"2024-04-27T15:56:12.077950Z","iopub.execute_input":"2024-04-27T15:56:12.078296Z","iopub.status.idle":"2024-04-27T15:56:12.086148Z","shell.execute_reply.started":"2024-04-27T15:56:12.078267Z","shell.execute_reply":"2024-04-27T15:56:12.085045Z"},"trusted":true},"execution_count":57,"outputs":[{"execution_count":57,"output_type":"execute_result","data":{"text/plain":"(750,)"},"metadata":{}}]},{"cell_type":"markdown","source":"This code prints the first 10 elements of a list `sampled_indices` after squeezed","metadata":{"id":"tkJtRCjKMT1v"}},{"cell_type":"code","source":"sampled_indices[:10]","metadata":{"id":"vHf5uSm7LAQ_","outputId":"8f2a0298-371e-4185-86fa-41b47da5989b","execution":{"iopub.status.busy":"2024-04-27T15:56:12.087812Z","iopub.execute_input":"2024-04-27T15:56:12.088154Z","iopub.status.idle":"2024-04-27T15:56:12.094946Z","shell.execute_reply.started":"2024-04-27T15:56:12.088115Z","shell.execute_reply":"2024-04-27T15:56:12.093744Z"},"trusted":true},"execution_count":58,"outputs":[{"execution_count":58,"output_type":"execute_result","data":{"text/plain":"array([94, 44, 39, 51, 57, 62, 22, 84, 23, 42])"},"metadata":{}}]},{"cell_type":"code","source":"print('Input:\\n', repr(''.join(tokenizer.sequences_to_texts([input_example_batch[0].numpy()[:50]]))))\nprint()\nprint('Next char prediction:\\n', repr(''.join(tokenizer.sequences_to_texts([sampled_indices[:50]]))))","metadata":{"id":"B5UQ3Di_HDpU","outputId":"4ae2db19-7333-4d4d-a108-905c2acbbebe","execution":{"iopub.status.busy":"2024-04-27T15:56:12.096424Z","iopub.execute_input":"2024-04-27T15:56:12.096783Z","iopub.status.idle":"2024-04-27T15:56:12.109077Z","shell.execute_reply.started":"2024-04-27T15:56:12.096752Z","shell.execute_reply":"2024-04-27T15:56:12.108047Z"},"trusted":true},"execution_count":59,"outputs":[{"name":"stdout","text":"Input:\n '📕 S t r a w b e r r y B o t t o m C h e e s e c a k e P i e \\n \\n 🥩 \\n \\n • \" 1 R e a d y -'\n\nNext char prediction:\n \"$ ️ B A R q ▪ & ︎ 🥩 ~ c R Q ␣ b ~ 2 \\\\ ' ▪ ( 1 S f - ! ️ z ️ Q Q | ✍ c Q D ✍ 1 K $ ▪ & w G 9 , l g l\"\n","output_type":"stream"}]},{"cell_type":"markdown","source":"### Trying the model with variable input","metadata":{"id":"c2nHDT7KLQ5n"}},{"cell_type":"code","source":"for input_example_batch_custom, target_example_batch_custom in dataset_train.take(1):\n random_input = np.zeros(shape=(BATCH_SIZE, 10))\n example_batch_predictions_custom = model(random_input)\n print('Prediction shape: ', example_batch_predictions_custom.shape, \"# (batch_size, sequence_length, vocab_size)\\n\")\n print('Custom length input: ')\n print(random_input)","metadata":{"id":"VQh1GAsZLTat","outputId":"449a48f4-63b4-43fc-918f-80e77de78633","execution":{"iopub.status.busy":"2024-04-27T15:56:12.110291Z","iopub.execute_input":"2024-04-27T15:56:12.110634Z","iopub.status.idle":"2024-04-27T15:56:12.316968Z","shell.execute_reply.started":"2024-04-27T15:56:12.110608Z","shell.execute_reply":"2024-04-27T15:56:12.316037Z"},"trusted":true},"execution_count":60,"outputs":[{"name":"stdout","text":"Prediction shape: (64, 10, 101) # (batch_size, sequence_length, vocab_size)\n\nCustom length input: \n[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]\n","output_type":"stream"}]},{"cell_type":"markdown","source":"## Training the model","metadata":{"id":"bV0iaMFSkGpi"}},{"cell_type":"markdown","source":"### Attach an optimizer, and a loss function","metadata":{"id":"umVu4Km9kT9b"}},{"cell_type":"markdown","source":"This code defines a loss function for a neural network model. The loss function is used to measure the error between the model's predictions and the true labels. In this case, the loss function is the sparse categorical cross-entropy loss, which is commonly used for multi-class classification problems.\nThe code first defines the `loss` function, which takes two arguments: `labels` and `logits`. The `labels` argument is the true labels for the data, and the `logits` argument is the model's predictions. The function uses the `tf.keras.losses.sparse_categorical_crossentropy` function to compute the cross-entropy loss between the labels and the logits. The `from_logits` argument is set to `True`, which indicates that the logits are not probabilities but rather the unnormalized outputs of the model.\nThe code then computes the loss for an example batch of data. The `target_example_batch` variable contains the true labels for the example batch, and the `example_batch_predictions` variable contains the model's predictions for the example batch. The `loss` function is called with these two variables as arguments, and the result is stored in the `example_batch_loss` variable.\nThe code then prints the shape of the example batch predictions and the shape of the scalar loss. The shape of the example batch predictions is `(batch_size, sequence_length, vocab_size)`, where `batch_size` is the number of examples in the batch, `sequence_length` is the length of the sequences in the batch, and `vocab_size` is the size of the vocabulary. The shape of the scalar loss is `()`, which indicates that it is a scalar value.\nFinally, the code prints the mean of the scalar loss. This value represents the average loss for the example batch.","metadata":{"id":"VgFQ3fIhR00v"}},{"cell_type":"code","source":"def loss(labels, logits):\n entropy = tf.keras.losses.sparse_categorical_crossentropy(\n y_true=labels,\n y_pred=logits,\n from_logits=True\n )\n\n return entropy\n\nexample_batch_loss = loss(target_example_batch, example_batch_predictions)\n\nprint(\"Prediction shape: \", example_batch_predictions.shape, \" # (batch_size, sequence_length, vocab_size)\")\nprint(\"scalar_loss.shape: \", example_batch_loss.shape)\nprint(\"scalar_loss: \", example_batch_loss.numpy().mean())","metadata":{"id":"taxxBk3qQSSj","outputId":"c7913dd8-1e0d-4dfe-982f-8eff65681e14","execution":{"iopub.status.busy":"2024-04-27T15:56:12.318324Z","iopub.execute_input":"2024-04-27T15:56:12.319171Z","iopub.status.idle":"2024-04-27T15:56:12.355941Z","shell.execute_reply.started":"2024-04-27T15:56:12.319141Z","shell.execute_reply":"2024-04-27T15:56:12.354960Z"},"trusted":true},"execution_count":61,"outputs":[{"name":"stdout","text":"Prediction shape: (64, 750, 101) # (batch_size, sequence_length, vocab_size)\nscalar_loss.shape: (64, 750)\nscalar_loss: 4.620006\n","output_type":"stream"}]},{"cell_type":"markdown","source":"`adam_optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)`: This line creates an instance of the Adam optimizer, which is a popular optimization algorithm used in neural networks. The learning rate is set to 0.001, which is a common value for this parameter.\n\n`model.compile(optimizer=adam_optimizer, loss=loss, metrics=['accuracy'])`: This line compiles the model by specifying the optimizer, loss function, and evaluation metric. The model is assumed to have been defined previously.\n\n`optimizer=adam_optimizer`: This argument specifies the optimizer to use during training. In this case, it's the Adam optimizer created in the previous step.\n\n`loss=loss`: This argument specifies the loss function to use during training. The loss variable is assumed to have been defined previously. This loss function is used to calculate the error between the predicted output and the actual output.\n\n`metrics=['accuracy']`: This argument specifies the evaluation metric(s) to use during training. In this case, it's using the accuracy metric, which calculates the fraction of correct predictions.\n\n","metadata":{"id":"XLzrVY0YXl0_"}},{"cell_type":"code","source":"adam_optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)\n\nmodel.compile(\n optimizer=adam_optimizer,\n loss=loss,\n metrics=['accuracy']\n)","metadata":{"id":"SKQc_EF0VQaR","execution":{"iopub.status.busy":"2024-04-27T15:56:12.357326Z","iopub.execute_input":"2024-04-27T15:56:12.358068Z","iopub.status.idle":"2024-04-27T15:56:12.376102Z","shell.execute_reply.started":"2024-04-27T15:56:12.358033Z","shell.execute_reply":"2024-04-27T15:56:12.375131Z"},"trusted":true},"execution_count":62,"outputs":[]},{"cell_type":"markdown","source":"### Creating a checkpoints directory","metadata":{"id":"tJ3esbgbrNpc"}},{"cell_type":"markdown","source":"1. **checkpoint_dir = 'tmp/checkpoints'**: This line creates a variable called `checkpoint_dir` and assigns it the value 'tmp/checkpoints'. This variable will be used to store the checkpoints during the training process.\n2. **os.makedirs(checkpoint_dir, exist_ok=True)**: This line uses the `os.makedirs()` function from the Python `os` module to create a directory named 'tmp/checkpoints'. The `exist_ok=True` argument specifies that if the directory already exists, it should not raise an error.","metadata":{"id":"AG84x4SkriQC"}},{"cell_type":"code","source":"checkpoint_dir = 'tmp/checkpoints'\nos.makedirs(checkpoint_dir, exist_ok=True)","metadata":{"id":"uMCPsahRrMlx","execution":{"iopub.status.busy":"2024-04-27T15:56:12.377317Z","iopub.execute_input":"2024-04-27T15:56:12.377663Z","iopub.status.idle":"2024-04-27T15:56:12.382619Z","shell.execute_reply.started":"2024-04-27T15:56:12.377630Z","shell.execute_reply":"2024-04-27T15:56:12.381751Z"},"trusted":true},"execution_count":63,"outputs":[]},{"cell_type":"markdown","source":"### Configuring callbacks","metadata":{"id":"kNMuGh6OkYgO"}},{"cell_type":"markdown","source":" This code creates an instance of the `EarlyStopping` callback from the `tf.keras.callbacks` module in TensorFlow. This callback is used to stop the training of a neural network model when a certain condition is met, in this case when the `loss` metric stops improving for a specified number of epochs.\n1. `patience=5`: This argument specifies the number of epochs to wait before stopping the training if the `loss` metric does not improve. In this case, the training will stop if the `loss` metric does not improve for 2 consecutive epochs.\n2. `monitor='loss'`: This argument specifies the metric that the callback will monitor to determine whether to stop the training. In this case, the callback will monitor the `loss` metric.\n3. `restore_best_weights=True`: This argument specifies whether to restore the best weights found during training if the training is stopped early. In this case, the best weights will be restored if the training is stopped early.\n4. `verbose=1`: This argument specifies the verbosity level of the callback. In this case, the callback will print a message to the console every time it checks the `loss` metric.","metadata":{"id":"4WTh8VIdqfmq"}},{"cell_type":"code","source":"early_stopping_callback = tf.keras.callbacks.EarlyStopping(\n patience=5,\n monitor='loss',\n restore_best_weights=True,\n verbose=1\n)","metadata":{"id":"2C0WQ2t2pDes","execution":{"iopub.status.busy":"2024-04-27T15:56:12.383854Z","iopub.execute_input":"2024-04-27T15:56:12.384203Z","iopub.status.idle":"2024-04-27T15:56:12.393258Z","shell.execute_reply.started":"2024-04-27T15:56:12.384177Z","shell.execute_reply":"2024-04-27T15:56:12.392483Z"},"trusted":true},"execution_count":64,"outputs":[]},{"cell_type":"markdown","source":" The first line of code defines the prefix for the checkpoint files. The prefix is the path to the directory where the checkpoint files will be saved, followed by the string `ckpt_` and a placeholder for the epoch number. In this case, the checkpoint files will be saved in the directory `tmp/checkpoints/` and will have names like `ckpt_1.h5`, `ckpt_2.h5`, and so on, where the number corresponds to the epoch at which the checkpoint was saved.\nThe second line of code creates a `ModelCheckpoint` callback. The `ModelCheckpoint` callback is used to save the model's weights at the end of each epoch. The `filepath` argument specifies the prefix for the checkpoint files, and the `save_weights_only` argument specifies that only the model's weights should be saved, not the entire model.","metadata":{"id":"rJ7-dnGuulVR"}},{"cell_type":"code","source":"checkpoint_prefix = os.path.join(checkpoint_dir, 'ckpt_{epoch}')\ncheckpoint_callback=tf.keras.callbacks.ModelCheckpoint(\n filepath=checkpoint_prefix,\n save_weights_only=True\n)","metadata":{"id":"-f0QNGU2ruCY","execution":{"iopub.status.busy":"2024-04-27T15:56:12.394523Z","iopub.execute_input":"2024-04-27T15:56:12.395291Z","iopub.status.idle":"2024-04-27T15:56:12.403628Z","shell.execute_reply.started":"2024-04-27T15:56:12.395257Z","shell.execute_reply":"2024-04-27T15:56:12.402724Z"},"trusted":true},"execution_count":65,"outputs":[]},{"cell_type":"markdown","source":"### Execute the training","metadata":{"id":"2un8oTRj89Nu"}},{"cell_type":"markdown","source":"**EPOCHS = 60**:This line sets the number of epochs for training the model. An epoch represents one complete pass through the entire training dataset. In this case, the model will be trained for a total of 65 epochs.\n\n**INITIAL_EPOCH = 1**: This line sets the initial epoch number. It's typically set to 1, indicating that the training starts from the first epoch.\n\n**STEPS_PER_EPOCH = 700**: This line sets the number of steps or iterations per epoch. Each step involves updating the model's weights based on a batch of training data. In this case, there will be 650 steps per epoch","metadata":{"id":"XgOClpl4NJEg"}},{"cell_type":"code","source":"EPOCHS = 60\nINITIAL_EPOCH = 1\nSTEPS_PER_EPOCH = 700","metadata":{"id":"WTT0ACjj9CJ0","execution":{"iopub.status.busy":"2024-04-27T15:56:12.404875Z","iopub.execute_input":"2024-04-27T15:56:12.405180Z","iopub.status.idle":"2024-04-27T15:56:12.413427Z","shell.execute_reply.started":"2024-04-27T15:56:12.405157Z","shell.execute_reply":"2024-04-27T15:56:12.412580Z"},"trusted":true},"execution_count":66,"outputs":[]},{"cell_type":"markdown","source":"The `fit` method is used to train the model on a given dataset.\n1. `x=dataset_train`: This line specifies the training dataset that will be used to train the model. The `dataset_train` variable is assumed to contain the training data, which is typically a collection of input-output pairs.\n2. `epochs=EPOCHS`: This line specifies the number of epochs for which the model will be trained. An epoch refers to one complete pass through the entire training dataset.\n3. `steps_per_epoch=STEPS_PER_EPOCH`: This line specifies the number of steps per epoch. Each step refers to one batch of data that is passed through the model during training.\n4. `initial_epoch=INITIAL_EPOCH`: This line specifies the initial epoch from which the training should start. This is useful if you want to resume training from a previously saved checkpoint.\n5. `callbacks=[checkpoint_callback, early_stopping_callback]`: This line specifies a list of callback functions that will be invoked during the training process. Callback functions are used to monitor the training progress and perform various actions, such as saving checkpoints and early stopping.","metadata":{"id":"lE1gpR4WM68B"}},{"cell_type":"code","source":"\nhistory = model.fit(\n x=dataset_train,\n epochs=EPOCHS,\n steps_per_epoch=STEPS_PER_EPOCH,\n initial_epoch=INITIAL_EPOCH,\n callbacks=[\n checkpoint_callback,\n early_stopping_callback\n ]\n)","metadata":{"id":"8Iu26cqF9Ii4","outputId":"26ae08cf-0da9-4c17-85a8-d38d666a7aaa","execution":{"iopub.status.busy":"2024-04-27T15:56:12.414504Z","iopub.execute_input":"2024-04-27T15:56:12.414764Z","iopub.status.idle":"2024-04-27T19:27:26.185549Z","shell.execute_reply.started":"2024-04-27T15:56:12.414741Z","shell.execute_reply":"2024-04-27T19:27:26.184608Z"},"trusted":true},"execution_count":67,"outputs":[{"name":"stdout","text":"Epoch 2/60\n700/700 [==============================] - 218s 306ms/step - loss: 1.0226 - accuracy: 0.7188\nEpoch 3/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.4705 - accuracy: 0.8586\nEpoch 4/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.4008 - accuracy: 0.8769\nEpoch 5/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.3697 - accuracy: 0.8853\nEpoch 6/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.3503 - accuracy: 0.8908\nEpoch 7/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.3352 - accuracy: 0.8950\nEpoch 8/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.3252 - accuracy: 0.8978\nEpoch 9/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.3160 - accuracy: 0.9004\nEpoch 10/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.3086 - accuracy: 0.9025\nEpoch 11/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.3020 - accuracy: 0.9044\nEpoch 12/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2968 - accuracy: 0.9058\nEpoch 13/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2914 - accuracy: 0.9074\nEpoch 14/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2866 - accuracy: 0.9088\nEpoch 15/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2828 - accuracy: 0.9099\nEpoch 16/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2793 - accuracy: 0.9109\nEpoch 17/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2751 - accuracy: 0.9121\nEpoch 18/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2727 - accuracy: 0.9128\nEpoch 19/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2699 - accuracy: 0.9136\nEpoch 20/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2673 - accuracy: 0.9144\nEpoch 21/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2647 - accuracy: 0.9151\nEpoch 22/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2628 - accuracy: 0.9156\nEpoch 23/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2607 - accuracy: 0.9162\nEpoch 24/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2582 - accuracy: 0.9170\nEpoch 25/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2571 - accuracy: 0.9173\nEpoch 26/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2555 - accuracy: 0.9177\nEpoch 27/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2537 - accuracy: 0.9183\nEpoch 28/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2525 - accuracy: 0.9186\nEpoch 29/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2512 - accuracy: 0.9189\nEpoch 30/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2503 - accuracy: 0.9192\nEpoch 31/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2490 - accuracy: 0.9196\nEpoch 32/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2483 - accuracy: 0.9198\nEpoch 33/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2475 - accuracy: 0.9200\nEpoch 34/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2460 - accuracy: 0.9204\nEpoch 35/60\n700/700 [==============================] - 215s 306ms/step - loss: 0.2458 - accuracy: 0.9204\nEpoch 36/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2450 - accuracy: 0.9206\nEpoch 37/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2444 - accuracy: 0.9209\nEpoch 38/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2437 - accuracy: 0.9211\nEpoch 39/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2436 - accuracy: 0.9211\nEpoch 40/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2429 - accuracy: 0.9212\nEpoch 41/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2422 - accuracy: 0.9214\nEpoch 42/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2421 - accuracy: 0.9215\nEpoch 43/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2421 - accuracy: 0.9214\nEpoch 44/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2408 - accuracy: 0.9218\nEpoch 45/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2414 - accuracy: 0.9217\nEpoch 46/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2410 - accuracy: 0.9217\nEpoch 47/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2406 - accuracy: 0.9219\nEpoch 48/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2405 - accuracy: 0.9219\nEpoch 49/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2404 - accuracy: 0.9219\nEpoch 50/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2402 - accuracy: 0.9219\nEpoch 51/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2397 - accuracy: 0.9221\nEpoch 52/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2400 - accuracy: 0.9220\nEpoch 53/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2401 - accuracy: 0.9219\nEpoch 54/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2392 - accuracy: 0.9222\nEpoch 55/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2394 - accuracy: 0.9221\nEpoch 56/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2395 - accuracy: 0.9220\nEpoch 57/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2395 - accuracy: 0.9220\nEpoch 58/60\n700/700 [==============================] - 215s 306ms/step - loss: 0.2390 - accuracy: 0.9223\nEpoch 59/60\n700/700 [==============================] - 215s 307ms/step - loss: 0.2394 - accuracy: 0.9220\nEpoch 60/60\n700/700 [==============================] - 214s 306ms/step - loss: 0.2395 - accuracy: 0.9220\n","output_type":"stream"}]},{"cell_type":"markdown","source":"### Saving the trained model to file","metadata":{"id":"3MLHcmTkhvm5"}},{"cell_type":"markdown","source":" This code is related to saving the recurrent neural network (RNN) model .\n1. **model_name_h5**: This variable is used to define the name of the model file that will be saved. It combines the string 'recipe_generation_rnn_raw_' with the value of the variable INITIAL_EPOCH, which is likely an integer representing the initial epoch of the training process. The resulting string is then concatenated with the '.h5' extension, which is commonly used for saving Keras models in the HDF5 format.\n2. **model.save(model_name, save_format='h5')**: This line of code saves the model named model to the file specified by model_name. The save_format argument is set to 'h5', indicating that the model should be saved in the HDF5 format.\n","metadata":{"id":"1wLOIuJHhULE"}},{"cell_type":"code","source":"model_name_h5 = 'recipe_generation_rnn_raw_' + str(INITIAL_EPOCH) + '.h5'\nmodel.save(model_name_h5, save_format='h5')","metadata":{"id":"F_Lgm0a1f3-X","outputId":"c4e4a5df-3597-4e60-fa87-9fa8fc53e058","execution":{"iopub.status.busy":"2024-04-27T19:47:53.942665Z","iopub.execute_input":"2024-04-27T19:47:53.943376Z","iopub.status.idle":"2024-04-27T19:47:54.093473Z","shell.execute_reply.started":"2024-04-27T19:47:53.943342Z","shell.execute_reply":"2024-04-27T19:47:54.092441Z"},"trusted":true},"execution_count":86,"outputs":[]},{"cell_type":"markdown","source":"1.import pickle: This line imports the pickle module, which provides functions for serializing and deserializing Python objects.\n\n2.model_name_pkl = 'recipe_generation_rnn_raw_' + str(INITIAL_EPOCH) + '.pkl': This line creates a variable model_name_pkl that represents the desired filename for the saved model. It concatenates a string 'recipe_generation_rnn_raw_', the value of the INITIAL_EPOCH variable (converted to a string using str()), and the .pkl extension. The resulting filename will include the value of INITIAL_EPOCH and end with .pkl, indicating that it's a pickle file.\n\n3.with open(model_name_pkl, 'wb') as f:: This line opens a file with the name specified by model_name_pkl in write binary mode ('wb'). The with statement ensures that the file is properly closed after the block of code inside it is executed.\n\n4.pickle.dump(model, f): This line uses the pickle.dump() function to serialize and save the model object to the file f. The pickle.dump() function takes two arguments: the object to be serialized (model in this case) and the file object (f). It writes the serialized representation of the object to the file.","metadata":{}},{"cell_type":"code","source":"import pickle\n\nmodel_name_pkl = 'recipe_generation_rnn_raw_' + str(INITIAL_EPOCH) + '.pkl'\nwith open(model_name_pkl, 'wb') as f:\n pickle.dump(model, f)","metadata":{"execution":{"iopub.status.busy":"2024-04-27T19:48:06.096506Z","iopub.execute_input":"2024-04-27T19:48:06.096868Z","iopub.status.idle":"2024-04-27T19:48:06.472361Z","shell.execute_reply.started":"2024-04-27T19:48:06.096839Z","shell.execute_reply":"2024-04-27T19:48:06.470980Z"},"trusted":true},"execution_count":87,"outputs":[]},{"cell_type":"markdown","source":"### Visualizing training progress","metadata":{"id":"XazsPU5Fim5R"}},{"cell_type":"markdown","source":"1. **def render_training_history_loss(training_history):**: This line defines a Python function named render_training_history_loss(training_history) that takes a training_history object as its input. This object typically contains information about the training process of a machine learning model, such as the loss values at different epochs.\n2. **loss = training_history.history['loss']**: This line extracts the loss values from the training_history object and stores them in a variable named loss. The 'loss' key is commonly used to store the loss values during training.\n3. **plt.title('Loss')**: This line sets the title of the plot to 'Loss'.\n4. **plt.xlabel('Epoch')**: This line sets the label for the x-axis of the plot to 'Epoch'.\n5. **plt.ylabel('Loss')**: This line sets the label for the y-axis of the plot to 'Loss'.\n6. **plt.plot(loss, label='Training set')**: This line plots the loss values stored in the loss variable. The label 'Training set' is used to identify the plotted line.\n7. **plt.legend()**: This line adds a legend to the plot, which shows the labels associated with each line.\n8. **plt.grid(linestyle='--', linewidth=1, alpha=0.5)**: This line adds a grid to the plot with dashed lines (linestyle='--'), a line width of 1 pixel (linewidth=1), and a transparency of 50% (alpha=0.5).\n9. **plt.show()**: This line displays the plot on the screen.","metadata":{"id":"UQdxiTsXtupj"}},{"cell_type":"code","source":"def render_training_history_loss(training_history):\n loss = training_history.history['loss']\n\n plt.title('Loss')\n plt.xlabel('Epoch')\n plt.ylabel('Loss')\n plt.plot(loss, label='Training set')\n plt.legend()\n plt.grid(linestyle='--', linewidth=1, alpha=0.5)\n plt.show()","metadata":{"id":"kS3hINGxiLei","execution":{"iopub.status.busy":"2024-04-27T19:27:26.625651Z","iopub.execute_input":"2024-04-27T19:27:26.625973Z","iopub.status.idle":"2024-04-27T19:27:26.631876Z","shell.execute_reply.started":"2024-04-27T19:27:26.625944Z","shell.execute_reply":"2024-04-27T19:27:26.630748Z"},"trusted":true},"execution_count":70,"outputs":[]},{"cell_type":"code","source":"render_training_history_loss(history)","metadata":{"id":"yoe2DL4bxfnm","outputId":"1ad6adf6-7e52-4675-9f10-6135f6e03c64","execution":{"iopub.status.busy":"2024-04-27T19:27:26.633124Z","iopub.execute_input":"2024-04-27T19:27:26.633501Z","iopub.status.idle":"2024-04-27T19:27:26.949156Z","shell.execute_reply.started":"2024-04-27T19:27:26.633457Z","shell.execute_reply":"2024-04-27T19:27:26.948372Z"},"trusted":true},"execution_count":71,"outputs":[{"output_type":"display_data","data":{"text/plain":"
","image/png":"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/fcnbf/hD3+In/3sZ9i8eTNee+01ZGZmYsWKFUkvXnc82blzJ66//nq8+uqreO655xCJRHDuueciEAgo9/nWt76Fv/71r/jzn/+MnTt3oq2tDV/4whcMHLWxysvLcc8992DPnj1444038NnPfhYXXXQR3nvvPQDMazxef/11/PKXv0y4ZA6zS+6EE05Ae3u78vPSSy8pbcws0ZEjR3DqqafCarXiH//4B95//3385Cc/QV5ennIf3T4TZPrElixZIl9//fXK76IoyqWlpfKGDRsMHNXkBUB+4oknlN8lSZKLi4vlH/3oR8ptfX19st1ul//4xz8aMMLJq7OzUwYg79y5U5blWE5Wq1X+85//rNzngw8+kAHIu3btMmqYk05eXp784IMPMq9x6O/vl2fNmiU/99xz8plnninfeOONsixzWRvJunXr5AULFiRtY2bJ3XrrrfJpp502YruenwmcyfmEwuEw9uzZg+XLlyu3mUwmLF++HLt27TJwZFPH4cOH4fF4VBnm5ORg6dKlzHAYr9cLAMjPzwcA7NmzB5FIRJXdnDlzUFlZyewAiKKIRx99FIFAAMuWLWNe43D99dfj85//vCojgMvaaD766COUlpaipqYGV1xxBZqamgAws5E8/fTTWLx4Mb785S+jqKgIJ510En79618r7Xp+JrDI+YS6u7shiqJyGYo4t9utXFeLRhfPiRmOTpIk3HTTTTj11FNx4oknAohlZ7PZEi46e7xn984778DlcsFut+Oaa67BE088gXnz5jGvMTz66KPYu3evcq3AoZhdckuXLsXDDz+MrVu34oEHHsDhw4dx+umno7+/n5mN4NChQ3jggQcwa9YsbNu2Dddeey2++c1v4re//S0AfT8TJsVlHYhobNdffz3effdd1fZ+Sm727NnYt28fvF4vHn/8caxatQo7d+40eliTWnNzM2688UY899xzcDgcRg9nyjj//POV/8+fPx9Lly5FVVUV/vSnPyEjI8PAkU1ekiRh8eLF+MEPfgAAOOmkk/Duu+9i8+bNWLVqla7PxZmcT6iwsBBmszlhb/mOjg4UFxcbNKqpJZ4TMxzZmjVr8Le//Q0vvPACysvLlduLi4sRDofR19enuv/xnp3NZkNdXR0WLVqEDRs2YMGCBfjpT3/KvEaxZ88edHZ24uSTT4bFYoHFYsHOnTvxs5/9DBaL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"},"metadata":{}}]},{"cell_type":"markdown","source":"1. **def render_training_history_accuracy(training_history):**: This line defines a Python function named render_training_history_accuracy(training_history) that takes a training_history object as its input. This object typically contains information about the training process of a machine learning model, such as the loss values at different epochs.\n2. **accuracy = training_history.history['accuracy']**: This line extracts the loss values from the training_history object and stores them in a variable named accuracy. The 'accuracy' key is commonly used to store the accuracy values during training.\n3. **plt.title('Accuracy')**: This line sets the title of the plot to 'Accuracy'.\n4. **plt.xlabel('Epoch')**: This line sets the label for the x-axis of the plot to 'Epoch'.\n5. **plt.ylabel('Accuracy')**: This line sets the label for the y-axis of the plot to 'Accuracy'.\n6. **plt.plot(loss, label='Training set')**: This line plots the loss values stored in the accuracy variable. The label 'Training set' is used to identify the plotted line.\n7. **plt.legend()**: This line adds a legend to the plot, which shows the labels associated with each line.\n8. **plt.grid(linestyle='--', linewidth=1, alpha=0.5)**: This line adds a grid to the plot with dashed lines (linestyle='--'), a line width of 1 pixel (linewidth=1), and a transparency of 50% (alpha=0.5).\n9. **plt.show()**: This line displays the plot on the screen.","metadata":{}},{"cell_type":"code","source":"def render_training_history_accuracy(training_history):\n accuracy = training_history.history['accuracy']\n\n plt.title('Accuracy')\n plt.xlabel('Epoch')\n plt.ylabel('Accuracy')\n plt.plot(accuracy, label='Training set')\n plt.legend()\n plt.grid(linestyle='--', linewidth=1, alpha=0.5)\n plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-04-27T19:27:26.950239Z","iopub.execute_input":"2024-04-27T19:27:26.950498Z","iopub.status.idle":"2024-04-27T19:27:26.956461Z","shell.execute_reply.started":"2024-04-27T19:27:26.950475Z","shell.execute_reply":"2024-04-27T19:27:26.955446Z"},"trusted":true},"execution_count":72,"outputs":[]},{"cell_type":"code","source":"render_training_history_accuracy(history)","metadata":{"execution":{"iopub.status.busy":"2024-04-27T19:27:26.957885Z","iopub.execute_input":"2024-04-27T19:27:26.958294Z","iopub.status.idle":"2024-04-27T19:27:27.213140Z","shell.execute_reply.started":"2024-04-27T19:27:26.958261Z","shell.execute_reply":"2024-04-27T19:27:27.212198Z"},"trusted":true},"execution_count":73,"outputs":[{"output_type":"display_data","data":{"text/plain":"
","image/png":"iVBORw0KGgoAAAANSUhEUgAAAkoAAAHHCAYAAABA5XcCAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8WgzjOAAAACXBIWXMAAA9hAAAPYQGoP6dpAACUTElEQVR4nOzdeZgU1aE28Ld6qV5m3/d9WDQqKMiIW1xQXC6JisY1oDG4XHCBL1FQEJfomJggceVeA2oiBK4G90hEFIwRQUFFRFC22bcGpmd6Znqv74+my6npZaaLnukeeH/PMw9MVfXp029XV505dfqUIEmSBCIiIiIKoIl1BYiIiIjiFRtKRERERCGwoUREREQUAhtKRERERCGwoUREREQUAhtKRERERCGwoUREREQUAhtKRERERCGwoUREREQUAhtKRERERCGwoUREceW5556DIAioqqqKdVWIiCDwXm9EFE/OOOMMNDY2Yv/+/fjhhx9QWVkZ6yoR0TGMPUpEFDf27duHTz/9FIsWLUJWVhaWL18e6yoF1dXVFesqENEQYUOJiOLG8uXLkZaWhksvvRRXXnll0IZSe3s7Zs+ejdLSUhgMBhQWFmLatGmwWCzyNna7HQ8++CBGjhwJo9GIvLw8XHHFFdizZw8AYP369RAEAevXr1eUvX//fgiCgJdeekleduONNyIxMRF79uzBJZdcgqSkJFx//fUAgH//+9+46qqrUFxcDIPBgKKiIsyePRs9PT0B9d65cyd+8YtfICsrCyaTCaNGjcL9998PAPjoo48gCAJef/31gMetWLECgiBg48aNEedJREdOF+sKEBH5LV++HFdccQVEUcS1116L559/Hp9//jlOPfVUAIDNZsNZZ52F7777Dr/61a9wyimnwGKx4K233kJ9fT0yMzPh8XjwX//1X1i3bh2uueYa3HXXXejs7MTatWuxfft2VFRURFwvt9uNyZMn48wzz8Qf//hHmM1mAMCrr76K7u5u3H777cjIyMDmzZvx9NNPo76+Hq+++qr8+G3btuGss86CXq/HLbfcgtLSUuzZswdvv/02Hn30UZxzzjkoKirC8uXLcfnllwdkUlFRgYkTJx5BskSkmkREFAe++OILCYC0du1aSZIkyev1SoWFhdJdd90lb/PAAw9IAKTVq1cHPN7r9UqSJEnLli2TAEiLFi0Kuc1HH30kAZA++ugjxfp9+/ZJAKQXX3xRXjZ9+nQJgDR37tyA8rq7uwOWVVdXS4IgSDU1NfKys88+W0pKSlIs610fSZKkefPmSQaDQWpvb5eXtba2SjqdTlq4cGHA8xDR0OClNyKKC8uXL0dOTg7OPfdcAIAgCLj66quxcuVKeDweAMA//vEPjBkzJqDXxb+9f5vMzEzccccdIbdR4/bbbw9YZjKZ5P93dXXBYrHg9NNPhyRJ+PLLLwEAbW1t+Pjjj/GrX/0KxcXFIeszbdo0OBwOvPbaa/KyVatWwe1244YbblBdbyI6MmwoEVHMeTwerFy5Eueeey727duH3bt3Y/fu3aiqqkJLSwvWrVsHANizZw9OOOGEsGXt2bMHo0aNgk4XvZEFOp0OhYWFActra2tx4403Ij09HYmJicjKysJPf/pTAIDVagUA7N27FwD6rffo0aNx6qmnKsZlLV++HKeddhq/+UcUQxyjREQx9+GHH6KpqQkrV67EypUrA9YvX74cF154YdSeL1TPkr/nqi+DwQCNRhOw7QUXXICDBw/i3nvvxejRo5GQkICGhgbceOON8Hq9Eddr2rRpuOuuu1BfXw+Hw4HPPvsMzzzzTMTlEFH0sKFERDG3fPlyZGdn49lnnw1Yt3r1arz++utYsmQJKioqsH379rBlVVRUYNOmTXC5XNDr9UG3SUtLA+D7Bl1vNTU1A67zN998g++//x4vv/wypk2bJi9fu3atYrvy8nIA6LfeAHDNNddgzpw5+Pvf/46enh7o9XpcffXVA64TEUUfL70RUUz19PRg9erV+K//+i9ceeWVAT+zZs1CZ2cn3nrrLUydOhVff/110K/RS4fnzp06dSosFkvQnhj/NiUlJdBqtfj4448V65977rkB11ur1SrK9P//z3/+s2K7rKwsnH322Vi2bBlqa2uD1scvMzMTF198MV555RUsX74cF110ETIzMwdcJyKKPvYoEVFMvfXWW+js7MTPfvazoOtPO+00efLJFStW4LXXXsNVV12FX/3qVxg3bhwOHjyIt956C0uWLMGYMWMwbdo0/PWvf8WcOXOwefNmnHXWWejq6sIHH3yA//7v/8bPf/5zpKSk4KqrrsLTTz8NQRBQUVGBd955B62trQOu9+jRo1FRUYHf/OY3aGhoQHJyMv7xj3/g0KFDAds+9dRTOPPMM3HKKafglltuQVlZGfbv3493330XX331lWLbadOm4corrwQAPPLIIwMPkogGRyy/ckdENGXKFMloNEpdXV0ht7nxxhslvV4vWSwW6cCBA9KsWbOkgoICSRRFqbCwUJo+fbpksVjk7bu7u6X7779fKisrk/R6vZSbmytdeeWV0p49e+Rt2trapKlTp0pms1lKS0uTbr31Vmn79u1BpwdISEgIWq8dO3ZIkyZNkhITE6XMzExpxowZ0tdffx1QhiRJ0vbt26XLL79cSk1NlYxGozRq1ChpwYIFAWU6HA4pLS1NSklJkXp6egaYIhENFt7rjYgojrjdbuTn52PKlClYunRprKtDdMzjGCUiojjyxhtvoK2tTTFAnIhihz1KRERxYNOmTdi2bRseeeQRZGZmYuvWrbGuEhGBPUpERHHh+eefx+23347s7Gz89a9/jXV1iOgw9igRERERhcAeJSIiIqIQ2FAiIiIiCoETTqrk9XrR2NiIpKSkI7ojOREREQ0dSZLQ2dmJ/Pz8gHs4BsOGkkqNjY0oKiqKdTWIiIhIhbq6OhQWFva7HRtKKiUlJQHwBZ2cnBy1cu12O2pra1FcXAyj0Ri1co92zE0d5qYOc4scM1OHuakTLreOjg4UFRXJ5/H+sKGkkv9yW3JyclQbSmazGTqdDsnJydDp+PYMFHNTh7mpw9wix8zUYW7qDCS3gQ6b4fQAKnV0dCAlJQVWqzWqDSUiIiIaPJGev/mttzjj8XjQ0dEBj8cT66oMK8xNHeamDnOLHDNTh7mpE83c2FCKMy6XC42NjXC5XLGuyrDC3NRhbuowt8gxM3WYmzrRzI0XPAeZx+OJ6I1yOBzwer1wOByDWKujT7zlptfrodVqY10NIiI6QmwoDRJJktDc3Iz29vaIH+d2u9HQ0MD5mSIQj7mlpqYiNzc3bupDRESRi3lD6dlnn8UTTzyB5uZmjBkzBk8//TQmTJgQdFuXy4Xq6mq8/PLLaGhowKhRo/D73/8eF110kbxNdXU1Vq9ejZ07d8JkMuH000/H73//e4waNUre5pxzzsGGDRsUZd96661YsmRJ1F6Xv5GUnZ0Ns9k84JOl1+uF0+mEKIoDmgiLfOIpN0mS0N3djdbWVgBAXl5eTOtDRETqxbShtGrVKsyZMwdLlixBVVUVFi9ejMmTJ2PXrl3Izs4O2H7+/Pl45ZVX8MILL2D06NH417/+hcsvvxyffvopTj75ZADAhg0bMHPmTJx66qlwu9247777cOGFF2LHjh1ISEiQy5oxYwYefvhh+Xez2Ry11+XxeORGUkZGRkSP9Xq90Gq10Ov1MT/hDyfxlpvJZAIAtLa2Ijs7O24vwwmCAKPRyF6vCDG3yDEzdZibOtHMLabTA1RVVeHUU0/FM888A8B3sisqKsIdd9yBuXPnBmyfn5+P+++/HzNnzpSXTZ06FSaTCa+88krQ52hra0N2djY2bNiAs88+G4CvR2ns2LFYvHix6rqH+3qh3W7Hvn37UFpaKp8w6djT09OD/fv3o6ysjBPFERHFiUinB4hZj5LT6cSWLVswb948eZlGo8GkSZOwcePGoI9xOBwBJxyTyYRPPvkk5PNYrVYAQHp6umL58uXL8corryA3NxdTpkzBggULwvYqORwOxUDhjo4OAL5GkSiKitcA+C6/SJIEr9erKMe/vu9ywNcCFgRBfmxfGo0m5Dr/Y9WW21+dgq3rr06xLDceMuy7DzidzoCy/b1gwQb9C4IAg8EAwLef9eW/zOhyuQK+Ausv139Jsi//58jhcAS8Hv9AdLfbDbfbHfA6RVGEJElBB84bDAYIghD0tep0Ouh0ukErNx4zDFau/7XG43szWBmG+lKL/7UGKzdchvG8fx9JhjxGDM0xIlhW4cSsoWSxWODxeJCTk6NYnpOTg507dwZ9zOTJk7Fo0SKcffbZqKiowLp167B69eqQ8yR4vV7cfffdOOOMM3DCCSfIy6+77jqUlJQgPz8f27Ztw7333otdu3Zh9erVIetbXV2Nhx56KGB5bW0tEhMT5d+Tk5PlRpnT6Qzo9vP3MLlcroA303/ZyG63BzxOq9XKDbJgO4l/p3a73QF56PV66HS6oB8IjUYjf9CcTmfAB8K/8wUrV6fTQaPRBC3X3+0ZqlxRFKHVauHxeAI+EP7XGuwD0bvcvhm63W4YjcaQB5VoZBis3N4Z9i7X6XQqPvAWi0VuYPtlZmYiMzMTPT09qK+vD3jOiooKAL5b5fStU0lJCUwmEw4dOoSDBw8q1vkHkjudTuzfvz+gviNHjgQA1NTUoLW1FampqfLstQUFBUhKSoLVakVbW5visUlJSSgoKIDb7Q4oFwBGjhwJQRDQ3NyM7u5uxbrc3FykpqbCZrOhublZsc5sNqO4uBiSJAUtt6KiAnq9Hm1tbejs7FSsy8rKQkZGBrq7u9HQ0KBYJ4oiysvLAfg+q30/c6WlpTAajThw4EDAFy/S09ORnZ0Nh8OBmpoaxTpJkqDRaFBSUoKGhoaAfaKwsBCJiYmwWq2wWCyKdcnJycjPzw+Z4ejRowH4xjn29PQo1uXl5SElJQWdnZ1oaWlRrEtISEBRURG8Xm/QcisrK6HT6dDa2gqbzaZYl52djfT0dHR1daGxsVGxzmg0orS0FIBvf+n7WS4rK4PBYIDFYpH/MPXrneHevXvR3t4u72s6nQ6VlZUAgPr6+oDjQHFxMcxmc9D9OyUlBXl5eXC5XAGvVRAEeUxqU1NTwEkxPz8fycnJ6OjokMcR+iUmJqKwsBAejydohiNGjIBWq0VLSwu6uroU63JycpCWlgabzYampibFOpPJhJKSEgAIWm55eTlEUQx6jEhOTkZnZycyMzMDPo9DcYxoaGgIOL4Ph2OE2+2W97e8vDzFMaLv/t+fmF16a2xsREFBAT799FNMnDhRXn7PPfdgw4YN2LRpU8Bj2traMGPGDLz99tsQBAEVFRWYNGkSli1bFnBAAYDbb78d7733Hj755JOwN7778MMPcf7552P37t3yTtdXsB6loqIitLS0KLru/A2HvXv3ygfh3vrrDfE3DoKNtRmOPUqlpaW46667cNdddw2o3PXr1+P888/HoUOHkJKSMuD6er1euFwuuQEWDz1Kdrsd+/fvR2lpKcxmc1z+tdjR0YHa2loUFRXJzzXc/1rsbbAydDgcaGpqQmlpqbxf9MYeJZ/e+7fNZkNdXZ1iX2OPkk+4HiW32436+noUFxcHnBPYoxS6XIfDIe9vCQkJivemo6MDOTk58X/pLTMzU26Z99bS0oLc3Nygj8nKysIbb7wBu92OAwcOID8/H3PnzpX/Yuxt1qxZeOedd/Dxxx/3e3fgqqoqAAjbUDIYDPIO2ZvRaAxoDPl7hDQaTciBxaGW+3fIUI/1n7BDCTeQOdxj+xvwtnDhQjz44IMRl/v5558jISFhwDmceeaZaGpqQkpKiqrX6t++v9d6pBmGGufW+7EajUbeDwAoLtH2pdVqww74DjfGSa/XQ6/XB12n0WjCPlYUReh0OhgMhoDt/AetYHr37IUqN5TBKjdWGQY7Lgx2ucMtQ61WC4PBEHJfi8V7E48ZBivX3wDq77UeTRlGq1z//uYvy//eBGsYhhOzrweJoohx48Zh3bp18jKv14t169YpepiCMRqNctfeP/7xD/z85z+X10mShFmzZuH111/Hhx9+iLKysn7r8tVXXwE4tr/G3dTUJP8sXrwYycnJimW/+c1v5G39cxYNRFZWVkTfKBRFkXMPERFFSSwuGrk8Xli7XWiy9uCAzQG7yxOTekRLTKcHmDNnDqZPn47x48djwoQJWLx4Mbq6unDTTTcBAKZNm4aCggJUV1cDADZt2oSGhgaMHTsWDQ0NePDBB+H1enHPPffIZc6cORMrVqzAm2++iaSkJPk6Z0pKCkwmE/bs2YMVK1bgkksuQUZGBrZt24bZs2fj7LPPxkknnTT0IcSJ3r14/t4c/7L169fj3HPPxT//+U/Mnz8f33zzDd5//30UFRVhzpw5+Oyzz9DV1YXjjjsO1dXVmDRpklxWaWkp7r77btx9990AfH8NvPDCC3j33Xfxr3/9CwUFBfjTn/6En/3sZ4rnOnToEFJTU/HSSy/h7rvvxqpVq3D33Xejrq4OZ555Jl588UW5Yet2uzF79mz87W9/g1arxa9//Ws0NzfDarXijTfeCPp6a2pqMGvWLHzyySdwOp0oLS3FE088gUsuuQQAsH37dvz2t7/Fv//9byQkJODCCy/Ek08+iczMTNx4443YsGEDNmzYgD//+c8AIH/LkYiiw+uV0N7jwsEuBw7YnDjY5YRXAgw6DQx6DQw6reL/ok4Dr1eC2yvB4/XC7ZXg9vz4u8sjweXxwuk+/ONR/uvxSvBKErwSIEmA9/Bldt//lXXr/Xdc7z/pJPge6/u/9OP/JQk9Lg+6nR70OH3/drs86HG60e30wOXxQq/VQNRpIPb5VwMJjp4uJH/VDb1OB43GdxzVCID2cA+33eVBp92NTocbnXYXbHY3Ou1u2By+H0EA9BoNtBoBOq0AnUaATqs5/K8ArSBAq/H/aKDVwPevAGgEAeH+bnW6vehyetDtcKPb5UG3wwOnJ3D4glYjwCxqkWjQyf+aRC20GgGaw0+gOfy6/M8pCALuOn8ETihIiXwHiqKYNpSuvvpqtLW14YEHHkBzczPGjh2LNWvWyAO8a2trFZcy7HY75s+fj7179yIxMRGXXHIJ/va3vyE1NVXe5vnnnwfgmwKgtxdffBE33ngjRFHEBx98IDfKioqKMHXqVMyfP3/QXqf/QzLQbSVBix6XB4IQfFxQJEx6bdR6Z+bOnYs//vGPKC8vR1paGurq6nDJJZfg0UcfhcFgwF//+ldMmTIFu3btQnFxcchyHnroIfzhD3/AE088gaeffhrXX389ampqAr6Z6Nfd3Y0//vGP+Nvf/gaNRoMbbrgBv/nNb7B8+XIAwO9//3usWLECS5cuxfHHH4+nnnoKb7zxBs4999yQdZg5cyacTic+/vhjJCQkYMeOHfKg/Pb2dpx33nn49a9/jSeffBI9PT2499578Ytf/AIffvgh/vznP+P777/HCSecIM/FlZWVpTbWmBJFEWVlZSG75Sm44ZSb23P4RHb4pOxw+Y4rvhMRIMB3UtIIACDA45Vgd3ngcHsV//r/3+P0oOtwWV0O5b/dTrevoQEAkgR/+0KSfvwWqFZr8Z2QBQEazY8naY1GgMPlwcEuX6PoULczoIFybItsAHJvkgRf48UDYAhvGafTCHAffhM9XsnXmLMP7GqE37SJJaqeO5qf0ZjPzD1r1izMmjUr6Lr169crfv/pT3+KHTt2hC2vv+69oqKigFm5B1uPy4PjH/jXkD6n346HJ8MsRudtfvjhh3HBBRfIv6enp2PMmDHy74888ghef/11vPXWWyHfUwC48cYbce211wIAHnvsMTz11FPYvHmzYob13lwuF5YsWSKPH5s1a5ZistCnn34a8+bNw9SpUwEAzzzzDP75z3+GfS21tbWYOnUqTjzxRABQjHN75plncPLJJ+Oxxx6Tly1btgxFRUX4/vvvMXLkSIiiCLPZHHI83XDR+xt7NHBHkpvX6/vD6cfeC9+/XkmC1+v7v9PtRbfLjR6nBz0uT8C/NocbXQ43uhy+noQuhxtdTrdiebfTjS6nB073kf/BFUspJj0yEkSkJ4jQaAQ43V443F443L5Gn/x/txdaQfixl0Tj6zHRagTotb6GmKjVwKDz9dT07cHRHW6sCQjs1fA1KH16n2F+PN1I8G/Re9veDVGTXguTqIVZ1MIk6mDW+/+vhajVKHq4lD1fEtwer7yP+PcXj/fH/xv1GiQadEgy6pFo1CHJqEOSwff/BIMWkHC4Z83Xq+b79/DvXi+8h9d5vBI8kq8Xzt87F+6cKkmAqNPALPqep/e/ZlELvVYDj1eSG+k2hxvdjsP/Hl7mlXvtJMVr9PfkVWYnhnz+cKJ5bIt5Q4mGj/Hjxyt+t9lsePDBB/Huu++iqakJbrcbPT09qK2tDVtO70ucCQkJSE5ODviabm9ms1kxyD4vL0/e3mq1oqWlBePHj4fT6YROp4NWq8W4ceNCflMPAO68807cfvvteP/99zFp0iRMnTpVrtfXX3+Njz76SDHtg9+ePXvkr80eDVwuFywWCzIzM4dF70i8cDicqG9uhTk5FS6vRu5h6Tncq9Jpd8Nic8Bi8102arM5YLE5YbE5cLDLCU8Mukp0GgEJBh1EnX+uNwCHLw/5Lhn5TlR6reC7rNXr8pax1/8TDl86STDoYNJrFSdIk157uIEhQMCPvVaA744FHdYOJCQlQdBofSdnSZIveXm8vufOTDQgPUFERoKItAQRem3sZ9qPpeH+GdVqBCQZ9Ugy6pHT/+ZRE83c2FAaAia9FjsenjygbX1fa3TCYIjOPctM+ujdOqP3LWAA4De/+Q3Wrl2LP/7xj6isrITJZMKVV17Z7zcK+u604aYfCLV9sL9yPB5PyG9K9PXrX/8akydPxrvvvov3338f1dXV+NOf/oQ77rgDNpsNU6ZMwe9///uAxx1tA/49Hg+sVivS0tKG5UFYDUmS4HB7cajbKTdiDhxuxBzw/7/LiS6HGw63B3aXV/7Xf/lpsHpp/D0ZBp0GJlELo97X+DD7/y9qDzdOdEg0+BonCQYdkgw6JBz+SfT/X9TC7P9X/LGBFCu+6TI6UFqawZnqI3AsfkajIZq5saE0BARBGPDlL6/XC63kgUHUxcU9y8L5z3/+gxtvvBGXX345AF8PU7CJwAZTSkoKcnJy8MUXX8jTPHg8HmzduhVjx44N+9iioiLcdtttuO222zBv3jy88MILuOOOO3DKKafgH//4B0pLS0M2vERRDDnRKQ0+p9uL9h4nOnpcsPb+6Xah/fD/O3p8A1t9g1xd8viITrsLLk/0enTM4o+XUBJE3wDVRIMOGQkiMhMNyEwy+P5N9P2elWRAklEHjX9szuEBrPymJ1F8YkOJVBsxYgRWr16NKVOmQBAELFiwIGzP0GC544478Pjjj6O4uBgnnnginn32WRw6dCjsiefuu+/GxRdfjJEjR+LQoUP46KOPcNxxxwHwDfR+4YUXcO211+Kee+5Beno6du/ejZUrV+Ivf/kLtFotSktLsWnTJuzfvx+JiYlIT0+P+4ZtvOtyuNFk7UFDux1N7T1ostrlQb3WHhcOdTtxqMuF9m4nupxH3kjVagS5MZORKCLr8L++3w1INOhg0GtgPHwZSv5XrwXcLrQ11WNkRRnMZt7PkehoxoYSqbZo0SL86le/wumnn47MzEzce++9AdPvD4V7770XTU1NmDFjBrRaLW655RZMnjw57KRvHo8HM2fORH19PZKTk3HRRRfhySefBOC7xcF//vMf3HvvvbjwwgvhcDhQUlKCiy66SG4M/eY3v8H06dNx/PHHo6enh9MDhGF3eWCxOdDWefjn8P9bOx1osdrRcLhRZO2J7Os4ggAkG/VIMSl/kuV/fYNbk/2DW416xb+Jog4ajbpeHLtdQKdeo/rxRDR8xOwWJsNduLsP2+127Nu3T9Vd471eLzweD7RaLXsoItA7NwA47rjj8Itf/AKPPPJIzOp0JPvBUHG5XDh06FBE1/ElSUJrpwM/tNhQc7BLvuzV0eNGR48LHXaXfEnsULcrogZQklGH/BQT8lONyEs1ITNBRIpZRJpZjzSziFSzHqmHf0826mPWUFGT27GOmanD3NQJl1u483cw7FGKM+Fue0LB1dTU4P3338dPf/pTOBwOPPPMM9i3bx+uu+66WFct7un1emRnZwdd5/X6GkS7W234vqUTP7R24ocW3/87IpwLRdRqkJVkUP4kGpCTbER+qhH5qSbkpRiRZBweJ4JwuVFwzEwd5qZONHNjQynOSJIEr9cr3yeM+qfRaPDSSy/hN7/5DSRJwgknnIAPPvhAHnNEwXXaXWg41I3atg60dXvQ3OFAQ3sPGtt70NhuR5O1J+SgZ40AlGYkoDwrAWlmUb7klWzUIeVwb0+KSY9Usx5ZiUYkm3RH1f7s8XjgcDhgMBjCXuKlHzEzdZibOtHMjQ2lOCNJEpxOp3wnZOpfUVER/v3vf8sfCvbI+fajJqsd37d0ou5QD5qtPWi2OtDc0YNmqx3NVvuABkT7G0QjchIxMicJldm+f8uzEmDQHbsHbZfLhdraWpSWlvLkNUDMTB3mpk40c2NDiWgYkyQJjYcbRLtb/JfIbNjdaoPN0f/lsSSDDhlmDUoyk1CUkYD8VBMKUk3IP/yTk2SA7hif8I+Ijm1sKA0ijpM/tkXz/Xd5vKg50I3drTbsafM1hPz/7w7RM6TTCCjLTEBJRgLyU43ISTYiL8WI3GQjclN8PxqvG/v370dpaWncDjgnIoolNpQGgX+EfXd3N0wmzrFyrOru7gYQOLN4OHaXB/ssXb5eocO9Qz+02rDf0iXfXLIvvdbXIBqRnYQROYkYkZ2EkTmJKMlI6Hc2ZnuEg7KJiI41bCgNAq1Wi9TUVPl+ZGazecDjjbxeL1wuFyRJ4libCMRTbpIkobu7G62trUhNTQ16fdzmcGPP4V6h3W02/NDi6x2qOdAV8o7pZlGLiqxEVGb7fvz/L8kwH9H9sAZ62xdSYm6RY2bqMDd1opUb51FSqb95GCRJQnNzM9rb24e+chQXUlNTkZGVjW8aOrCjqePHhlGrDc0d9pCPSzbq5IHT/p8ROUnISzZygkMioiPEeZTihCAIyMvLQ3Z2NlyuyGYcpuHL5fHi+5ZOfF7bgf98Wosv9n+NHlfwMURZSQZUZCX4GkLZSRiRnYjKnERkJfIbj0RE8YINpUGm1Woj+mqi3W5HfX09CgsLObg2ArHKze7y4NvGDny+/yA27jmAL/YfDPjafZpZj7FFqYoeosqsJKSYYz+5Ivc3dZhb5JiZOsxNnWjmxoZSHHK7OcBWjcHOTZIk1B/qwZd17fiy9hC+rG3HjsYOOD3KGwGnmPSoKkvHxIoMTKzIwMjspLi+ZMb9TR3mFjlmpg5zUydaubGhRBRCt9ONbfVWfFnbjq2HG0YWmyNgu4wEEScXp+G0cl/j6Ljc5LhuGBER0cCxoUQEX29R7cFubK09hK017fiy7hC+a+qEp89X0HQaAT/JT8bJxWk4uTgVJxeloSjdxDFFRERHKTaU6JjV4/Tg3z+0Ye2OFny0qxUWmzNgm9xkI04p8TWITilJxU/yU2DU8zYCRETHCk4PoFKkXy8cKN4AUZ2B5nawy4l137Vg7Y4WfPxDG+yuH8cXiVoNTihIxinFaTi52Ncwyks5uicM5f6mDnOLHDNTh7mpEy43Tg8wzGm1WpjN5lhXY9gJl1tDew/WbG/G+9824/P9BxUTOhakmnDhT3JwwfE5GFeSdszd6JX7mzrMLXLMTB3mpk40c2NDKc64XC4cOnQIaWlpEd364ljXN7eaA114b3sz3vumCV/XWxXbHp+XLDeOjs9LPqbHF3F/U4e5RY6ZqcPc1IlmbmwoxRmPx4ODBw8iOTmZH4oIeDwefL23GdutB7B2pwU7mjrkdYIAnFqSjskn5OLC43NQlM6/zvy4v6nD3CLHzNRhbupEMzc2lGjY8nolfFnXjg++a8H725uwx9Itr9NqBJxWno6LT8jDhT/JQXYSJ2ojIqLIsaFEw0qP04P/7LZg7Y4WrNvZovimmk4DnF6egUvH5OOC43ORniDGsKZERHQ0YEOJ4p7T7cW/vm3GW1834t99vqmWZNDhnNHZ+GllGkrFLpwwqoLT/BMRUdSwoRRntFotUlJS+DVQADUHurBicy1e+6IeB7p+7DkqSDVh0nHZuOD4XEwoS4eo08DlcsFisTC3CHF/U4e5RY6ZqcPc1IlmbpxHSaXBmkfpWOfyeLF2RwtWbKrFJ7st8vLsJAN+Mb4IF5+Ye8x/U42IiNTjPErDnNfrhcvlgl6vh0ajiXV1hkyTtQevfFaD//uiHm2dvvupCQJw1ogsXF9VjPNHZ0OnDZ3HsZrbkWJu6jC3yDEzdZibOtHMLeapP/vssygtLYXRaERVVRU2b94ccluXy4WHH34YFRW+cShjxozBmjVrIi7Tbrdj5syZyMjIQGJiIqZOnYqWlpaovzY1nE4n9u3bB6cz8HYaR6PtDVbcvfJLnPX7j/DsR3vQ1ulAZqIB/31OBT7+7bn4668mYPJPcsM2koBjL7doYW7qMLfIMTN1mJs60cwtpg2lVatWYc6cOVi4cCG2bt2KMWPGYPLkyWhtbQ26/fz58/E///M/ePrpp7Fjxw7cdtttuPzyy/Hll19GVObs2bPx9ttv49VXX8WGDRvQ2NiIK664YtBfL/l4vRI+2tmK6174DP/19Cd446tGuL0SqsrS8dz1p2DjvPNwz0WjOd8RERHFXEzHKFVVVeHUU0/FM888A8DXVVZUVIQ77rgDc+fODdg+Pz8f999/P2bOnCkvmzp1KkwmE1555ZUBlWm1WpGVlYUVK1bgyiuvBADs3LkTxx13HDZu3IjTTjttQHUfrDFKdrsd+/fvl3vEjiZ2lwdvftWAF/69D7tbbQB88x1demIeZpxVjhMLU9SXfRTnNpiYmzrMLXLMTB3mpk643IbNGCWn04ktW7Zg3rx58jKNRoNJkyZh48aNQR/jcDgCXrDJZMInn3wy4DK3bNkCl8uFSZMmyduMHj0axcXFETWUaOBcHi/+vrkWT63bDYvNN/4o0aDDtROKcOMZZShIPbpvPEtERMNXzBpKFosFHo8HOTk5iuU5OTnYuXNn0MdMnjwZixYtwtlnn42KigqsW7cOq1evhsfjGXCZzc3NEEURqampAds0NzeHrK/D4YDD4ZB/7+jw3SLDbrdDFH+c2FCj0UAURXi93qDXRv0NPYfDgb6def5p1iVJUjxX73KDrQMAg8EAQRDgdDrh9XoV63Q6HXQ6HTweD1wul2KdIAgwGAzya+lLFEVoNL6v3/tz9tNqtdDr9UHL9dfp3W+a8MSanag52AMAyEs24JenFeG6qhKkJhjhcrkCntdfbiQZOhwOeDweuY5utxtut1vxuFhnGKzccBlG473pL0On0ynfZdtPr9dDq9UOWobx+N5EmqHD4ZC/eRnqs6zVaoOWe6THiMF8bwbzGOH/jPaum/+1Bis3XIZqjhF9y43HDIOV63a7IQgCvF5vwGOH4hgRiwyjUW7v/a3vexMsq3CG1bfe/vznP2PGjBkYPXo0BEFARUUFbrrpJixbtmzQn7u6uhoPPfRQwPLa2lokJibKvycnJyM/Px9utxv79+8P2H706NEAfA22np4exbq8vDykpKQgNzcXTU1NinUJCQkoKiqC1+sNWm5lZSV0Oh1aW1ths9kU67Kzs5Geno6uri40NjYq1hmNRpSWlgIAampqAj4QZWVlMBgMsFgssFqVN5dNT09HdnY2HA4HamtrFeu2tzrxt20d8g1p04xaXD82DReNTIZOI0EUfB+QQ4cO4eDBg4rHpqSkIC8vDy6XK+C1CoKAUaNGAQCampoUO7xWq5UPBh0dHQFj3RITE1FYWAiPxxM0wxEjRkCr1aKlpQVdXV2KdTk5OUhLS4PNZgt4b0wmE0pKSgAgaLnl5eUQRREWi0VuYPtlZmYiMzMTPT09qK+vV6zT6/WoqKgAANTV1QUc6EpKSmAymYJmmJqaitzcXDidzoA6aTQajBw5EgDkuad6v6aCggIkJSXBarWira1N8dikpCQUFBSE3L9HjhwJQRDQ3NyM7u5uxbrc3FykpqbCZrMF/FFiNptRXFwMSZKClltRUQG9Xo+2tjZ0dnYq1mVlZSEjIwPd3d1oaGhQrBNFEeXl5QB8n9W+B2Z/t/yBAwfQ3t6uWNd7/66pqVGs02q18n64Z8+egBNjYWEhEhMTYbVaYbFYFOuicYzo7OwM+AJKvB8jmpqaFPuaTqdDZWUlAKC+vj7gxFhcXAyz2RzVYwTgG8KRnJw8rI4Ro0aNgs1mCzjODsUxoqGhIaAhNVyOEf79re8xou/+35+YjVFyOp0wm8147bXXcNlll8nLp0+fjvb2drz55pshH2u323HgwAHk5+dj7ty5eOedd/Dtt98OqMwPP/wQ559/Pg4dOqToVSopKcHdd9+N2bNnB33OYD1KRUVFaGlpUVzjPFb/WvSXu6u5E3/8YA/+vfsAACBB1OJXpxfjxonFSDD82C7nX4vK1xqrHqXh+tdisHLjMUP2KIXvdWaPkg+PET5DdYzo6OhATk7OgMcoxXww94QJE/D0008D8A28Li4uxqxZs4IO5u7L5XLhuOOOwy9+8Qs89thjAyrTP5j773//O6ZOnQoA2LVrF0aPHh0Xg7n9f3nl5eXJH4DhoLXTjt+/twurv6yHJAE6jYDrqopxx3kjkJU0+K9juOYWa8xNHeYWOWamDnNTJ1xuw2YwNwDMmTMH06dPx/jx4zFhwgQsXrwYXV1duOmmmwAA06ZNQ0FBAaqrqwEAmzZtQkNDA8aOHYuGhgY8+OCD8Hq9uOeeewZcZkpKCm6++WbMmTMH6enpSE5Oxh133IGJEyfGxUBuSZJgt9sDWvDxyu3x4q8ba/Dk2u/R6fD9BXDpSXn47YWjUJqZMGT1GG65xQvmpg5zixwzU4e5qRPN3GLaULr66qvR1taGBx54AM3NzRg7dizWrFkjD8aura1VzKhpt9sxf/587N27F4mJibjkkkvwt7/9TXEJrb8yAeDJJ5+ERqPB1KlT4XA4MHnyZDz33HND9rqPFp/vP4gFb2zHzmbf9eCTClPw0M9+gpOL02JcMyIioujgvd5UOpbnUWrrdKD6ve+weqtv4GyqWY97Jo/G1acWQauJzT3YhkNu8Yi5qcPcIsfM1GFu6hwV8yjR8OP2ePHKZzX40/u+y2yCAFxzahF+O3k00hPE/gsgIiIaZthQijN6vR75+fnynErx4lCXEzP++gW+qDkEwHeZ7eGfn4CxRamxrdhh8ZpbvGNu6jC3yDEzdZibOtHMjZfeVBqsS2/xqP5QN6Yt24y9bV1IMuow9+LRuObU4phdZiMiIlIr0vN3TG+KS4HcbjcOHjwYMIdErOxo7MAVz32KvW1dyEsx4h+3n47rq0rirpEUb7kNF8xNHeYWOWamDnNTJ5q5saEUZ9xuN1pbW+PiQ/HpHguu/p+NaO10YFROElb/9+kYmZMU62oFFU+5DSfMTR3mFjlmpg5zUyeauXGMEgX19teN+H//9zWcHi8mlKXjhWnjkWLiNXIiIjq2sKFEAZZ+sg+PvLMDAHDxCbl48uqxMOq1Ma4VERHR0GNDiWRer4TH1+zE/368FwAwfWIJHpjyk7gbj0RERDRU2FCKMxqNBomJiYoZyYeCJEl48O1v8deNvruk33PRKNz+0woIwvBoJMUqt+GOuanD3CLHzNRhbupEMzdOD6DS0TY9gP9ymyAAf5h6Eq4aXxTrKhEREUUdpwcY5iRJgtvtHtIbIH6wowW/e9c3JmnexaOHZSMpFrkdDZibOswtcsxMHeamTjRzY0MpzjgcDuzevRsOh2NInm97gxV3rvwSkgRcO6EYM84qH5Lnjbahzu1owdzUYW6RY2bqMDd1opkbG0rHsCZrD25++XN0Oz04a0QmHv75T4bNmCQiIqKhwIbSMarL4cbNL32Blg4HRmQn4tnrT4Fey92BiIioN54Zj0Eer4Q7//4ldjR1IDNRxLIbT0WykZNJEhER9cWG0jHod+/uwLqdrTDoNHhh2ngUpZtjXSUiIqK4xOkBVBqs6QEkSYLX64VGoxmU8UJ/3bgfD7z5LQDg2etOwaUn5UX9OWJhsHM7WjE3dZhb5JiZOsxNnXC5RXr+5oSTcUYQBGi1g3O7kM37DuLBt3yNpN9OHnXUNJKAwc3taMbc1GFukWNm6jA3daKZGy+9xRmn04m6ujo4nc6oluvxSnjwrW/hlYDLTy7Af59TEdXyY22wcjvaMTd1mFvkmJk6zE2daObGhlKc8Xq96OrqgtfrjWq5/9hSjx1NHUgy6rDgv44/6rpwByu3ox1zU4e5RY6ZqcPc1IlmbmwoHQO6HG488f4uAMCd541AeoIY4xoREREND2woHQOWbNiDtk4HSjLMmHZ6SayrQ0RENGywoXSUa2zvwf9+vBeA7z5uBh0HBRIREQ0UG0pxRqfTIScnBzpddL6Q+Ic1O+FwezGhLB2Tf5IblTLjUbRzO1YwN3WYW+SYmTrMTZ1o5sbk44xOp0NaWlpUyvqqrh1vfNUIAFhw6dE3gLu3aOZ2LGFu6jC3yDEzdZibOtHMjT1Kccbj8cBqtcLj8RxROZIk4Xfv7AAAXHFKAU4sTIlG9eJWtHI71jA3dZhb5JiZOsxNnWjmxoZSnHG5XGhqaoLL5Tqicv75TTO+qDkEo16DeyaPjlLt4le0cjvWMDd1mFvkmJk6zE2daObGhtJRyO7y4PE13wEAbj27ArkpxhjXiIiIaHhiQ+ko9NKn+1F3sAc5yQbc+tPyWFeHiIho2GJD6ShjsTnw7Ie7AQC/nTwaZpHj9YmIiNRiQynOCIIAk8mk+htqT679Hp0ON04oSMYVJxdEuXbx60hzO1YxN3WYW+SYmTrMTZ1o5hbzhtKzzz6L0tJSGI1GVFVVYfPmzWG3X7x4MUaNGgWTyYSioiLMnj0bdrtdXl9aWgpBEAJ+Zs6cKW9zzjnnBKy/7bbbBu01RsJgMKCkpAQGgyHixza29+Dvm2sB+KYD0GiOnQ/WkeR2LGNu6jC3yDEzdZibOtHMLabXZVatWoU5c+ZgyZIlqKqqwuLFizF58mTs2rUL2dnZAduvWLECc+fOxbJly3D66afj+++/x4033ghBELBo0SIAwOeff674OuD27dtxwQUX4KqrrlKUNWPGDDz88MPy72azeZBe5dD55AcLvBJwcnEqqsozYl0dIiKiYS+mPUqLFi3CjBkzcNNNN+H444/HkiVLYDabsWzZsqDbf/rppzjjjDNw3XXXobS0FBdeeCGuvfZaRS9UVlYWcnNz5Z933nkHFRUV+OlPf6ooy2w2K7ZLTk4e1Nc6UHa7HTt37lT0kg3Up3ssAIAzKzOjXa24dyS5HcuYmzrMLXLMTB3mpk40c4tZj5LT6cSWLVswb948eZlGo8GkSZOwcePGoI85/fTT8corr2Dz5s2YMGEC9u7di3/+85/45S9/GfI5XnnlFcyZMyfgOuXy5cvxyiuvIDc3F1OmTMGCBQvC9io5HA44HA75946ODgC+N0MURcVrEEURXq8XTqczoByj0SiXJ0mSYp1erwcAeL1exXP1LleSpIB1ACCKIj7dcwAAMK4oSbFz6HQ66HQ6eDyegDklBEGQuyaD7VCiKEKj0cDlcgVM3KXVaqHX64OW2/u1BitXr9dDq9WGLTeSDB0OB9xut1yW2+2G2+1WPK6/DA0GAwRBgNPphNfrVayLRobByg2XYTTem/4ydDqdcLvdijz8781gZRiP702kGfauY6jPcqj9+0iPEYP53gzmMcL/Ge1dt6E8RvQtNx4zDFauv45erzfgsUNxjIhFhtEot/f+1ve9ibTxFLOGksVigcfjQU5OjmJ5Tk4Odu7cGfQx1113HSwWC84880xIkgS3243bbrsN9913X9Dt33jjDbS3t+PGG28MKKekpAT5+fnYtm0b7r33XuzatQurV68OWd/q6mo89NBDActra2uRmJgo/56cnIz8/Hy43W7s378/YPvRo32TPzY3N6Onp0exLi8vDwaDAQ6HA3V1dYp71CQkJKCoqAherzdouUJKLlo7HRC1AtI97di/v0Nel52djfT0dHR1daGxsVHxOKPRiNLSUgBATU1NwAeirKwMBoMBFosFVqtVsS49PR3Z2dlwOByora1VrNPpdKisrAQA1NfXB+z0xcXFMJvNOHToEA4ePKhYl5KSgry8PLhcroDXKggCRo0aBQBoamqSd3i324329nb09PQgISEBHR0daG1tVTw2MTERhYWF8Hg8QTMcMWIEtFotWlpa0NXVpViXk5ODtLQ02Gw2NDU1KdaZTCaUlJQAQNByy8vLIYoiLBaL3MD2y8zMRGZmJnp6elBfX69Yp9frUVFRAQCoq6sLONCVlJTAZDIFzTA1NRW5ublwOp0BddJoNBg5ciQA337Y3t4OAPL+VlBQgKSkJFitVrS1tSkem5SUhIKCgpD798iRIyEIApqbm9Hd3a1Yl5ubi9TUVNhsNjQ3NyvWmc1mFBcXQ5KkoOVWVFRAr9ejra0NnZ2dinVZWVnIyMhAd3c3GhoaFOtEUUR5uW+KjNra2oADs3985IEDB+Qc/Hrv3zU1NYp1kiTJf3zV19cHnBgLCwuRmJgIq9UKi8WiWHekx4iUlBR0dnaipaVFsa6/Y0RlZSV0Oh1aW1ths9kU64biGFFXV6fY14b6GOGXn5+P5OTkYXOM8F/t6OnpCfg8DsUxoqGhIaAhNRyOEf5zAuD73PQ+RvTd//sjSH33+iHS2NiIgoICfPrpp5g4caK8/J577sGGDRuwadOmgMesX78e11xzDX73u9+hqqoKu3fvxl133YUZM2ZgwYIFAdtPnjwZoiji7bffDluXDz/8EOeffz52794t73R9BetRKioqQktLi+Ky3ZH+tehyubB3714UFBQoBqH115r+v63NeOCtb3FaWTpemn6yYt2x0qNUV1eHsrIyJCQkDJu/FmPdo9TR0YHa2loUFRXJzzUc/loMVu5Q9yg1NTXJXx5hj1L/xwibzYa6ujrFvsYeJZ/+epTq6+tRXFwMjUY5WoY9SqHL9Z8TioqKkJCQoHhvOjo6kJOTA6vVOqBhNzHrUcrMzJRb5r21tLQgNzf4Xe4XLFiAX/7yl/j1r38NADjxxBPR1dWFW265Bffff79iJ6qpqcEHH3wQtpfIr6qqCgDCNpQMBkPQ0fNGo1HeoXrTaDRBl/cuLxiXywWNRgODwRD08YIgBF2+ca/vstuZIzJDPq9Wq4VWqw1Zp3D11ev18qXBoSo30gx1Op1cD/8HLphQGfr1vpTa15G81sEq90gyFEUROp0u6P42WBnG43sTzf1wKModbhlqtVoYDIaQ+1os3pt4zDBYuf4GUH+v9WjKMFrl+vc3f1n+9yZYwzCcmA3mFkUR48aNw7p16+RlXq8X69atU/Qw9dbd3R3QovbvkH1bvC+++CKys7Nx6aWX9luXr776CoCvey7W/JcKwu1EfXm9ktxQmlhx7A3kBtTlRsxNLeYWOWamDnNTJ5q5xXR6gDlz5mD69OkYP348JkyYgMWLF6Orqws33XQTAGDatGkoKChAdXU1AGDKlClYtGgRTj75ZPnS24IFCzBlyhRFC97r9eLFF1/E9OnTA1qle/bswYoVK3DJJZcgIyMD27Ztw+zZs3H22WfjpJNOGroXH4K/ezES3zV3oL3bhQRRi5MKUwapZvFNTW7E3NRibpFjZuowN3WimVtMG0pXX3012tra8MADD6C5uRljx47FmjVr5AHetbW1ih6k+fPnQxAEzJ8/Hw0NDcjKysKUKVPw6KOPKsr94IMPUFtbi1/96lcBzymKIj744AO5UVZUVISpU6di/vz5g/tiB8jpdMJisSAzM3PAb/LGw992m1CWDr025nOIxoSa3Ii5qcXcIsfM1GFu6kQzt5gN5h7uOjo6kJKSMuDBYANlt9uxf/9++ds4A/Grlz7Hhztbcf8lx2HG2cfmTXDV5EbMTS3mFjlmpg5zUydcbpGev4/N7oejiNvjxeZ9vq99TqzgbNxERETRxIbSMPdNgxU2hxspJj2Oz4uP2cWJiIiOFmwoDXP+2bgnlmccUzfBJSIiGgpsKMUZrVYrzzE1EP6B3Mf6ZbdIcyMf5qYOc4scM1OHuakTzdxi+q03CqTX65GZObC5kBxuDz7f7xufdPox3lCKJDf6EXNTh7lFjpmpw9zUiWZu7FGKM/6p/vtONx/Ml7XtcLi9yEw0oDI7sd/tj2aR5EY/Ym7qMLfIMTN1mJs60cyNDaU443K5gt5kMxj/+KTTKzLkG3QeqyLJjX7E3NRhbpFjZuowN3WimRsbSsPYxj2+u5If65fdiIiIBgsbSsNUt9ONL2vbAQCnH6P3dyMiIhpsbCgNU5/vPwS3V0JBqglF6aZYV4eIiOioxIZSnBEEAXq9vt8xRxs5PklhoLmREnNTh7lFjpmpw9zUiWZuvNebSoN1r7eB+vkzn+DreiuevHoMLj+5cMifn4iIaDjivd6OAdYeF75psAIAJpZzfBIREdFgYUMpztjtdvzwww+w2+0ht9m87yC8ElCelYDcFN5NGhhYbhSIuanD3CLHzNRhbupEMzc2lOJQfxNkfcppAYLihGzqMDd1mFvkmJk6zE2daOXGhtIw9ONAbl52IyIiGkxsKA0zFpsDO5s7AQCnlbNHiYiIaDCxoTTMfLbX15t0XF4y0hPEGNeGiIjo6MaGUpwRRRElJSUQxeCNoN73d6Mf9ZcbBcfc1GFukWNm6jA3daKZmy4K9aEo0mg0MJlCz7T92eGG0kRedlPoLzcKjrmpw9wix8zUYW7qRDM39ijFGZfLhdbW1pB3PG5o7wEAjMpNGspqxb3+cqPgmJs6zC1yzEwd5qZONHNjQynOeDweHDx4MOjXGiVJgsPtBQCYRO1QVy2uhcuNQmNu6jC3yDEzdZibOtHMjQ2lYcTfSAIAg45vHRER0WDj2XYYcbh+bCgZ9exRIiIiGmxsKA0jdrevC1GrEaDX8q0jIiIabDzbxhmtVovU1FRotYE9Rv4eJV52CxQuNwqNuanD3CLHzNRhbupEMzdODxBn9Ho9cnNzg67z9yjxslugcLlRaMxNHeYWOWamDnNTJ5q5sWsizni9Xtjtdni93oB1dtfhhhJ7lAKEy41CY27qMLfIMTN1mJs60cyNZ9w443Q6sX//fjidzoB1/m+9GdijFCBcbhQac1OHuUWOmanD3NSJZm5sKA0j/h4ljlEiIiIaGjE/4z777LMoLS2F0WhEVVUVNm/eHHb7xYsXY9SoUTCZTCgqKsLs2bNht9vl9Q8++CAEQVD8jB49WlGG3W7HzJkzkZGRgcTEREydOhUtLS2D8vqiye5ijxIREdFQimlDadWqVZgzZw4WLlyIrVu3YsyYMZg8eTJaW1uDbr9ixQrMnTsXCxcuxHfffYelS5di1apVuO+++xTb/eQnP0FTU5P888knnyjWz549G2+//TZeffVVbNiwAY2NjbjiiisG7XVGi8PNMUpERERDKabfelu0aBFmzJiBm266CQCwZMkSvPvuu1i2bBnmzp0bsP2nn36KM844A9dddx0AoLS0FNdeey02bdqk2E6n04Uc7W61WrF06VKsWLEC5513HgDgxRdfxHHHHYfPPvsMp512WjRfoioaTfCGkL9Hid96Cy5UbhQec1OHuUWOmanD3NSJVm4xayg5nU5s2bIF8+bNk5dpNBpMmjQJGzduDPqY008/Ha+88go2b96MCRMmYO/evfjnP/+JX/7yl4rtfvjhB+Tn58NoNGLixImorq5GcXExAGDLli1wuVyYNGmSvP3o0aNRXFyMjRs3hmwoORwOOBwO+feOjg4Avst4oigqXoMoivB6vUEHkRmNRrk8SZIU6/R6PYxGI8rLy+F2uxWXFDUajdyjpNdAsQ4ADAYDBEGA0+kMGOWv0+mg0+ng8XgCbhAoCAIMBoP8WvoSRREajQYulyvgnjlarRZ6vT5oub1fa7By9Xo9tFpt2HIjzbC4uBh6vR4A4Ha74Xa7FY/zvzeSJCneS7/BzjBYueEyjMZ701+GgiDInw3/c/jfm8HKMB7fGzUZjhw5EkDoz3Ko/ftIjxGD+d4M5jECQMC+NtTHiN7lxmOGoY4RI0eOhMfjCXjsUBwjYpFhtMr1729ut1vx3gTLKpyYNZQsFgs8Hg9ycnIUy3NycrBz586gj7nuuutgsVhw5plnQpIkuN1u3HbbbYpLb1VVVXjppZcwatQoNDU14aGHHsJZZ52F7du3IykpCc3NzRBFEampqQHP29zcHLK+1dXVeOihhwKW19bWIjExUf49OTkZ+fn5cLvd2L9/f8D2/vFSzc3N6OnpUazLy8tDSkoKOjs7A8ZMJSQkyD1KbkdPQNmVlZXQ6XRobW2FzWZTrMvOzkZ6ejq6urrQ2NioWGc0GlFaWgoAqKmpCfhAlJWVwWAwwGKxwGq1Ktalp6cjOzsbDocDtbW1inU6nQ6VlZUAgPr6+oCdvri4GGazGYcOHcLBgwcV61JSUpCXlweXyxXwOgVBwKhRowAATU1NATt8fn4+kpOT0dHREXAJNzExEYWFhfB4PEHfmxEjRkCr1aKlpQVdXV2KdTk5OUhLS4PNZkNTU5NinclkQklJCQAELbe8vByiKMJiscgNbL/MzExkZmaip6cH9fX1inV6vR4VFRUAgLq6uoADXUlJCUwmU9AMU1NTkZubK3/zozeNRiOf5BsaGgIOkgUFBUhKSoLVakVbW5tiXVJSEgoKCkLu3yNHjoQgCGhubkZ3d7diXW5uLlJTU2Gz2QI+a2azGcXFxZAkKWi5FRUV0Ov1aGtrQ2dnp2JdVlYWMjIy0N3djYaGBsU6URRRXl4OwPdZ7Xtg9o+PPHDgANrb2xXreu/fNTU1inVarRYjRowA4Nu/+54YCwsLkZiYCKvVCovFolg3mMeIoqIieL3eoOXyGOHDY4TPsXyM6Lv/90eQ+u71Q6SxsREFBQX49NNPMXHiRHn5Pffcgw0bNgRcTgOA9evX45prrsHvfvc7VFVVYffu3bjrrrswY8YMLFiwIOjztLe3o6SkBIsWLcLNN9+MFStW4KabbgpokU6YMAHnnnsufv/73wctJ1iPUlFREVpaWpCcnCwvP9K/Ft1uN+rq6pCVlSX/peAv94X/1OKJf+3CFWPz8NhlxyseG+u/FmPdo+RwONDc3IyioiKYzeZh9ddiLHuUOjs70djYiNzcXPm5hstfi33LHcoMnU4nLBYLCgoKAIA9SgM4RvhPfr33NfYo+YQ7Rng8HrS0tCAvLw+CIKgqd7hlGI1y/eeE3NxcJCQkKN6bjo4O5OTkwGq1Ks7focSsRykzM1NumffW0tIScnzRggUL8Mtf/hK//vWvAQAnnngiurq6cMstt+D+++8Pej0yNTUVI0eOxO7duwFAbkG3t7crepXCPS/gexN6N1z8jEajvEP1ptFogi7vXV4wLpcLbrcbBoMh4PH+eZQSjGLIsntfBuxLq9WGnc49XH31er18WWuoyo00Q0mS5H3A/4ELRhCEsOUOVoaxeG/6y1Cv10OSpKD722BlGI/vjZoMnU4nJEkasv27t+GWoVarhcFgCLmvMcPQ5drtdjidzn7rdDRlGK1y/fubvyz/exPp3EoxGyEmiiLGjRuHdevWycu8Xi/WrVun6GHqrbu7O6Ax5N8hQ3WM2Ww27NmzB3l5eQCAcePGQa/XK553165dqK2tDfm88cLhn5lbz4F9REREQyGm33qbM2cOpk+fjvHjx2PChAlYvHgxurq65G/BTZs2DQUFBaiurgYATJkyBYsWLcLJJ58sX3pbsGABpkyZIjeYfvOb32DKlCkoKSlBY2MjFi5cCK1Wi2uvvRaA79r2zTffjDlz5iA9PR3Jycm44447MHHixLj4xls4P044yW+9ERERDYWYNpSuvvpqtLW14YEHHkBzczPGjh2LNWvWyAO8a2trFT1I8+fPhyAImD9/PhoaGpCVlYUpU6bg0Ucflbepr6/HtddeiwMHDiArKwtnnnkmPvvsM2RlZcnbPPnkk9BoNJg6dSocDgcmT56M5557buheuEr+S2/sUSIiIhoaMRvMPdx1dHQgJSVlwIPBBsrj8aC7uxtmszngOvfdK7/EG181Yv6lx+HXZ5VH7TmPBuFyo9CYmzrMLXLMTB3mpk643CI9f8e0R4kCabVaJCUlBV0n3xSXM3MHCJcbhcbc1GFukWNm6jA3daKZG8+4ccbtduPAgQMBX40Eeo1R4szcAcLlRqExN3WYW+SYmTrMTZ1o5saGUpxxu91oa2sL0VBij1Io4XKj0JibOswtcsxMHeamTjRz4xl3GJFvisseJSIioiHBhtIwwpviEhERDS02lIYRf48SL70RERENDZ5x44xGo0FSUlLQ27GwRym0cLlRaMxNHeYWOWamDnNTJ5q5cXqAOCOKonyjzb7YoxRauNwoNOamDnOLHDNTh7mpE83ceMaNM5IkweVyBb13nYM9SiGFy41CY27qMLfIMTN1mJs60cyNDaU443A4sGfPHjgcjoB1djdvihtKuNwoNOamDnOLHDNTh7mpE83ceMYdJjxeCS6Pr2XMm+ISERENDTaUhgn/+CSAPUpERERDhWfcYcL/jTeAPUpERERDJeKGUmlpKR5++GHU1tYORn0oBH+Pkl4rQKsRYlwbIiKiY0PEDaW7774bq1evRnl5OS644AKsXLmSg8yiyGAwYOTIkTAYDIrl8hxK7E0KKlRuFB5zU4e5RY6ZqcPc1IlmbqoaSl999RU2b96M4447DnfccQfy8vIwa9YsbN269YgrdKwTBAEajQaCoOw1srsOz6HE8UlBhcqNwmNu6jC3yDEzdZibOtHMTfVZ95RTTsFTTz2FxsZGLFy4EH/5y19w6qmnYuzYsVi2bBnnfFDJ6XSitrYWTqdTsdzh9vUocXxScKFyo/CYmzrMLXLMTB3mpk40c1M9M7fL5cLrr7+OF198EWvXrsVpp52Gm2++GfX19bjvvvvwwQcfYMWKFUdcwWON1+tFd3c3vF6vYrm/R4nfeAsuVG4UHnNTh7lFjpmpw9zUiWZuETeUtm7dihdffBF///vfodFoMG3aNDz55JMYPXq0vM3ll1+OU0899YgrRz9ijxIREdHQi7ihdOqpp+KCCy7A888/j8suuwx6vT5gm7KyMlxzzTVRqSD5sEeJiIho6EXcUNq7dy9KSkrCbpOQkIAXX3xRdaUo0I8NJfYoERERDZWIuydaW1uxadOmgOWbNm3CF198EZVKHct0Oh1yc3Oh0ynbsD9eemOPUjChcqPwmJs6zC1yzEwd5qZONHOL+Kw7c+ZM1NXVBSxvaGjAzJkzj7hCxzqdTofU1NTAhhJ7lMIKlRuFx9zUYW6RY2bqMDd1oplbxA2lHTt24JRTTglYfvLJJ2PHjh1HXKFjndvtRnt7O9xut2K5f8JJ9igFFyo3Co+5qcPcIsfM1GFu6kQzt4jPugaDAS0tLQHLm5qa2OKNArfbjebm5oA3138LE/YoBRcqNwqPuanD3CLHzNRhbupEM7eIG0oXXngh5s2bB6vVKi9rb2/HfffdhwsuuOCIK0TBybcwYUOJiIhoyETcBfTHP/4RZ599NkpKSnDyyScDAL766ivk5OTgb3/7W9QrSD7+HiVeeiMiIho6ETeUCgoKsG3bNixfvhxff/01TCYTbrrpJlx77bVB51Si6JDHKLFHiYiIaMioGlSUkJCAW265Jdp1IQAajQZmsxkajbLnSL4pLnuUggqVG4XH3NRhbpFjZuowN3WimZvq0dc7duwIesO5n/3sZ0dcqWOZKIooLi4OWO6fR4ljlIILlRuFx9zUYW6RY2bqMDd1oplbxE2tvXv3YsyYMTjhhBNw6aWX4rLLLsNll12Gyy+/HJdffnnEFXj22WdRWloKo9GIqqoqbN68Oez2ixcvxqhRo2AymVBUVITZs2fDbrfL66urq3HqqaciKSkJ2dnZuOyyy7Br1y5FGeeccw4EQVD83HbbbRHXfTBIkgSv1wtJkhTLeQuT8ELlRuExN3WYW+SYmTrMTZ1o5hbxWfeuu+5CWVkZWltbYTab8e233+Ljjz/G+PHjsX79+ojKWrVqFebMmYOFCxdi69atGDNmDCZPnozW1tag269YsQJz587FwoUL8d1332Hp0qVYtWoV7rvvPnmbDRs2YObMmfjss8+wdu1auFwuXHjhhejq6lKUNWPGDDQ1Nck/f/jDHyKNYlA4HA58//33cDgciuV23hQ3rFC5UXjMTR3mFjlmpg5zUyeauUV86W3jxo348MMPkZmZCY1GA41GgzPPPBPV1dW488478eWXXw64rEWLFmHGjBm46aabAABLlizBu+++i2XLlmHu3LkB23/66ac444wzcN111wEASktLce211ypuqbJmzRrFY1566SVkZ2djy5YtOPvss+XlZrMZubm5Eb32WHKwR4mIiGjIRXzW9Xg8SEpKAgBkZmaisbERAFBSUhJwiSscp9OJLVu2YNKkST9WRqPBpEmTsHHjxqCPOf3007Flyxb58tzevXvxz3/+E5dccknI5/HP95Senq5Yvnz5cmRmZuKEE07AvHnz0N3dPeC6x4K/R8nIHiUiIqIhE3GP0gknnICvv/4aZWVlqKqqwh/+8AeIooj//d//RXl5+YDLsVgs8Hg8yMnJUSzPycnBzp07gz7muuuug8ViwZlnnglJkuB2u3HbbbcpLr315vV6cffdd+OMM87ACSecoCinpKQE+fn52LZtG+69917s2rULq1evDllfh8Oh6MLr6OgAANjtdoiiKC/XaDQQRRFerzdgoDsAGI1Guby+10790yt4vd7AS29O3+yiok5QjMnyMxgMEAQBTqcTXq9XsU6n00Gn08Hj8cDlcinWCYIAg8Egv5a+RFGERqOBy+WCx+NRrNNqtdDr9UHL7f1ag5Wr1+uh1WrDlhtJhg6HA263Wy7L7XYHzMjqf28kSQraHTvYGQYrN1yG0Xhv+svQ6XTC7XYr8vC/N4OVYTy+N5Fm2LuOoT7LofbvIz1GDOZ7M5jHCP9ntHfdhvIY0bfceMwwWLn+Onq93oDHDsUxIhYZRqPc3vtb3/cmWFbhRNxQmj9/vjze5+GHH8Z//dd/4ayzzkJGRgZWrVoVaXERWb9+PR577DE899xzqKqqwu7du3HXXXfhkUcewYIFCwK2nzlzJrZv345PPvlEsbz31AYnnngi8vLycP7552PPnj2oqKgI+tzV1dV46KGHApbX1tYiMTFR/j05ORn5+flwu93Yv39/wPajR48GADQ3N6Onp0exLi8vDwaDAQ6HA3V1dYpbwnTZfTuyQasJWm5lZSV0Oh1aW1ths9kU67Kzs5Geno6uri65B9DPaDSitLQUAFBTUxPwgSgrK4PBYIDFYlHMxg74eumys7PhcDhQW1urWKfT6VBZWQkAqK+vD9jpi4uLYTabcejQIRw8eFCxLiUlBXl5eXC5XAGvVRAEjBo1CoDvtjn+Hd5/X5+enh4kJCSgo6MjYKxbYmIiCgsL4fF4gmY4YsQIaLVatLS0BIxpy8nJQVpaGmw2G5qamhTrTCYTSkpKACBoueXl5RBFERaLRW5g+2VmZiIzMxM9PT2or69XrNPr9fL+WFdXF3CgKykpgclkCpphamoqcnNz4XQ6A+qk0WgwcuRIAL79sL29HQDk/a2goABJSUmwWq1oa2tTPDYpKQkFBQUh9++RI0dCEAQ0NzcH9NLm5uYiNTUVNpsNzc3NinVmsxnFxcWQJClouRUVFdDr9Whra0NnZ6diXVZWFjIyMtDd3Y2GhgbFOlEU5T/gamtrAw7M/i+SHDhwQM7Br/f+XVNTo1gnSRIEQQDg27/7nhgLCwuRmJgIq9UKi8WiWHekx4iUlBR0dnYG3EoqISEBRUVF8Hq9cXmMqKurU+xrQ32M8MvPz0dycvKwOUYkJycDAHp6egI+j0NxjGhoaAhoSA2HY4T/nAD4Pje9jxF99//+CFIUhoQfPHgQaWlp8oFjIJxOJ8xmM1577TVcdtll8vLp06ejvb0db775ZsBjzjrrLJx22ml44okn5GWvvPIKbrnlFthsNsV8CbNmzcKbb76Jjz/+GGVlZWHr0tXVhcTERKxZswaTJ08Ouk2wHqWioiK0tLTIOzJw5H8tajQa+YPdO89zFn2C5g4H3px5OkZlmQLKjfVfi7HuUfL3MJpMprjttYjHHiW73Q6XywWdTifvb8Phr8Vg5Q5lhpIkyc/rdDrZozSAY4S/97L3vsYeJZ/+jhH+MvrWlz1Kocv1nxN0Oh30er3iveno6EBOTg6sVqvi/B1KRD1KLpcLJpMJX331leJSVt/xPwMhiiLGjRuHdevWyQ0lr9eLdevWYdasWUEf093dHTB5lH8n6n3CvOOOO/D6669j/fr1/TaSAN8tWABfqzMUg8Eg75C9GY1GeYfqTaPRBF3eu7xQTKbAhpDT43t9JlEXttzelwH70mq1cl7BhCtXr9eHnHl9sMo9kgz9H7hgBEGISYaxeG/6yzDU/gsMXobx+N4M1n54LO3f/R0jgh3XjrTcoy3DcOUCCFnf/sodbhkO9nsTrGEYTkSDufV6PYqLiwNapmrNmTMHL7zwAl5++WV89913uP3229HV1SV/C27atGmYN2+evP2UKVPw/PPPY+XKldi3bx/Wrl2LBQsWYMqUKfKOOXPmTLzyyitYsWIFkpKS0NzcrOjC3rNnDx555BFs2bIF+/fvx1tvvYVp06bh7LPPxkknnRSV13UknE5n0K5OeR4lDuYOKlRuFB5zU4e5RY6ZqcPc1IlmbhGPUbr//vtx33334W9/+5uqnqTerr76arS1teGBBx5Ac3Mzxo4dizVr1sgDvGtraxU9SPPnz4cgCJg/fz4aGhqQlZWFKVOm4NFHH5W3ef755wH4JpXs7cUXX8SNN94IURTxwQcfYPHixejq6kJRURGmTp2K+fPnH9FriRav14vOzk5kZGQolvtn5jZweoCgQuVG4TE3dZhb5JiZOsxNnWjmFnFD6ZlnnsHu3buRn5+PkpISJCQkKNZv3bo1ovJmzZoV8lJb3wksdTodFi5ciIULF4Ysr78hV0VFRdiwYUNEdYw1l8cLj9f3utijRERENHQibij1HnhNQ8N/2Q1gjxIREdFQirihFK43hwaH/7IbABh0bCgRERENFZ5144xOp0NWVpZixL+/R8mg00Q0BcOxJFhu1D/mpg5zixwzU4e5qRPN3CIuQaMJf7KO1jfijlU6nS5g8Jnd5b8hLtu1oQTLjfrH3NRhbpFjZuowN3WimVvEDaXXX39d8bvL5cKXX36Jl19+OejM1RQZj8eD7u5umM1mecoDh9t/Q1wO5A4lWG7UP+amDnOLHDNTh7mpE83cIm4o/fznPw9YduWVV+InP/kJVq1ahZtvvvmIKnSsc7lcaGhoQGlpqfzm+nuU2FAKLVhu1D/mpg5zixwzU4e5qRPN3KJ2Lee0007DunXrolUc9eLvUeKlNyIioqEVlTNvT08PnnrqKRQUFESjOOrDwR4lIiKimIj40lvfm99KkoTOzk6YzWa88sorUa0c+fT+1hsRERENnYgbSk8++aSioaTRaJCVlYWqqiqkpaVFtXLHIkEQIIqiImP/PErsUQotWG7UP+amDnOLHDNTh7mpE83cBKm/e35QUB0dHUhJSYHVakVycvKgPtfKzbWYu/obTDouG3+ZfuqgPhcREdHRLNLzd8TXcl588UW8+uqrActfffVVvPzyy5EWRwMg3xCX93kjIiIaUhE3lKqrq5GZmRmwPDs7G4899lhUKnUss9vt+P7772G3239c5h+jxPu8hRQsN+ofc1OHuUWOmanD3NSJZm4Rn3lra2tRVlYWsLykpAS1tbVHXCECvF6v4nfOozQwfXOjgWFu6jC3yDEzdZibOtHKLeKGUnZ2NrZt2xaw/Ouvv+Y064OE8ygRERHFRsRn3muvvRZ33nknPvroI3g8Hng8Hnz44Ye46667cM011wxGHY957FEiIiKKjYinB3jkkUewf/9+nH/++fJdeb1eL6ZNm8YxSoPEzh4lIiKimIi4oSSKIlatWoXf/e53+Oqrr2AymXDiiSeipKRkMOp3zBFFEaWlpRBFUV7Gmbn7Fyw36h9zU4e5RY6ZqcPc1IlmbhE3lPxGjBiBESNGHHEFSEmj0cBoNCqW+XuUjOxRCilYbtQ/5qYOc4scM1OHuakTzdwiPvNOnToVv//97wOW/+EPf8BVV10VlUody1wuF5qbm+FyueRl/h4lA3uUQgqWG/WPuanD3CLHzNRhbupEM7eIG0off/wxLrnkkoDlF198MT7++OMjrtCxzuPxoL29HR6PR17m/9abkfMohRQsN+ofc1OHuUWOmanD3NSJZm4Rn3ltNlvQa356vR4dHR1HXCEK9ONNcdmjRERENJQibiideOKJWLVqVcDylStX4vjjj49KpUjpx5viskeJiIhoKEU8mHvBggW44oorsGfPHpx33nkAgHXr1mHFihV47bXXol5B+rFHycgeJSIioiEVcUNpypQpeOONN/DYY4/htddeg8lkwpgxY/Dhhx8iPT19MOp4TNFqtUhPT4dW+2OjyC4P5maPUijBcqP+MTd1mFvkmJk6zE2daOYmSJIkHUkBHR0d+Pvf/46lS5diy5Ytx8yAs46ODqSkpMBqtSI5OXlQn6vqsQ/Q0uHAO3eciRMKUgb1uYiIiI5mkZ6/VXdRfPzxx5g+fTry8/Pxpz/9Ceeddx4+++wztcXRYV6vFz09PYqb+fEWJv0Llhv1j7mpw9wix8zUYW7qRDO3iBpKzc3NePzxxzFixAhcddVVSE5OhsPhwBtvvIHHH38cp5566hFX6FjndDpRU1MDp9MpL+NNcfsXLDfqH3NTh7lFjpmpw9zUiWZuAz7zTpkyBaNGjcK2bduwePFiNDY24umnnz7iClB4kiSxR4mIiChGBjyY+7333sOdd96J22+/nbcuGUL+qQEADuYmIiIaagM+837yySfo7OzEuHHjUFVVhWeeeQYWi2Uw60ZQNpQ4PQAREdHQGnBD6bTTTsMLL7yApqYm3HrrrVi5ciXy8/Ph9Xqxdu1adHZ2qqrAs88+i9LSUhiNRlRVVWHz5s1ht1+8eDFGjRoFk8mEoqIizJ49G3a7PaIy7XY7Zs6ciYyMDCQmJmLq1KloaWlRVf/B0PvrjI7DcyhpBECvFWJVpWGBX59Vh7mpw9wix8zUYW7qRC036Qjs3LlT+u1vfyvl5uZKRqNRmjJlSkSPX7lypSSKorRs2TLp22+/lWbMmCGlpqZKLS0tQbdfvny5ZDAYpOXLl0v79u2T/vWvf0l5eXnS7NmzIyrztttuk4qKiqR169ZJX3zxhXTaaadJp59+ekR1t1qtEgDJarVG9LhI1R7okkrufUcaPf+9QX0eIiKiY0Gk5+8jaij5ud1u6fXXX4+4oTRhwgRp5syZ8u8ej0fKz8+Xqqurg24/c+ZM6bzzzlMsmzNnjnTGGWcMuMz29nZJr9dLr776qrzNd999JwGQNm7cOOC6D1VD6fvmDqnk3neksQ/9a1Cfh4iI6FgQ6fk74pm5g9Fqtbjssstw2WWXDfgxTqcTW7Zswbx58+RlGo0GkyZNwsaNG4M+5vTTT8crr7yCzZs3Y8KECdi7dy/++c9/4pe//OWAy9yyZQtcLhcmTZokbzN69GgUFxdj48aNOO2004I+t8PhgMPhkH/33wDYbrcrbhKs0WggiiK8Xm/QryUajUa5PKnPXJ96vR5utxu1tbXIzs6GwWCAtasHACAenhpAkiRFPfwMBgMEQYDT6QyYN0Kn00Gn08Hj8cDlcinWCYIAg8Egv5a+RFGERqOBy+UKmExUq9VCr9cHLbf3aw1Wrl6vh1arDVtuJBk6HA40NTWhuLgYZrMZbrcbbrdb8Tj/exOrDIOVGy7DaLw3/WXY2dmJhoYG5OXlyc/lf28GK8N4fG8izdDpdKKtrQ2FhYUAEPSzHGr/PtJjxGC+N4N5jLDZbGhqalLsa0N5jOhbbjxmGKxcj8eD5uZm5OfnQxCUwy+G4hgRiwyjUa7/nJCXl4eEhATFexMsq3Ci0lBSw2KxwOPxICcnR7E8JycHO3fuDPqY6667DhaLBWeeeSYkSYLb7cZtt92G++67b8BlNjc3QxRFpKamBmzT3Nwcsr7V1dV46KGHApbX1tYiMTFR/j05ORn5+flwu93Yv39/wPajR4+W69HT06NY5z+A2Gw2OBwO6HQ61LT4ttELvh3V6/UGLbeyshI6nQ6tra2w2WyKddnZ2UhPT0dXVxcaGxsV64xGI0pLSwEANTU1AR+IsrIyGAwGWCwWWK1Wxbr09HRkZ2fD4XCgtrZWsU6n06GyshIAUF9fH7DT+xs0hw4dwsGDBxXrUlJSkJeXB5fLFfBaBUHAqFGjAABNTU3yDu92u9He3o7MzEyYzWZ0dHSgtbVV8djExEQUFhbC4/EEzXDEiBHQarVoaWlBV1eXYl1OTg7S0tLkg31vJpMJJSUlABC03PLycoiiCIvFIjew/TIzM5GZmYmenh7U19cr1un1elRUVAAA6urqAg50JSUlMJlMQTNMTU1Fbm4unE5nQJ00Gg1GjhwJwJehxWKB2+2GTuc7HBQUFCApKQlWqxVtbW2KxyYlJaGgoCDk/j1y5EgIgoDm5mZ0d3cr1uXm5iI1NRU2my3gs2Y2m1FcXAxJkoKWW1FRAb1ej7a2toDxkFlZWcjIyEB3dzcaGhoU60RRRHl5OQDfZ7Xvgdk/lvHAgQNob29XrOu9f9fU1CjWSZIEQRAgSRIaGhoCToyFhYVITEyE1WoN+NLLkR4jUlJS0NnZGTCuMiEhAUVFRXF7jKirq0N7e7u8rw31McIvPz8fycnJw+YYkZycDJfLhe7u7oDP41AcIxoaGgIaUsPhGOE/J7jdbuTl5SmOEX33//7ErKGkxvr16/HYY4/hueeeQ1VVFXbv3o277roLjzzyCBYsWDCozz1v3jzMmTNH/r2jowNFRUUoLi5WTIGu0fh6fnQ6nXxwCSY3NzdoK93lcsFgMKCgoAAGgwGNnoMAGpFgFOXyg5XrH7SWnZ2NzMxMxTr/CTAhISHgsb3/QvF/kPvWCfCd0NPS0oI+p8FgCPta/X91Bys3LS0tYAp5f7l6vT5suXl5eYoeJcB3QAJ8Bxez2azY3v/eaLXaoOX61+fk5AT9SwfwHUjDZRisXP9jMzMzA+6H6H+tJpMpbLlFRUUB5fp7MsNlKIpiv/uh0+lEUVGRokcJ8J2MEhISFNv3t3/765ybmxtRhv5yBUEIm6G/URRsndlsDpthcXFxQLn+DDMyMgL+eAq3f/v/WgV8+3ewzzLgy7D3H1K9X6vaYwTgOxn59/W+5cbrMcK/D/fe1/yG4hjRt9zhcoxwu93o6OiI2TGioKAg7P4dr8cI/zmhqKhIrqP/GNG3MdqfmDWUMjMz5ZZ5by0tLcjNzQ36mAULFuCXv/wlfv3rXwMATjzxRHR1deGWW27B/fffP6Ay/SeG9vZ2xYEx3PMCvg963w834Ptry99F2ZtGowm6vHd5wbhcLmg0GhgMBhiNRngF387sn2xSEISw5fa+DNiXVqsN+y2AcOXq9Xr5wzFU5UaaoU6nk+vh/4s1mFhlGIv3pr8MRVGETqeT97feBivDeHxvorkfDkW5wy1DrVYLg8EQcl+LxXsTjxkGK9ffI9bfaz2aMoxWuf79zV+W/72JdLbumM1gKIoixo0bh3Xr1snLvF4v1q1bh4kTJwZ9THd3t9yq9PPvkJIkDajMcePGQa/XK7bZtWsXamtrQz5vLPnnUTJwVm4iIqIhF9NLb3PmzMH06dMxfvx4TJgwAYsXL0ZXVxduuukmAMC0adNQUFCA6upqAL7bqCxatAgnn3yyfOltwYIFmDJlitxg6q/MlJQU3HzzzZgzZw7S09ORnJyMO+64AxMnTgw5kHso6fV6FBYWyq1/++F5lHj7kvD65kYDw9zUYW6RY2bqMDd1oplbTBtKV199Ndra2vDAAw+gubkZY8eOxZo1a+TB2LW1tYoepPnz50MQBMyfPx8NDQ3IysrClClT8Oijjw64TAB48sknodFoMHXqVDgcDkyePBnPPffc0L3wMLRarWJMg9yjxBvihtU3NxoY5qYOc4scM1OHuakTzdwEqe8oLRqQjo4OpKSkwGq1BgySOxIulwtWqxUpKSnQ6/VY9sk+PPzODkwZk4+nrz05as9ztOmbGw0Mc1OHuUWOmanD3NQJl1uk5292U8QZj8cjT3MAAHa371/2KIXXNzcaGOamDnOLHDNTh7mpE83cePaNcw6X79KbUc+3ioiIaKjx7Bvn/D1KRh0HcxMREQ01NpTinL9HycAeJSIioiHHs2+c0Wg0SE5Olr/t52CP0oD0zY0Ghrmpw9wix8zUYW7qRDO3YXULk2OBKIrIz8+Xf7fLY5TYUAqnb240MMxNHeYWOWamDnNTJ5q5sYkaZ/x3cvbfA8ffo8RLb+H1zY0Ghrmpw9wix8zUYW7qRDM3nn3jjNPpxN69e+V70cg9Srz0Flbf3GhgmJs6zC1yzEwd5qZONHNjQynO+W9hwh4lIiKiocezb5z78RYm7FEiIiIaamwoxbkfb4rLt4qIiGio8ewb59ijREREFDu8Ka5Kg3VT3L7O/P2HqD/Ug9f/+3ScXJw2aM9DRER0LOBNcY8y/m+9sUeJiIho6LGhFGccDgdqamrgcDh8v7s5Rmkg+uZGA8Pc1GFukWNm6jA3daKZG8++cUaSJPT09MB/RdTBmbkHpG9uNDDMTR3mFjlmpg5zUyeaubGhFMc8XglOj//SG98qIiKiocazbxxzun+cep09SkREREOPDaU45p9DCWCPEhERUSzw7Btn9Ho98vLyoNfr5TmUdBoBOi3fqnB650YDx9zUYW6RY2bqMDd1opmbLgr1oSjSarVISUkBANhddgC87DYQvXOjgWNu6jC3yDEzdZibOtHMjd0UccbtduPQoUNwu92wH54agJfd+tc7Nxo45qYOc4scM1OHuakTzdx4Bo4zbrcbLS0tcLvdnBogAr1zo4Fjbuowt8gxM3WYmzrRzI0NpTjmH8xt4GSTREREMcEzcBzjDXGJiIhiiw2lOObvUeLtS4iIiGKDZ+A4o9FokJCQAI1GA7ubs3IPVO/caOCYmzrMLXLMTB3mpk40c+P0AHFGFEUUFRUBABxyjxIvvfWnd240cMxNHeYWOWamDnNTJ5q5sYkaZyRJgsfjgSRJco+SkWOU+tU7Nxo45qYOc4scM1OHuakTzdzYUIozDocDP/zwAxwOh9yjxG+99a93bjRwzE0d5hY5ZqYOc1MnmrnFxRn42WefRWlpKYxGI6qqqrB58+aQ255zzjkQBCHg59JLL5W3CbZeEAQ88cQT8jalpaUB6x9//PFBfZ2RcrBHiYiIKKZiPkZp1apVmDNnDpYsWYKqqiosXrwYkydPxq5du5CdnR2w/erVq+F0OuXfDxw4gDFjxuCqq66SlzU1NSke89577+Hmm2/G1KlTFcsffvhhzJgxQ/49KSkpWi8rKvitNyIiotiKeUNp0aJFmDFjBm666SYAwJIlS/Duu+9i2bJlmDt3bsD26enpit9XrlwJs9msaCjl5uYqtnnzzTdx7rnnory8XLE8KSkpYNt4Is+jxMHcREREMRHThpLT6cSWLVswb948eZlGo8GkSZOwcePGAZWxdOlSXHPNNUhISAi6vqWlBe+++y5efvnlgHWPP/44HnnkERQXF+O6667D7NmzodMFj8ThcCiudXZ0dAAA7HY7RFFU1F8URXi9XkXPl5/RaJTL6zvIzH+XY6/XC4fDAVuP7/E6+MoSRRGSJAW95mowGCAIApxOJ7xer2KdTqeDTqeDx+OBy+VSrBMEAQaDQX4tfYmiCI1GA5fLBY/Ho1in1Wqh1+uDltv7tQYrV6/XQ6vVhi03kgwdDgfcbrdcltvtDpi63v/exCrDYOWGyzAa701/GTqdTt/tcnrl4X9vBivDeHxvIs2wdx1DfZZD7d9HeowYzPdmMI8R/s9o77oN5TGib7nxmGGwcv119Hq9AY8dimNELDKMRrm997e+702wrMKJaUPJYrHA4/EgJydHsTwnJwc7d+7s9/GbN2/G9u3bsXTp0pDbvPzyy0hKSsIVV1yhWH7nnXfilFNOQXp6Oj799FPMmzcPTU1NWLRoUdByqqur8dBDDwUsr62tRWJiovx7cnIy8vPz4Xa7sX///oDtR48eDQBobm5GT0+PYl1eXh6Sk5ORnZ2NxsZGWNqtAIBuWwdaWlpQVFQEr9cbtNzKykrodDq0trbCZrMp1mVnZyM9PR1dXV1obGxUrDMajSgtLQUA1NTUBHwgysrKYDAYYLFYYLVaFevS09ORnZ0Nh8OB2tpaxTqdTofKykoAQH19fcBOX1xcDLPZjEOHDuHgwYOKdSkpKcjLy4PL5Qp4rYIgYNSoUQB8l1j9O7wkSdBoNPLzdHR0oLW1VfHYxMREFBYWwuPxBM1wxIgR0Gq1aGlpQVdXl2JdTk4O0tLSYLPZAi7tmkwmlJSUAEDQcsvLyyGKIiwWi9zA9svMzERmZiZ6enpQX1+vWKfX61FRUQEAqKurCzjQlZSUwGQyBc0wNTUVubm5cDqdAXXSaDQYOXIkAN9nUKPRoLGxEYIgAAAKCgqQlJQEq9WKtrY2xWOTkpJQUFAQcv8eOXIkBEFAc3Mzuru7Fetyc3ORmpoKm82G5uZmxTqz2Yzi4mJIkhS03IqKCuj1erS1taGzs1OxLisrCxkZGeju7kZDQ4NinSiKck9ybW1twIHZPzbywIEDaG9vV6zrvX/X1NQo1mk0GlRWVkKr1WLv3r0BJ8bCwkIkJibCarXCYrEo1h3pMSIlJQWdnZ1oaWlRrEtISIjrY0RjY6NiXxvqY4Rffn4+kpOTh80xIiMjA5WVlejp6Qk4zg7FMaKhoSGgITUcjhH+c0JjYyOys7MVx4i++39/BCmG3zlsbGxEQUEBPv30U0ycOFFefs8992DDhg3YtGlT2Mffeuut2LhxI7Zt2xZym9GjR+OCCy7A008/HbasZcuW4dZbb4XNZpNb6L0F61EqKipCS0sLkpOT5eXR/GvxN//Yjne+acHcySPwqzNK4/qvxVj3KPUtd7j8tRjrHqXh+tdisHLjMUP2KPEYAfAY0Vs8HCM6OjqQk5MDq9WqOH+HEtMepczMTLl13ltLS0u/Y4e6urqwcuVKPPzwwyG3+fe//41du3Zh1apV/dalqqpKbgH7/xrpzWAwBG1AGY1GeYfqTaPRBF3eu7xgnE4nWltbkZ2dDdfh9zrRZJAv7wmCELbc3pcB+9JqtdBqQ493CleuXq+XLw0OVbmRZNg7N61WK38wgolVhrF4b/rLUBAEtLW1ITs7O6B+g5VhPL43kWbodDpRX1+P7OzskJ9lNeX2Fq7c4ZahVquFx+ORP6N96zAUx4i+4jHDYOX23tfCPfZoyjAa5fY+J/jL8r83wRqG4cT061SiKGLcuHFYt26dvMzr9WLdunWKHqZgXn31VTgcDtxwww0ht1m6dCnGjRuHMWPG9FuXr776ChqNJug37YaS1+uFzWbzXY928RYmA9U7Nxo45qYOc4scM1OHuakTzdxi/q23OXPmYPr06Rg/fjwmTJiAxYsXo6urS/4W3LRp01BQUIDq6mrF45YuXYrLLrsMGRkZQcvt6OjAq6++ij/96U8B6zZu3IhNmzbh3HPPRVJSEjZu3IjZs2fjhhtuQFpaWvRfpEoON29hQkREFEsxbyhdffXVaGtrwwMPPIDm5maMHTsWa9askQd419bWBtzUbteuXfjkk0/w/vvvhyx35cqVkCQJ1157bcA6g8GAlStX4sEHH4TD4UBZWRlmz56NOXPmRPfFHSF/jxIbSkRERLER84YSAMyaNQuzZs0Kum79+vUBy0aNGtXv/VtuueUW3HLLLUHXnXLKKfjss88irudQk+dR4qU3IiKimOAZOM7odDp58JnDxUtvA9U7Nxo45qYOc4scM1OHuakTzdyYfJzR6XTy7OP+W5iwR6l/vXOjgWNu6jC3yDEzdZibOtHMjWfgOOPxeNDR0eGbydbNMUoD1Ts3Gjjmpg5zixwzU4e5qRPN3NhQijMulwuNjY2+adZ5U9wB650bDRxzU4e5RY6ZqcPc1IlmbjwDx7EfB3OzR4mIiCgW2FCKU26PF26v75t97FEiIiKKDZ6B45Td/eNsouxRIiIiig02lOKM/z42Ls+P80TxW2/98+cmCEKsqzKsMDd1mFvkmJk6zE2daObG6QHijMFgQGlpKRraewAAok4DjYYfkP74c6PIMDd1mFvkmJk6zE2daObGroo4xTmUiIiIYo9n4Thjt9uxa9cudHb5epQ4h9LA+HOz2+2xrsqwwtzUYW6RY2bqMDd1opkbG0pxSJKkXjfE5Vs0UP3d/4+CY27qMLfIMTN1mJs60cqNZ+E4xTmUiIiIYo8NpTjlcHNWbiIioljjWThO+S+9sUeJiIgodthQijOiKKKsrAyew28Ne5QGxp+bKIqxrsqwwtzUYW6RY2bqMDd1opkb51GKMxqNBgaDAU7P4cHc7FEaEH9uFBnmpg5zixwzU4e5qRPN3NhdEWdcLheamprQ7fDd8djAHqUB8efGO2xHhrmpw9wix8zUYW7qRDM3noXjjMfjgdVqRbfDDYA9SgPlz83j8cS6KsMKc1OHuUWOmanD3NSJZm5sKMUpeXoA9igRERHFDM/CcYrzKBEREcUeG0pxyn+vN97ChIiIKHbYUIozWq0W6enpcHp8U6/zprgD489Nq2XDMhLMTR3mFjlmpg5zUyeauXF6gDij1+uRnZ0Nl7cJAHuUBsqfG0WGuanD3CLHzNRhbupEMzd2V8QZj8eD7u5u9DgPf+uNg7kHxJ8bvxkSGeamDnOLHDNTh7mpE83ceBaOMy6XC7W1tbAfbihxMPfA+HPjXCORYW7qMLfIMTN1mJs60cyNDaU4ZT/8rTf2KBEREcUOz8JxysGb4hIREcUcG0pxysEeJSIiopjjWTgO6XQ62N2cRylSOh2/xKkGc1OHuUWOmanD3NSJVm5x0VB69tlnUVpaCqPRiKqqKmzevDnktueccw4EQQj4ufTSS+VtbrzxxoD1F110kaKcgwcP4vrrr0dycjJSU1Nx8803w2azDdprHCij0YjKykrOoxQhf25GozHWVRlWmJs6zC1yzEwd5qZONHOL+Vl41apVmDNnDhYuXIitW7dizJgxmDx5MlpbW4Nuv3r1ajQ1Nck/27dvh1arxVVXXaXY7qKLLlJs9/e//12x/vrrr8e3336LtWvX4p133sHHH3+MW265ZdBeZ6T8Y5TYo0RERBQ7MW8oLVq0CDNmzMBNN92E448/HkuWLIHZbMayZcuCbp+eno7c3Fz5Z+3atTCbzQENJYPBoNguLS1NXvfdd99hzZo1+Mtf/oKqqiqceeaZePrpp7Fy5Uo0NjYO6uvtj91ux+7du9Hj4jxKkfDnZrfbY12VYYW5qcPcIsfM1GFu6kQzt5he+HQ6ndiyZQvmzZsnL9NoNJg0aRI2btw4oDKWLl2Ka665BgkJCYrl69evR3Z2NtLS0nDeeefhd7/7HTIyMgAAGzduRGpqKsaPHy9vP2nSJGg0GmzatAmXX355wPM4HA44HA75946ODgC+N0MURUX9RVGE1+uF0+kMKMffDehwOCBJkmKdXq+Xc/EP5obHDbvdLpcrSZKiHn4GgwGCIMDpdMLr9SrW6XQ66HQ6eDyegDklBEGAwWCQX0tfoihCo9HA5XIFTNyl1Wqh1+uDltv7tQYrV6/XQ6vVhi03kgwdDgfsdrtcltvthtvtVjwu1hkGKzdchtF4b/rL0Ol0wm63K/LwvzeDlWE8vjeRZuhwOOTXEOqzHGr/PtJjxGC+N4N5jPB/RnvXbSiPEX3LjccMg5Xrr6fX6w147FAcI2KRYTTK7b2/9X1vIm08xbShZLFY4PF4kJOTo1iek5ODnTt39vv4zZs3Y/v27Vi6dKli+UUXXYQrrrgCZWVl2LNnD+677z5cfPHF2LhxI7RaLZqbmwOmNtfpdEhPT0dzc3PQ56qursZDDz0UsLy2thaJiYny78nJycjPz4fb7cb+/fsDth89ejQAoLm5GT09PYp1eXl5MBgMvjf38KW31qYGuK06JCQkoKioCF6vN2i5lZWV0Ol0aG1tDRhrlZ2djfT0dHR1dQX0mBmNRpSWlgIAampqAj4QZWVlMBgMsFgssFqtinXp6enIzs6Gw+FAbW2tYp1Op0NlZSUAoL6+PmCnLy4uhtlsxqFDh3Dw4EHFupSUFOTl5cHlcgW8VkEQMGrUKABAU1OTvMO73W60t7ejp6cHCQkJ6OjoCLh8m5iYiMLCQng8nqAZjhgxAlqtFi0tLejq6lKsy8nJQVpaGmw2G5qamhTrTCYTSkpKACBoueXl5RBFERaLRW5g+2VmZiIzMxM9PT2or69XrNPr9aioqAAA1NXVBRzoSkpKYDKZgmaYmpqK3NxcOJ3OgDppNBqMHDkSgG8/bG9vB/DjwMeCggIkJSXBarWira1N8dikpCQUFBSE3L9HjhwJQRDQ3NyM7u5uxbrc3FykpqbCZrMFfM7MZjOKi4shSVLQcisqKqDX69HW1obOzk7FuqysLGRkZKC7uxsNDQ2KdaIoory8HIDvs9r3wOwfG3ngwAE5B7/e+3dNTY1inSRJEAQBgG//7ntiLCwsRGJiIqxWKywWi2LdkR4jUlJS0NnZiZaWFsW6eD9G1NXVKfa1oT5G+OXn5yM5OXnYHCOSk5MBAD09PQGfx6E4RjQ0NAQ0pIbDMcJ/TgB8n5vex4hIxyMLUt+9fgg1NjaioKAAn376KSZOnCgvv+eee7BhwwZs2rQp7ONvvfVWbNy4Edu2bQu73d69e1FRUYEPPvgA559/Ph577DG8/PLL2LVrl2K77OxsPPTQQ7j99tsDygjWo1RUVISWlhZ5RwaO/K9Fl8uFXT/swc+X7wcAbL73bCSb9DH/S2c49CjV1dWhrKwMCQkJw+avxVj3KHV0dKC2thZFRUXycw2HvxaDlTvUPUpNTU0oLS2FIAjsURrAMcJms6Gurk6xr7FHyae/HqX6+noUFxdDo1EOxWCPUuhy/eeEoqIiJCQkKN6bjo4O5OTkwGq1Ks7focS0RykzM1NunffW0tKC3NzcsI/t6urCypUr8fDDD/f7POXl5cjMzMTu3btx/vnnIzc3N+AvCbfbjYMHD4Z8XoPBIO+QvRmNxqCj6jUaTdjR9sHKAnzTrrt77ZMpSWbFpJOCIIQtt/dlwL60Wm3YOymHK1ev18uXBoeq3Egz1Ol0cj38H7hgYpVhLN6b/jIURRE6nQ4GgyFgu8HKMB7fm2juh0NR7nDLUKvVwmAwhNzXYvHexGOGwcr1N4D6e61HU4bRKte/v/nL8r83wRqG4cR0pLAoihg3bhzWrVsnL/N6vVi3bp2ihymYV199FQ6HAzfccEO/z1NfX48DBw4gLy8PADBx4kS0t7djy5Yt8jYffvghvF4vqqqqVL6a6NDr9cjMzQcACAIgajmYeyD0ej2Ki4tDHgwoOOamDnOLHDNTh7mpE83cYn4WnjNnDl544QW8/PLL+O6773D77bejq6sLN910EwBg2rRpisHefkuXLsVll10mD9D2s9ls+O1vf4vPPvsM+/fvx7p16/Dzn/8clZWVmDx5MgDguOOOw0UXXYQZM2Zg8+bN+M9//oNZs2bhmmuuQX5+/uC/6DC0Wi00Ol8L3qDTyOMgKDytVguz2Rz2LzkKxNzUYW6RY2bqMDd1oplbzKf7vPrqq9HW1oYHHngAzc3NGDt2LNasWSMP8K6trQ24Lrtr1y588skneP/99wPK02q12LZtG15++WW0t7cjPz8fF154IR555BFFF+Ly5csxa9YsnH/++dBoNJg6dSqeeuqpwX2xA+ByudDY4hscxzmUBs7lcuHQoUNIS0vjX14RYG7qMLfIMTN1mJs60cwt5g0lAJg1axZmzZoVdN369esDlo0aNSpgcJmfyWTCv/71r36fMz09HStWrIionkPB4/Gg9WA7AM7KHQmPx4ODBw8iOTmZB5MIMDd1mFvkmJk6zE2daObGM3Ecch2+fQl7lIiIiGKLDaU45J9s0qhjQ4mIiCiW2FCKQ/INcXn7EiIiopjimTjOaLVa6AwmAOxRioRWq0VKSgq/GRIh5qYOc4scM1OHuakTzdziYjA3/Uiv18OU6JsplD1KA6fX6+V5smjgmJs6zC1yzEwd5qZONHPjmTjOeL1edPX4Zg01sEdpwPxT1vedEp/CY27qMLfIMTN1mJs60cyNDaU443Q60dDiu72KkT1KA+Z0OrFv376Ip6Y/1jE3dZhb5JiZOsxNnWjmxjNxHJIHc7NHiYiIKKbYUIpDTnkeJb49REREscQzcRxyujnhJBERUTxgQykOOb3+S298eyLBGwirw9zUYW6RY2bqMDd1opUbpweIM0ajEabEFABW9ihFwGg0YtSoUbGuxrDD3NRhbpFjZuowN3WimRu7LOKQw+UBwB4lIiKiWOOZOM44HA4ctHYC4BilSDgcDuzfvx8OhyPWVRlWmJs6zC1yzEwd5qZONHNjQynOSJKEHqcbAL/1FglJkmC32yFJUqyrMqwwN3WYW+SYmTrMTZ1o5sYzcRxycB4lIiKiuMCGUhziPEpERETxgWfiOOT0+O5NY+AYJSIiophiQynO6PV6SIJv1gZ+623g9Ho98vPzodfrY12VYYW5qcPcIsfM1GFu6kQzN86jFGe0Wq084SS/9TZwWq0WycnJsa7GsMPc1GFukWNm6jA3daKZG7ss4ozb7UaPw/etN/YoDZzb7cbBgwfhdrtjXZVhhbmpw9wix8zUYW7qRDM3nonjjNvthv3whJPsURo4t9uN1tZWHkwixNzUYW6RY2bqMDd1opkbG0pxyMGb4hIREcUFNpTijNcrwcWb4hIREcUFnonjjH9qAIA9SkRERLHGhlKccXp+/L+RPUoDptFokJiYCI2GmUWCuanD3CLHzNRhbupEMzdODxBnJI2vF0mrEaDT8oMxUKIoorCwMNbVGHaYmzrMLXLMTB3mpk40c+OZOM7IN8Rlb1JEJEmC2+3mjSMjxNzUYW6RY2bqMDd1opkbz8ZxpqPLDgAQ2VCKiMPhwO7du+FwOGJdlWGFuanD3CLHzNRhbupEMzeejeOMw+0bzM0eJSIiotiLi7Pxs88+i9LSUhiNRlRVVWHz5s0htz3nnHMgCELAz6WXXgoAcLlcuPfee3HiiSciISEB+fn5mDZtGhobGxXllJaWBpTx+OOPD+rrHAiH2zeamzfEJSIiir2YN5RWrVqFOXPmYOHChdi6dSvGjBmDyZMno7W1Nej2q1evRlNTk/yzfft2aLVaXHXVVQCA7u5ubN26FQsWLMDWrVuxevVq7Nq1Cz/72c8Cynr44YcVZd1xxx2D+loHwt+jxDmUiIiIYi/m33pbtGgRZsyYgZtuugkAsGTJErz77rtYtmwZ5s6dG7B9enq64veVK1fCbDbLDaWUlBSsXbtWsc0zzzyDCRMmoLa2FsXFxfLypKQk5ObmRvslHRGHi5feiIiI4kVMz8ZOpxNbtmzBpEmT5GUajQaTJk3Cxo0bB1TG0qVLcc011yAhISHkNlarFYIgIDU1VbH88ccfR0ZGBk4++WQ88cQTcXEvHY/ge0uMYszbsMOKwWDAiBEjYDAYYl2VYYW5qcPcIsfM1GFu6kQzt5iejS0WCzweD3JychTLc3JysHPnzn4fv3nzZmzfvh1Lly4NuY3dbse9996La6+9FsnJyfLyO++8E6eccgrS09Px6aefYt68eWhqasKiRYuCluNwOBSj5zs6OuTyRVGUl2s0GoiiCK/XC6fTGVCO0WiUy+v7tUW9Xi/f503UCrDb7QHlSpIUdBS/wWCAIAhwOp3wer2KdTqdDjqdDh6PBy6XS7FOEAR5R+r9fH6iKEKj0cDlcsHj8SjWabVa6PX6oOX2fq3BytXr9dBqtWHLVZuhVquF2+0OaPjGOsNg5YbLMBrvTX8ZOp3OIc8wHt+bwdoPg5V7pMeIeN2/eYw4Oo8RschwsN+bYFmFM6y7LZYuXYoTTzwREyZMCLre5XLhF7/4BSRJwvPPP69YN2fOHPn/J510EkRRxK233orq6uqgLdDq6mo89NBDActra2uRmJgo/56cnIz8/Hy43W7s378/YPvRo0cDAJqbm9HT06NYl5eXhy67bwdwO3oUj09ISEBRURG8Xm/QcisrK6HT6dDa2gqbzaZYl52djfT0dHR1dQUMajcajSgtLQUA1NTUBHwgysrKYDAYYLFYYLVaFevS09ORnZ0Nh8OB2tpaxTqdTofKykoAQH19fcBOX1xcDLPZjEOHDuHgwYOKdSkpKcjLy4PL5Qp4rYIgYNSoUQCApqYmeYf3eDyw2WyorKxERkYGOjo6Asa5JSYmorCwEB6PJ2iGI0aMgFarRUtLC7q6uhTrcnJykJaWBpvNhqamJsU6k8mEkpISAAhabnl5OURRhMVikRvYfpmZmcjMzERPTw/q6+sV6/R6PSoqKgAAdXV1AQe6kpISmEymoBmmpqYiNzcXTqczoE4ajQYjR44E4Nt/Dx48iMTERGi1vi8QFBQUICkpCVarFW1tbYrHJiUloaCgIOT+PXLkSAiCgObmZnR3dyvW5ebmIjU1FTabDc3NzYp1ZrMZxcXFkCQpaLkVFRXQ6/Voa2tDZ2enYl1WVhYyMjLQ3d2NhoYGxTpRFFFeXi6/1r4HUP+XSA4cOID29nbFut77d01NTUCdEhISkJOTg/r6+oATWGFhIRITE2G1WmGxWBTrjvQYkZKSgs7OTrS0tATUJ56PEfv27YPNZpP3taE+Rvjl5+cjOTl52BwjUlJS4Ha7kZiYGPCeD8UxoqGhIaAhNRyOEf5zQmJiInJzcxXHiL77f38EKYazWDmdTpjNZrz22mu47LLL5OXTp09He3s73nzzzZCP7erqQn5+Ph5++GHcddddAev9jaS9e/fiww8/REZGRti6fPvttzjhhBOwc+dO+UPWW7AepaKiIrS0tCh6qo70r8UXPt6Dx//1Ay4+PgtP/uKkgHL512LwDB0OB+rq6lBWVoaEhAT+tTjADDs6OlBbW4uioiL5uYb7X4u9DVaGDocDTU1N8rdn2aPU/zHCZrOhrq5Osa+xR8kn3DHC7Xajvr4excXFAbfjYI9S6HL954SioiIkJCQo3puOjg7k5OTAarUqzt+hxLRHSRRFjBs3DuvWrZMbSl6vF+vWrcOsWbPCPvbVV1+Fw+HADTfcELDO30j64Ycf8NFHH/XbSAKAr776ChqNBtnZ2UHXGwyGoD1NRqNR3qF602g0QZf3Li8Y/7fezAZd0McLghC23N6XAfvSarVyr0Ew4crV6/XQ6/VDWm6kGep0Orke/g9cMLHKMBbvTX8ZiqIInU4Hg8EQsN1gZRiP700098OhKHe4ZajVamEwGELua7F4b+Ixw2Dl+htA/b3WoynDaJXr39/8Zfnfm2ANw3Bifultzpw5mD59OsaPH48JEyZg8eLF6Orqkr8FN23aNBQUFKC6ulrxuKVLl+Kyyy4LaAS5XC5ceeWV2Lp1K9555x14PB65Cy89PR2iKGLjxo3YtGkTzj33XCQlJWHjxo2YPXs2brjhBqSlpQ3NCw/B4To8j5KO8ygRERHFWswbSldffTXa2trwwAMPoLm5GWPHjsWaNWvkAd61tbUB3Y27du3CJ598gvfffz+gvIaGBrz11lsAgLFjxyrWffTRRzjnnHNgMBiwcuVKPPjgg3A4HCgrK8Ps2bMV45ZihfMoERERxY+YjlEazjo6OpCSkjLga5wDteCNb/C3z2ox85xy/Pai46JW7tHO7Xajs7MTSUlJIbtsKRBzU4e5RY6ZqcPc1AmXW6Tnb6YeZ5yHpwcwcR6liOh0uphfNh2OmJs6zC1yzEwd5qZONHPj9Z04Y3f5RvqLWiHGNRlePB4PrFZrwDc7KDzmpg5zixwzU4e5qRPN3NhQijPdTl9DSc93JiIulwtNTU1Bpymg0JibOswtcsxMHeamTjRz4+k4zjgPD+YWOZibiIgo5ng2jjMaQYBew5viEhERxQOOGI4zz183Bvv370dpaW6sq0JERHTMY7dFnBEEASaTCYLAwdyRYG7qMDd1mFvkmJk6zE2daObGeZRUGqx5lIiIiGjwRHr+Zo8SERERUQhsKMUZu92OnTt3Br0TNIXG3NRhbuowt8gxM3WYmzrRzI0NJSIiIqIQ2FAiIiIiCoENJSIiIqIQ2FAiIiIiCoHTA6g0WNMDeL1euN1u6HQ6aDRsxw4Uc1OHuanD3CLHzNRhbuqEyy3S8zdn5o4zGo0GoijGuhrDDnNTh7mpw9wix8zUYW7qRDM3Nk/jjNPpRGNjI5xOZ6yrMqwwN3WYmzrMLXLMTB3mpk40c2NDKc54vV50dHTA6/XGuirDCnNTh7mpw9wix8zUYW7qRDM3NpSIiIiIQmBDiYiIiCgEDuZWyf9lwY6OjqiWa7fbYbPZ0NHRwWvSEWBu6jA3dZhb5JiZOsxNnXC5+c/bA/3SPxtKKnV2dgIAioqKYlwTIiIiilRnZydSUlL63Y7zKKnk9XrR2NiIpKQkCIIQtXI7OjpQVFSEurq6qM7PdLRjbuowN3WYW+SYmTrMTZ1wuUmShM7OTuTn5w9obir2KKmk0WhQWFg4aOUnJyfzQ6ECc1OHuanD3CLHzNRhbuqEym0gPUl+HMxNREREFAIbSkREREQhsKEUZwwGAxYuXAiDwRDrqgwrzE0d5qYOc4scM1OHuakTzdw4mJuIiIgoBPYoEREREYXAhhIRERFRCGwoEREREYXAhhIRERFRCGwoxZlnn30WpaWlMBqNqKqqwubNm2Ndpbjy8ccfY8qUKcjPz4cgCHjjjTcU6yVJwgMPPIC8vDyYTCZMmjQJP/zwQ2wqGyeqq6tx6qmnIikpCdnZ2bjsssuwa9cuxTZ2ux0zZ85ERkYGEhMTMXXqVLS0tMSoxvHh+eefx0knnSRPWDdx4kS899578npm1r/HH38cgiDg7rvvlpcxt0APPvggBEFQ/IwePVpez8xCa2howA033ICMjAyYTCaceOKJ+OKLL+T10TgnsKEUR1atWoU5c+Zg4cKF2Lp1K8aMGYPJkyejtbU11lWLG11dXRgzZgyeffbZoOv/8Ic/4KmnnsKSJUuwadMmJCQkYPLkybDb7UNc0/ixYcMGzJw5E5999hnWrl0Ll8uFCy+8EF1dXfI2s2fPxttvv41XX30VGzZsQGNjI6644ooY1jr2CgsL8fjjj2PLli344osvcN555+HnP/85vv32WwDMrD+ff/45/ud//gcnnXSSYjlzC+4nP/kJmpqa5J9PPvlEXsfMgjt06BDOOOMM6PV6vPfee9ixYwf+9Kc/IS0tTd4mKucEieLGhAkTpJkzZ8q/ezweKT8/X6quro5hreIXAOn111+Xf/d6vVJubq70xBNPyMva29slg8Eg/f3vf49BDeNTa2urBEDasGGDJEm+jPR6vfTqq6/K23z33XcSAGnjxo2xqmZcSktLk/7yl78ws350dnZKI0aMkNauXSv99Kc/le666y5JkrivhbJw4UJpzJgxQdcxs9Duvfde6cwzzwy5PlrnBPYoxQmn04ktW7Zg0qRJ8jKNRoNJkyZh48aNMazZ8LFv3z40NzcrMkxJSUFVVRUz7MVqtQIA0tPTAQBbtmyBy+VS5DZ69GgUFxczt8M8Hg9WrlyJrq4uTJw4kZn1Y+bMmbj00ksV+QDc18L54YcfkJ+fj/Lyclx//fWora0FwMzCeeuttzB+/HhcddVVyM7Oxsknn4wXXnhBXh+tcwIbSnHCYrHA4/EgJydHsTwnJwfNzc0xqtXw4s+JGYbm9Xpx991344wzzsAJJ5wAwJebKIpITU1VbMvcgG+++QaJiYkwGAy47bbb8Prrr+P4449nZmGsXLkSW7duRXV1dcA65hZcVVUVXnrpJaxZswbPP/889u3bh7POOgudnZ3MLIy9e/fi+eefx4gRI/Cvf/0Lt99+O+688068/PLLAKJ3TtBFr8pEFO9mzpyJ7du3K8Y/UGijRo3CV199BavVitdeew3Tp0/Hhg0bYl2tuFVXV4e77roLa9euhdFojHV1ho2LL75Y/v9JJ52EqqoqlJSU4P/+7/9gMpliWLP45vV6MX78eDz22GMAgJNPPhnbt2/HkiVLMH369Kg9D3uU4kRmZia0Wm3ANxlaWlqQm5sbo1oNL/6cmGFws2bNwjvvvIOPPvoIhYWF8vLc3Fw4nU60t7crtmdugCiKqKysxLhx41BdXY0xY8bgz3/+MzMLYcuWLWhtbcUpp5wCnU4HnU6HDRs24KmnnoJOp0NOTg5zG4DU1FSMHDkSu3fv5r4WRl5eHo4//njFsuOOO06+bBmtcwIbSnFCFEWMGzcO69atk5d5vV6sW7cOEydOjGHNho+ysjLk5uYqMuzo6MCmTZuO6QwlScKsWbPw+uuv48MPP0RZWZli/bhx46DX6xW57dq1C7W1tcd0bsF4vV44HA5mFsL555+Pb775Bl999ZX8M378eFx//fXy/5lb/2w2G/bs2YO8vDzua2GcccYZAVOdfP/99ygpKQEQxXPCkYw4p+hauXKlZDAYpJdeeknasWOHdMstt0ipqalSc3NzrKsWNzo7O6Uvv/xS+vLLLyUA0qJFi6Qvv/xSqqmpkSRJkh5//HEpNTVVevPNN6Vt27ZJP//5z6WysjKpp6cnxjWPndtvv11KSUmR1q9fLzU1Nck/3d3d8ja33XabVFxcLH344YfSF198IU2cOFGaOHFiDGsde3PnzpU2bNgg7du3T9q2bZs0d+5cSRAE6f3335ckiZkNVO9vvUkScwvm//2//yetX79e2rdvn/Sf//xHmjRpkpSZmSm1trZKksTMQtm8ebOk0+mkRx99VPrhhx+k5cuXS2azWXrllVfkbaJxTmBDKc48/fTTUnFxsSSKojRhwgTps88+i3WV4spHH30kAQj4mT59uiRJvq+DLliwQMrJyZEMBoN0/vnnS7t27YptpWMsWF4ApBdffFHepqenR/rv//5vKS0tTTKbzdLll18uNTU1xa7SceBXv/qVVFJSIomiKGVlZUnnn3++3EiSJGY2UH0bSswt0NVXXy3l5eVJoihKBQUF0tVXXy3t3r1bXs/MQnv77belE044QTIYDNLo0aOl//3f/1Wsj8Y5QZAkSVLd70VERER0FOMYJSIiIqIQ2FAiIiIiCoENJSIiIqIQ2FAiIiIiCoENJSIiIqIQ2FAiIiIiCoENJSIiIqIQ2FAiIooSQRDwxhtvxLoaRBRFbCgR0VHhxhtvhCAIAT8XXXRRrKtGRMOYLtYVICKKlosuuggvvviiYpnBYIhRbYjoaMAeJSI6ahgMBuTm5ip+0tLSAPguiz3//PO4+OKLYTKZUF5ejtdee03x+G+++QbnnXceTCYTMjIycMstt8Bmsym2WbZsGX7yk5/AYDAgLy8Ps2bNUqy3WCy4/PLLYTabMWLECLz11luD+6KJaFCxoUREx4wFCxZg6tSp+Prrr3H99dfjmmuuwXfffQcA6OrqwuTJk5GWlobPP/8cr776Kj744ANFQ+j555/HzJkzccstt+Cbb77BW2+9hcrKSsVzPPTQQ/jFL36Bbdu24ZJLLsH111+PgwcPDunrJKIoit49fImIYmf69OmSVquVEhISFD+PPvqoJEmSBEC67bbbFI+pqqqSbr/9dkmSJOl///d/pbS0NMlms8nr3333XUmj0UjNzc2SJElSfn6+dP/994esAwBp/vz58u82m00CIL333ntRe51ENLQ4RomI/n/7ds+aOhiGcfxK0UGDDiKKW7eQDrroILqUTm6C3Yq4ihBc3PUT2LFTx6Lg4KpDx4A41Un9AiJ1LIW66BkOCFJyOJTTyLH/3/S8hHA/28WTO2fj+vpaDw8PR2uxWOwwzufzR3v5fF4vLy+SpPl8rkwmI9M0D/uFQkG73U7L5VKGYWi1Wunm5uaPNaTT6cPYNE1Fo1G9vr5+9UgAToygBOBsmKb56VPYvxIKhf7quWAweDQ3DEO73e47SgLgA3qUAPwYk8nk09y2bUmSbduazWZ6f38/7Luuq4uLC1mWpUgkosvLSz0/P/taM4DT4kYJwNnYbrdar9dHa4FAQPF4XJI0GAyUzWZVLBb19PSk6XSqx8dHSdLd3Z3a7bZqtZo6nY42m40cx1G1WlUymZQkdTod1et1JRIJlUolvb29yXVdOY7j70EB+IagBOBsjEYjpVKpozXLsrRYLCT9/iOt3++r0WgolUqp1+vp6upKkhQOhzUej9VsNpXL5RQOh1WpVNTtdg/vqtVq+vj40P39vVqtluLxuG5vb/07IADfGfv9fn/qIgDguxmGoeFwqHK5fOpSAPxH6FECAADwQFACAADwQI8SgB+BLgMAX8GNEgAAgAeCEgAAgAeCEgAAgAeCEgAAgAeCEgAAgAeCEgAAgAeCEgAAgAeCEgAAgAeCEgAAgIdf7D6MPCRt9Y8AAAAASUVORK5CYII="},"metadata":{}}]},{"cell_type":"markdown","source":"# Test the model","metadata":{}},{"cell_type":"markdown","source":"1. test dataset is created from a `data_test` array using `tf.data.Dataset.from_tensor_slices`. This returns a `tf.data.Dataset` object that can be efficiently processed in parallel during training and evaluation.\n\n2. `transform_element` function is applied to each element in the dataset using map. This function is used to transform the raw input data into a format that can be processed by the model.\n\n3. the dataset is shuffled and batched using shuffle and batch methods. The `SHUFFLE_BUFFER_SIZE` and `BATCH_SIZE` variables are used to set the size of the shuffle buffer and the batch size, respectively. The `drop_remainder` argument is set to True to drop any remaining data that does not make up a complete batch, so that the number of batches is equal to the number of observations divided by the batch size.\n\n4. `model.evaluate` method is called to evaluate the model on the test dataset. This method returns a dictionary with the evaluation metrics specified during the compile method of the model, such as accuracy, loss, and any other metrics defined. The evaluate method returns the average metrics over all batches in the test dataset.","metadata":{}},{"cell_type":"code","source":"# prompt: test data using data_test\n\ntest_data = tf.data.Dataset.from_tensor_slices(data_test)\n\n# Apply the transformation function to each element in the dataset\ntest_data = test_data.map(transform_element)\n\n# Shuffle and batch the dataset\ntest_data = test_data.shuffle(SHUFFLE_BUFFER_SIZE).batch(BATCH_SIZE, drop_remainder=True)\n\nmodel.evaluate(test_data)","metadata":{"execution":{"iopub.status.busy":"2024-04-27T19:27:27.214510Z","iopub.execute_input":"2024-04-27T19:27:27.214881Z","iopub.status.idle":"2024-04-27T19:29:35.021772Z","shell.execute_reply.started":"2024-04-27T19:27:27.214847Z","shell.execute_reply":"2024-04-27T19:29:35.020809Z"},"trusted":true},"execution_count":74,"outputs":[{"name":"stdout","text":"298/298 [==============================] - 38s 126ms/step - loss: 0.2457 - accuracy: 0.9201\n","output_type":"stream"},{"execution_count":74,"output_type":"execute_result","data":{"text/plain":"[0.24566957354545593, 0.920109212398529]"},"metadata":{}}]},{"cell_type":"markdown","source":"## Generating text","metadata":{"id":"nQYiKiKfn5C9"}},{"cell_type":"markdown","source":"### Restore the latest checkpoint","metadata":{"id":"Mau8c_NMn6vO"}},{"cell_type":"markdown","source":" The `tf.train.latest_checkpoint(checkpoint_dir)` function in TensorFlow is used to find the latest checkpoint file in a given directory. A checkpoint file contains the saved state of a TensorFlow model, including the values of its trainable variables.\n1. It takes a single argument, `checkpoint_dir`, which is the path to the directory where the checkpoint files are stored.\n2. Inside the directory, it looks for files with the `.index` extension. These files contain the metadata about the checkpoint, such as the version number and the names of the variables that are saved.\n3. It selects the checkpoint file with the highest version number. This is the most recent checkpoint that has been saved.\n4. The function returns the path to the latest checkpoint file.","metadata":{"id":"2oYdB5WDo_Yv"}},{"cell_type":"code","source":"tf.train.latest_checkpoint(checkpoint_dir)","metadata":{"id":"VFtTGIUwn_wY","outputId":"83e4de7c-420f-481a-98fa-589db87f3e4a","execution":{"iopub.status.busy":"2024-04-27T19:29:35.023043Z","iopub.execute_input":"2024-04-27T19:29:35.023400Z","iopub.status.idle":"2024-04-27T19:29:35.030770Z","shell.execute_reply.started":"2024-04-27T19:29:35.023374Z","shell.execute_reply":"2024-04-27T19:29:35.029801Z"},"trusted":true},"execution_count":75,"outputs":[{"execution_count":75,"output_type":"execute_result","data":{"text/plain":"'tmp/checkpoints/ckpt_60'"},"metadata":{}}]},{"cell_type":"markdown","source":"#### Creating simplified version of the model","metadata":{"id":"3g6c9hFp0ltH"}},{"cell_type":"markdown","source":"This code sets the `simplified_batch_size` to 1","metadata":{"id":"JuSc81J018ge"}},{"cell_type":"code","source":"simplified_batch_size = 1","metadata":{"id":"NDnlcAYe0OHJ","execution":{"iopub.status.busy":"2024-04-27T19:29:35.031996Z","iopub.execute_input":"2024-04-27T19:29:35.032281Z","iopub.status.idle":"2024-04-27T19:29:35.040731Z","shell.execute_reply.started":"2024-04-27T19:29:35.032257Z","shell.execute_reply":"2024-04-27T19:29:35.039809Z"},"trusted":true},"execution_count":76,"outputs":[]},{"cell_type":"markdown","source":"This code builds a simplified version of the model with the specified hyperparameters. It then loads the weights from the latest checkpoint in the \"tmp/checkpoints\" directory and builds the model with a batch size of 1.\n1. It defines a function called `build_model` that takes several arguments, including the vocabulary size, embedding dimension, RNN units, and batch size. This function is used to build the model architecture.\n2. It sets the `simplified_batch_size` to 1. This means that the simplified model will only process one sample at a time.\n3. It calls the `build_model` function to build the simplified model with the specified hyperparameters and a batch size of 1.\n4. It loads the weights from the latest checkpoint in the \"tmp/checkpoints\" directory into the simplified model. This allows the simplified model to start training from the point where the original model left off.\n5. It builds the simplified model with a batch size of 1. This is necessary because the model was built with a batch size of 1, and it cannot be changed after the model has been built.\n","metadata":{"id":"_atBzxJs10yO"}},{"cell_type":"code","source":"model_simplified = build_model(vocab_size=VOCABULARY_SIZE,\n embedding_dim=256,\n rnn_units=1024,\n batch_size=simplified_batch_size)\nmodel_simplified.load_weights(tf.train.latest_checkpoint(\"tmp/checkpoints\"))\nmodel_simplified.build(tf.TensorShape([simplified_batch_size, None]))","metadata":{"id":"F0vDHYTi01DM","execution":{"iopub.status.busy":"2024-04-27T19:29:35.041873Z","iopub.execute_input":"2024-04-27T19:29:35.042158Z","iopub.status.idle":"2024-04-27T19:29:35.363013Z","shell.execute_reply.started":"2024-04-27T19:29:35.042135Z","shell.execute_reply":"2024-04-27T19:29:35.361973Z"},"trusted":true},"execution_count":77,"outputs":[]},{"cell_type":"markdown","source":"This code prints a summary of the simplified model's architecture. This provides information about the model's layers, their shapes, and the number of trainable parameters.","metadata":{"id":"jDyaQp_02P3t"}},{"cell_type":"code","source":"model_simplified.summary()","metadata":{"id":"8IsCMv4l1KHW","outputId":"faa61f2d-7449-4f0b-fe5d-6ffdf41ede9b","execution":{"iopub.status.busy":"2024-04-27T19:29:35.364257Z","iopub.execute_input":"2024-04-27T19:29:35.364536Z","iopub.status.idle":"2024-04-27T19:29:35.382644Z","shell.execute_reply.started":"2024-04-27T19:29:35.364512Z","shell.execute_reply":"2024-04-27T19:29:35.381771Z"},"trusted":true},"execution_count":78,"outputs":[{"name":"stdout","text":"Model: \"sequential_1\"\n_________________________________________________________________\n Layer (type) Output Shape Param # \n=================================================================\n embedding_1 (Embedding) (1, None, 256) 25856 \n \n lstm_1 (LSTM) (1, None, 1024) 5246976 \n \n dense_1 (Dense) (1, None, 101) 103525 \n \n=================================================================\nTotal params: 5376357 (20.51 MB)\nTrainable params: 5376357 (20.51 MB)\nNon-trainable params: 0 (0.00 Byte)\n_________________________________________________________________\n","output_type":"stream"}]},{"cell_type":"markdown","source":"This specifies the number of features or variables and the order in which they should be provided to the model for processing.","metadata":{"id":"3BG9npNr3dfl"}},{"cell_type":"code","source":"model_simplified.input_shape","metadata":{"id":"Ub4KLTr52b5x","outputId":"e2ca1a05-5732-4a4c-c946-032b50ca8bb6","execution":{"iopub.status.busy":"2024-04-27T19:29:35.383763Z","iopub.execute_input":"2024-04-27T19:29:35.384051Z","iopub.status.idle":"2024-04-27T19:29:35.390022Z","shell.execute_reply.started":"2024-04-27T19:29:35.384026Z","shell.execute_reply":"2024-04-27T19:29:35.388955Z"},"trusted":true},"execution_count":79,"outputs":[{"execution_count":79,"output_type":"execute_result","data":{"text/plain":"(1, None)"},"metadata":{}}]},{"cell_type":"markdown","source":"This code defines a function generate_text that generates text using a trained machine learning model.\n\n**padded_start_string = STOP_WORD_TITLE + start_string**: This line creates a padded start string by concatenating the STOP_WORD_TITLE constant with the start_string argument. The STOP_WORD_TITLE constant is used to separate the generated text from the input text.\n\n**input_indices = np.array(tokenizer.texts_to_sequences([padded_start_string])):** This line converts the padded start string to a sequence of integers using the tokenizer object. The tokenizer object is a Keras utility that converts text into a sequence of integers that can be used as input to a machine learning model.\n\n**text_generated = []:** This line initializes an empty list to store the generated text.\n\n**model.reset_states():** This line resets the internal state of the machine learning model. This is necessary because the model is a recurrent neural network, which maintains an internal state between predictions.\n\n**for char_index in range(num_generate)::** This loop generates num_generate characters of text.\n\n**predictions = model(input_indices):** This line feeds the input sequence to the machine learning model and generates predictions.\n\n**predictions = tf.squeeze(predictions, 0)**: This line removes the batch dimension from the predictions. The batch dimension is not needed because we are generating only one character at a time.\n\n**predicted_id = tf.random.categorical(predictions, num_samples=1)[-1,0].numpy():** This line generates a random sample from the predicted distribution. The tf.random.categorical function generates a categorical distribution from the predictions, and the [-1,0] indexing operation extracts the predicted probability of the next character.\n\n**input_indices = tf.expand_dims([predicted_id], 0):** This line converts the predicted character index into a sequence of length 1. This is necessary because the machine learning model expects input sequences of a fixed length.\n\n**next_character = tokenizer.sequences_to_texts(input_indices.numpy())[0]:** This line converts the predicted character index back into a character using the tokenizer object.\n\n**text_generated.append(next_character):** This line appends the generated character to the text_generated list.\n\n**return (padded_start_string + ''.join(text_generated)):** This line returns the generated text as a string. The padded_start_string constant is prepended to the generated text to separate it from the input text.","metadata":{"id":"bsZrvj3Pk-sf"}},{"cell_type":"code","source":"def generate_text(model, start_string, num_generate = 1000):\n # Evaluation step (generating text using the learned model)\n\n padded_start_string = STOP_WORD_TITLE + start_string\n\n # Converting our start string to numbers (vectorizing).\n input_indices = np.array(tokenizer.texts_to_sequences([padded_start_string]))\n\n # Empty string to store our results.\n text_generated = []\n\n # Here batch size == 1.\n model.reset_states()\n for char_index in range(num_generate):\n predictions = model(input_indices)\n # remove the batch dimension\n predictions = tf.squeeze(predictions, 0)\n\n # Using a categorical distribution to predict the character returned by the model.\n predicted_id = tf.random.categorical(\n predictions,\n num_samples=1\n )[-1,0].numpy()\n\n # We pass the predicted character as the next input to the model\n # along with the previous hidden state.\n input_indices = tf.expand_dims([predicted_id], 0)\n\n next_character = tokenizer.sequences_to_texts(input_indices.numpy())[0]\n\n text_generated.append(next_character)\n\n return (padded_start_string + ''.join(text_generated))","metadata":{"id":"u5YfR0N84kLi","execution":{"iopub.status.busy":"2024-04-27T19:29:35.391191Z","iopub.execute_input":"2024-04-27T19:29:35.391491Z","iopub.status.idle":"2024-04-27T19:29:35.399965Z","shell.execute_reply.started":"2024-04-27T19:29:35.391467Z","shell.execute_reply":"2024-04-27T19:29:35.399053Z"},"trusted":true},"execution_count":80,"outputs":[]},{"cell_type":"markdown","source":"This code defines a function generate_combinations that generates text using different combinations of input strings and temperature values. Here's a breakdown of what it does:\n\n**recipe_length = 751**: This line sets the length of the generated text to 1000 characters.\n\n**ingredients = input(\"Enter your ingredients (One or two ingredients): \")**: This line prompts the user to enter one or two ingredients using the input function and assigns the user's input to the variable ingredients.\n\n\n\n**generated_text = generate_text(model, start_string=letter, num_generate = recipe_length, temperature=temperature)**: This line generates text using the generate_text function. The model argument is the trained machine learning model, start_string is the ingredients string, and num_generate is the length of the generated text.\n\n**print(f'Attempt: \"{letter}\")**: This line prints a message indicating the current input string .\n\n**print('-----------------------------------')**: This line prints a separator line.\n\n**print(generated_text)**: This line prints the generated text.\n\n**print('\\n\\n')**: This line prints a blank line to separate the generated text from the next iteration.\n","metadata":{"id":"R2vHWq2olutu"}},{"cell_type":"code","source":"def generate_combinations(model):\n recipe_length = 751\n ingredients = ['rice ','potato ','pasta ','onion ','chicken ','meat ','salt ',\n 'sugar ','fish ','cheese ','toamato ','chocolate ','vanilla ']\n for ingredient in ingredients:\n generated_text = generate_text(\n model,\n start_string=ingredient,\n num_generate = recipe_length,\n )\n print(f'Attempt: \"{ingredient}\"')\n print('-----------------------------------')\n print(generated_text)\n print('\\n\\n')","metadata":{"id":"2lcLuauRDMMS","execution":{"iopub.status.busy":"2024-04-27T19:29:35.401083Z","iopub.execute_input":"2024-04-27T19:29:35.401470Z","iopub.status.idle":"2024-04-27T19:29:35.413527Z","shell.execute_reply.started":"2024-04-27T19:29:35.401446Z","shell.execute_reply":"2024-04-27T19:29:35.412622Z"},"trusted":true},"execution_count":81,"outputs":[]},{"cell_type":"code","source":"generate_combinations(model_simplified)","metadata":{"id":"xhvbqSiEbZeU","outputId":"1c2eefaa-380e-4f83-b317-12e30ff737c3","execution":{"iopub.status.busy":"2024-04-27T19:29:35.423962Z","iopub.execute_input":"2024-04-27T19:29:35.424925Z","iopub.status.idle":"2024-04-27T19:31:03.327183Z","shell.execute_reply.started":"2024-04-27T19:29:35.424873Z","shell.execute_reply":"2024-04-27T19:31:03.326200Z"},"trusted":true},"execution_count":82,"outputs":[{"name":"stdout","text":"Attempt: \"rice \"\n-----------------------------------\n📕 rice Pickled Spaghetti And Very Loves And Pretzelle) \n\n🥩\n\n• \"6 oz. nonfat yogurt\"\n• \"16 oz. Kraft Caramels\"\n• \"16 to 20 salmon fillets\"\n\n✍️\n\n▪︎ \"Spread peanut butter on bread slice.\"\n▪︎ \"Cover with a tito small piece of banana slices and top with cherries\n▪︎ reserving sugar to top.\"\n▪︎ \"For best results\n▪︎ use 3 1/2 tablespoons chopped pecans into cheesecloth bag.\"\n▪︎ \"Top with remaining bread cube and bake as directed on directions.\"\n▪︎ \"Stir except using 3 cups bit slices (youblet).\"\n␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣\n\n\n\nAttempt: \"potato \"\n-----------------------------------\n📕 potato Shoulder\"\n\n🥩\n\n• \"1 pkg. frozen hash brown potatoes\"\n• \"1 large onion\n• chopped\"\n• \"2 eggs\"\n• \"1 1/2 sleeves American cheese\"\n• \"salt and freshly ground pepper to taste\"\n• \"lemon slices or can Bleuffles\"\n\n✍️\n\n▪︎ \"Mix all ingredients.\"\n▪︎ \"Bake in baking dish for 30 minutes at 350\\u00b0.\"\n␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣\n\n\n\nAttempt: \"pasta \"\n-----------------------------------\n📕 pasta or Viva Turtles\n\n🥩\n\n• \"2 c. Fruit\n• crushed\"\n• \"1 tsp. almond extract\"\n• \"3 c. flour\"\n• \"1 c. packed brown sugar\"\n• \"1 c. whole wheat flour\"\n• \"1/2 tsp. salt\"\n• \"1/2 tsp. baking powder\"\n• \"1/2 tsp. soda\"\n• \"1 tsp. ground cinnamon\"\n• \"1/2 tsp. baking soda\"\n\n✍️\n\n▪︎ \"Preheat oven to 375\\u00b0.\"\n▪︎ \"Combine flour\n▪︎ sugar\n▪︎ baking powder\n▪︎ baking soda and cloves.\"\n▪︎ \"Add Crisco\n▪︎ egg and milk.\"\n▪︎ \"Beat until smooth.\"\n▪︎ \"Add flour\n▪︎ baking soda and chocolate chunks.\"\n▪︎ \"Stir in first mixture.\"\n▪︎ \"Fill greased 1 3/4 x 8 1/2-inch loaf pan (greased pans) and bake 35 to 40 minutes or until brown.\"\n▪︎ \"Cool on rack.\"\n▪︎ \"Sprinkle pecan pieces with warm Crisco.\"\n▪︎ \"Serve when cool.\"\n␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣\n\n\n\nAttempt: \"onion \"\n-----------------------------------\n📕 onion Countraunt\n\n🥩\n\n• \"3 large potatoes\n• peeled and thinly sliced\"\n• \"2 Tbsp. butter or margarine\"\n• \"1 1/4 tsp. salt\"\n• \"1/8 tsp. pepper\"\n• \"1 c. flour\"\n• \"1/4 tsp. pepper\"\n• \"Tony Cake\"\n\n✍️\n\n▪︎ \"Combine first five ingredients in this oil.\"\n▪︎ \"Mix well.\"\n▪︎ \"Pare and press into bottom of greased pan or 1 1/2-quart shallow casserole.\"\n▪︎ \"Dot with butter.\"\n▪︎ \"Sprinkle 1 cup of tarragon with flaked corn flakes.\"\n▪︎ \"Bake in 375\\u00b0 oven until brown.\"\n␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣\n\n\n\nAttempt: \"chicken \"\n-----------------------------------\n📕 chicken Schnop Cooking Au Gratin\n\n🥩\n\n• \"1 1/2 c. flour\"\n• \"2 2/3 c. quick-cooking oats (I use 2 c. or more)\"\n• \"1 tsp. salt\"\n• \"1/4 tsp. soda\"\n• \"1 tsp. baking powder\"\n• \"1/4 tsp. salt\"\n• \"1 egg\"\n• \"1 Tbsp. oil\"\n• \"peel of 3 large bunkers -Lax golden bread loaf pastry\"\n• \"1/2 c. butter or margarine\n• melted\"\n• \"1/2 c. firmly packed brown sugar\"\n• \"1/4 c. water\"\n\n✍️\n\n▪︎ \"In medium bowl\n▪︎ sift the flour\n▪︎ baking powder\n▪︎ cinnamon\n▪︎ nutmeg and sugar.\"\n▪︎ \"Mix sugar\n▪︎ molasses\n▪︎ shortening and 1/4 cup Buttermilk.\"\n▪︎ \"Add to the egg mixture\n▪︎ beating constantly to boiling.\"\n▪︎ \"Add the diced banana and stir thoroughly.\"\n▪︎ \"Mixture will be thick.\"\n▪︎ \"Pour into a greased 9-inch square pan.\"\n▪︎ \"Cover with apple mixture.\"\n▪︎ \"Bake at 350\\u00b0 for\n\n\n\nAttempt: \"meat \"\n-----------------------------------\n📕 meat Brothoust Tramler) \n\n🥩\n\n• \"1 c. flour\"\n• \"1/2 tsp. cinnamon\"\n• \"1 1/2 tsp. baking powder\"\n• \"1/2 c. persimmon pulp\"\n• \"3/4 c. white sugar\"\n• \"3/4 c. brown sugar\"\n• \"1 1/4 c. whole wheat flour\"\n• \"3/4 c. rhubarb\n• chopped *\"\n• \"1/2 tsp. baking soda\"\n• \"1/4 tsp. salt\"\n• \"1/2 c. raisins\"\n\n✍️\n\n▪︎ \"Mix dry ingredients; sift together.\"\n▪︎ \"Add eggs\n▪︎ salt\n▪︎ sugar and margarine; beat well. Place a thin layer in 11 x 7 x 2-inch baking pan; coat well.\"\n▪︎ \"Bake at 350\\u00b0 for 30 to 45 minutes\n▪︎ or until toothpick comes out clean.\"\n␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣\n\n\n\nAttempt: \"salt \"\n-----------------------------------\n📕 salt Red Au Sugar Ludge) \n\n🥩\n\n• \"1 lb. marshmallows or 3 Tbsp. instant coffee (strawberries\n• None-Lay Piero shell\"\n• \"1/2 to 1 tsp. caramolis liquid\"\n• \"1 Tbsp. creme de cacao\"\n• \"1 tsp. caref nuts (optional)\"\n\n✍️\n\n▪︎ \"In medium bowl\n▪︎ mix chocolate whip in bowl.\"\n▪︎ \"Add egg white\n▪︎ vanilla and walnuts to which carefully to mash.\"\n▪︎ \"Gently heat sweet real gooden over medium heat until sugar melts.\"\n▪︎ \"Pour hot liquid into mold.\"\n▪︎ \"\\tid\"\n▪︎ \"to tray.\"\n▪︎ \"Use white paper fitted Ly 2 bothes Cake.\"\n▪︎ \"Spread soda wafers over cherry.\"\n␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣\n\n\n\nAttempt: \"sugar \"\n-----------------------------------\n📕 sugar Co boiled Campfires\n\n🥩\n\n• \"1 1/4 c. all-purpose flour\"\n• \"2 tsp. baking powder\"\n• \"1/2 tsp. salt\"\n• \"1/2 c. soft shortening (margarine)\"\n• \"2 eggs\"\n• \"1 c. sugar\"\n• \"1 Tbsp. grated orange peel\"\n• \"1 tsp. vanilla\"\n• \"1 c. oat bread crumbs (about 3 c.)\"\n• \"1/2 c. chopped pecans or walnuts or calories or A Blender instant coffee powder\"\n• \"1/4 tsp. ground cinnamon\"\n\n✍️\n\n▪︎ \"Heat oven to 375\\u00b0. Spoon from dough into a 9 x 12-inch pan; set aside. Beat egg whites until stiff; fold into the batter. Pour into pan. Gradually add unbeaten egg and blend.\"\n␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣\n\n\n\nAttempt: \"fish \"\n-----------------------------------\n📕 fish Do No EEg Holeyamati\n\n🥩\n\n• \"1 3/4 c. dry bread crumbs or curry or 6 (8 oz.) pkg. frozen chopped spinach\n• thawed and drained\"\n• \"1 tsp. salt\"\n• \"1/2 tsp. oregano\"\n• \"1/2 tsp. paprika\"\n• \"1/4 tsp. crushed basil\"\n• \"1/2 tsp. grated orange peel\"\n• \"1 can (115 oz.) Monte Mexican-style shinack (fat-free) and cut up an eighttore baked\n• 6 to 8 sheets of a mest.\"\n\n✍️\n\n▪︎ \"In a 1 1/2-quart baking dish\n▪︎ blend soup\n▪︎ milk\n▪︎ dash of paprika and pepper sauce.\"\n▪︎ \"Add the onion mixture with pork chops and spice mixture.\"\n▪︎ \"Sprinkle enough margarine in a pan on all sides of bag to brown; cover and bake at 350\\u00b0 for 45 minutes.\"\n␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣\n\n\n\nAttempt: \"cheese \"\n-----------------------------------\n📕 cheese square Cookie Hhill shrimp and Jimmed Eggplant Garkins Or Bouil crust for 24 barbecues eating 6 minutes in 13 quarts)\"\n• \"8 Tbsp. honey\"\n\n✍️\n\n▪︎ \"Microwave:\"\n▪︎ \"Combine all ingredients in a bowl; add salt supreme and mix.\"\n▪︎ \"Refrigerate three darl.\"\n▪︎ \"Makes about 2 cups.\"\n␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣\n\n\n\nAttempt: \"toamato \"\n-----------------------------------\n📕 toamato Chip)(Serves 10) \n\n🥩\n\n• \"1/2 c. butter or margarine\"\n• \"6 thin slices Swith picks\"\n• \"1 tsp. onion salt\"\n• \"pepper or sesame oil\"\n• \"salt and pepper to taste\"\n• \"Hot of whole cinnamon hearts\"\n• \"maple flour\"\n• \"3 lb. wieners\"\n• \"cauliflower (optional)\"\n\n✍️\n\n▪︎ \"Heat half cinnamon and whet blender (extra mounds).\"\n▪︎ \"Roll 3 times\n▪︎ debone fryer 4 to 5 inches from heat and drain well (or add about 1 cup of chopped nuts if you use an ovenca or low heat\n▪︎ while can thicken pouring all the way through consistency over lid or fish filling to the touch together; leave them out) halfway and strain through away.\"\n▪︎ \"Remove the seeds on both sides.\"\n▪︎ \"Place the skin on bottom rack of bearing together in 10-inch skillet.\"\n▪︎ Salt to taste.\"\n▪︎ \n\n\n\nAttempt: \"chocolate \"\n-----------------------------------\n📕 chocolate Squares\n\n🥩\n\n• \"3 c. flour\"\n• \"1/4 c. sugar\"\n• \"2 1/2 tsp. baking powder\"\n• \"1/2 tsp. salt\"\n• \"1 c. apple butter\"\n• \"1 egg\"\n• \"1/2 tsp. cinnamon\"\n• \"pastry for 1-cup\"\n\n✍️\n\n▪︎ \"Sift flour\n▪︎ baking powder and salt.\"\n▪︎ \"Beat cats egg.\"\n▪︎ \"Add sugar and shortening.\"\n▪︎ \"Add buttermilk and egg and mix thoroughly.\"\n▪︎ \"Fold in apples.\"\n▪︎ \"Bake in oven for 15 to 20 minutes at 375\\u00b0.\"\n␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣␣\n\n\n\nAttempt: \"vanilla \"\n-----------------------------------\n📕 vanilla Fread\n\n🥩\n\n• \"2 to 4 c. frozen cooking apricot halves\"\n• \"1 1/4 c. sugar\"\n• \"3 Tbsp. flour\"\n• \"1/2 tsp. cloves\"\n• \"1 tsp. ground cinnamon\"\n• \"1 tsp. ground nutmeg\"\n• \"1 tsp. nutmeg\"\n• \"3/4 c. Fruits of chocolate candies\"\n• \"1/4 c. butter\"\n• \"1 1/2 tsp. almond flavoring\"\n• \"fruit (thawed)\"\n\n✍️\n\n▪︎ \"Melt the butter\n▪︎ butter and chocolate over low heat\n▪︎ stirring until smooth; add to boiling water a sugar and stir until mixture is almost melted.\"\n▪︎ \"Remove from heat. Stir in pecans\n▪︎ honey\n▪︎ vanilla and baking soda until the mixture is light and fluffy.\"\n▪︎ \"Pour thoroughly mix into this oil in saucepan\n▪︎ stirring with fork.\"\n▪︎ \"Stir in nuts and coconut and combine with remaining ingredients.\"\n▪︎ \"Pour into pastry lined 9-inch square pan.\n\n\n\n","output_type":"stream"}]},{"cell_type":"code","source":"def generate_combinations(model):\n recipe_length = 751\n ingredients = input(\"Enter your ingredients (One or two ingredients): \")\n generated_text = generate_text(\n model,\n start_string=ingredients,\n num_generate = recipe_length\n )\n print(f'Attempt: \"{ingredients}\"')\n print('-----------------------------------')\n print(generated_text)\n print('\\n\\n')","metadata":{"execution":{"iopub.status.busy":"2024-04-27T19:31:03.328638Z","iopub.execute_input":"2024-04-27T19:31:03.329323Z","iopub.status.idle":"2024-04-27T19:31:03.334735Z","shell.execute_reply.started":"2024-04-27T19:31:03.329286Z","shell.execute_reply":"2024-04-27T19:31:03.333763Z"},"trusted":true},"execution_count":83,"outputs":[]},{"cell_type":"code","source":"generate_combinations(model_simplified)","metadata":{"execution":{"iopub.status.busy":"2024-04-27T19:31:03.336080Z","iopub.execute_input":"2024-04-27T19:31:03.337028Z","iopub.status.idle":"2024-04-27T19:47:49.172475Z","shell.execute_reply.started":"2024-04-27T19:31:03.336991Z","shell.execute_reply":"2024-04-27T19:47:49.170951Z"},"trusted":true},"execution_count":84,"outputs":[{"traceback":["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m","\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)","Cell \u001b[0;32mIn[84], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mgenerate_combinations\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel_simplified\u001b[49m\u001b[43m)\u001b[49m\n","Cell \u001b[0;32mIn[83], line 3\u001b[0m, in \u001b[0;36mgenerate_combinations\u001b[0;34m(model)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mgenerate_combinations\u001b[39m(model):\n\u001b[1;32m 2\u001b[0m recipe_length \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m751\u001b[39m\n\u001b[0;32m----> 3\u001b[0m ingredients \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43minput\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mEnter your ingredients (One or two ingredients): \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 4\u001b[0m generated_text \u001b[38;5;241m=\u001b[39m generate_text(\n\u001b[1;32m 5\u001b[0m model,\n\u001b[1;32m 6\u001b[0m start_string\u001b[38;5;241m=\u001b[39mingredients,\n\u001b[1;32m 7\u001b[0m num_generate \u001b[38;5;241m=\u001b[39m recipe_length\n\u001b[1;32m 8\u001b[0m )\n\u001b[1;32m 9\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mAttempt: \u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mingredients\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m'\u001b[39m)\n","File \u001b[0;32m/opt/conda/lib/python3.10/site-packages/ipykernel/kernelbase.py:1202\u001b[0m, in \u001b[0;36mKernel.raw_input\u001b[0;34m(self, prompt)\u001b[0m\n\u001b[1;32m 1200\u001b[0m msg \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mraw_input was called, but this frontend does not support input requests.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 1201\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m StdinNotImplementedError(msg)\n\u001b[0;32m-> 1202\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_input_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 1203\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mstr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1204\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_parent_ident\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mshell\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1205\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_parent\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mshell\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1206\u001b[0m \u001b[43m \u001b[49m\u001b[43mpassword\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 1207\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n","File \u001b[0;32m/opt/conda/lib/python3.10/site-packages/ipykernel/kernelbase.py:1245\u001b[0m, in \u001b[0;36mKernel._input_request\u001b[0;34m(self, prompt, ident, parent, password)\u001b[0m\n\u001b[1;32m 1242\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyboardInterrupt\u001b[39;00m:\n\u001b[1;32m 1243\u001b[0m \u001b[38;5;66;03m# re-raise KeyboardInterrupt, to truncate traceback\u001b[39;00m\n\u001b[1;32m 1244\u001b[0m msg \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInterrupted by user\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m-> 1245\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyboardInterrupt\u001b[39;00m(msg) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m 1246\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m:\n\u001b[1;32m 1247\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlog\u001b[38;5;241m.\u001b[39mwarning(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInvalid Message:\u001b[39m\u001b[38;5;124m\"\u001b[39m, exc_info\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n","\u001b[0;31mKeyboardInterrupt\u001b[0m: Interrupted by user"],"ename":"KeyboardInterrupt","evalue":"Interrupted by user","output_type":"error"}]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"scrolled":true},"execution_count":null,"outputs":[]}]}