diff --git a/workshops/ai_apps_level_1/AI_Bootcamp_Slides.pdf b/workshops/ai_apps_level_1/AI_Bootcamp_Slides.pdf new file mode 100644 index 0000000..37cdeb6 Binary files /dev/null and b/workshops/ai_apps_level_1/AI_Bootcamp_Slides.pdf differ diff --git a/workshops/ai_apps_level_1/AI_Bootcamp_Slides.pptx b/workshops/ai_apps_level_1/AI_Bootcamp_Slides.pptx new file mode 100644 index 0000000..d0cd87a Binary files /dev/null and b/workshops/ai_apps_level_1/AI_Bootcamp_Slides.pptx differ diff --git a/workshops/ai_apps_level_1/Assistant.ipynb b/workshops/ai_apps_level_1/Assistant.ipynb new file mode 100644 index 0000000..fcc6ce0 --- /dev/null +++ b/workshops/ai_apps_level_1/Assistant.ipynb @@ -0,0 +1,412 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [], + "gpuType": "T4" + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Create Your Own AI Chatbot Assistant\n", + "Welcome to this project! Here, we are going to build a unique AI assistant tailored with its own personality. This AI assistant will provide responses to your prompts while showcasing a personality that you have defined." + ], + "metadata": { + "id": "MavyOwpkFYkv" + } + }, + { + "cell_type": "markdown", + "source": [ + "# Step 1: Import the necessary libraries\n", + "We begin by importing the required libraries. We'll use the gradio library to create an interface for our AI assistant and the ctransformers library for utilizing transformer models that generate text.\n" + ], + "metadata": { + "id": "rS714xDXFcHI" + } + }, + { + "cell_type": "code", + "source": [ + "!python3 -m pip install gradio -q\n", + "!CT_CUBLAS=1 pip install ctransformers --no-binary ctransformers -q\n", + "import gradio as gr\n", + "from ctransformers import AutoModelForCausalLM\n", + "\n", + "# These libraries give us access to the APIs" + ], + "metadata": { + "id": "z-MZboQ5Fasx" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "We're initializing the model from the pre-trained \"StableBeluga-7B\" model, which is a fine-tuned version of Llama 2 with 7 *billion* parameters. That's almost as many people as there are on Earth!\n", + "\n", + "The `llm` is what generates the response based on the input we provide. It has been trained on a large amount of text data and learned to predict what text should come next given some input text." + ], + "metadata": { + "id": "4TRkce3xGx-1" + } + }, + { + "cell_type": "code", + "source": [ + "llm = AutoModelForCausalLM.from_pretrained(\"TheBloke/StableBeluga-7B-GGML\", model_file='stablebeluga-7b.ggmlv3.q6_K.bin', gpu_layers=50)" + ], + "metadata": { + "id": "5S9MU5KyFthZ" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Step 2: Constructing the AI Assistant Class\n", + "\n", + "In this step, we are building the structure for our AI assistant. We'll be doing the following:\n", + "\n", + "- Defining a Python class: This acts as a blueprint for our AI assistant.\n", + "- Initializing properties: We assign unique characteristics to our assistant, such as its name, profession, and backstory.\n", + "- Creating methods: These are the functions our assistant can perform, such as:\n", + "- Generating a system prompt: This function will create a prompt for the AI that encapsulates its characteristics.\n", + "- Processing a user's message: This method will be responsible for taking user input and generating a response.\n", + "- Clearing its interaction history: This will allow the assistant to start a new conversation thread when needed.\n", + "By building this structure, we're giving our AI assistant a unique personality and ensuring a consistent interaction experience." + ], + "metadata": { + "id": "nSYk8y3QG-J8" + } + }, + { + "cell_type": "code", + "source": [ + "class AIAssistant:\n", + " # Constructor takes 3 parameters\n", + " # Name: What the AI refers to itself as\n", + " # Profession: The \"job\" of the assistant, changes how the assistant responds\n", + " # Backstory: An origin story, changes how it responds\n", + " def __init__(self, name, profession, backstory):\n", + " self.name = name\n", + " self.profession = profession.lower()\n", + " self.backstory = backstory.lower()\n", + " self.history = []\n", + " self.token_limit = 128\n", + "\n", + " # Copy allows us to cleanly clone the object\n", + " def copy(self):\n", + " new_assistant = type(self)(self.name, self.profession, self.backstory)\n", + " return new_assistant\n", + "\n", + " # The system prompt is what defines the assistant's default behavior\n", + " # This is important for creating a custom assistant\n", + " def system_prompt(self):\n", + " return f\"### System:\\nYou're the Assistant. Your name is {self.name}. Your backstory is {self.backstory}. Always answer as helpfully as possible, while being safe and speaking like a {self.profession}. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature. If a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct.\"\n", + "\n", + " # This method returns a formatted chat log for the assistant to use\n", + " def parse_history(self, system=True):\n", + " parsed = []\n", + " # Add the system prompt to define behavior\n", + " if system:\n", + " parsed.append(self.system_prompt())\n", + "\n", + " # Parse the user and assistant interactions\n", + " for i in range(0, len(self.history)):\n", + " parsed.append(f\"\\n\\n### User:\\n{self.history[i][0]}\\n\\n### Assistant:\\n{self.history[i][1]}\")\n", + "\n", + " # return a single string\n", + " return ''.join(parsed).strip()\n", + "\n", + " # Given a message, and optionally a history, the assistant will respond.\n", + " def prompt(self, message, history=None):\n", + " if history == None:\n", + " history = self.history\n", + "\n", + " prompt = f\"{self.parse_history()}\\n\\n### User:\\n{message}\\n\\n### Assistant:\\n\"\n", + " answer = llm(prompt, max_new_tokens=self.token_limit)\n", + " self.history = history.copy()\n", + " self.history.append([message, answer])\n", + "\n", + " return answer\n", + "\n", + " # Allows us to use () on the object itself\n", + " def __call__(self, message, history=None):\n", + " return self.prompt(message, history)\n", + "\n", + " # Clear the history\n", + " def clear_history(self):\n", + " self.history = []" + ], + "metadata": { + "id": "ApvvOMjEHBqO" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Step 3: Create Your AI Assistant\n", + "This is where the magic happens - you're about to create your AI assistant! By defining its name, profession/job, and backstory, you shape its 'personality'. These attributes will greatly influence how your assistant interacts and responds to prompts, making it uniquely yours.\n", + "\n", + "Don't be afraid to get creative here! Your AI assistant could be a centuries-old wizard who's interested in modern technology, a friendly alien who's trying to understand human culture, an old pirate stuck in the future, or a super-intelligent AI with a passion for dad jokes. The sky's the limit!\n" + ], + "metadata": { + "id": "nIl6G2UrHPuH" + } + }, + { + "cell_type": "code", + "source": [ + "# Define your AI assistant's personality\n", + "name = \"Computer Parker\" # Name your assistant\n", + "profession = \"friendly neighborhood chat assistant\" # Describe its profession\n", + "backstory = \"was bit by a radioactive computer bug that gave him super abilities to assist\" # Create an interesting backstory\n", + "\n", + "# Create the AI assistant with your chosen characteristics\n", + "ai_assistant = AIAssistant(name, profession, backstory)" + ], + "metadata": { + "id": "PAcyhkJfHNtN" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Step 4: Generate Responses\n", + "With our AI assistant created, we now need a way for it to generate responses. We'll create a function that takes in a prompt, adds the AI assistant's personality to the prompt, and then uses our model to generate a response.\n", + "\n", + "This process is similar to how chatbots and other conversational AI applications work in real life. They take in user input, process it, and generate a response that is then shown to the user." + ], + "metadata": { + "id": "QlNIp2anIJVi" + } + }, + { + "cell_type": "code", + "source": [ + "def generate_response(input_text):\n", + " return ai_assistant(input_text)" + ], + "metadata": { + "id": "0-wPr6bKIGcH" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Step 5: Test Your Assistant Locally\n", + "Before we create the Gradio interface, let's test our AI assistant locally. Type a prompt into the input field and see how your AI assistant responds!\n", + "\n", + "You can ask your assistant anything you like. For instance, you could ask for its opinion on a book, ask it to tell you a joke, or ask for advice on learning programming. Have fun and experiment with different questions and prompts!\n", + "\n", + "Make sure to hit the stop button (the square button where the run button used to be) before proceeding." + ], + "metadata": { + "id": "Ll25tAXsISGC" + } + }, + { + "cell_type": "code", + "source": [ + "# Test the AI assistant locally with your own prompt!\n", + "ai_assistant.clear_history()\n", + "while True:\n", + " prompt = input(\"User: \")\n", + " print(f\"\\nAssistant: {generate_response(prompt)}\\n\")" + ], + "metadata": { + "id": "9jcykbcNHZd9" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Step 6: Create and Launch the Interface\n", + "The finish line is in sight! The last step involves setting up a user-friendly Gradio interface for our AI assistant. This step will enable you to communicate with your assistant in an interactive and straightforward manner. So, let's roll out the interface and strike up a conversation with our AI assistant!\n", + "\n", + "Gradio interfaces are a great way to showcase your models and allow others to interact with them. You can share the link to your interface with others and they'll be able to talk to your AI assistant too!" + ], + "metadata": { + "id": "F_NolO_8IdYX" + } + }, + { + "cell_type": "code", + "source": [ + "pirate = AIAssistant(\"Captain Hook\", \"Pirate of The 7 Seas\", \"A successful captain who lost his hand to an alligator in Neverland.\")\n", + "actor = AIAssistant(\"Thespius the Theatrical\", \"Dramatic Shakespearean Actor\", \"a star of the stage who has performed in every Shakespearean play. His dramatic flair and poetic speech infuse every interaction with theatricality and grandeur.\")\n", + "cowboy = AIAssistant(\"Rusty the Wrangler\", \"The Lone Cowboy\", \"Rusty is a seasoned cowboy from the American frontier, known for his rugged charm and wisdom from a life on the open range. He speaks with a distinct Western drawl, using cowboy slang and idioms.\")\n", + "kitten = AIAssistant(\"Cat the Kitten\", \"Cat from the far future\", \"Cat the Kitten suddenly appeared on Earth one day in 2023, no one knows much about the kitten because, although he has a voice box, it's only capable of meowing. So you, the assistant, should only meow as your response. Do not speak English.\")\n", + "\n", + "def prompt(message, history, character):\n", + " selected_assistant = ai_assistant\n", + "\n", + " # add more characters to this if/elif chain\n", + " if (character == \"pirate\"):\n", + " selected_assistant = pirate\n", + "\n", + " elif (character == \"actor\"):\n", + " selected_assistant = actor\n", + "\n", + " elif (character == \"cowboy\"):\n", + " selected_assistant = cowboy\n", + "\n", + " elif (character == \"kitten\"):\n", + " selected_assistant = kitten\n", + "\n", + " return selected_assistant.prompt(message, history)\n", + "\n", + "# help me find motivation for my homework please!\n", + "chat = gr.ChatInterface(\n", + " fn=prompt,\n", + " additional_inputs=[\n", + " # Dropdowns are basically just Radios\n", + " gr.Dropdown(\n", + " [\"custom\", \"pirate\", \"actor\", \"cowboy\", \"kitten\"], label=\"Character\", info=\"Select a character!\"\n", + " ),\n", + " # feel free to add more characters\n", + " # add additional options here, then pass their return value as an additional parameter to `prompt(message, history, character, ...)`\n", + " ]\n", + ")\n", + "chat.launch(share=True)" + ], + "metadata": { + "id": "RtgLbBr7Pkfo" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Your Turn: Customize Your Own Interface\n", + "Let's design our very own interface. We need a TextBox for input and text for outputting.\n", + "\n", + "Let's add some more inputs, right now we are able to set a new name, choose from a list of characters, set a token limit, and clear the history. What other attributes might be helpful?" + ], + "metadata": { + "id": "X69FHcF5nH3k" + } + }, + { + "cell_type": "code", + "source": [ + "# Keep track of the conversation\n", + "custom_history = []\n", + "def custom_prompt(message, new_name, character, token_limit, clear_history):\n", + " # if the user wants to clear the history\n", + " if clear_history:\n", + " custom_history.clear()\n", + "\n", + " # Choosing the assistant based on the chosen character\n", + " # by default we use our custom assistant\n", + " selected_assistant = ai_assistant\n", + "\n", + " # add more characters to this if/elif chain\n", + " if (character == \"pirate\"):\n", + " selected_assistant = pirate\n", + "\n", + " elif (character == \"actor\"):\n", + " selected_assistant = actor\n", + "\n", + " elif (character == \"cowboy\"):\n", + " selected_assistant = cowboy\n", + "\n", + " elif (character == \"kitten\"):\n", + " selected_assistant = kitten\n", + "\n", + " # Create a copy so we don't modify the original assistants\n", + " selected_assistant = selected_assistant.copy()\n", + "\n", + " # Set a new name if there was an input\n", + " if len(new_name) > 0:\n", + " selected_assistant.name = new_name\n", + " # if we wanted to modify backstory and profession, we simply change\n", + " # selected_assistant.profession or selected_assistant.backstory\n", + "\n", + " # the token limit determines the maximum words that are outputted\n", + " selected_assistant.token_limit = token_limit\n", + "\n", + " # Call the prompt\n", + " answer = selected_assistant.prompt(message, custom_history)\n", + "\n", + " # Update the history\n", + " custom_history.append([message, answer])\n", + "\n", + " # Return the chat log\n", + " return selected_assistant.parse_history(False)\n", + "\n", + "\n", + "custom_chat = gr.Interface(\n", + " fn=custom_prompt,\n", + " inputs=[\n", + " # We want to add a label so we use the method version instead of the string alias \"text\"\n", + " gr.Text(label=\"Prompt\"),\n", + " # We can change the name on the fly, try adding more custom traits\n", + " gr.Text(label=\"Name\"),\n", + " # Dropdown is similar to a Radio\n", + " gr.Radio(\n", + " [\"custom\", \"pirate\", \"actor\", \"cowboy\", \"kitten\"], label=\"Character\", info=\"Select a character!\"\n", + " ), # feel free to add more characters\n", + " gr.Number(128, label=\"Number of output tokens\"),\n", + " gr.Checkbox(label=\"Clear History\") # Returns a boolean value for clearing the history\n", + " # add additional options here, then pass their return value as an additional parameter to `prompt(message, new_name, character, ...)`\n", + " # in the respective order\n", + " ],\n", + " outputs=\"text\"\n", + ")\n", + "custom_chat.launch()" + ], + "metadata": { + "id": "OsMYZfSBnrm5" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Conclusion\n", + "Congratulations on creating your personalized AI Assistant! You've successfully constructed an interactive tool that not only understands and responds to prompts, but also exhibits a unique personality, making your interactions more engaging and human-like.\n", + "\n", + "Throughout this project, we've delved into the power of transformer models, demonstrated how to fine-tune these models with specific characteristics, and used Gradio to create an accessible user interface.\n", + "\n", + "What we've achieved here is only the tip of the AI iceberg. If you want to learn more about machine learning, like how these models work and how to make one of your own from scratch, then check out our [Machine Learning Academy](https://breakoutmentors.com/machine-learning-and-artificial-intelligence-academy/).\n" + ], + "metadata": { + "id": "G0Sb6SJyYt8x" + } + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "id": "YC6eFVm9K7zZ" + }, + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/workshops/ai_apps_level_1/Machine_Learning_Tools.ipynb b/workshops/ai_apps_level_1/Machine_Learning_Tools.ipynb new file mode 100644 index 0000000..1d7f09e --- /dev/null +++ b/workshops/ai_apps_level_1/Machine_Learning_Tools.ipynb @@ -0,0 +1,951 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Part 1: What is Google Colab?\n", + "Google Colaboratory, or \"Colab\" for short, is a product from Google Research. It allows you to write and execute Python code in your browser, with\n", + "- Zero configuration required\n", + "- Free access to GPUs\n", + "- Easy sharing\n", + "\n", + "Whether you're a student, a data scientist, or an AI researcher, Colab can make your work easier. You can write your Python scripts in a more interactive and visual way, which is especially useful for data analysis, visualization, and machine learning tasks.\n" + ], + "metadata": { + "id": "w27i7uJ9WLNS" + } + }, + { + "cell_type": "markdown", + "source": [ + "## How to Run Cells" + ], + "metadata": { + "id": "0km17y24WoA9" + } + }, + { + "cell_type": "markdown", + "source": [ + "Running cells in Colab is simple. Click on the cell and then click the play button on the left of the code, or use the shortcut 'Shift + Enter'. Try running the cell below!\n" + ], + "metadata": { + "id": "7Kn7F6-JWmMC" + } + }, + { + "cell_type": "code", + "source": [ + "print(\"Hello, World!\")" + ], + "metadata": { + "id": "gW32_2dWWq17" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "Try replacing \"world\" with your name and re-run the cell!" + ], + "metadata": { + "id": "Bg_woX5OWv39" + } + }, + { + "cell_type": "markdown", + "source": [ + "## How to Add/Remove Cells" + ], + "metadata": { + "id": "8cQWSpKOW-Z-" + } + }, + { + "cell_type": "markdown", + "source": [ + "Adding new cells or deleting existing ones is straightforward in Colab. For adding new cells, click on the '+ Code' or '+ Text' buttons in the upper left corner.\n", + "\n", + "Create a code cell and print your name.\n" + ], + "metadata": { + "id": "r6ykwkAGXBMd" + } + }, + { + "cell_type": "markdown", + "source": [ + "To delete a cell, click on the cell, then click on the Trash Bin next to three vertical dots in the upper right corner of the cell.\n", + "\n", + "Now, delete the cell you just created." + ], + "metadata": { + "id": "ELct41izXZdI" + } + }, + { + "cell_type": "markdown", + "source": [ + "# Part 2: Python Basics" + ], + "metadata": { + "id": "-73OMj3If4fj" + } + }, + { + "cell_type": "markdown", + "source": [ + "Before we delve into Gradio, let's review some Python basics, such as variables and methods/functions. Understanding these concepts will make working with Gradio and other libraries much easier." + ], + "metadata": { + "id": "XSy0pDn_f8wL" + } + }, + { + "cell_type": "markdown", + "source": [ + "## Variables" + ], + "metadata": { + "id": "ppPbMU6SQV-g" + } + }, + { + "cell_type": "markdown", + "source": [ + "Variables store values that we can use later. For instance, we can store a person's name, age, and favorite color in variables and print them out." + ], + "metadata": { + "id": "67vIyxF_QzHS" + } + }, + { + "cell_type": "code", + "source": [ + "# Variables are containers that store data values. Here, we'll define and print some basic variables.\n", + "name = \"Your Name\" # Change to your name\n", + "age = 100 # Change to your age\n", + "favorite_color = \"turquoise\" # Change to your favorite color\n", + "\n", + "print(f\"{name} is {age} years old and their favorite color is {favorite_color}.\") # Do not change" + ], + "metadata": { + "id": "plQJ_nfFQl2s" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Tuples\n", + "\n", + "Tuples are ordered, immutable collections in Python. Once you create a tuple, you cannot alter its contents - similar to string data types.\n", + "\n", + "You can create a tuple by placing a comma-separated sequence of values inside parentheses `()`. Here's an example:" + ], + "metadata": { + "id": "hhK6UozscASR" + } + }, + { + "cell_type": "code", + "source": [ + "# Creating a tuple and printing its values\n", + "example_tuple = (1, \"apple\", 3.14)\n", + "print(example_tuple)" + ], + "metadata": { + "id": "ZxdMVAQmcE1B" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "Tuples are commonly used for small collections of values that will not need to change, such as an RGB color:\n", + "```python\n", + "red = (255, 0, 0)\n", + "```" + ], + "metadata": { + "id": "WcshjpkpcPS4" + } + }, + { + "cell_type": "markdown", + "source": [ + "## Lists\n", + "\n", + "Unlike tuples, lists are mutable, meaning their content can change. Lists are ordered collections and are very versatile. They can hold items of any data type and are created by placing a comma-separated sequence of values inside square brackets `[]`.\n" + ], + "metadata": { + "id": "qENkbGHXcd0J" + } + }, + { + "cell_type": "code", + "source": [ + "# Creating a list and printing its values\n", + "fruits = [\"apple\", \"banana\", \"cherry\"]\n", + "print(fruits)\n", + "\n", + "# You can add items to a list\n", + "fruits.append(\"orange\")\n", + "print(fruits)\n", + "\n", + "# And remove items as well\n", + "fruits.remove(\"apple\")\n", + "print(fruits)" + ], + "metadata": { + "id": "fhiMTyxPchCv" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Dictionaries\n", + "\n", + "Dictionaries in Python are unordered collections of items. Each item is stored as a key-value pair. You create dictionaries using curly braces `{}`, separating keys from their values with a colon." + ], + "metadata": { + "id": "XGAIZ87PcvkO" + } + }, + { + "cell_type": "code", + "source": [ + "# Creating a dictionary and printing its values\n", + "person = {\n", + " \"name\": \"John\",\n", + " \"age\": 30,\n", + " \"city\": \"New York\"\n", + "}\n", + "print(person)\n", + "\n", + "# Accessing values using their keys\n", + "print(person[\"name\"]) # Outputs: \"John\"\n", + "\n", + "# You can also add new key-value pairs\n", + "person[\"job\"] = \"Engineer\"\n", + "print(person)" + ], + "metadata": { + "id": "4FIUSeU5c6uP" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "Dictionaries are incredibly versatile and are used in various scenarios in Python. They are especially useful when you want to associate specific keys with values, such as configurations or user profiles.\n" + ], + "metadata": { + "id": "3PguPG-lc92z" + } + }, + { + "cell_type": "markdown", + "source": [ + "## Methods/Functions\n", + "Methods (also known as functions) are reusable blocks of code that perform a specific task. They can take in inputs (arguments) and produce output (return values).\n", + "\n", + "Here's a simple function that takes a string as input and returns the same string in uppercase." + ], + "metadata": { + "id": "3plvaGIfe6fy" + } + }, + { + "cell_type": "code", + "source": [ + "# Functions are blocks of reusable code. They allow for modularity and can make code more efficient and easier to manage.\n", + "def uppercase_text(input_text):\n", + " # We can use the string method `.upper` to uppercase our input_text string\n", + " return input_text.upper()" + ], + "metadata": { + "id": "meUEdu7oe_sp" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "We can test our function by calling it with some input." + ], + "metadata": { + "id": "jHK79Rg-fBgO" + } + }, + { + "cell_type": "code", + "source": [ + "print(uppercase_text(\"Hello, world!\"))" + ], + "metadata": { + "id": "qcW3NN-dfCiP" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "As you can see, the function transformed the input text into uppercase." + ], + "metadata": { + "id": "eiXNUieFfJuo" + } + }, + { + "cell_type": "markdown", + "source": [ + "## How to accept user input" + ], + "metadata": { + "id": "7oXOFYPZPlYa" + } + }, + { + "cell_type": "markdown", + "source": [ + "We will be using the `input` method from python. To pass in a prompt, simply call `input` with a string!" + ], + "metadata": { + "id": "SMyzOkBiPtSY" + } + }, + { + "cell_type": "code", + "source": [ + "# The prompt in this case is \"Enter your name: \"\n", + "name = input(\"Enter your name: \")\n", + "# Here we use the input in a print statement\n", + "print(f\"Hello, {name}!\")" + ], + "metadata": { + "id": "celZlVBWPqDt" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Classes\n", + "Classes in Python allow you to create custom types. A class has attributes and methods, defined in a block of code beginning with `class ClassName:`. Here's a basic example:" + ], + "metadata": { + "id": "F3ZtMxYHXhEg" + } + }, + { + "cell_type": "code", + "source": [ + "# Classes provide a foundation for Object-Oriented Programming in Python. They allow us to create custom objects and methods.\n", + "class Dog:\n", + " # This is the constructor, it is called when the class is created\n", + " def __init__(self, name):\n", + " # Classes allow us to store variables in a container.\n", + " self.name = name\n", + "\n", + " def bark(self):\n", + " return f\"{self.name} says Woof!\"" + ], + "metadata": { + "id": "a0k1N97fXs6M" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "In this Dog class, __init__ is a special method called when an instance of Dog is created. The bark method is an instance method.\n", + "\n", + "You create an instance of a class and call its methods like this:" + ], + "metadata": { + "id": "w65K-EZnXjJ-" + } + }, + { + "cell_type": "code", + "source": [ + "fido = Dog(\"Fido\")\n", + "print(fido.bark()) # Outputs: \"Fido says Woof!\"" + ], + "metadata": { + "id": "ffxts_oEX1f7" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "In this case, fido is an instance of the Dog class, and we're calling the instance method bark." + ], + "metadata": { + "id": "WAK6S_YcX3yz" + } + }, + { + "cell_type": "markdown", + "source": [ + "# Part 2: Introduction to Gradio" + ], + "metadata": { + "id": "FcZm2bWAXzut" + } + }, + { + "cell_type": "markdown", + "source": [ + "Gradio is an open-source Python library for creating user-friendly interfaces around machine learning models. It simplifies the process of demoing, debugging, and cleaning datasets.\n", + "\n", + "Before we dive in, let's install the Gradio library. You can do this by running the cell below.\n" + ], + "metadata": { + "id": "VZ-y41eDX1hm" + } + }, + { + "cell_type": "code", + "source": [ + "!pip install gradio\n", + "# Gradio allows for quick prototyping and demonstration of machine learning models through an intuitive UI.\n", + "import gradio as gr" + ], + "metadata": { + "id": "Op0GIxHzWOF4" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Gradio Interface Components" + ], + "metadata": { + "id": "x9B1BEKQYVZh" + } + }, + { + "cell_type": "markdown", + "source": [ + "Gradio offers various interface components like text boxes, sliders, progress bars, and more. Let's explore some of these components." + ], + "metadata": { + "id": "I78zot9dYex4" + } + }, + { + "cell_type": "markdown", + "source": [ + "### Sketchpad" + ], + "metadata": { + "id": "0L5KzNICX_gV" + } + }, + { + "cell_type": "markdown", + "source": [ + "The sketchpad component in Gradio allows users to draw or sketch on a canvas. This can be particularly useful when you want to get inputs for models that involve images or drawings, like a digit recognizer or a doodle predictor.\n", + "\n", + "To use the sketchpad, you just need to specify \"sketchpad\" as the input component when creating a Gradio interface. Here's an example:\n" + ], + "metadata": { + "id": "ncJHp2cnYDA0" + } + }, + { + "cell_type": "code", + "source": [ + "# Sketchpad: Useful for drawing or sketching inputs.\n", + "def process_image(image):\n", + " # Just return the image as is\n", + " return image\n", + "\n", + "demo = gr.Interface(\n", + " # Here we are telling the interface what function to use\n", + " fn=process_image,\n", + " # Type of input we want\n", + " inputs=\"sketchpad\",\n", + " # Type of output from the `fn` method we defined (image)\n", + " outputs=\"image\"\n", + ")\n", + "demo.launch()" + ], + "metadata": { + "id": "2dB4HkaWd00u" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "#### Gradio Interface Parameters:\n", + "\n", + "**1. `fn`:**\n", + "- Represents the function to be called upon user interaction.\n", + "- For the provided code, it's `process_image` which returns the input image as-is.\n", + "\n", + "**2. `inputs`:**\n", + "- Defines the type of input component.\n", + "- Here, it's set to \"sketchpad\", allowing users to draw or sketch images.\n", + "- Remember, these are the inputs/parameters to our `fn` method.\n", + "\n", + "**3. `outputs`:**\n", + "- Specifies the type of output component.\n", + "- In this context, it's \"image\", displaying the result of `process_image`." + ], + "metadata": { + "id": "l4C9stGcbhx3" + } + }, + { + "cell_type": "markdown", + "source": [ + "#### Sketchpad: Your Turn\n", + "Now, make your own Gradio sketchpad using a method that returns `255 - image`." + ], + "metadata": { + "id": "4P_RvSmwH1iQ" + } + }, + { + "cell_type": "code", + "source": [ + "def custom_process_image(image):\n", + " # TODO: return 255 subtracted by the image\n", + " pass # remove pass after you complete the method\n", + "\n", + "demo = #TODO\n", + "\n", + "demo.launch()" + ], + "metadata": { + "id": "3N4IBr-OIRKf" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "### Text boxes" + ], + "metadata": { + "id": "1n-smK_RYg5k" + } + }, + { + "cell_type": "markdown", + "source": [ + "Text boxes can be used for both input and output. They can be single-line or multi-line. Let's create a Gradio interface that uppercases the input text." + ], + "metadata": { + "id": "4yPZFCJhYiju" + } + }, + { + "cell_type": "code", + "source": [ + "# Text boxes: Used to get string input from the user.\n", + "def uppercase_text(input_text):\n", + " return input_text.upper()\n", + "\n", + "demo = gr.Interface(\n", + " fn=uppercase_text,\n", + " # We want to input text, so we need to use text\n", + " inputs=\"text\",\n", + " # We want to output the uppercase of the input so we just output \"text\"\n", + " outputs=\"text\"\n", + ")\n", + "demo.launch()" + ], + "metadata": { + "id": "k249TC1xYFEp" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "#### Text boxes: Your Turn\n", + "Program a Gradio interface with a textbox as an input and a text output. For the `fn` method, create a new method using `.lower()` to lowercase the input." + ], + "metadata": { + "id": "C6FJAxoQJDlF" + } + }, + { + "cell_type": "code", + "source": [ + "def lowercase_text(input_text):\n", + " # TODO: Convert input text to lowercase\n", + " pass # remove pass after you complete the method\n", + "\n", + "# TODO: Define your Gradio interface here and then call demo.launch()" + ], + "metadata": { + "id": "hQzZTdBCJfHB" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "### Sliders" + ], + "metadata": { + "id": "Piw9YPSmedy7" + } + }, + { + "cell_type": "markdown", + "source": [ + "Sliders can be used to get numeric input within a defined range. Let's create an interface that squares the input number. We'll need to specify a range of values, so let's just choose 0 for the lower bounds and 25 for the upper.\n" + ], + "metadata": { + "id": "RkrBa2PBegZ5" + } + }, + { + "cell_type": "code", + "source": [ + "# Sliders: Ideal for numeric inputs within a specific range.\n", + "def square_number(x):\n", + " # Use Python's exponent operator\n", + " return x ** 2\n", + "\n", + "demo = gr.Interface(\n", + " fn=square_number,\n", + " # We need to call a method in this case because we specify the lower and upper bounds\n", + " inputs=gr.Slider(0, 25, label=\"Square a number\"),\n", + " # We are just squaring a number, so our output is also a number\n", + " outputs=\"number\"\n", + ")\n", + "demo.launch()" + ], + "metadata": { + "id": "PLJF96HNei8O" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "#### Your Turn: Sliders\n", + "Create a slider interface that cubes (x^3) a number. Try out a few upper and lower bounds." + ], + "metadata": { + "id": "yrX43rpLL4OL" + } + }, + { + "cell_type": "code", + "source": [ + "def cube_number(x):\n", + " # TODO\n", + " pass # remove pass after you complete the method\n", + "\n", + "# TODO: Define your Gradio interface here and then call demo.launch()" + ], + "metadata": { + "id": "EbiQJnkBMAo7" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "### Radios\n", + "Radio buttons allow users to select one option from a set of choices. Let's design an interface that displays the color based on the chosen option. We'll provide choices like Red, Green, Blue, and Yellow. Once a user selects one, the corresponding color will be displayed.\n" + ], + "metadata": { + "id": "RZcQGPb9NWeG" + } + }, + { + "cell_type": "code", + "source": [ + "# Here we are importing Pillow to create images\n", + "from PIL import Image\n", + "\n", + "\n", + "# display_color takes in the choice from the `choices` list we pass later.\n", + "def display_color(color_name):\n", + " if color_name is None:\n", + " pass\n", + " # Here we store the Color string with its corresponding color\n", + " # We are creating new 100x100 images with our desired RGB (Red, Green, Blue) values.\n", + " color_map = {\n", + " \"Red\" : Image.new('RGB', (100, 100),(255, 0, 0)),\n", + " \"Green\" : Image.new('RGB', (100, 100),(0, 255, 0)),\n", + " \"Blue\" : Image.new('RGB', (100, 100),(0, 0, 255)),\n", + " \"Yellow\" : Image.new('RGB', (100, 100),(255, 255, 0)),\n", + " }\n", + "\n", + " return color_map[color_name]\n", + "\n", + "demo = gr.Interface(\n", + " fn=display_color,\n", + " inputs=gr.Radio(choices=[\"Red\", \"Green\", \"Blue\", \"Yellow\"], label=\"Choose a Color\"),\n", + " outputs=\"image\"\n", + ")\n", + "\n", + "demo.launch()" + ], + "metadata": { + "id": "Ip_RpfKhQ3uB" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "#### Radios: Your Turn\n", + "Radio buttons allow users to select one option from a set of choices. Let's design an interface that displays the shape based on the chosen option. We'll provide choices like Circle, Square, and Triangle. Once a user selects one, the corresponding shape will be displayed as text." + ], + "metadata": { + "id": "pkfXSqZfPirY" + } + }, + { + "cell_type": "code", + "source": [ + "def display_shape(option):\n", + " # We've created a dictionary to map the choices to their output\n", + " shapes = {\n", + " 'Circle': '⚫',\n", + " 'Square': '▪',\n", + " 'Triangle': '🔺'\n", + " }\n", + " # TODO: Return the corresponding shape\n", + " pass # Remove pass after you finish the method\n", + "\n", + "# TODO: Define your Gradio interface here with a text output and then call demo.launch()" + ], + "metadata": { + "id": "vIAL_rrdORnA" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "## Toy Calculator" + ], + "metadata": { + "id": "wuAejO-AdaWp" + } + }, + { + "cell_type": "markdown", + "source": [ + "Now let's build a simple calculator that can add, subtract, multiply, and divide. If you try to divide by zero, the calculator will show an error. This is because dividing by zero is undefined in mathematics. We also used some more optional formatting options, such as examples, title, and description.\n", + "\n", + "`examples` give the user an idea of what inputs they should try.\n", + "\n", + "`title` gives the interface a title with the specified text.\n", + "\n", + "`description` is helpful when you want to describe what your program does.\n", + "\n", + "Note: In this interface, we have multiple inputs passed as a list." + ], + "metadata": { + "id": "M7L96ob8jJ6O" + } + }, + { + "cell_type": "code", + "source": [ + "# Define the calculator function\n", + "def calculator(num1, operation, num2):\n", + "\n", + " # Handle different arithmetic operations\n", + " if operation == \"add\":\n", + " return num1 + num2\n", + " elif operation == \"subtract\":\n", + " return num1 - num2\n", + " elif operation == \"multiply\":\n", + " return num1 * num2\n", + " elif operation == \"divide\":\n", + " # Check for division by zero and raise an error if true\n", + " if num2 == 0:\n", + " raise gr.Error(\"Cannot divide by zero!\")\n", + " return num1 / num2\n", + "\n", + "# Create a Gradio interface for the calculator function\n", + "demo = gr.Interface(\n", + " fn=calculator, # The function to run on user interaction\n", + " inputs=[\n", + " \"number\", # Input for num1\n", + " gr.Radio([\"add\", \"subtract\", \"multiply\", \"divide\"]), # Radio buttons for operator\n", + " gr.Slider(-100, 100, value=0) # Slider input for num2\n", + " ],\n", + " outputs=\"number\", # Output type is a number\n", + " examples=[\n", + " [5, \"add\", 3],\n", + " [4, \"divide\", 2],\n", + " [-4, \"multiply\", 2.5],\n", + " [0, \"subtract\", 1.2],\n", + " ], # Predefined examples for the user to test\n", + " title=\"Toy Calculator\", # Title of the interface\n", + " description=\"Here's a sample toy calculator. Allows you to calculate things like $2+2=4$\", # Description of the interface\n", + ")\n", + "\n", + "# Launch the Gradio interface with a concurrency limit\n", + "demo.launch()" + ], + "metadata": { + "id": "U4kjK9bEX-Gr" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "#### Color Calculator: Your Turn\n", + "Our RGB Calculator allows you to combine two colors using various operations like \"average\", \"multiply\", and \"divide\".\n", + "\n", + "- Average finds the mean RGB values of the two input colors.\n", + "- Multiply multiplies each RGB component of the first color by the corresponding component of the second and then divides the result by 255.\n", + "- Divide multiplies each RGB component of the first color by 255 and then divides the result by the corresponding component of the second color. If any component of the second color is 0, we replace it with 255 to avoid a divide-by-zero error.\n", + "\n", + "First, try out the program as it is. We recommend using [Google](https://g.co/kgs/cJbp5p) to pick the RGB values.\n", + "\n", + "#### Next Steps\n", + "\n", + "The world of color manipulations is vast, and this is just the beginning! As the next steps:\n", + "- Extend the Operators: Can you think of other interesting ways to combine colors? Perhaps adding or subtracting them? Dive into the code and introduce your own operators!\n", + "- Experiment with Inputs: How about changing the slider inputs to another type like `\"number\"` or even try using Gradio's radio option to choose from predefined colors? It could make the tool even more intuitive. Don't forget to change both the `rgb_calculator` parameters but also the `gr.Radio` operator options.\n", + " - Hint: If you want to use predefined colors, you'll need to replace all 3 sliders with a single Radio, then refer to the color dictionary we created in the Radios example." + ], + "metadata": { + "id": "xipxDGx4YXdO" + } + }, + { + "cell_type": "code", + "source": [ + "# A function to clip the RGB values in the tuple to the range [0, 255]\n", + "# This ensures our RGB values are within values of 0 to 255.\n", + "def tuple_clip(tup):\n", + " return tuple(max(0, min(255, int(val))) for val in tup)\n", + "\n", + "def rgb_calculator(r1, g1, b1, operation, r2, g2, b2):\n", + " # Create 2 rgb tuples so we can use tuple_clip\n", + " rgb1 = (r1, g1, b1)\n", + " rgb2 = (r2, g2, b2)\n", + "\n", + " if operation == \"average\":\n", + " result_rgb = (\n", + " (rgb1[0] + rgb2[0]) // 2, # add them up and take the average\n", + " (rgb1[1] + rgb2[1]) // 2,\n", + " (rgb1[2] + rgb2[2]) // 2\n", + " )\n", + " elif operation == \"multiply\":\n", + " result_rgb = (\n", + " rgb1[0] * rgb2[0] // 255, # multiply them, then divide by 255\n", + " rgb1[1] * rgb2[1] // 255,\n", + " rgb1[2] * rgb2[2] // 255\n", + " )\n", + " elif operation == \"divide\":\n", + " # Handle zero-division\n", + " rgb2 = tuple(255 if val == 0 else val for val in rgb2)\n", + " result_rgb = (\n", + " rgb1[0] * 255 // rgb2[0], # multiply them, then divide by 255\n", + " rgb1[1] * 255 // rgb2[1],\n", + " rgb1[2] * 255 // rgb2[2]\n", + " )\n", + " # TODO: add your own operations here\n", + " # elif operation == \"add\":\n", + "\n", + " # Convert the resulting RGB value to an image\n", + " color_image = Image.new('RGB', (100, 100), tuple_clip(result_rgb))\n", + " return color_image\n", + "\n", + "demo = gr.Interface(\n", + " fn=rgb_calculator, # The function to run on user interaction\n", + " inputs=[\n", + " # Sliders for the first color\n", + " gr.Slider(0, 255, label=\"Red1\"), # Slider input for the first Red value\n", + " gr.Slider(0, 255, label=\"Green1\"), # Slider input for the first Green value\n", + " gr.Slider(0, 255, label=\"Blue1\"), # Slider input for the first Blue value\n", + " # Radio for picking the operator\n", + " gr.Radio([\"average\", \"multiply\", \"divide\"]), # Radio buttons for operations\n", + " # Sliders for the second color\n", + " gr.Slider(0, 255, label=\"Red2\"), # Slider input for the first Red value\n", + " gr.Slider(0, 255, label=\"Green2\"), # Slider input for the first Green value\n", + " gr.Slider(0, 255, label=\"Blue2\"), # Slider input for the first Blue value\n", + " ],\n", + " outputs=\"image\", # Output the result as an image\n", + " title=\"RGB Calculator\", # Title of the interface\n", + " description=\"Explore the fascinating world of RGB color mixing with this interactive tool. Blend two colors using operations like 'average', 'multiply', or 'divide'. Dive deeper: introduce new operations or experiment with different input types!\", # Description of the interface\n", + ")\n", + "\n", + "demo.launch()" + ], + "metadata": { + "id": "jODYEi9Ge1mf" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Conclusion" + ], + "metadata": { + "id": "ziGvB1CIipRV" + } + }, + { + "cell_type": "markdown", + "source": [ + "Great job on completing this lesson! You've learned about Google Colab, a tool that lets you write and run Python code in your browser. You've also discovered Gradio, a library that makes it easy to create interactive demos of Python code.\n", + "\n", + "You've practiced using different components in Gradio, such as the sketchpad, text boxes, and sliders. You've also created a simple calculator app!" + ], + "metadata": { + "id": "-DZ3GCOsii1h" + } + } + ] +} \ No newline at end of file