commit 53b78a41f9a47d8f3d415268ab920cdecd53226d Author: Alexander Hinrichs Date: Sun Dec 7 20:02:18 2025 +0100 Initial Commit: TODO 0 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..348cb0a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +ai-programming-with-python/08-pre-trained-image-classification/__pycache__ +ai-programming-with-python/C02P8-pre-trained-image-classifier/__pycache__ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/.python-version b/ai-programming-with-python/C02P8-pre-trained-image-classifier/.python-version new file mode 100644 index 0000000..e4fba21 --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/.python-version @@ -0,0 +1 @@ +3.12 diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/adjust_results4_isadog.py b/ai-programming-with-python/C02P8-pre-trained-image-classifier/adjust_results4_isadog.py new file mode 100644 index 0000000..c54fe19 --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/adjust_results4_isadog.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# */AIPND-revision/intropyproject-classify-pet-images/adjust_results4_isadog.py +# +# PROGRAMMER: +# DATE CREATED: +# REVISED DATE: +# PURPOSE: Create a function adjust_results4_isadog that adjusts the results +# dictionary to indicate whether or not the pet image label is of-a-dog, +# and to indicate whether or not the classifier image label is of-a-dog. +# All dog labels from both the pet images and the classifier function +# will be found in the dognames.txt file. We recommend reading all the +# dog names in dognames.txt into a dictionary where the 'key' is the +# dog name (from dognames.txt) and the 'value' is one. If a label is +# found to exist within this dictionary of dog names then the label +# is of-a-dog, otherwise the label isn't of a dog. Alternatively one +# could also read all the dog names into a list and then if the label +# is found to exist within this list - the label is of-a-dog, otherwise +# the label isn't of a dog. +# This function inputs: +# -The results dictionary as results_dic within adjust_results4_isadog +# function and results for the function call within main. +# -The text file with dog names as dogfile within adjust_results4_isadog +# function and in_arg.dogfile for the function call within main. +# This function uses the extend function to add items to the list +# that's the 'value' of the results dictionary. You will be adding the +# whether or not the pet image label is of-a-dog as the item at index +# 3 of the list and whether or not the classifier label is of-a-dog as +# the item at index 4 of the list. Note we recommend setting the values +# at indices 3 & 4 to 1 when the label is of-a-dog and to 0 when the +# label isn't a dog. +# +## +# TODO 4: Define adjust_results4_isadog function below, specifically replace the None +# below by the function definition of the adjust_results4_isadog function. +# Notice that this function doesn't return anything because the +# results_dic dictionary that is passed into the function is a mutable +# data type so no return is needed. +# +def adjust_results4_isadog(results_dic, dogfile): + """ + Adjusts the results dictionary to determine if classifier correctly + classified images 'as a dog' or 'not a dog' especially when not a match. + Demonstrates if model architecture correctly classifies dog images even if + it gets dog breed wrong (not a match). + Parameters: + results_dic - Dictionary with 'key' as image filename and 'value' as a + List. Where the list will contain the following items: + index 0 = pet image label (string) + index 1 = classifier label (string) + index 2 = 1/0 (int) where 1 = match between pet image + and classifer labels and 0 = no match between labels + ------ where index 3 & index 4 are added by this function ----- + NEW - index 3 = 1/0 (int) where 1 = pet image 'is-a' dog and + 0 = pet Image 'is-NOT-a' dog. + NEW - index 4 = 1/0 (int) where 1 = Classifier classifies image + 'as-a' dog and 0 = Classifier classifies image + 'as-NOT-a' dog. + dogfile - A text file that contains names of all dogs from the classifier + function and dog names from the pet image files. This file has + one dog name per line dog names are all in lowercase with + spaces separating the distinct words of the dog name. Dog names + from the classifier function can be a string of dog names separated + by commas when a particular breed of dog has multiple dog names + associated with that breed (ex. maltese dog, maltese terrier, + maltese) (string - indicates text file's filename) + Returns: + None - results_dic is mutable data type so no return needed. + """ + None diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/adjust_results4_isadog_hints.py b/ai-programming-with-python/C02P8-pre-trained-image-classifier/adjust_results4_isadog_hints.py new file mode 100644 index 0000000..ccf7fae --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/adjust_results4_isadog_hints.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# */AIPND-revision/intropyproject-classify-pet-images/adjust_results4_isadog_hints.py +# +# PROGRAMMER: +# DATE CREATED: +# REVISED DATE: +# PURPOSE: This is a *hints* file to help guide students in creating the +# function adjust_results4_isadog that adjusts the results dictionary +# to indicate whether or not the pet image label is of-a-dog, +# and to indicate whether or not the classifier image label is of-a-dog. +# All dog labels from both the pet images and the classifier function +# will be found in the dognames.txt file. We recommend reading all the +# dog names in dognames.txt into a dictionary where the 'key' is the +# dog name (from dognames.txt) and the 'value' is one. If a label is +# found to exist within this dictionary of dog names then the label +# is of-a-dog, otherwise the label isn't of a dog. Alternatively one +# could also read all the dog names into a list and then if the label +# is found to exist within this list - the label is of-a-dog, otherwise +# the label isn't of a dog. +# This function inputs: +# -The results dictionary as results_dic within adjust_results4_isadog +# function and results for the function call within main. +# -The text file with dog names as dogfile within adjust_results4_isadog +# function and in_arg.dogfile for the function call within main. +# This function uses the extend function to add items to the list +# that's the 'value' of the results dictionary. You will be adding the +# whether or not the pet image label is of-a-dog as the item at index +# 3 of the list and whether or not the classifier label is of-a-dog as +# the item at index 4 of the list. Note we recommend setting the values +# at indices 3 & 4 to 1 when the label is of-a-dog and to 0 when the +# label isn't a dog. +# +## +# TODO 4: EDIT and ADD code BELOW to do the following that's stated in the +# comments below that start with "TODO: 4" for the adjust_results4_isadog +# function. Specifically EDIT and ADD code to define the +# adjust_results4_isadog function. Notice that this function doesn't return +# anything because the results_dic dictionary that is passed into the +# function is a mutable data type so no return is needed. +# +def adjust_results4_isadog(results_dic, dogfile): + """ + Adjusts the results dictionary to determine if classifier correctly + classified images 'as a dog' or 'not a dog' especially when not a match. + Demonstrates if model architecture correctly classifies dog images even if + it gets dog breed wrong (not a match). + Parameters: + results_dic - Dictionary with 'key' as image filename and 'value' as a + List. Where the list will contain the following items: + index 0 = pet image label (string) + index 1 = classifier label (string) + index 2 = 1/0 (int) where 1 = match between pet image + and classifer labels and 0 = no match between labels + ------ where index 3 & index 4 are added by this function ----- + NEW - index 3 = 1/0 (int) where 1 = pet image 'is-a' dog and + 0 = pet Image 'is-NOT-a' dog. + NEW - index 4 = 1/0 (int) where 1 = Classifier classifies image + 'as-a' dog and 0 = Classifier classifies image + 'as-NOT-a' dog. + dogfile - A text file that contains names of all dogs from the classifier + function and dog names from the pet image files. This file has + one dog name per line dog names are all in lowercase with + spaces separating the distinct words of the dog name. Dog names + from the classifier function can be a string of dog names separated + by commas when a particular breed of dog has multiple dog names + associated with that breed (ex. maltese dog, maltese terrier, + maltese) (string - indicates text file's filename) + Returns: + None - results_dic is mutable data type so no return needed. + """ + # Creates dognames dictionary for quick matching to results_dic labels from + # real answer & classifier's answer + dognames_dic = dict() + + # Reads in dognames from file, 1 name per line & automatically closes file + with open(dogfile, "r") as infile: + # Reads in dognames from first line in file + line = infile.readline() + + # Processes each line in file until reaching EOF (end-of-file) by + # processing line and adding dognames to dognames_dic with while loop + while line != "": + + # TODO: 4a. REPLACE pass with CODE to remove the newline character + # from the variable line + # + # Process line by striping newline from line + pass + + # TODO: 4b. REPLACE pass with CODE to check if the dogname(line) + # exists within dognames_dic, then if the dogname(line) + # doesn't exist within dognames_dic then add the dogname(line) + # to dognames_dic as the 'key' with the 'value' of 1. + # + # adds dogname(line) to dogsnames_dic if it doesn't already exist + # in the dogsnames_dic dictionary + pass + + # Reads in next line in file to be processed with while loop + # if this line isn't empty (EOF) + line = infile.readline() + + + # Add to whether pet labels & classifier labels are dogs by appending + # two items to end of value(List) in results_dic. + # List Index 3 = whether(1) or not(0) Pet Image Label is a dog AND + # List Index 4 = whether(1) or not(0) Classifier Label is a dog + # How - iterate through results_dic if labels are found in dognames_dic + # then label "is a dog" index3/4=1 otherwise index3/4=0 "not a dog" + for key in results_dic: + + # Pet Image Label IS of Dog (e.g. found in dognames_dic) + if results_dic[key][0] in dognames_dic: + + # Classifier Label IS image of Dog (e.g. found in dognames_dic) + # appends (1, 1) because both labels are dogs + if results_dic[key][1] in dognames_dic: + results_dic[key].extend((1, 1)) + + # TODO: 4c. REPLACE pass BELOW with CODE that adds the following to + # results_dic dictionary for the key indicated by the + # variable key - append (1,0) to the value using + # the extend list function. This indicates + # the pet label is-a-dog, classifier label is-NOT-a-dog. + # + # Classifier Label IS NOT image of dog (e.g. NOT in dognames_dic) + # appends (1,0) because only pet label is a dog + else: + pass + + # Pet Image Label IS NOT a Dog image (e.g. NOT found in dognames_dic) + else: + # TODO: 4d. REPLACE pass BELOW with CODE that adds the following to + # results_dic dictionary for the key indicated by the + # variable key - append (0,1) to the value uisng + # the extend list function. This indicates + # the pet label is-NOT-a-dog, classifier label is-a-dog. + # + # Classifier Label IS image of Dog (e.g. found in dognames_dic) + # appends (0, 1)because only Classifier labe is a dog + if results_dic[key][1] in dognames_dic: + pass + + # TODO: 4e. REPLACE pass BELOW with CODE that adds the following to + # results_dic dictionary for the key indicated by the + # variable key - append (0,0) to the value using the + # extend list function. This indicates + # the pet label is-NOT-a-dog, classifier label is-NOT-a-dog. + # + # Classifier Label IS NOT image of Dog (e.g. NOT in dognames_dic) + # appends (0, 0) because both labels aren't dogs + else: + pass + \ No newline at end of file diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/calculates_results_stats.py b/ai-programming-with-python/C02P8-pre-trained-image-classifier/calculates_results_stats.py new file mode 100644 index 0000000..1345839 --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/calculates_results_stats.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# */AIPND-revision/intropyproject-classify-pet-images/calculates_results_stats.py +# +# PROGRAMMER: +# DATE CREATED: +# REVISED DATE: +# PURPOSE: Create a function calculates_results_stats that calculates the +# statistics of the results of the programrun using the classifier's model +# architecture to classify the images. This function will use the +# results in the results dictionary to calculate these statistics. +# This function will then put the results statistics in a dictionary +# (results_stats_dic) that's created and returned by this function. +# This will allow the user of the program to determine the 'best' +# model for classifying the images. The statistics that are calculated +# will be counts and percentages. Please see "Intro to Python - Project +# classifying Images - xx Calculating Results" for details on the +# how to calculate the counts and percentages for this function. +# This function inputs: +# -The results dictionary as results_dic within calculates_results_stats +# function and results for the function call within main. +# This function creates and returns the Results Statistics Dictionary - +# results_stats_dic. This dictionary contains the results statistics +# (either a percentage or a count) where the key is the statistic's +# name (starting with 'pct' for percentage or 'n' for count) and value +# is the statistic's value. This dictionary should contain the +# following keys: +# n_images - number of images +# n_dogs_img - number of dog images +# n_notdogs_img - number of NON-dog images +# n_match - number of matches between pet & classifier labels +# n_correct_dogs - number of correctly classified dog images +# n_correct_notdogs - number of correctly classified NON-dog images +# n_correct_breed - number of correctly classified dog breeds +# pct_match - percentage of correct matches +# pct_correct_dogs - percentage of correctly classified dogs +# pct_correct_breed - percentage of correctly classified dog breeds +# pct_correct_notdogs - percentage of correctly classified NON-dogs +# +## +# TODO 5: Define calculates_results_stats function below, please be certain to replace None +# in the return statement with the results_stats_dic dictionary that you create +# with this function +# +def calculates_results_stats(results_dic): + """ + Calculates statistics of the results of the program run using classifier's model + architecture to classifying pet images. Then puts the results statistics in a + dictionary (results_stats_dic) so that it's returned for printing as to help + the user to determine the 'best' model for classifying images. Note that + the statistics calculated as the results are either percentages or counts. + Parameters: + results_dic - Dictionary with key as image filename and value as a List + (index)idx 0 = pet image label (string) + idx 1 = classifier label (string) + idx 2 = 1/0 (int) where 1 = match between pet image and + classifer labels and 0 = no match between labels + idx 3 = 1/0 (int) where 1 = pet image 'is-a' dog and + 0 = pet Image 'is-NOT-a' dog. + idx 4 = 1/0 (int) where 1 = Classifier classifies image + 'as-a' dog and 0 = Classifier classifies image + 'as-NOT-a' dog. + Returns: + results_stats_dic - Dictionary that contains the results statistics (either + a percentage or a count) where the key is the statistic's + name (starting with 'pct' for percentage or 'n' for count) + and the value is the statistic's value. See comments above + and the previous topic Calculating Results in the class for details + on how to calculate the counts and statistics. + """ + # Replace None with the results_stats_dic dictionary that you created with + # this function + return None diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/calculates_results_stats_hints.py b/ai-programming-with-python/C02P8-pre-trained-image-classifier/calculates_results_stats_hints.py new file mode 100644 index 0000000..0b90eda --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/calculates_results_stats_hints.py @@ -0,0 +1,181 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# */AIPND-revision/intropyproject-classify-pet-images/calculates_results_stats_hints.py +# +# PROGRAMMER: +# DATE CREATED: +# REVISED DATE: +# PURPOSE: This is a *hints* file to help guide students in creating the +# function calculates_results_stats that calculates the statistics +# of the results of the programrun using the classifier's model +# architecture to classify the images. This function will use the +# results in the results dictionary to calculate these statistics. +# This function will then put the results statistics in a dictionary +# (results_stats_dic) that's created and returned by this function. +# This will allow the user of the program to determine the 'best' +# model for classifying the images. The statistics that are calculated +# will be counts and percentages. Please see "Intro to Python - Project +# classifying Images - xx Calculating Results" for details on the +# how to calculate the counts and percentages for this function. +# This function inputs: +# -The results dictionary as results_dic within calculates_results_stats +# function and results for the function call within main. +# This function creates and returns the Results Statistics Dictionary - +# results_stats_dic. This dictionary contains the results statistics +# (either a percentage or a count) where the key is the statistic's +# name (starting with 'pct' for percentage or 'n' for count) and value +# is the statistic's value. This dictionary should contain the +# following keys: +# n_images - number of images +# n_dogs_img - number of dog images +# n_notdogs_img - number of NON-dog images +# n_match - number of matches between pet & classifier labels +# n_correct_dogs - number of correctly classified dog images +# n_correct_notdogs - number of correctly classified NON-dog images +# n_correct_breed - number of correctly classified dog breeds +# pct_match - percentage of correct matches +# pct_correct_dogs - percentage of correctly classified dogs +# pct_correct_breed - percentage of correctly classified dog breeds +# pct_correct_notdogs - percentage of correctly classified NON-dogs +# +## +# TODO 5: EDIT and ADD code BELOW to do the following that's stated in the +# comments below that start with "TODO: 5" for the calculates_results_stats +# function. Please be certain to replace None in the return statement with +# the results_stats_dic dictionary that you create with this function +# +def calculates_results_stats(results_dic): + """ + Calculates statistics of the results of the program run using classifier's model + architecture to classifying pet images. Then puts the results statistics in a + dictionary (results_stats_dic) so that it's returned for printing as to help + the user to determine the 'best' model for classifying images. Note that + the statistics calculated as the results are either percentages or counts. + Parameters: + results_dic - Dictionary with key as image filename and value as a List + (index)idx 0 = pet image label (string) + idx 1 = classifier label (string) + idx 2 = 1/0 (int) where 1 = match between pet image and + classifer labels and 0 = no match between labels + idx 3 = 1/0 (int) where 1 = pet image 'is-a' dog and + 0 = pet Image 'is-NOT-a' dog. + idx 4 = 1/0 (int) where 1 = Classifier classifies image + 'as-a' dog and 0 = Classifier classifies image + 'as-NOT-a' dog. + Returns: + results_stats_dic - Dictionary that contains the results statistics (either + a percentage or a count) where the key is the statistic's + name (starting with 'pct' for percentage or 'n' for count) + and the value is the statistic's value. See comments above + and the classroom Item XX Calculating Results for details + on how to calculate the counts and statistics. + """ + # Creates empty dictionary for results_stats_dic + results_stats_dic = dict() + + # Sets all counters to initial values of zero so that they can + # be incremented while processing through the images in results_dic + results_stats_dic['n_dogs_img'] = 0 + results_stats_dic['n_match'] = 0 + results_stats_dic['n_correct_dogs'] = 0 + results_stats_dic['n_correct_notdogs'] = 0 + results_stats_dic['n_correct_breed'] = 0 + + # process through the results dictionary + for key in results_dic: + + # Labels Match Exactly + if results_dic[key][2] == 1: + results_stats_dic['n_match'] += 1 + + # TODO: 5a. REPLACE pass with CODE that counts how many pet images of + # dogs had their breed correctly classified. This happens + # when the pet image label indicates the image is-a-dog AND + # the pet image label and the classifier label match. You + # will need to write a conditional statement that determines + # when the dog breed is correctly classified and then + # increments 'n_correct_breed' by 1. Recall 'n_correct_breed' + # is a key in the results_stats_dic dictionary with it's value + # representing the number of correctly classified dog breeds. + # + # Pet Image Label is a Dog AND Labels match- counts Correct Breed + pass + + # Pet Image Label is a Dog - counts number of dog images + if results_dic[key][3] == 1: + results_stats_dic['n_dogs_img'] += 1 + + # Classifier classifies image as Dog (& pet image is a dog) + # counts number of correct dog classifications + if results_dic[key][4] == 1: + results_stats_dic['n_correct_dogs'] += 1 + + # TODO: 5b. REPLACE pass with CODE that counts how many pet images + # that are NOT dogs were correctly classified. This happens + # when the pet image label indicates the image is-NOT-a-dog + # AND the classifier label indicates the images is-NOT-a-dog. + # You will need to write a conditional statement that + # determines when the classifier label indicates the image + # is-NOT-a-dog and then increments 'n_correct_notdogs' by 1. + # Recall the 'else:' above 'pass' already indicates that the + # pet image label indicates the image is-NOT-a-dog and + # 'n_correct_notdogs' is a key in the results_stats_dic dictionary + # with it's value representing the number of correctly + # classified NOT-a-dog images. + # + # Pet Image Label is NOT a Dog + else: + # Classifier classifies image as NOT a Dog(& pet image isn't a dog) + # counts number of correct NOT dog clasifications. + pass + + + # Calculates run statistics (counts & percentages) below that are calculated + # using the counters from above. + + # calculates number of total images + results_stats_dic['n_images'] = len(results_dic) + + # calculates number of not-a-dog images using - images & dog images counts + results_stats_dic['n_notdogs_img'] = (results_stats_dic['n_images'] - + results_stats_dic['n_dogs_img']) + + # TODO: 5c. REPLACE zero(0.0) with CODE that calculates the % of correctly + # matched images. Recall that this can be calculated by the + # number of correctly matched images ('n_match') divided by the + # number of images('n_images'). This result will need to be + # multiplied by 100.0 to provide the percentage. + # + # Calculates % correct for matches + results_stats_dic['pct_match'] = 0.0 + + # TODO: 5d. REPLACE zero(0.0) with CODE that calculates the % of correctly + # classified dog images. Recall that this can be calculated by + # the number of correctly classified dog images('n_correct_dogs') + # divided by the number of dog images('n_dogs_img'). This result + # will need to be multiplied by 100.0 to provide the percentage. + # + # Calculates % correct dogs + results_stats_dic['pct_correct_dogs'] = 0.0 + + # TODO: 5e. REPLACE zero(0.0) with CODE that calculates the % of correctly + # classified breeds of dogs. Recall that this can be calculated + # by the number of correctly classified breeds of dog('n_correct_breed') + # divided by the number of dog images('n_dogs_img'). This result + # will need to be multiplied by 100.0 to provide the percentage. + # + # Calculates % correct breed of dog + results_stats_dic['pct_correct_breed'] = 0.0 + + # Calculates % correct not-a-dog images + # Uses conditional statement for when no 'not a dog' images were submitted + if results_stats_dic['n_notdogs_img'] > 0: + results_stats_dic['pct_correct_notdogs'] = (results_stats_dic['n_correct_notdogs'] / + results_stats_dic['n_notdogs_img'])*100.0 + else: + results_stats_dic['pct_correct_notdogs'] = 0.0 + + + # TODO 5f. REPLACE None with the results_stats_dic dictionary that you + # created with this function + return None diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/check_images.py b/ai-programming-with-python/C02P8-pre-trained-image-classifier/check_images.py new file mode 100644 index 0000000..37e0b46 --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/check_images.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# */AIPND-revision/intropyproject-classify-pet-images/check_images.py +# +# TODO 0: Add your information below for Programmer & Date Created. +# PROGRAMMER: Alexander Hinrichs +# DATE CREATED: 07.12.2025 +# REVISED DATE: +# PURPOSE: Classifies pet images using a pretrained CNN model, compares these +# classifications to the true identity of the pets in the images, and +# summarizes how well the CNN performed on the image classification task. +# Note that the true identity of the pet (or object) in the image is +# indicated by the filename of the image. Therefore, your program must +# first extract the pet image label from the filename before +# classifying the images using the pretrained CNN model. With this +# program we will be comparing the performance of 3 different CNN model +# architectures to determine which provides the 'best' classification. +# +# Use argparse Expected Call with <> indicating expected user input: +# python check_images.py --dir --arch +# --dogfile +# Example call: +# python check_images.py --dir pet_images/ --arch vgg --dogfile dognames.txt +## + +# Imports python modules +from time import time, sleep + +# Imports print functions that check the lab +from print_functions_for_lab_checks import * + +# Imports functions created for this program +from get_input_args import get_input_args +from get_pet_labels import get_pet_labels +from classify_images import classify_images +from adjust_results4_isadog import adjust_results4_isadog +from calculates_results_stats import calculates_results_stats +from print_results import print_results + + +# Main program function defined below +def main(): + # TODO 0: Measures total program runtime by collecting start time + start_time = time() + + # TODO 1: Define get_input_args function within the file get_input_args.py + # This function retrieves 3 Command Line Arugments from user as input from + # the user running the program from a terminal window. This function returns + # the collection of these command line arguments from the function call as + # the variable in_arg + in_arg = get_input_args() + + # Function that checks command line arguments using in_arg + check_command_line_arguments(in_arg) + + # TODO 2: Define get_pet_labels function within the file get_pet_labels.py + # Once the get_pet_labels function has been defined replace 'None' + # in the function call with in_arg.dir Once you have done the replacements + # your function call should look like this: + # get_pet_labels(in_arg.dir) + # This function creates the results dictionary that contains the results, + # this dictionary is returned from the function call as the variable results + results = get_pet_labels(None) + + # Function that checks Pet Images in the results Dictionary using results + check_creating_pet_image_labels(results) + + # TODO 3: Define classify_images function within the file classiy_images.py + # Once the classify_images function has been defined replace first 'None' + # in the function call with in_arg.dir and replace the last 'None' in the + # function call with in_arg.arch Once you have done the replacements your + # function call should look like this: + # classify_images(in_arg.dir, results, in_arg.arch) + # Creates Classifier Labels with classifier function, Compares Labels, + # and adds these results to the results dictionary - results + classify_images(None, results, None) + + # Function that checks Results Dictionary using results + check_classifying_images(results) + + # TODO 4: Define adjust_results4_isadog function within the file adjust_results4_isadog.py + # Once the adjust_results4_isadog function has been defined replace 'None' + # in the function call with in_arg.dogfile Once you have done the + # replacements your function call should look like this: + # adjust_results4_isadog(results, in_arg.dogfile) + # Adjusts the results dictionary to determine if classifier correctly + # classified images as 'a dog' or 'not a dog'. This demonstrates if + # model can correctly classify dog images as dogs (regardless of breed) + adjust_results4_isadog(results, None) + + # Function that checks Results Dictionary for is-a-dog adjustment using results + check_classifying_labels_as_dogs(results) + + # TODO 5: Define calculates_results_stats function within the file calculates_results_stats.py + # This function creates the results statistics dictionary that contains a + # summary of the results statistics (this includes counts & percentages). This + # dictionary is returned from the function call as the variable results_stats + # Calculates results of run and puts statistics in the Results Statistics + # Dictionary - called results_stats + results_stats = calculates_results_stats(results) + + # Function that checks Results Statistics Dictionary using results_stats + check_calculating_results(results, results_stats) + + # TODO 6: Define print_results function within the file print_results.py + # Once the print_results function has been defined replace 'None' + # in the function call with in_arg.arch Once you have done the + # replacements your function call should look like this: + # print_results(results, results_stats, in_arg.arch, True, True) + # Prints summary results, incorrect classifications of dogs (if requested) + # and incorrectly classified breeds (if requested) + print_results(results, results_stats, None, True, True) + + # TODO 0: Measure total program runtime by collecting end time + end_time = time() + + # TODO 0: Computes overall runtime in seconds & prints it in hh:mm:ss format + tot_time = ( + end_time - start_time + ) # calculate difference between end time and start time + print( + "\n** Total Elapsed Runtime:", + str(int((tot_time / 3600))) + + ":" + + str(int((tot_time % 3600) / 60)) + + ":" + + str(int((tot_time % 3600) % 60)), + ) + + +# Call to main function to run the program +if __name__ == "__main__": + main() diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/check_images.txt b/ai-programming-with-python/C02P8-pre-trained-image-classifier/check_images.txt new file mode 100644 index 0000000..0012815 --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/check_images.txt @@ -0,0 +1,20 @@ +Questions regarding Uploaded Image Classification: + +1. Did the three model architectures classify the breed of dog in Dog_01.jpg to be the same breed? If not, report the differences in the classifications. + +Answer: + + +2. Did each of the three model architectures classify the breed of dog in Dog_01.jpg to be the same breed of dog as that model architecture classified Dog_02.jpg? If not, report the differences in the classifications. + +Answer: + + +3. Did the three model architectures correctly classify Animal_Name_01.jpg and Object_Name_01.jpg to not be dogs? If not, report the misclassifications. + +Answer: + + +4. Based upon your answers for questions 1. - 3. above, select the model architecture that you feel did the best at classifying the four uploaded images. Describe why you selected that model architecture as the best on uploaded image classification. + +Answer: diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/classifier.py b/ai-programming-with-python/C02P8-pre-trained-image-classifier/classifier.py new file mode 100644 index 0000000..7f8b035 --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/classifier.py @@ -0,0 +1,74 @@ +import ast +from PIL import Image +import torchvision.transforms as transforms +from torch.autograd import Variable +import torchvision.models as models +from torch import __version__ + +resnet18 = models.resnet18(pretrained=True) +alexnet = models.alexnet(pretrained=True) +vgg16 = models.vgg16(pretrained=True) + +models = {'resnet': resnet18, 'alexnet': alexnet, 'vgg': vgg16} + +# obtain ImageNet labels +with open('imagenet1000_clsid_to_human.txt') as imagenet_classes_file: + imagenet_classes_dict = ast.literal_eval(imagenet_classes_file.read()) + +def classifier(img_path, model_name): + # load the image + img_pil = Image.open(img_path) + + # define transforms + preprocess = transforms.Compose([ + transforms.Resize(256), + transforms.CenterCrop(224), + transforms.ToTensor(), + transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) + ]) + + # preprocess the image + img_tensor = preprocess(img_pil) + + # resize the tensor (add dimension for batch) + img_tensor.unsqueeze_(0) + + # wrap input in variable, wrap input in variable - no longer needed for + # v 0.4 & higher code changed 04/26/2018 by Jennifer S. to handle PyTorch upgrade + pytorch_ver = __version__.split('.') + + # pytorch versions 0.4 & hihger - Variable depreciated so that it returns + # a tensor. So to address tensor as output (not wrapper) and to mimic the + # affect of setting volatile = True (because we are using pretrained models + # for inference) we can set requires_gradient to False. Here we just set + # requires_grad_ to False on our tensor + if int(pytorch_ver[0]) > 0 or int(pytorch_ver[1]) >= 4: + img_tensor.requires_grad_(False) + + # pytorch versions less than 0.4 - uses Variable because not-depreciated + else: + # apply model to input + # wrap input in variable + data = Variable(img_tensor, volatile = True) + + # apply model to input + model = models[model_name] + + # puts model in evaluation mode + # instead of (default)training mode + model = model.eval() + + # apply data to model - adjusted based upon version to account for + # operating on a Tensor for version 0.4 & higher. + if int(pytorch_ver[0]) > 0 or int(pytorch_ver[1]) >= 4: + output = model(img_tensor) + + # pytorch versions less than 0.4 + else: + # apply data to model + output = model(data) + + # return index corresponding to predicted class + pred_idx = output.data.numpy().argmax() + + return imagenet_classes_dict[pred_idx] diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/classify_images.py b/ai-programming-with-python/C02P8-pre-trained-image-classifier/classify_images.py new file mode 100644 index 0000000..7472e3a --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/classify_images.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# */AIPND-revision/intropyproject-classify-pet-images/classify_images.py +# +# PROGRAMMER: +# DATE CREATED: +# REVISED DATE: +# PURPOSE: Create a function classify_images that uses the classifier function +# to create the classifier labels and then compares the classifier +# labels to the pet image labels. This function inputs: +# -The Image Folder as image_dir within classify_images and function +# and as in_arg.dir for function call within main. +# -The results dictionary as results_dic within classify_images +# function and results for the functin call within main. +# -The CNN model architecture as model wihtin classify_images function +# and in_arg.arch for the function call within main. +# This function uses the extend function to add items to the list +# that's the 'value' of the results dictionary. You will be adding the +# classifier label as the item at index 1 of the list and the comparison +# of the pet and classifier labels as the item at index 2 of the list. +# +## +# Imports classifier function for using CNN to classify images +from classifier import classifier + +# TODO 3: Define classify_images function below, specifically replace the None +# below by the function definition of the classify_images function. +# Notice that this function doesn't return anything because the +# results_dic dictionary that is passed into the function is a mutable +# data type so no return is needed. +# +def classify_images(images_dir, results_dic, model): + """ + Creates classifier labels with classifier function, compares pet labels to + the classifier labels, and adds the classifier label and the comparison of + the labels to the results dictionary using the extend function. Be sure to + format the classifier labels so that they will match your pet image labels. + The format will include putting the classifier labels in all lower case + letters and strip the leading and trailing whitespace characters from them. + For example, the Classifier function returns = 'Maltese dog, Maltese terrier, Maltese' + so the classifier label = 'maltese dog, maltese terrier, maltese'. + Recall that dog names from the classifier function can be a string of dog + names separated by commas when a particular breed of dog has multiple dog + names associated with that breed. For example, you will find pet images of + a 'dalmatian'(pet label) and it will match to the classifier label + 'dalmatian, coach dog, carriage dog' if the classifier function correctly + classified the pet images of dalmatians. + PLEASE NOTE: This function uses the classifier() function defined in + classifier.py within this function. The proper use of this function is + in test_classifier.py Please refer to this program prior to using the + classifier() function to classify images within this function + Parameters: + images_dir - The (full) path to the folder of images that are to be + classified by the classifier function (string) + results_dic - Results Dictionary with 'key' as image filename and 'value' + as a List. Where the list will contain the following items: + index 0 = pet image label (string) + --- where index 1 & index 2 are added by this function --- + NEW - index 1 = classifier label (string) + NEW - index 2 = 1/0 (int) where 1 = match between pet image + and classifer labels and 0 = no match between labels + model - Indicates which CNN model architecture will be used by the + classifier function to classify the pet images, + values must be either: resnet alexnet vgg (string) + Returns: + None - results_dic is mutable data type so no return needed. + """ + None \ No newline at end of file diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/classify_images_hints.py b/ai-programming-with-python/C02P8-pre-trained-image-classifier/classify_images_hints.py new file mode 100644 index 0000000..fdbcf89 --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/classify_images_hints.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# */AIPND-revision/intropyproject-classify-pet-images/classify_images_hints.py +# +# PROGRAMMER: +# DATE CREATED: +# REVISED DATE: +# PURPOSE: This is a *hints* file to help guide students in creating the +# function classify_images that uses the classifier function +# to create the classifier labels and then compares the classifier +# labels to the pet image labels. This function inputs: +# -The Image Folder as image_dir within classify_images and function +# and as in_arg.dir for function call within main. +# -The results dictionary as results_dic within classify_images +# function and results for the functin call within main. +# -The CNN model architecture as model wihtin classify_images function +# and in_arg.arch for the function call within main. +# This function uses the extend function to add items to the list +# that's the 'value' of the results dictionary. You will be adding the +# classifier label as the item at index 1 of the list and the comparison +# of the pet and classifier labels as the item at index 2 of the list. +# +## +# Imports classifier function for using CNN to classify images +from classifier import classifier + +# TODO 3: EDIT and ADD code BELOW to do the following that's stated in the +# comments below that start with "TODO: 3" for the classify_images function +# Specifically EDIT and ADD code to define the classify_images function. +# Notice that this function doesn't return anything because the +# results_dic dictionary that is passed into the function is a mutable +# data type so no return is needed. +# +def classify_images(images_dir, results_dic, model): + """ + Creates classifier labels with classifier function, compares pet labels to + the classifier labels, and adds the classifier label and the comparison of + the labels to the results dictionary using the extend function. Be sure to + format the classifier labels so that they will match your pet image labels. + The format will include putting the classifier labels in all lower case + letters and strip the leading and trailing whitespace characters from them. + For example, the Classifier function returns = 'Maltese dog, Maltese terrier, Maltese' + so the classifier label = 'maltese dog, maltese terrier, maltese'. + Recall that dog names from the classifier function can be a string of dog + names separated by commas when a particular breed of dog has multiple dog + names associated with that breed. For example, you will find pet images of + a 'dalmatian'(pet label) and it will match to the classifier label + 'dalmatian, coach dog, carriage dog' if the classifier function correctly + classified the pet images of dalmatians. + PLEASE NOTE: This function uses the classifier() function defined in + classifier.py within this function. The proper use of this function is + in test_classifier.py Please refer to this program prior to using the + classifier() function to classify images within this function + Parameters: + images_dir - The (full) path to the folder of images that are to be + classified by the classifier function (string) + results_dic - Results Dictionary with 'key' as image filename and 'value' + as a List. Where the list will contain the following items: + index 0 = pet image label (string) + --- where index 1 & index 2 are added by this function --- + NEW - index 1 = classifier label (string) + NEW - index 2 = 1/0 (int) where 1 = match between pet image + and classifer labels and 0 = no match between labels + model - Indicates which CNN model architecture will be used by the + classifier function to classify the pet images, + values must be either: resnet alexnet vgg (string) + Returns: + None - results_dic is mutable data type so no return needed. + """ + # Process all files in the results_dic - use images_dir to give fullpath + # that indicates the folder and the filename (key) to be used in the + # classifier function + for key in results_dic: + + # TODO: 3a. Set the string variable model_label to be the string that's + # returned from using the classifier function instead of the + # empty string below. + # + # Runs classifier function to classify the images classifier function + # inputs: path + filename and model, returns model_label + # as classifier label + model_label = "" + + # TODO: 3b. BELOW REPLACE pass with CODE to process the model_label to + # convert all characters within model_label to lowercase + # letters and then remove whitespace characters from the ends + # of model_label. Be certain the resulting processed string + # is named model_label. + # + # Processes the results so they can be compared with pet image labels + # set labels to lowercase (lower) and stripping off whitespace(strip) + pass + + # defines truth as pet image label + truth = results_dic[key][0] + + # TODO: 3c. REPLACE pass BELOW with CODE that uses the extend list function + # to add the classifier label (model_label) and the value of + # 1 (where the value of 1 indicates a match between pet image + # label and the classifier label) to the results_dic dictionary + # for the key indicated by the variable key + # + # If the pet image label is found within the classifier label list of terms + # as an exact match to on of the terms in the list - then they are added to + # results_dic as an exact match(1) using extend list function + if truth in model_label: + pass + + # TODO: 3d. REPLACE pass BELOW with CODE that uses the extend list function + # to add the classifier label (model_label) and the value of + # 0 (where the value of 0 indicates NOT a match between the pet + # image label and the classifier label) to the results_dic + # dictionary for the key indicated by the variable key + # + # if not found then added to results dictionary as NOT a match(0) using + # the extend function + else: + pass diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/dognames.txt b/ai-programming-with-python/C02P8-pre-trained-image-classifier/dognames.txt new file mode 100644 index 0000000..1e4bd7c --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/dognames.txt @@ -0,0 +1,224 @@ +chihuahua +japanese spaniel +maltese dog, maltese terrier, maltese +pekinese, pekingese, peke +shih-tzu +blenheim spaniel +papillon +toy terrier +rhodesian ridgeback +afghan hound, afghan +basset, basset hound +beagle +bloodhound, sleuthhound +bluetick +black-and-tan coonhound +walker hound, walker foxhound +english foxhound +redbone +borzoi, russian wolfhound +irish wolfhound +italian greyhound +whippet +ibizan hound, ibizan podenco +norwegian elkhound, elkhound +otterhound, otter hound +saluki, gazelle hound +scottish deerhound, deerhound +weimaraner +staffordshire bullterrier, staffordshire bull terrier +american staffordshire terrier, staffordshire terrier, american pit bull terrier, pit bull terrier +bedlington terrier +border terrier +kerry blue terrier +irish terrier +norfolk terrier +norwich terrier +yorkshire terrier +wire-haired fox terrier +lakeland terrier +sealyham terrier, sealyham +airedale, airedale terrier +cairn, cairn terrier +australian terrier +dandie dinmont, dandie dinmont terrier +boston bull, boston terrier +miniature schnauzer +giant schnauzer +standard schnauzer, schnauzer +scotch terrier, scottish terrier, scottie +tibetan terrier, chrysanthemum dog +silky terrier, sydney silky +soft-coated wheaten terrier +west highland white terrier +lhasa, lhasa apso +flat-coated retriever +curly-coated retriever +golden retriever +labrador retriever +chesapeake bay retriever +german shorthaired pointer +vizsla, hungarian pointer +english setter +irish setter, red setter +gordon setter +brittany spaniel +clumber, clumber spaniel +english springer, english springer spaniel +welsh springer spaniel +cocker spaniel, english cocker spaniel, cocker +sussex spaniel +irish water spaniel +kuvasz +schipperke +groenendael +malinois +briard +kelpie +komondor +old english sheepdog, bobtail +shetland sheepdog, shetland sheep dog, shetland +collie +border collie +bouvier des flandres, bouviers des flandres +rottweiler +german shepherd, german shepherd dog, german police dog, alsatian +doberman, doberman pinscher +miniature pinscher +greater swiss mountain dog +bernese mountain dog +appenzeller +entlebucher +boxer +bull mastiff +tibetan mastiff +french bulldog +great dane +saint bernard, st bernard +eskimo dog, husky +malamute, malemute, alaskan malamute +siberian husky +dalmatian, coach dog, carriage dog +affenpinscher, monkey pinscher, monkey dog +basenji +pug, pug-dog +leonberg +newfoundland, newfoundland dog +great pyrenees +samoyed, samoyede +pomeranian +chow, chow chow +keeshond +brabancon griffon +pembroke, pembroke welsh corgi, corgi +cardigan, cardigan welsh corgi, corgi +toy poodle +miniature poodle +standard poodle, poodle +mexican hairless +affenpinscher +afghan hound +airedale terrier +akita +alaskan malamute +american eskimo dog +american foxhound +american staffordshire terrier +american water spaniel +anatolian shepherd dog +australian cattle dog +australian shepherd +basset hound +bearded collie +beauceron +belgian malinois +belgian sheepdog +belgian tervuren +bichon frise +black and tan coonhound +black russian terrier +bloodhound +bluetick coonhound +borzoi +boston terrier +bouvier des flandres +boykin spaniel +brittany +brussels griffon +bull terrier +bulldog +bullmastiff +cairn terrier +canaan dog +cane corso +cardigan welsh corgi +cavalier king charles spaniel +chinese crested +chinese shar-pei +chow chow +clumber spaniel +cocker spaniel +corgi +dachshund +dalmatian +dandie dinmont terrier +deerhound +doberman pinscher +dogue de bordeaux +english cocker spaniel +english springer spaniel +english toy spaniel +entlebucher mountain dog +field spaniel +finnish spitz +german pinscher +german shepherd dog +german wirehaired pointer +glen of imaal terrier +greyhound +havanese +ibizan hound +icelandic sheepdog +irish red and white setter +irish setter +japanese chin +leonberger +lhasa apso +lowchen +maltese +manchester terrier +mastiff +neapolitan mastiff +newfoundland +norwegian buhund +norwegian elkhound +norwegian lundehund +nova scotia duck tolling retriever +old english sheepdog +otterhound +parson russell terrier +pekingese +pembroke welsh corgi +petit basset griffon vendeen +pharaoh hound +plott +pointer +poodle +portuguese water dog +pug +saint bernard +saluki +samoyed +schnauzer +scottish terrier +sealyham terrier +shetland sheepdog +silky terrier +smooth fox terrier +staffordshire bull terrier +tibetan terrier +vizsla +walker hound +wirehaired pointing griffon +xoloitzcuintli +dog diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/get_input_args.py b/ai-programming-with-python/C02P8-pre-trained-image-classifier/get_input_args.py new file mode 100644 index 0000000..e74c961 --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/get_input_args.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# */AIPND-revision/intropyproject-classify-pet-images/get_input_args.py +# +# PROGRAMMER: +# DATE CREATED: +# REVISED DATE: +# PURPOSE: Create a function that retrieves the following 3 command line inputs +# from the user using the Argparse Python module. If the user fails to +# provide some or all of the 3 inputs, then the default values are +# used for the missing inputs. Command Line Arguments: +# 1. Image Folder as --dir with default value 'pet_images' +# 2. CNN Model Architecture as --arch with default value 'vgg' +# 3. Text File with Dog Names as --dogfile with default value 'dognames.txt' +# +## +# Imports python modules +import argparse + +# TODO 1: Define get_input_args function below please be certain to replace None +# in the return statement with parser.parse_args() parsed argument +# collection that you created with this function +# +def get_input_args(): + """ + Retrieves and parses the 3 command line arguments provided by the user when + they run the program from a terminal window. This function uses Python's + argparse module to created and defined these 3 command line arguments. If + the user fails to provide some or all of the 3 arguments, then the default + values are used for the missing arguments. + Command Line Arguments: + 1. Image Folder as --dir with default value 'pet_images' + 2. CNN Model Architecture as --arch with default value 'vgg' + 3. Text File with Dog Names as --dogfile with default value 'dognames.txt' + This function returns these arguments as an ArgumentParser object. + Parameters: + None - simply using argparse module to create & store command line arguments + Returns: + parse_args() -data structure that stores the command line arguments object + """ + # Create Parse using ArgumentParser + + # Create 3 command line arguments as mentioned above using add_argument() from ArguementParser method + + + # Replace None with parser.parse_args() parsed argument collection that + # you created with this function + return None diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/get_input_args_hints.py b/ai-programming-with-python/C02P8-pre-trained-image-classifier/get_input_args_hints.py new file mode 100644 index 0000000..5c2148a --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/get_input_args_hints.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# */AIPND-revision/intropyproject-classify-pet-images/get_input_args_hints.py +# +# PROGRAMMER: +# DATE CREATED: +# REVISED DATE: +# PURPOSE: This is a *hints* file to help guide students in creating the +# function that retrieves the following 3 command line inputs from +# the user using the Argparse Python module. If the user fails to +# provide some or all of the 3 inputs, then the default values are +# used for the missing inputs. Command Line Arguments: +# 1. Image Folder as --dir with default value 'pet_images' +# 2. CNN Model Architecture as --arch with default value 'vgg' +# 3. Text File with Dog Names as --dogfile with default value 'dognames.txt' +# +## +# Imports python modules +import argparse + +# TODO 1: EDIT and ADD code BELOW to do the following that's stated in the +# comments below that start with "TODO: 1" for the get_input_args function +# Please be certain to replace None in the return statement with +# parser.parse_args() parsed argument collection that you created with +# this function +# +def get_input_args(): + """ + Retrieves and parses the 3 command line arguments provided by the user when + they run the program from a terminal window. This function uses Python's + argparse module to created and defined these 3 command line arguments. If + the user fails to provide some or all of the 3 arguments, then the default + values are used for the missing arguments. + Command Line Arguments: + 1. Image Folder as --dir with default value 'pet_images' + 2. CNN Model Architecture as --arch with default value 'vgg' + 3. Text File with Dog Names as --dogfile with default value 'dognames.txt' + This function returns these arguments as an ArgumentParser object. + Parameters: + None - simply using argparse module to create & store command line arguments + Returns: + parse_args() -data structure that stores the command line arguments object + """ + # Creates parse + parser = argparse.ArgumentParser() + + # Creates 3 command line arguments args.dir for path to images files, + # args.arch which CNN model to use for classification, args.labels path to + # text file with names of dogs. + parser.add_argument('--dir', type=str, default='pet_images/', + help='path to folder of images') + # TODO: 1a. EDIT parse.add_argument statements BELOW to add type & help for: + # --arch - the CNN model architecture + # --dogfile - text file of names of dog breeds + parser.add_argument('--arch', default = 'vgg' ) + parser.add_argument('--dogfile', default = 'dognames.txt' ) + + # TODO: 1b. Replace None with parser.parse_args() parsed argument + # collection that you created with this function + return None diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/get_pet_labels.py b/ai-programming-with-python/C02P8-pre-trained-image-classifier/get_pet_labels.py new file mode 100644 index 0000000..8894216 --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/get_pet_labels.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# */AIPND-revision/intropyproject-classify-pet-images/get_pet_labels.py +# +# PROGRAMMER: +# DATE CREATED: +# REVISED DATE: +# PURPOSE: Create the function get_pet_labels that creates the pet labels from +# the image's filename. This function inputs: +# - The Image Folder as image_dir within get_pet_labels function and +# as in_arg.dir for the function call within the main function. +# This function creates and returns the results dictionary as results_dic +# within get_pet_labels function and as results within main. +# The results_dic dictionary has a 'key' that's the image filename and +# a 'value' that's a list. This list will contain the following item +# at index 0 : pet image label (string). +# +## +# Imports python modules +from os import listdir + +# TODO 2: Define get_pet_labels function below please be certain to replace None +# in the return statement with results_dic dictionary that you create +# with this function +# +def get_pet_labels(image_dir): + """ + Creates a dictionary of pet labels (results_dic) based upon the filenames + of the image files. These pet image labels are used to check the accuracy + of the labels that are returned by the classifier function, since the + filenames of the images contain the true identity of the pet in the image. + Be sure to format the pet labels so that they are in all lower case letters + and with leading and trailing whitespace characters stripped from them. + (ex. filename = 'Boston_terrier_02259.jpg' Pet label = 'boston terrier') + Parameters: + image_dir - The (full) path to the folder of images that are to be + classified by the classifier function (string) + Returns: + results_dic - Dictionary with 'key' as image filename and 'value' as a + List. The list contains for following item: + index 0 = pet image label (string) + """ + # Replace None with the results_dic dictionary that you created with this + # function + return None diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/get_pet_labels_hints.py b/ai-programming-with-python/C02P8-pre-trained-image-classifier/get_pet_labels_hints.py new file mode 100644 index 0000000..33d6046 --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/get_pet_labels_hints.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# */AIPND-revision/intropyproject-classify-pet-images/get_pet_labels_hints.py +# +# PROGRAMMER: +# DATE CREATED: +# REVISED DATE: +# PURPOSE: This is a *hints* file to help guide students in creating the +# function get_pet_labels that creates the pet labels from the image's +# filename. This function inputs: +# - The Image Folder as image_dir within get_pet_labels function and +# as in_arg.dir for the function call within the main function. +# This function creates and returns the results dictionary as results_dic +# within get_pet_labels function and as results within main. +# The results_dic dictionary has a 'key' that's the image filename and +# a 'value' that's a list. This list will contain the following item +# at index 0 : pet image label (string). +# +## +# Imports python modules +from os import listdir + +# TODO 2: EDIT and ADD code BELOW to do the following that's stated in the +# comments below that start with "TODO: 2" for the get_pet_labels function +# Please be certain to replace None in the return statement with +# results_dic dictionary that you create with this function +# +def get_pet_labels(image_dir): + """ + Creates a dictionary of pet labels (results_dic) based upon the filenames + of the image files. These pet image labels are used to check the accuracy + of the labels that are returned by the classifier function, since the + filenames of the images contain the true identity of the pet in the image. + Be sure to format the pet labels so that they are in all lower case letters + and with leading and trailing whitespace characters stripped from them. + (ex. filename = 'Boston_terrier_02259.jpg' Pet label = 'boston terrier') + Parameters: + image_dir - The (full) path to the folder of images that are to be + classified by the classifier function (string) + Returns: + results_dic - Dictionary with 'key' as image filename and 'value' as a + List. The list contains for following item: + index 0 = pet image label (string) + """ + # Creates list of files in directory + in_files = listdir(image_dir) + + # Processes each of the files to create a dictionary where the key + # is the filename and the value is the picture label (below). + + # Creates empty dictionary for the results (pet labels, etc.) + results_dic = dict() + + # Processes through each file in the directory, extracting only the words + # of the file that contain the pet image label + for idx in range(0, len(in_files), 1): + + # Skips file if starts with . (like .DS_Store of Mac OSX) because it + # isn't an pet image file + if in_files[idx][0] != ".": + + # Creates temporary label variable to hold pet label name extracted + pet_label = "" + + # TODO: 2a. BELOW REPLACE pass with CODE that will process each + # filename in the in_files list to extract the dog breed + # name from the filename. Recall that each filename can be + # accessed by in_files[idx]. Be certain to place the + # extracted dog breed name in the variable pet_label + # that's created as an empty string ABOVE + pass + + # If filename doesn't already exist in dictionary add it and it's + # pet label - otherwise print an error message because indicates + # duplicate files (filenames) + if in_files[idx] not in results_dic: + results_dic[in_files[idx]] = [pet_label] + + else: + print("** Warning: Duplicate files exist in directory:", + in_files[idx]) + + # TODO 2b. Replace None with the results_dic dictionary that you created + # with this function + return None diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/imagenet1000_clsid_to_human.txt b/ai-programming-with-python/C02P8-pre-trained-image-classifier/imagenet1000_clsid_to_human.txt new file mode 100644 index 0000000..4a6ca07 --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/imagenet1000_clsid_to_human.txt @@ -0,0 +1,1000 @@ +{0: 'tench, Tinca tinca', + 1: 'goldfish, Carassius auratus', + 2: 'great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias', + 3: 'tiger shark, Galeocerdo cuvieri', + 4: 'hammerhead, hammerhead shark', + 5: 'electric ray, crampfish, numbfish, torpedo', + 6: 'stingray', + 7: 'cock', + 8: 'hen', + 9: 'ostrich, Struthio camelus', + 10: 'brambling, Fringilla montifringilla', + 11: 'goldfinch, Carduelis carduelis', + 12: 'house finch, linnet, Carpodacus mexicanus', + 13: 'junco, snowbird', + 14: 'indigo bunting, indigo finch, indigo bird, Passerina cyanea', + 15: 'robin, American robin, Turdus migratorius', + 16: 'bulbul', + 17: 'jay', + 18: 'magpie', + 19: 'chickadee', + 20: 'water ouzel, dipper', + 21: 'kite', + 22: 'bald eagle, American eagle, Haliaeetus leucocephalus', + 23: 'vulture', + 24: 'great grey owl, great gray owl, Strix nebulosa', + 25: 'European fire salamander, Salamandra salamandra', + 26: 'common newt, Triturus vulgaris', + 27: 'eft', + 28: 'spotted salamander, Ambystoma maculatum', + 29: 'axolotl, mud puppy, Ambystoma mexicanum', + 30: 'bullfrog, Rana catesbeiana', + 31: 'tree frog, tree-frog', + 32: 'tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui', + 33: 'loggerhead, loggerhead turtle, Caretta caretta', + 34: 'leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea', + 35: 'mud turtle', + 36: 'terrapin', + 37: 'box turtle, box tortoise', + 38: 'banded gecko, gecko', + 39: 'common iguana, iguana, Iguana iguana', + 40: 'American chameleon, anole, Anolis carolinensis', + 41: 'whiptail, whiptail lizard', + 42: 'agama', + 43: 'frilled lizard, Chlamydosaurus kingi', + 44: 'alligator lizard', + 45: 'Gila monster, Heloderma suspectum', + 46: 'green lizard, Lacerta viridis', + 47: 'African chameleon, Chamaeleo chamaeleon', + 48: 'Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis', + 49: 'African crocodile, Nile crocodile, Crocodylus niloticus', + 50: 'American alligator, Alligator mississipiensis', + 51: 'triceratops', + 52: 'thunder snake, worm snake, Carphophis amoenus', + 53: 'ringneck snake, ring-necked snake, ring snake', + 54: 'hognose snake, puff adder, sand viper', + 55: 'green snake, grass snake', + 56: 'king snake, kingsnake', + 57: 'garter snake, grass snake', + 58: 'water snake', + 59: 'vine snake', + 60: 'night snake, Hypsiglena torquata', + 61: 'boa constrictor, Constrictor constrictor', + 62: 'rock python, rock snake, Python sebae', + 63: 'Indian cobra, Naja naja', + 64: 'green mamba', + 65: 'sea snake', + 66: 'horned viper, cerastes, sand viper, horned asp, Cerastes cornutus', + 67: 'diamondback, diamondback rattlesnake, Crotalus adamanteus', + 68: 'sidewinder, horned rattlesnake, Crotalus cerastes', + 69: 'trilobite', + 70: 'harvestman, daddy longlegs, Phalangium opilio', + 71: 'scorpion', + 72: 'black and gold garden spider, Argiope aurantia', + 73: 'barn spider, Araneus cavaticus', + 74: 'garden spider, Aranea diademata', + 75: 'black widow, Latrodectus mactans', + 76: 'tarantula', + 77: 'wolf spider, hunting spider', + 78: 'tick', + 79: 'centipede', + 80: 'black grouse', + 81: 'ptarmigan', + 82: 'ruffed grouse, partridge, Bonasa umbellus', + 83: 'prairie chicken, prairie grouse, prairie fowl', + 84: 'peacock', + 85: 'quail', + 86: 'partridge', + 87: 'African grey, African gray, Psittacus erithacus', + 88: 'macaw', + 89: 'sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita', + 90: 'lorikeet', + 91: 'coucal', + 92: 'bee eater', + 93: 'hornbill', + 94: 'hummingbird', + 95: 'jacamar', + 96: 'toucan', + 97: 'drake', + 98: 'red-breasted merganser, Mergus serrator', + 99: 'goose', + 100: 'black swan, Cygnus atratus', + 101: 'tusker', + 102: 'echidna, spiny anteater, anteater', + 103: 'platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus', + 104: 'wallaby, brush kangaroo', + 105: 'koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus', + 106: 'wombat', + 107: 'jellyfish', + 108: 'sea anemone, anemone', + 109: 'brain coral', + 110: 'flatworm, platyhelminth', + 111: 'nematode, nematode worm, roundworm', + 112: 'conch', + 113: 'snail', + 114: 'slug', + 115: 'sea slug, nudibranch', + 116: 'chiton, coat-of-mail shell, sea cradle, polyplacophore', + 117: 'chambered nautilus, pearly nautilus, nautilus', + 118: 'Dungeness crab, Cancer magister', + 119: 'rock crab, Cancer irroratus', + 120: 'fiddler crab', + 121: 'king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica', + 122: 'American lobster, Northern lobster, Maine lobster, Homarus americanus', + 123: 'spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish', + 124: 'crayfish, crawfish, crawdad, crawdaddy', + 125: 'hermit crab', + 126: 'isopod', + 127: 'white stork, Ciconia ciconia', + 128: 'black stork, Ciconia nigra', + 129: 'spoonbill', + 130: 'flamingo', + 131: 'little blue heron, Egretta caerulea', + 132: 'American egret, great white heron, Egretta albus', + 133: 'bittern', + 134: 'crane', + 135: 'limpkin, Aramus pictus', + 136: 'European gallinule, Porphyrio porphyrio', + 137: 'American coot, marsh hen, mud hen, water hen, Fulica americana', + 138: 'bustard', + 139: 'ruddy turnstone, Arenaria interpres', + 140: 'red-backed sandpiper, dunlin, Erolia alpina', + 141: 'redshank, Tringa totanus', + 142: 'dowitcher', + 143: 'oystercatcher, oyster catcher', + 144: 'pelican', + 145: 'king penguin, Aptenodytes patagonica', + 146: 'albatross, mollymawk', + 147: 'grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus', + 148: 'killer whale, killer, orca, grampus, sea wolf, Orcinus orca', + 149: 'dugong, Dugong dugon', + 150: 'sea lion', + 151: 'Chihuahua', + 152: 'Japanese spaniel', + 153: 'Maltese dog, Maltese terrier, Maltese', + 154: 'Pekinese, Pekingese, Peke', + 155: 'Shih-Tzu', + 156: 'Blenheim spaniel', + 157: 'papillon', + 158: 'toy terrier', + 159: 'Rhodesian ridgeback', + 160: 'Afghan hound, Afghan', + 161: 'basset, basset hound', + 162: 'beagle', + 163: 'bloodhound, sleuthhound', + 164: 'bluetick', + 165: 'black-and-tan coonhound', + 166: 'Walker hound, Walker foxhound', + 167: 'English foxhound', + 168: 'redbone', + 169: 'borzoi, Russian wolfhound', + 170: 'Irish wolfhound', + 171: 'Italian greyhound', + 172: 'whippet', + 173: 'Ibizan hound, Ibizan Podenco', + 174: 'Norwegian elkhound, elkhound', + 175: 'otterhound, otter hound', + 176: 'Saluki, gazelle hound', + 177: 'Scottish deerhound, deerhound', + 178: 'Weimaraner', + 179: 'Staffordshire bullterrier, Staffordshire bull terrier', + 180: 'American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier', + 181: 'Bedlington terrier', + 182: 'Border terrier', + 183: 'Kerry blue terrier', + 184: 'Irish terrier', + 185: 'Norfolk terrier', + 186: 'Norwich terrier', + 187: 'Yorkshire terrier', + 188: 'wire-haired fox terrier', + 189: 'Lakeland terrier', + 190: 'Sealyham terrier, Sealyham', + 191: 'Airedale, Airedale terrier', + 192: 'cairn, cairn terrier', + 193: 'Australian terrier', + 194: 'Dandie Dinmont, Dandie Dinmont terrier', + 195: 'Boston bull, Boston terrier', + 196: 'miniature schnauzer', + 197: 'giant schnauzer', + 198: 'standard schnauzer, schnauzer', + 199: 'Scotch terrier, Scottish terrier, Scottie', + 200: 'Tibetan terrier, chrysanthemum dog', + 201: 'silky terrier, Sydney silky', + 202: 'soft-coated wheaten terrier', + 203: 'West Highland white terrier', + 204: 'Lhasa, Lhasa apso', + 205: 'flat-coated retriever', + 206: 'curly-coated retriever', + 207: 'golden retriever', + 208: 'Labrador retriever', + 209: 'Chesapeake Bay retriever', + 210: 'German shorthaired pointer', + 211: 'vizsla, Hungarian pointer', + 212: 'English setter', + 213: 'Irish setter, red setter', + 214: 'Gordon setter', + 215: 'Brittany spaniel', + 216: 'clumber, clumber spaniel', + 217: 'English springer, English springer spaniel', + 218: 'Welsh springer spaniel', + 219: 'cocker spaniel, English cocker spaniel, cocker', + 220: 'Sussex spaniel', + 221: 'Irish water spaniel', + 222: 'kuvasz', + 223: 'schipperke', + 224: 'groenendael', + 225: 'malinois', + 226: 'briard', + 227: 'kelpie', + 228: 'komondor', + 229: 'Old English sheepdog, bobtail', + 230: 'Shetland sheepdog, Shetland sheep dog, Shetland', + 231: 'collie', + 232: 'Border collie', + 233: 'Bouvier des Flandres, Bouviers des Flandres', + 234: 'Rottweiler', + 235: 'German shepherd, German shepherd dog, German police dog, alsatian', + 236: 'Doberman, Doberman pinscher', + 237: 'miniature pinscher', + 238: 'Greater Swiss Mountain dog', + 239: 'Bernese mountain dog', + 240: 'Appenzeller', + 241: 'EntleBucher', + 242: 'boxer', + 243: 'bull mastiff', + 244: 'Tibetan mastiff', + 245: 'French bulldog', + 246: 'Great Dane', + 247: 'Saint Bernard, St Bernard', + 248: 'Eskimo dog, husky', + 249: 'malamute, malemute, Alaskan malamute', + 250: 'Siberian husky', + 251: 'dalmatian, coach dog, carriage dog', + 252: 'affenpinscher, monkey pinscher, monkey dog', + 253: 'basenji', + 254: 'pug, pug-dog', + 255: 'Leonberg', + 256: 'Newfoundland, Newfoundland dog', + 257: 'Great Pyrenees', + 258: 'Samoyed, Samoyede', + 259: 'Pomeranian', + 260: 'chow, chow chow', + 261: 'keeshond', + 262: 'Brabancon griffon', + 263: 'Pembroke, Pembroke Welsh corgi, corgi', + 264: 'Cardigan, Cardigan Welsh corgi, corgi', + 265: 'toy poodle', + 266: 'miniature poodle', + 267: 'standard poodle, poodle', + 268: 'Mexican hairless', + 269: 'timber wolf, grey wolf, gray wolf, Canis lupus', + 270: 'white wolf, Arctic wolf, Canis lupus tundrarum', + 271: 'red wolf, maned wolf, Canis rufus, Canis niger', + 272: 'coyote, prairie wolf, brush wolf, Canis latrans', + 273: 'dingo, warrigal, warragal, Canis dingo', + 274: 'dhole, Cuon alpinus', + 275: 'African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus', + 276: 'hyena, hyaena', + 277: 'red fox, Vulpes vulpes', + 278: 'kit fox, Vulpes macrotis', + 279: 'Arctic fox, white fox, Alopex lagopus', + 280: 'grey fox, gray fox, Urocyon cinereoargenteus', + 281: 'tabby, tabby cat, cat', + 282: 'tiger cat, cat', + 283: 'Persian cat, cat', + 284: 'Siamese cat, Siamese, cat', + 285: 'Egyptian cat, cat', + 286: 'cougar, puma, mountain lion, painter, panther, Felis concolor', + 287: 'lynx', + 288: 'leopard, Panthera pardus', + 289: 'snow leopard, ounce, Panthera uncia', + 290: 'jaguar, panther, Panthera onca, Felis onca', + 291: 'lion, king of beasts, Panthera leo', + 292: 'tiger, Panthera tigris', + 293: 'cheetah, chetah, Acinonyx jubatus', + 294: 'brown bear, bruin, Ursus arctos', + 295: 'American black bear, black bear, Ursus americanus, Euarctos americanus', + 296: 'ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus', + 297: 'sloth bear, Melursus ursinus, Ursus ursinus', + 298: 'mongoose', + 299: 'meerkat, mierkat', + 300: 'tiger beetle', + 301: 'ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle', + 302: 'ground beetle, carabid beetle', + 303: 'long-horned beetle, longicorn, longicorn beetle', + 304: 'leaf beetle, chrysomelid', + 305: 'dung beetle', + 306: 'rhinoceros beetle', + 307: 'weevil', + 308: 'fly', + 309: 'bee', + 310: 'ant, emmet, pismire', + 311: 'grasshopper, hopper', + 312: 'cricket', + 313: 'walking stick, walkingstick, stick insect', + 314: 'cockroach, roach', + 315: 'mantis, mantid', + 316: 'cicada, cicala', + 317: 'leafhopper', + 318: 'lacewing, lacewing fly', + 319: "dragonfly, darning needle, devil's darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk", + 320: 'damselfly', + 321: 'admiral', + 322: 'ringlet, ringlet butterfly', + 323: 'monarch, monarch butterfly, milkweed butterfly, Danaus plexippus', + 324: 'cabbage butterfly', + 325: 'sulphur butterfly, sulfur butterfly', + 326: 'lycaenid, lycaenid butterfly', + 327: 'starfish, sea star', + 328: 'sea urchin', + 329: 'sea cucumber, holothurian', + 330: 'wood rabbit, cottontail, cottontail rabbit, rabbit', + 331: 'hare', + 332: 'Angora, Angora rabbit', + 333: 'hamster', + 334: 'porcupine, hedgehog', + 335: 'fox squirrel, eastern fox squirrel, Sciurus niger', + 336: 'marmot', + 337: 'beaver', + 338: 'guinea pig, Cavia cobaya', + 339: 'sorrel', + 340: 'zebra', + 341: 'hog, pig, grunter, squealer, Sus scrofa', + 342: 'wild boar, boar, Sus scrofa', + 343: 'warthog', + 344: 'hippopotamus, hippo, river horse, Hippopotamus amphibius', + 345: 'ox', + 346: 'water buffalo, water ox, Asiatic buffalo, Bubalus bubalis', + 347: 'bison', + 348: 'ram, tup', + 349: 'bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis', + 350: 'ibex, Capra ibex', + 351: 'hartebeest', + 352: 'impala, Aepyceros melampus', + 353: 'gazelle', + 354: 'Arabian camel, dromedary, Camelus dromedarius', + 355: 'llama', + 356: 'weasel', + 357: 'mink', + 358: 'polecat, fitch, foulmart, foumart, Mustela putorius', + 359: 'black-footed ferret, ferret, Mustela nigripes', + 360: 'otter', + 361: 'skunk, polecat, wood pussy', + 362: 'badger', + 363: 'armadillo', + 364: 'three-toed sloth, ai, Bradypus tridactylus', + 365: 'orangutan, orang, orangutang, Pongo pygmaeus', + 366: 'gorilla, Gorilla gorilla', + 367: 'chimpanzee, chimp, Pan troglodytes', + 368: 'gibbon, Hylobates lar', + 369: 'siamang, Hylobates syndactylus, Symphalangus syndactylus', + 370: 'guenon, guenon monkey', + 371: 'patas, hussar monkey, Erythrocebus patas', + 372: 'baboon', + 373: 'macaque', + 374: 'langur', + 375: 'colobus, colobus monkey', + 376: 'proboscis monkey, Nasalis larvatus', + 377: 'marmoset', + 378: 'capuchin, ringtail, Cebus capucinus', + 379: 'howler monkey, howler', + 380: 'titi, titi monkey', + 381: 'spider monkey, Ateles geoffroyi', + 382: 'squirrel monkey, Saimiri sciureus', + 383: 'Madagascar cat, ring-tailed lemur, Lemur catta', + 384: 'indri, indris, Indri indri, Indri brevicaudatus', + 385: 'Indian elephant, Elephas maximus', + 386: 'African elephant, Loxodonta africana', + 387: 'lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens', + 388: 'giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca', + 389: 'barracouta, snoek', + 390: 'eel', + 391: 'coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch', + 392: 'rock beauty, Holocanthus tricolor', + 393: 'anemone fish', + 394: 'sturgeon', + 395: 'gar, garfish, garpike, billfish, Lepisosteus osseus', + 396: 'lionfish', + 397: 'puffer, pufferfish, blowfish, globefish', + 398: 'abacus', + 399: 'abaya', + 400: "academic gown, academic robe, judge's robe", + 401: 'accordion, piano accordion, squeeze box', + 402: 'acoustic guitar', + 403: 'aircraft carrier, carrier, flattop, attack aircraft carrier', + 404: 'airliner', + 405: 'airship, dirigible', + 406: 'altar', + 407: 'ambulance', + 408: 'amphibian, amphibious vehicle', + 409: 'analog clock', + 410: 'apiary, bee house', + 411: 'apron', + 412: 'ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin', + 413: 'assault rifle, assault gun', + 414: 'backpack, back pack, knapsack, packsack, rucksack, haversack', + 415: 'bakery, bakeshop, bakehouse', + 416: 'balance beam, beam', + 417: 'balloon', + 418: 'ballpoint, ballpoint pen, ballpen, Biro', + 419: 'Band Aid', + 420: 'banjo', + 421: 'bannister, banister, balustrade, balusters, handrail', + 422: 'barbell', + 423: 'barber chair', + 424: 'barbershop', + 425: 'barn', + 426: 'barometer', + 427: 'barrel, cask', + 428: 'barrow, garden cart, lawn cart, wheelbarrow', + 429: 'baseball', + 430: 'basketball', + 431: 'bassinet', + 432: 'bassoon', + 433: 'bathing cap, swimming cap', + 434: 'bath towel', + 435: 'bathtub, bathing tub, bath, tub', + 436: 'beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon', + 437: 'beacon, lighthouse, beacon light, pharos', + 438: 'beaker', + 439: 'bearskin, busby, shako', + 440: 'beer bottle', + 441: 'beer glass', + 442: 'bell cote, bell cot', + 443: 'bib', + 444: 'bicycle-built-for-two, tandem bicycle, tandem', + 445: 'bikini, two-piece', + 446: 'binder, ring-binder', + 447: 'binoculars, field glasses, opera glasses', + 448: 'birdhouse', + 449: 'boathouse', + 450: 'bobsled, bobsleigh, bob', + 451: 'bolo tie, bolo, bola tie, bola', + 452: 'bonnet, poke bonnet', + 453: 'bookcase', + 454: 'bookshop, bookstore, bookstall', + 455: 'bottlecap', + 456: 'bow', + 457: 'bow tie, bow-tie, bowtie', + 458: 'brass, memorial tablet, plaque', + 459: 'brassiere, bra, bandeau', + 460: 'breakwater, groin, groyne, mole, bulwark, seawall, jetty', + 461: 'breastplate, aegis, egis', + 462: 'broom', + 463: 'bucket, pail', + 464: 'buckle', + 465: 'bulletproof vest', + 466: 'bullet train, bullet', + 467: 'butcher shop, meat market', + 468: 'cab, hack, taxi, taxicab', + 469: 'caldron, cauldron', + 470: 'candle, taper, wax light', + 471: 'cannon', + 472: 'canoe', + 473: 'can opener, tin opener', + 474: 'cardigan', + 475: 'car mirror', + 476: 'carousel, carrousel, merry-go-round, roundabout, whirligig', + 477: "carpenter's kit, tool kit", + 478: 'carton', + 479: 'car wheel', + 480: 'cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM', + 481: 'cassette', + 482: 'cassette player', + 483: 'castle', + 484: 'catamaran', + 485: 'CD player', + 486: 'cello, violoncello', + 487: 'cellular telephone, cellular phone, cellphone, cell, mobile phone', + 488: 'chain', + 489: 'chainlink fence', + 490: 'chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour', + 491: 'chain saw, chainsaw', + 492: 'chest', + 493: 'chiffonier, commode', + 494: 'chime, bell, gong', + 495: 'china cabinet, china closet', + 496: 'Christmas stocking', + 497: 'church, church building', + 498: 'cinema, movie theater, movie theatre, movie house, picture palace', + 499: 'cleaver, meat cleaver, chopper', + 500: 'cliff dwelling', + 501: 'cloak', + 502: 'clog, geta, patten, sabot', + 503: 'cocktail shaker', + 504: 'coffee mug', + 505: 'coffeepot', + 506: 'coil, spiral, volute, whorl, helix', + 507: 'combination lock', + 508: 'computer keyboard, keypad', + 509: 'confectionery, confectionary, candy store', + 510: 'container ship, containership, container vessel', + 511: 'convertible', + 512: 'corkscrew, bottle screw', + 513: 'cornet, horn, trumpet, trump', + 514: 'cowboy boot', + 515: 'cowboy hat, ten-gallon hat', + 516: 'cradle', + 517: 'crane', + 518: 'crash helmet', + 519: 'crate', + 520: 'crib, cot', + 521: 'Crock Pot', + 522: 'croquet ball', + 523: 'crutch', + 524: 'cuirass', + 525: 'dam, dike, dyke', + 526: 'desk', + 527: 'desktop computer', + 528: 'dial telephone, dial phone', + 529: 'diaper, nappy, napkin', + 530: 'digital clock', + 531: 'digital watch', + 532: 'dining table, board', + 533: 'dishrag, dishcloth', + 534: 'dishwasher, dish washer, dishwashing machine', + 535: 'disk brake, disc brake', + 536: 'dock, dockage, docking facility', + 537: 'dogsled, dog sled, dog sleigh', + 538: 'dome', + 539: 'doormat, welcome mat', + 540: 'drilling platform, offshore rig', + 541: 'drum, membranophone, tympan', + 542: 'drumstick', + 543: 'dumbbell', + 544: 'Dutch oven', + 545: 'electric fan, blower', + 546: 'electric guitar', + 547: 'electric locomotive', + 548: 'entertainment center', + 549: 'envelope', + 550: 'espresso maker', + 551: 'face powder', + 552: 'feather boa, boa', + 553: 'file, file cabinet, filing cabinet', + 554: 'fireboat', + 555: 'fire engine, fire truck', + 556: 'fire screen, fireguard', + 557: 'flagpole, flagstaff', + 558: 'flute, transverse flute', + 559: 'folding chair', + 560: 'football helmet', + 561: 'forklift', + 562: 'fountain', + 563: 'fountain pen', + 564: 'four-poster', + 565: 'freight car', + 566: 'French horn, horn', + 567: 'frying pan, frypan, skillet', + 568: 'fur coat', + 569: 'garbage truck, dustcart', + 570: 'gasmask, respirator, gas helmet', + 571: 'gas pump, gasoline pump, petrol pump, island dispenser', + 572: 'goblet', + 573: 'go-kart', + 574: 'golf ball', + 575: 'golfcart, golf cart', + 576: 'gondola', + 577: 'gong, tam-tam', + 578: 'gown', + 579: 'grand piano, grand', + 580: 'greenhouse, nursery, glasshouse', + 581: 'grille, radiator grille', + 582: 'grocery store, grocery, food market, market', + 583: 'guillotine', + 584: 'hair slide', + 585: 'hair spray', + 586: 'half track', + 587: 'hammer', + 588: 'hamper', + 589: 'hand blower, blow dryer, blow drier, hair dryer, hair drier', + 590: 'hand-held computer, hand-held microcomputer', + 591: 'handkerchief, hankie, hanky, hankey', + 592: 'hard disc, hard disk, fixed disk', + 593: 'harmonica, mouth organ, harp, mouth harp', + 594: 'harp', + 595: 'harvester, reaper', + 596: 'hatchet', + 597: 'holster', + 598: 'home theater, home theatre', + 599: 'honeycomb', + 600: 'hook, claw', + 601: 'hoopskirt, crinoline', + 602: 'horizontal bar, high bar', + 603: 'horse cart, horse-cart', + 604: 'hourglass', + 605: 'iPod', + 606: 'iron, smoothing iron', + 607: "jack-o'-lantern", + 608: 'jean, blue jean, denim', + 609: 'jeep, landrover', + 610: 'jersey, T-shirt, tee shirt', + 611: 'jigsaw puzzle', + 612: 'jinrikisha, ricksha, rickshaw', + 613: 'joystick', + 614: 'kimono', + 615: 'knee pad', + 616: 'knot', + 617: 'lab coat, laboratory coat', + 618: 'ladle', + 619: 'lampshade, lamp shade', + 620: 'laptop, laptop computer', + 621: 'lawn mower, mower', + 622: 'lens cap, lens cover', + 623: 'letter opener, paper knife, paperknife', + 624: 'library', + 625: 'lifeboat', + 626: 'lighter, light, igniter, ignitor', + 627: 'limousine, limo', + 628: 'liner, ocean liner', + 629: 'lipstick, lip rouge', + 630: 'Loafer', + 631: 'lotion', + 632: 'loudspeaker, speaker, speaker unit, loudspeaker system, speaker system', + 633: "loupe, jeweler's loupe", + 634: 'lumbermill, sawmill', + 635: 'magnetic compass', + 636: 'mailbag, postbag', + 637: 'mailbox, letter box', + 638: 'maillot', + 639: 'maillot, tank suit', + 640: 'manhole cover', + 641: 'maraca', + 642: 'marimba, xylophone', + 643: 'mask', + 644: 'matchstick', + 645: 'maypole', + 646: 'maze, labyrinth', + 647: 'measuring cup', + 648: 'medicine chest, medicine cabinet', + 649: 'megalith, megalithic structure', + 650: 'microphone, mike', + 651: 'microwave, microwave oven', + 652: 'military uniform', + 653: 'milk can', + 654: 'minibus', + 655: 'miniskirt, mini', + 656: 'minivan', + 657: 'missile', + 658: 'mitten', + 659: 'mixing bowl', + 660: 'mobile home, manufactured home', + 661: 'Model T', + 662: 'modem', + 663: 'monastery', + 664: 'monitor', + 665: 'moped', + 666: 'mortar', + 667: 'mortarboard', + 668: 'mosque', + 669: 'mosquito net', + 670: 'motor scooter, scooter', + 671: 'mountain bike, all-terrain bike, off-roader', + 672: 'mountain tent', + 673: 'mouse, computer mouse', + 674: 'mousetrap', + 675: 'moving van', + 676: 'muzzle', + 677: 'nail', + 678: 'neck brace', + 679: 'necklace', + 680: 'nipple', + 681: 'notebook, notebook computer', + 682: 'obelisk', + 683: 'oboe, hautboy, hautbois', + 684: 'ocarina, sweet potato', + 685: 'odometer, hodometer, mileometer, milometer', + 686: 'oil filter', + 687: 'organ, pipe organ', + 688: 'oscilloscope, scope, cathode-ray oscilloscope, CRO', + 689: 'overskirt', + 690: 'oxcart', + 691: 'oxygen mask', + 692: 'packet', + 693: 'paddle, boat paddle', + 694: 'paddlewheel, paddle wheel', + 695: 'padlock', + 696: 'paintbrush', + 697: "pajama, pyjama, pj's, jammies", + 698: 'palace', + 699: 'panpipe, pandean pipe, syrinx', + 700: 'paper towel', + 701: 'parachute, chute', + 702: 'parallel bars, bars', + 703: 'park bench', + 704: 'parking meter', + 705: 'passenger car, coach, carriage', + 706: 'patio, terrace', + 707: 'pay-phone, pay-station', + 708: 'pedestal, plinth, footstall', + 709: 'pencil box, pencil case', + 710: 'pencil sharpener', + 711: 'perfume, essence', + 712: 'Petri dish', + 713: 'photocopier', + 714: 'pick, plectrum, plectron', + 715: 'pickelhaube', + 716: 'picket fence, paling', + 717: 'pickup, pickup truck', + 718: 'pier', + 719: 'piggy bank, penny bank', + 720: 'pill bottle', + 721: 'pillow', + 722: 'ping-pong ball', + 723: 'pinwheel', + 724: 'pirate, pirate ship', + 725: 'pitcher, ewer', + 726: "plane, carpenter's plane, woodworking plane", + 727: 'planetarium', + 728: 'plastic bag', + 729: 'plate rack', + 730: 'plow, plough', + 731: "plunger, plumber's helper", + 732: 'Polaroid camera, Polaroid Land camera', + 733: 'pole', + 734: 'police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria', + 735: 'poncho', + 736: 'pool table, billiard table, snooker table', + 737: 'pop bottle, soda bottle', + 738: 'pot, flowerpot', + 739: "potter's wheel", + 740: 'power drill', + 741: 'prayer rug, prayer mat', + 742: 'printer', + 743: 'prison, prison house', + 744: 'projectile, missile', + 745: 'projector', + 746: 'puck, hockey puck', + 747: 'punching bag, punch bag, punching ball, punchball', + 748: 'purse', + 749: 'quill, quill pen', + 750: 'quilt, comforter, comfort, puff', + 751: 'racer, race car, racing car', + 752: 'racket, racquet', + 753: 'radiator', + 754: 'radio, wireless', + 755: 'radio telescope, radio reflector', + 756: 'rain barrel', + 757: 'recreational vehicle, RV, R.V.', + 758: 'reel', + 759: 'reflex camera', + 760: 'refrigerator, icebox', + 761: 'remote control, remote', + 762: 'restaurant, eating house, eating place, eatery', + 763: 'revolver, six-gun, six-shooter', + 764: 'rifle', + 765: 'rocking chair, rocker', + 766: 'rotisserie', + 767: 'rubber eraser, rubber, pencil eraser', + 768: 'rugby ball', + 769: 'rule, ruler', + 770: 'running shoe', + 771: 'safe', + 772: 'safety pin', + 773: 'saltshaker, salt shaker', + 774: 'sandal', + 775: 'sarong', + 776: 'sax, saxophone', + 777: 'scabbard', + 778: 'scale, weighing machine', + 779: 'school bus', + 780: 'schooner', + 781: 'scoreboard', + 782: 'screen, CRT screen', + 783: 'screw', + 784: 'screwdriver', + 785: 'seat belt, seatbelt', + 786: 'sewing machine', + 787: 'shield, buckler', + 788: 'shoe shop, shoe-shop, shoe store', + 789: 'shoji', + 790: 'shopping basket', + 791: 'shopping cart', + 792: 'shovel', + 793: 'shower cap', + 794: 'shower curtain', + 795: 'ski', + 796: 'ski mask', + 797: 'sleeping bag', + 798: 'slide rule, slipstick', + 799: 'sliding door', + 800: 'slot, one-armed bandit', + 801: 'snorkel', + 802: 'snowmobile', + 803: 'snowplow, snowplough', + 804: 'soap dispenser', + 805: 'soccer ball', + 806: 'sock', + 807: 'solar dish, solar collector, solar furnace', + 808: 'sombrero', + 809: 'soup bowl', + 810: 'space bar', + 811: 'space heater', + 812: 'space shuttle', + 813: 'spatula', + 814: 'speedboat', + 815: "spider web, spider's web", + 816: 'spindle', + 817: 'sports car, sport car', + 818: 'spotlight, spot', + 819: 'stage', + 820: 'steam locomotive', + 821: 'steel arch bridge', + 822: 'steel drum', + 823: 'stethoscope', + 824: 'stole', + 825: 'stone wall', + 826: 'stopwatch, stop watch', + 827: 'stove', + 828: 'strainer', + 829: 'streetcar, tram, tramcar, trolley, trolley car', + 830: 'stretcher', + 831: 'studio couch, day bed', + 832: 'stupa, tope', + 833: 'submarine, pigboat, sub, U-boat', + 834: 'suit, suit of clothes', + 835: 'sundial', + 836: 'sunglass', + 837: 'sunglasses, dark glasses, shades', + 838: 'sunscreen, sunblock, sun blocker', + 839: 'suspension bridge', + 840: 'swab, swob, mop', + 841: 'sweatshirt', + 842: 'swimming trunks, bathing trunks', + 843: 'swing', + 844: 'switch, electric switch, electrical switch', + 845: 'syringe', + 846: 'table lamp', + 847: 'tank, army tank, armored combat vehicle, armoured combat vehicle', + 848: 'tape player', + 849: 'teapot', + 850: 'teddy, teddy bear', + 851: 'television, television system', + 852: 'tennis ball', + 853: 'thatch, thatched roof', + 854: 'theater curtain, theatre curtain', + 855: 'thimble', + 856: 'thresher, thrasher, threshing machine', + 857: 'throne', + 858: 'tile roof', + 859: 'toaster', + 860: 'tobacco shop, tobacconist shop, tobacconist', + 861: 'toilet seat', + 862: 'torch', + 863: 'totem pole', + 864: 'tow truck, tow car, wrecker', + 865: 'toyshop', + 866: 'tractor', + 867: 'trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi', + 868: 'tray', + 869: 'trench coat', + 870: 'tricycle, trike, velocipede', + 871: 'trimaran', + 872: 'tripod', + 873: 'triumphal arch', + 874: 'trolleybus, trolley coach, trackless trolley', + 875: 'trombone', + 876: 'tub, vat', + 877: 'turnstile', + 878: 'typewriter keyboard', + 879: 'umbrella', + 880: 'unicycle, monocycle', + 881: 'upright, upright piano', + 882: 'vacuum, vacuum cleaner', + 883: 'vase', + 884: 'vault', + 885: 'velvet', + 886: 'vending machine', + 887: 'vestment', + 888: 'viaduct', + 889: 'violin, fiddle', + 890: 'volleyball', + 891: 'waffle iron', + 892: 'wall clock', + 893: 'wallet, billfold, notecase, pocketbook', + 894: 'wardrobe, closet, press', + 895: 'warplane, military plane', + 896: 'washbasin, handbasin, washbowl, lavabo, wash-hand basin', + 897: 'washer, automatic washer, washing machine', + 898: 'water bottle', + 899: 'water jug', + 900: 'water tower', + 901: 'whiskey jug', + 902: 'whistle', + 903: 'wig', + 904: 'window screen', + 905: 'window shade', + 906: 'Windsor tie', + 907: 'wine bottle', + 908: 'wing', + 909: 'wok', + 910: 'wooden spoon', + 911: 'wool, woolen, woollen', + 912: 'worm fence, snake fence, snake-rail fence, Virginia fence', + 913: 'wreck', + 914: 'yawl', + 915: 'yurt', + 916: 'web site, website, internet site, site', + 917: 'comic book', + 918: 'crossword puzzle, crossword', + 919: 'street sign', + 920: 'traffic light, traffic signal, stoplight', + 921: 'book jacket, dust cover, dust jacket, dust wrapper', + 922: 'menu', + 923: 'plate', + 924: 'guacamole', + 925: 'consomme', + 926: 'hot pot, hotpot', + 927: 'trifle', + 928: 'ice cream, icecream', + 929: 'ice lolly, lolly, lollipop, popsicle', + 930: 'French loaf', + 931: 'bagel, beigel', + 932: 'pretzel', + 933: 'cheeseburger', + 934: 'hotdog, hot dog, red hot', + 935: 'mashed potato', + 936: 'head cabbage', + 937: 'broccoli', + 938: 'cauliflower', + 939: 'zucchini, courgette', + 940: 'spaghetti squash', + 941: 'acorn squash', + 942: 'butternut squash', + 943: 'cucumber, cuke', + 944: 'artichoke, globe artichoke', + 945: 'bell pepper', + 946: 'cardoon', + 947: 'mushroom', + 948: 'Granny Smith', + 949: 'strawberry', + 950: 'orange', + 951: 'lemon', + 952: 'fig', + 953: 'pineapple, ananas', + 954: 'banana', + 955: 'jackfruit, jak, jack', + 956: 'custard apple', + 957: 'pomegranate', + 958: 'hay', + 959: 'carbonara', + 960: 'chocolate sauce, chocolate syrup', + 961: 'dough', + 962: 'meat loaf, meatloaf', + 963: 'pizza, pizza pie', + 964: 'potpie', + 965: 'burrito', + 966: 'red wine', + 967: 'espresso', + 968: 'cup', + 969: 'eggnog', + 970: 'alp', + 971: 'bubble', + 972: 'cliff, drop, drop-off', + 973: 'coral reef', + 974: 'geyser', + 975: 'lakeside, lakeshore', + 976: 'promontory, headland, head, foreland', + 977: 'sandbar, sand bar', + 978: 'seashore, coast, seacoast, sea-coast', + 979: 'valley, vale', + 980: 'volcano', + 981: 'ballplayer, baseball player', + 982: 'groom, bridegroom', + 983: 'scuba diver', + 984: 'rapeseed', + 985: 'daisy', + 986: "yellow lady's slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum", + 987: 'corn', + 988: 'acorn', + 989: 'hip, rose hip, rosehip', + 990: 'buckeye, horse chestnut, conker', + 991: 'coral fungus', + 992: 'agaric', + 993: 'gyromitra', + 994: 'stinkhorn, carrion fungus', + 995: 'earthstar', + 996: 'hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa', + 997: 'bolete', + 998: 'ear, spike, capitulum', + 999: 'toilet tissue, toilet paper, bathroom tissue'} diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/main.py b/ai-programming-with-python/C02P8-pre-trained-image-classifier/main.py new file mode 100644 index 0000000..d0ec12b --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/main.py @@ -0,0 +1,6 @@ +def main(): + print("Hello from 08-pre-trained-image-classification!") + + +if __name__ == "__main__": + main() diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Basenji_00963.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Basenji_00963.jpg new file mode 100644 index 0000000..0968219 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Basenji_00963.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Basenji_00974.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Basenji_00974.jpg new file mode 100644 index 0000000..7e7c612 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Basenji_00974.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Basset_hound_01034.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Basset_hound_01034.jpg new file mode 100644 index 0000000..b81d151 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Basset_hound_01034.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Beagle_01125.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Beagle_01125.jpg new file mode 100644 index 0000000..4d4aef3 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Beagle_01125.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Beagle_01141.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Beagle_01141.jpg new file mode 100644 index 0000000..f6cf416 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Beagle_01141.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Beagle_01170.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Beagle_01170.jpg new file mode 100644 index 0000000..de34d75 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Beagle_01170.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Boston_terrier_02259.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Boston_terrier_02259.jpg new file mode 100644 index 0000000..0e4f57d Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Boston_terrier_02259.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Boston_terrier_02285.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Boston_terrier_02285.jpg new file mode 100644 index 0000000..88b875a Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Boston_terrier_02285.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Boston_terrier_02303.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Boston_terrier_02303.jpg new file mode 100644 index 0000000..0e2b8bc Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Boston_terrier_02303.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Boxer_02426.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Boxer_02426.jpg new file mode 100644 index 0000000..6e86314 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Boxer_02426.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Cocker_spaniel_03750.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Cocker_spaniel_03750.jpg new file mode 100644 index 0000000..ebad7b5 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Cocker_spaniel_03750.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Collie_03797.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Collie_03797.jpg new file mode 100644 index 0000000..1736c90 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Collie_03797.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Dalmatian_04017.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Dalmatian_04017.jpg new file mode 100644 index 0000000..f9d3213 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Dalmatian_04017.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Dalmatian_04037.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Dalmatian_04037.jpg new file mode 100644 index 0000000..5744b41 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Dalmatian_04037.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Dalmatian_04068.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Dalmatian_04068.jpg new file mode 100644 index 0000000..00c4eb3 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Dalmatian_04068.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/German_shepherd_dog_04890.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/German_shepherd_dog_04890.jpg new file mode 100644 index 0000000..70376cb Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/German_shepherd_dog_04890.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/German_shepherd_dog_04931.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/German_shepherd_dog_04931.jpg new file mode 100644 index 0000000..d58f655 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/German_shepherd_dog_04931.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/German_shorthaired_pointer_04986.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/German_shorthaired_pointer_04986.jpg new file mode 100644 index 0000000..9ddc179 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/German_shorthaired_pointer_04986.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Golden_retriever_05182.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Golden_retriever_05182.jpg new file mode 100644 index 0000000..38945b5 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Golden_retriever_05182.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Golden_retriever_05195.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Golden_retriever_05195.jpg new file mode 100644 index 0000000..bfb3043 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Golden_retriever_05195.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Golden_retriever_05223.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Golden_retriever_05223.jpg new file mode 100644 index 0000000..10ae800 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Golden_retriever_05223.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Golden_retriever_05257.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Golden_retriever_05257.jpg new file mode 100644 index 0000000..a7b9b4f Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Golden_retriever_05257.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Great_dane_05320.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Great_dane_05320.jpg new file mode 100644 index 0000000..1028269 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Great_dane_05320.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Great_pyrenees_05367.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Great_pyrenees_05367.jpg new file mode 100644 index 0000000..64cf191 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Great_pyrenees_05367.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Great_pyrenees_05435.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Great_pyrenees_05435.jpg new file mode 100644 index 0000000..2e11add Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Great_pyrenees_05435.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Miniature_schnauzer_06884.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Miniature_schnauzer_06884.jpg new file mode 100644 index 0000000..7b93f62 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Miniature_schnauzer_06884.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Poodle_07927.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Poodle_07927.jpg new file mode 100644 index 0000000..c16e0e3 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Poodle_07927.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Poodle_07956.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Poodle_07956.jpg new file mode 100644 index 0000000..fb58259 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Poodle_07956.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Rabbit_002.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Rabbit_002.jpg new file mode 100644 index 0000000..c30f03f Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Rabbit_002.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Saint_bernard_08010.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Saint_bernard_08010.jpg new file mode 100644 index 0000000..3f0cd56 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Saint_bernard_08010.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Saint_bernard_08036.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Saint_bernard_08036.jpg new file mode 100644 index 0000000..f0a327b Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/Saint_bernard_08036.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/cat_01.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/cat_01.jpg new file mode 100644 index 0000000..3ad27a1 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/cat_01.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/cat_02.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/cat_02.jpg new file mode 100644 index 0000000..150f6e7 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/cat_02.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/cat_07.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/cat_07.jpg new file mode 100644 index 0000000..7f94ef8 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/cat_07.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/fox_squirrel_01.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/fox_squirrel_01.jpg new file mode 100644 index 0000000..2f7cf08 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/fox_squirrel_01.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/gecko_02.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/gecko_02.jpg new file mode 100644 index 0000000..a5d52ef Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/gecko_02.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/gecko_80.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/gecko_80.jpg new file mode 100644 index 0000000..c6579b2 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/gecko_80.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/great_horned_owl_02.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/great_horned_owl_02.jpg new file mode 100644 index 0000000..a05442e Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/great_horned_owl_02.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/polar_bear_04.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/polar_bear_04.jpg new file mode 100644 index 0000000..902f892 Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/polar_bear_04.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/skunk_029.jpg b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/skunk_029.jpg new file mode 100644 index 0000000..02eda0a Binary files /dev/null and b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pet_images/skunk_029.jpg differ diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/print_functions_for_lab_checks.py b/ai-programming-with-python/C02P8-pre-trained-image-classifier/print_functions_for_lab_checks.py new file mode 100644 index 0000000..a002bb1 --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/print_functions_for_lab_checks.py @@ -0,0 +1,310 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# */AIPND/intropylab-classifying-images/print_functions_for_lab_checks.py +# +# PROGRAMMER: Jennifer S. +# DATE CREATED: 05/14/2018 +# REVISED DATE: <=(Date Revised - if any) +# PURPOSE: This set of functions can be used to check your code after programming +# each function. The top section of each part of the lab contains +# the section labeled 'Checking your code'. When directed within this +# section of the lab one can use these functions to more easily check +# your code. See the docstrings below each function for details on how +# to use the function within your code. +# +## + +# Functions below defined to help with "Checking your code", specifically +# running these functions with the appropriate input arguments within the +# main() funtion will print out what's needed for "Checking your code" +# +def check_command_line_arguments(in_arg): + """ + For Lab: Classifying Images - 7. Command Line Arguments + Prints each of the command line arguments passed in as parameter in_arg, + assumes you defined all three command line arguments as outlined in + '7. Command Line Arguments' + Parameters: + in_arg -data structure that stores the command line arguments object + Returns: + Nothing - just prints to console + """ + if in_arg is None: + print("* Doesn't Check the Command Line Arguments because 'get_input_args' hasn't been defined.") + else: + # prints command line agrs + print("Command Line Arguments:\n dir =", in_arg.dir, + "\n arch =", in_arg.arch, "\n dogfile =", in_arg.dogfile) + +def check_creating_pet_image_labels(results_dic): + """ For Lab: Classifying Images - 9/10. Creating Pet Image Labels + Prints first 10 key-value pairs and makes sure there are 40 key-value + pairs in your results_dic dictionary. Assumes you defined the results_dic + dictionary as was outlined in + '9/10. Creating Pet Image Labels' + Parameters: + results_dic - Dictionary with key as image filename and value as a List + (index)idx 0 = pet image label (string) + Returns: + Nothing - just prints to console + """ + if results_dic is None: + print("* Doesn't Check the Results Dictionary because 'get_pet_labels' hasn't been defined.") + else: + # Code to print 10 key-value pairs (or fewer if less than 10 images) + # & makes sure there are 40 pairs, one for each file in pet_images/ + stop_point = len(results_dic) + if stop_point > 10: + stop_point = 10 + print("\nPet Image Label Dictionary has", len(results_dic), + "key-value pairs.\nBelow are", stop_point, "of them:") + + # counter - to count how many labels have been printed + n = 0 + + # for loop to iterate through the dictionary + for key in results_dic: + + # prints only first 10 labels + if n < stop_point: + print("{:2d} key: {:>30} label: {:>26}".format(n+1, key, + results_dic[key][0]) ) + + # Increments counter + n += 1 + + # If past first 10 (or fewer) labels the breaks out of loop + else: + break + + +def check_classifying_images(results_dic): + """ For Lab: Classifying Images - 11/12. Classifying Images + Prints Pet Image Label and Classifier Label for ALL Matches followed by ALL + NOT matches. Next prints out the total number of images followed by how + many were matches and how many were not-matches to check all 40 images are + processed. Assumes you defined the results_dic dictionary as was + outlined in '11/12. Classifying Images' + Parameters: + results_dic - Dictionary with key as image filename and value as a List + (index)idx 0 = pet image label (string) + idx 1 = classifier label (string) + idx 2 = 1/0 (int) where 1 = match between pet image and + classifer labels and 0 = no match between labels + Returns: + Nothing - just prints to console + + """ + if results_dic is None: + print("* Doesn't Check the Results Dictionary because 'classify_images' hasn't been defined.") + elif len(results_dic[next(iter(results_dic))]) < 2: + print("* Doesn't Check the Results Dictionary because 'classify_images' hasn't been defined.") + else: + # Code for checking classify_images - + # Checks matches and not matches are classified correctly + # Checks that all 40 images are classified as a Match or Not-a Match + + # Sets counters for matches & NOT-matches + n_match = 0 + n_notmatch = 0 + + # Prints all Matches first + print("\n MATCH:") + for key in results_dic: + + # Prints only if a Match Index 2 == 1 + if results_dic[key][2] == 1: + + # Increments Match counter + n_match += 1 + print("\n{:>30}: \nReal: {:>26} Classifier: {:>30}".format(key, + results_dic[key][0], results_dic[key][1])) + + # Prints all NOT-Matches next + print("\n NOT A MATCH:") + for key in results_dic: + + # Prints only if NOT-a-Match Index 2 == 0 + if results_dic[key][2] == 0: + + # Increments Not-a-Match counter + n_notmatch += 1 + print("\n{:>30}: \nReal: {:>26} Classifier: {:>30}".format(key, + results_dic[key][0], results_dic[key][1])) + + # Prints Total Number of Images - expects 40 from pet_images folder + print("\n# Total Images",n_match + n_notmatch, "# Matches:",n_match , + "# NOT Matches:",n_notmatch) + + +def check_classifying_labels_as_dogs(results_dic): + """ For Lab: Classifying Images - 13. Classifying Labels as Dogs + Prints Pet Image Label, Classifier Label, whether Pet Label is-a-dog(1=Yes, + 0=No), and whether Classifier Label is-a-dog(1=Yes, 0=No) for ALL Matches + followed by ALL NOT matches. Next prints out the total number of images + followed by how many were matches and how many were not-matches to check + all 40 images are processed. Assumes you defined the results_dic dictionary + as was outlined in '13. Classifying Labels as Dogs' + Parameters: + results_dic - Dictionary with key as image filename and value as a List + (index)idx 0 = pet image label (string) + idx 1 = classifier label (string) + idx 2 = 1/0 (int) where 1 = match between pet image and + classifer labels and 0 = no match between labels + idx 3 = 1/0 (int) where 1 = pet image 'is-a' dog and + 0 = pet Image 'is-NOT-a' dog. + idx 4 = 1/0 (int) where 1 = Classifier classifies image + 'as-a' dog and 0 = Classifier classifies image + 'as-NOT-a' dog. + Returns: + Nothing - just prints to console + + """ + if results_dic is None: + print("* Doesn't Check the Results Dictionary because 'adjust_results4_isadog' hasn't been defined.") + elif len(results_dic[next(iter(results_dic))]) < 4 : + print("* Doesn't Check the Results Dictionary because 'adjust_results4_isadog' hasn't been defined.") + + else: + # Code for checking adjust_results4_isadog - + # Checks matches and not matches are classified correctly as "dogs" and + # "not-dogs" Checks that all 40 images are classified as a Match or Not-a + # Match + + # Sets counters for matches & NOT-matches + n_match = 0 + n_notmatch = 0 + + # Prints all Matches first + print("\n MATCH:") + for key in results_dic: + + # Prints only if a Match Index 2 == 1 + if results_dic[key][2] == 1: + + # Increments Match counter + n_match += 1 + print("\n{:>30}: \nReal: {:>26} Classifier: {:>30} \nPetLabelDog: {:1d} ClassLabelDog: {:1d}".format(key, + results_dic[key][0], results_dic[key][1], results_dic[key][3], + results_dic[key][4])) + + # Prints all NOT-Matches next + print("\n NOT A MATCH:") + for key in results_dic: + + # Prints only if NOT-a-Match Index 2 == 0 + if results_dic[key][2] == 0: + + # Increments Not-a-Match counter + n_notmatch += 1 + print("\n{:>30}: \nReal: {:>26} Classifier: {:>30} \nPetLabelDog: {:1d} ClassLabelDog: {:1d}".format(key, + results_dic[key][0], results_dic[key][1], results_dic[key][3], + results_dic[key][4])) + + # Prints Total Number of Images - expects 40 from pet_images folder + print("\n# Total Images",n_match + n_notmatch, "# Matches:",n_match , + "# NOT Matches:",n_notmatch) + + + +def check_calculating_results(results_dic, results_stats_dic): + """ For Lab: Classifying Images - 14. Calculating Results + Prints First statistics from the results stats dictionary (that was created + by the calculates_results_stats() function), then prints the same statistics + that were calculated in this function using the results dictionary. + Assumes you defined the results_stats dictionary and the statistics + as was outlined in '14. Calculating Results ' + Parameters: + results_dic - Dictionary with key as image filename and value as a List + (index)idx 0 = pet image label (string) + idx 1 = classifier label (string) + idx 2 = 1/0 (int) where 1 = match between pet image and + classifer labels and 0 = no match between labels + idx 3 = 1/0 (int) where 1 = pet image 'is-a' dog and + 0 = pet Image 'is-NOT-a' dog. + idx 4 = 1/0 (int) where 1 = Classifier classifies image + 'as-a' dog and 0 = Classifier classifies image + 'as-NOT-a' dog. + results_stats_dic - Dictionary that contains the results statistics (either + a percentage or a count) where the key is the statistic's + name (starting with 'pct' for percentage or 'n' for count) + and the value is the statistic's value + Returns: + Nothing - just prints to console + + """ + if results_stats_dic is None: + print("* Doesn't Check the Results Dictionary because 'calculates_results_stats' hasn't been defined.") + else: + # Code for checking results_stats_dic - + # Checks calculations of counts & percentages BY using results_dic + # to re-calculate the values and then compare to the values + # in results_stats_dic + + # Initialize counters to zero and number of images total + n_images = len(results_dic) + n_pet_dog = 0 + n_class_cdog = 0 + n_class_cnotd = 0 + n_match_breed = 0 + + # Interates through results_dic dictionary to recompute the statistics + # outside of the calculates_results_stats() function + for key in results_dic: + + # match (if dog then breed match) + if results_dic[key][2] == 1: + + # isa dog (pet label) & breed match + if results_dic[key][3] == 1: + n_pet_dog += 1 + + # isa dog (classifier label) & breed match + if results_dic[key][4] == 1: + n_class_cdog += 1 + n_match_breed += 1 + + # NOT dog (pet_label) + else: + + # NOT dog (classifier label) + if results_dic[key][4] == 0: + n_class_cnotd += 1 + + # NOT - match (not a breed match if a dog) + else: + + # NOT - match + # isa dog (pet label) + if results_dic[key][3] == 1: + n_pet_dog += 1 + + # isa dog (classifier label) + if results_dic[key][4] == 1: + n_class_cdog += 1 + + # NOT dog (pet_label) + else: + + # NOT dog (classifier label) + if results_dic[key][4] == 0: + n_class_cnotd += 1 + + + # calculates statistics based upon counters from above + n_pet_notd = n_images - n_pet_dog + pct_corr_dog = ( n_class_cdog / n_pet_dog )*100 + pct_corr_notdog = ( n_class_cnotd / n_pet_notd )*100 + pct_corr_breed = ( n_match_breed / n_pet_dog )*100 + + # prints calculated statistics + print("\n ** Statistics from calculates_results_stats() function:") + print("N Images: {:2d} N Dog Images: {:2d} N NotDog Images: {:2d} \nPct Corr dog: {:5.1f} Pct Corr NOTdog: {:5.1f} Pct Corr Breed: {:5.1f}".format( + results_stats_dic['n_images'], results_stats_dic['n_dogs_img'], + results_stats_dic['n_notdogs_img'], results_stats_dic['pct_correct_dogs'], + results_stats_dic['pct_correct_notdogs'], + results_stats_dic['pct_correct_breed'])) + print("\n ** Check Statistics - calculated from this function as a check:") + print("N Images: {:2d} N Dog Images: {:2d} N NotDog Images: {:2d} \nPct Corr dog: {:5.1f} Pct Corr NOTdog: {:5.1f} Pct Corr Breed: {:5.1f}".format( + n_images, n_pet_dog, n_pet_notd, pct_corr_dog, pct_corr_notdog, + pct_corr_breed)) diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/print_results.py b/ai-programming-with-python/C02P8-pre-trained-image-classifier/print_results.py new file mode 100644 index 0000000..bf44d69 --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/print_results.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# */AIPND-revision/intropyproject-classify-pet-images/print_results.py +# +# PROGRAMMER: +# DATE CREATED: +# REVISED DATE: +# PURPOSE: Create a function print_results that prints the results statistics +# from the results statistics dictionary (results_stats_dic). It +# should also allow the user to be able to print out cases of misclassified +# dogs and cases of misclassified breeds of dog using the Results +# dictionary (results_dic). +# This function inputs: +# -The results dictionary as results_dic within print_results +# function and results for the function call within main. +# -The results statistics dictionary as results_stats_dic within +# print_results function and results_stats for the function call within main. +# -The CNN model architecture as model wihtin print_results function +# and in_arg.arch for the function call within main. +# -Prints Incorrectly Classified Dogs as print_incorrect_dogs within +# print_results function and set as either boolean value True or +# False in the function call within main (defaults to False) +# -Prints Incorrectly Classified Breeds as print_incorrect_breed within +# print_results function and set as either boolean value True or +# False in the function call within main (defaults to False) +# This function does not output anything other than printing a summary +# of the final results. +## +# TODO 6: Define print_results function below, specifically replace the None +# below by the function definition of the print_results function. +# Notice that this function doesn't to return anything because it +# prints a summary of the results using results_dic and results_stats_dic +# +def print_results(results_dic, results_stats_dic, model, + print_incorrect_dogs = False, print_incorrect_breed = False): + """ + Prints summary results on the classification and then prints incorrectly + classified dogs and incorrectly classified dog breeds if user indicates + they want those printouts (use non-default values) + Parameters: + results_dic - Dictionary with key as image filename and value as a List + (index)idx 0 = pet image label (string) + idx 1 = classifier label (string) + idx 2 = 1/0 (int) where 1 = match between pet image and + classifer labels and 0 = no match between labels + idx 3 = 1/0 (int) where 1 = pet image 'is-a' dog and + 0 = pet Image 'is-NOT-a' dog. + idx 4 = 1/0 (int) where 1 = Classifier classifies image + 'as-a' dog and 0 = Classifier classifies image + 'as-NOT-a' dog. + results_stats_dic - Dictionary that contains the results statistics (either + a percentage or a count) where the key is the statistic's + name (starting with 'pct' for percentage or 'n' for count) + and the value is the statistic's value + model - Indicates which CNN model architecture will be used by the + classifier function to classify the pet images, + values must be either: resnet alexnet vgg (string) + print_incorrect_dogs - True prints incorrectly classified dog images and + False doesn't print anything(default) (bool) + print_incorrect_breed - True prints incorrectly classified dog breeds and + False doesn't print anything(default) (bool) + Returns: + None - simply printing results. + """ + None + diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/print_results_hints.py b/ai-programming-with-python/C02P8-pre-trained-image-classifier/print_results_hints.py new file mode 100644 index 0000000..adb95a0 --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/print_results_hints.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# */AIPND-revision/intropyproject-classify-pet-images/print_results_hints.py +# +# PROGRAMMER: +# DATE CREATED: +# REVISED DATE: +# PURPOSE: This is a *hints* file to help guide students in creating the +# function print_results that prints the results statistics from the +# results statistics dictionary (results_stats_dic). It should also +# allow the user to be able to print out cases of misclassified +# dogs and cases of misclassified breeds of dog using the Results +# dictionary (results_dic). +# This function inputs: +# -The results dictionary as results_dic within print_results +# function and results for the function call within main. +# -The results statistics dictionary as results_stats_dic within +# print_results function and results_stats for the function call within main. +# -The CNN model architecture as model wihtin print_results function +# and in_arg.arch for the function call within main. +# -Prints Incorrectly Classified Dogs as print_incorrect_dogs within +# print_results function and set as either boolean value True or +# False in the function call within main (defaults to False) +# -Prints Incorrectly Classified Breeds as print_incorrect_breed within +# print_results function and set as either boolean value True or +# False in the function call within main (defaults to False) +# This function does not output anything other than printing a summary +# of the final results. +## +# TODO 6: EDIT and ADD code BELOW to do the following that's stated in the +# comments below that start with "TODO: 6" for the print_results function. +# Specifically edit and add code below within the the print_results function. +# Notice that this function doesn't return anything because it prints +# a summary of the results using results_dic and results_stats_dic +# +def print_results(results_dic, results_stats_dic, model, + print_incorrect_dogs = False, print_incorrect_breed = False): + """ + Prints summary results on the classification and then prints incorrectly + classified dogs and incorrectly classified dog breeds if user indicates + they want those printouts (use non-default values) + Parameters: + results_dic - Dictionary with key as image filename and value as a List + (index)idx 0 = pet image label (string) + idx 1 = classifier label (string) + idx 2 = 1/0 (int) where 1 = match between pet image and + classifer labels and 0 = no match between labels + idx 3 = 1/0 (int) where 1 = pet image 'is-a' dog and + 0 = pet Image 'is-NOT-a' dog. + idx 4 = 1/0 (int) where 1 = Classifier classifies image + 'as-a' dog and 0 = Classifier classifies image + 'as-NOT-a' dog. + results_stats_dic - Dictionary that contains the results statistics (either + a percentage or a count) where the key is the statistic's + name (starting with 'pct' for percentage or 'n' for count) + and the value is the statistic's value + model - Indicates which CNN model architecture will be used by the + classifier function to classify the pet images, + values must be either: resnet alexnet vgg (string) + print_incorrect_dogs - True prints incorrectly classified dog images and + False doesn't print anything(default) (bool) + print_incorrect_breed - True prints incorrectly classified dog breeds and + False doesn't print anything(default) (bool) + Returns: + None - simply printing results. + """ + # Prints summary statistics over the run + print("\n\n*** Results Summary for CNN Model Architecture",model.upper(), + "***") + print("{:20}: {:3d}".format('N Images', results_stats_dic['n_images'])) + print("{:20}: {:3d}".format('N Dog Images', results_stats_dic['n_dogs_img'])) + + # TODO: 6a. REPLACE print("") with CODE that prints the text string + # 'N Not-Dog Images' and then the number of NOT-dog images + # that's accessed by key 'n_notdogs_img' using dictionary + # results_stats_dic + # + print("") + + + # Prints summary statistics (percentages) on Model Run + print(" ") + for key in results_stats_dic: + # TODO: 6b. REPLACE pass with CODE that prints out all the percentages + # in the results_stats_dic dictionary. Recall that all + # percentages in results_stats_dic have 'keys' that start with + # the letter p. You will need to write a conditional + # statement that determines if the key starts with the letter + # 'p' and then you want to use a print statement to print + # both the key and the value. Remember the value is accessed + # by results_stats_dic[key] + # + pass + + + # IF print_incorrect_dogs == True AND there were images incorrectly + # classified as dogs or vice versa - print out these cases + if (print_incorrect_dogs and + ( (results_stats_dic['n_correct_dogs'] + results_stats_dic['n_correct_notdogs']) + != results_stats_dic['n_images'] ) + ): + print("\nINCORRECT Dog/NOT Dog Assignments:") + + # process through results dict, printing incorrectly classified dogs + for key in results_dic: + + # TODO: 6c. REPLACE pass with CODE that prints out the pet label + # and the classifier label from results_dic dictionary + # ONLY when the classifier function (classifier label) + # misclassified dogs specifically: + # pet label is-a-dog and classifier label is-NOT-a-dog + # -OR- + # pet label is-NOT-a-dog and classifier label is-a-dog + # You will need to write a conditional statement that + # determines if the classifier function misclassified dogs + # See 'Adjusting Results Dictionary' section in + # 'Classifying Labels as Dogs' for details on the + # format of the results_dic dictionary. Remember the value + # is accessed by results_dic[key] and the value is a list + # so results_dic[key][idx] - where idx represents the + # index value of the list and can have values 0-4. + # + # Pet Image Label is a Dog - Classified as NOT-A-DOG -OR- + # Pet Image Label is NOT-a-Dog - Classified as a-DOG + pass + + # IF print_incorrect_breed == True AND there were dogs whose breeds + # were incorrectly classified - print out these cases + if (print_incorrect_breed and + (results_stats_dic['n_correct_dogs'] != results_stats_dic['n_correct_breed']) + ): + print("\nINCORRECT Dog Breed Assignment:") + + # process through results dict, printing incorrectly classified breeds + for key in results_dic: + + # Pet Image Label is-a-Dog, classified as-a-dog but is WRONG breed + if ( sum(results_dic[key][3:]) == 2 and + results_dic[key][2] == 0 ): + print("Real: {:>26} Classifier: {:>30}".format(results_dic[key][0], + results_dic[key][1])) diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/pyproject.toml b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pyproject.toml new file mode 100644 index 0000000..85148fc --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/pyproject.toml @@ -0,0 +1,10 @@ +[project] +name = "08-pre-trained-image-classification" +version = "0.1.0" +description = "Add your description here" +requires-python = ">=3.12" +dependencies = [ + "pillow>=12.0.0", + "torch>=2.9.1", + "torchvision>=0.24.1", +] diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/run_models_batch.sh b/ai-programming-with-python/C02P8-pre-trained-image-classifier/run_models_batch.sh new file mode 100644 index 0000000..f29b60b --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/run_models_batch.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# */AIPND-revision/intropyproject-classify-pet-images/run_models_batch.sh +# +# PROGRAMMER: Jennifer S. +# DATE CREATED: 02/08/2018 +# REVISED DATE: 02/27/2018 - +# PURPOSE: Runs all three models to test which provides 'best' solution. +# Please note output from each run has been piped into a text file. +# +# Usage: sh run_models_batch.sh -- will run program from commandline within Project Workspace +# +python check_images.py --dir pet_images/ --arch resnet --dogfile dognames.txt > resnet_pet-images.txt +python check_images.py --dir pet_images/ --arch alexnet --dogfile dognames.txt > alexnet_pet-images.txt +python check_images.py --dir pet_images/ --arch vgg --dogfile dognames.txt > vgg_pet-images.txt diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/run_models_batch_uploaded.sh b/ai-programming-with-python/C02P8-pre-trained-image-classifier/run_models_batch_uploaded.sh new file mode 100644 index 0000000..b39bdad --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/run_models_batch_uploaded.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# */AIPND-revision/intropyproject-classify-pet-images/run_models_batch_uploaded.sh +# +# PROGRAMMER: Jennifer S. +# DATE CREATED: 02/08/2018 +# REVISED DATE: 02/27/2018 - +# PURPOSE: Runs all three models to test which provides 'best' solution on the Uploaded Images. +# Please note output from each run has been piped into a text file. +# +# Usage: sh run_models_batch_uploaded.sh -- will run program from commandline within Project Workspace +# +python check_images.py --dir uploaded_images/ --arch resnet --dogfile dognames.txt > resnet_uploaded-images.txt +python check_images.py --dir uploaded_images/ --arch alexnet --dogfile dognames.txt > alexnet_uploaded-images.txt +python check_images.py --dir uploaded_images/ --arch vgg --dogfile dognames.txt > vgg_uploaded-images.txt diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/test_classifier.py b/ai-programming-with-python/C02P8-pre-trained-image-classifier/test_classifier.py new file mode 100644 index 0000000..e6eed4a --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/test_classifier.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# */AIPND/intropylab-classifying-images/test_classifier.py +# +# PROGRAMMER: Jennifer S. +# DATE CREATED: 01/30/2018 +# REVISED DATE: <=(Date Revised - if any) +# PURPOSE: To demonstrate the proper usage of the classifier() function that +# is defined in classifier.py This function uses CNN model +# architecture that has been pretrained on the ImageNet data to +# classify images. The only model architectures that this function +# will accept are: 'resnet', 'alexnet', and 'vgg'. See the example +# usage below. +# +# Usage: python test_classifier.py -- will run program from commandline + +# Imports classifier function for using pretrained CNN to classify images +from classifier import classifier + +# Defines a dog test image from pet_images folder +test_image="pet_images/Collie_03797.jpg" + +# Defines a model architecture to be used for classification +# NOTE: this function only works for model architectures: +# 'vgg', 'alexnet', 'resnet' +model = "vgg" + +# Demonstrates classifier() functions usage +# NOTE: image_classication is a text string - It contains mixed case(both lower +# and upper case letter) image labels that can be separated by commas when a +# label has more than one word that can describe it. +image_classification = classifier(test_image, model) + +# prints result from running classifier() function +print("\nResults from test_classifier.py\nImage:", test_image, "using model:", + model, "was classified as a:", image_classification) diff --git a/ai-programming-with-python/C02P8-pre-trained-image-classifier/uv.lock b/ai-programming-with-python/C02P8-pre-trained-image-classifier/uv.lock new file mode 100644 index 0000000..3c5d943 --- /dev/null +++ b/ai-programming-with-python/C02P8-pre-trained-image-classifier/uv.lock @@ -0,0 +1,523 @@ +version = 1 +revision = 3 +requires-python = ">=3.12" + +[[package]] +name = "08-pre-trained-image-classification" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "pillow" }, + { name = "torch" }, + { name = "torchvision" }, +] + +[package.metadata] +requires-dist = [ + { name = "pillow", specifier = ">=12.0.0" }, + { name = "torch", specifier = ">=2.9.1" }, + { name = "torchvision", specifier = ">=0.24.1" }, +] + +[[package]] +name = "filelock" +version = "3.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, +] + +[[package]] +name = "fsspec" +version = "2025.12.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/27/954057b0d1f53f086f681755207dda6de6c660ce133c829158e8e8fe7895/fsspec-2025.12.0.tar.gz", hash = "sha256:c505de011584597b1060ff778bb664c1bc022e87921b0e4f10cc9c44f9635973", size = 309748, upload-time = "2025-12-03T15:23:42.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/c7/b64cae5dba3a1b138d7123ec36bb5ccd39d39939f18454407e5468f4763f/fsspec-2025.12.0-py3-none-any.whl", hash = "sha256:8bf1fe301b7d8acfa6e8571e3b1c3d158f909666642431cc78a1b7b4dbc5ec5b", size = 201422, upload-time = "2025-12-03T15:23:41.434Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + +[[package]] +name = "mpmath" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, +] + +[[package]] +name = "networkx" +version = "3.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/fc/7b6fd4d22c8c4dc5704430140d8b3f520531d4fe7328b8f8d03f5a7950e8/networkx-3.6.tar.gz", hash = "sha256:285276002ad1f7f7da0f7b42f004bcba70d381e936559166363707fdad3d72ad", size = 2511464, upload-time = "2025-11-24T03:03:47.158Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/c7/d64168da60332c17d24c0d2f08bdf3987e8d1ae9d84b5bbd0eec2eb26a55/networkx-3.6-py3-none-any.whl", hash = "sha256:cdb395b105806062473d3be36458d8f1459a4e4b98e236a66c3a48996e07684f", size = 2063713, upload-time = "2025-11-24T03:03:45.21Z" }, +] + +[[package]] +name = "numpy" +version = "2.3.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/65/21b3bc86aac7b8f2862db1e808f1ea22b028e30a225a34a5ede9bf8678f2/numpy-2.3.5.tar.gz", hash = "sha256:784db1dcdab56bf0517743e746dfb0f885fc68d948aba86eeec2cba234bdf1c0", size = 20584950, upload-time = "2025-11-16T22:52:42.067Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/37/e669fe6cbb2b96c62f6bbedc6a81c0f3b7362f6a59230b23caa673a85721/numpy-2.3.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:74ae7b798248fe62021dbf3c914245ad45d1a6b0cb4a29ecb4b31d0bfbc4cc3e", size = 16733873, upload-time = "2025-11-16T22:49:49.84Z" }, + { url = "https://files.pythonhosted.org/packages/c5/65/df0db6c097892c9380851ab9e44b52d4f7ba576b833996e0080181c0c439/numpy-2.3.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee3888d9ff7c14604052b2ca5535a30216aa0a58e948cdd3eeb8d3415f638769", size = 12259838, upload-time = "2025-11-16T22:49:52.863Z" }, + { url = "https://files.pythonhosted.org/packages/5b/e1/1ee06e70eb2136797abe847d386e7c0e830b67ad1d43f364dd04fa50d338/numpy-2.3.5-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:612a95a17655e213502f60cfb9bf9408efdc9eb1d5f50535cc6eb365d11b42b5", size = 5088378, upload-time = "2025-11-16T22:49:55.055Z" }, + { url = "https://files.pythonhosted.org/packages/6d/9c/1ca85fb86708724275103b81ec4cf1ac1d08f465368acfc8da7ab545bdae/numpy-2.3.5-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3101e5177d114a593d79dd79658650fe28b5a0d8abeb8ce6f437c0e6df5be1a4", size = 6628559, upload-time = "2025-11-16T22:49:57.371Z" }, + { url = "https://files.pythonhosted.org/packages/74/78/fcd41e5a0ce4f3f7b003da85825acddae6d7ecb60cf25194741b036ca7d6/numpy-2.3.5-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b973c57ff8e184109db042c842423ff4f60446239bd585a5131cc47f06f789d", size = 14250702, upload-time = "2025-11-16T22:49:59.632Z" }, + { url = "https://files.pythonhosted.org/packages/b6/23/2a1b231b8ff672b4c450dac27164a8b2ca7d9b7144f9c02d2396518352eb/numpy-2.3.5-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0d8163f43acde9a73c2a33605353a4f1bc4798745a8b1d73183b28e5b435ae28", size = 16606086, upload-time = "2025-11-16T22:50:02.127Z" }, + { url = "https://files.pythonhosted.org/packages/a0/c5/5ad26fbfbe2012e190cc7d5003e4d874b88bb18861d0829edc140a713021/numpy-2.3.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:51c1e14eb1e154ebd80e860722f9e6ed6ec89714ad2db2d3aa33c31d7c12179b", size = 16025985, upload-time = "2025-11-16T22:50:04.536Z" }, + { url = "https://files.pythonhosted.org/packages/d2/fa/dd48e225c46c819288148d9d060b047fd2a6fb1eb37eae25112ee4cb4453/numpy-2.3.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b46b4ec24f7293f23adcd2d146960559aaf8020213de8ad1909dba6c013bf89c", size = 18542976, upload-time = "2025-11-16T22:50:07.557Z" }, + { url = "https://files.pythonhosted.org/packages/05/79/ccbd23a75862d95af03d28b5c6901a1b7da4803181513d52f3b86ed9446e/numpy-2.3.5-cp312-cp312-win32.whl", hash = "sha256:3997b5b3c9a771e157f9aae01dd579ee35ad7109be18db0e85dbdbe1de06e952", size = 6285274, upload-time = "2025-11-16T22:50:10.746Z" }, + { url = "https://files.pythonhosted.org/packages/2d/57/8aeaf160312f7f489dea47ab61e430b5cb051f59a98ae68b7133ce8fa06a/numpy-2.3.5-cp312-cp312-win_amd64.whl", hash = "sha256:86945f2ee6d10cdfd67bcb4069c1662dd711f7e2a4343db5cecec06b87cf31aa", size = 12782922, upload-time = "2025-11-16T22:50:12.811Z" }, + { url = "https://files.pythonhosted.org/packages/78/a6/aae5cc2ca78c45e64b9ef22f089141d661516856cf7c8a54ba434576900d/numpy-2.3.5-cp312-cp312-win_arm64.whl", hash = "sha256:f28620fe26bee16243be2b7b874da327312240a7cdc38b769a697578d2100013", size = 10194667, upload-time = "2025-11-16T22:50:16.16Z" }, + { url = "https://files.pythonhosted.org/packages/db/69/9cde09f36da4b5a505341180a3f2e6fadc352fd4d2b7096ce9778db83f1a/numpy-2.3.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d0f23b44f57077c1ede8c5f26b30f706498b4862d3ff0a7298b8411dd2f043ff", size = 16728251, upload-time = "2025-11-16T22:50:19.013Z" }, + { url = "https://files.pythonhosted.org/packages/79/fb/f505c95ceddd7027347b067689db71ca80bd5ecc926f913f1a23e65cf09b/numpy-2.3.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa5bc7c5d59d831d9773d1170acac7893ce3a5e130540605770ade83280e7188", size = 12254652, upload-time = "2025-11-16T22:50:21.487Z" }, + { url = "https://files.pythonhosted.org/packages/78/da/8c7738060ca9c31b30e9301ee0cf6c5ffdbf889d9593285a1cead337f9a5/numpy-2.3.5-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:ccc933afd4d20aad3c00bcef049cb40049f7f196e0397f1109dba6fed63267b0", size = 5083172, upload-time = "2025-11-16T22:50:24.562Z" }, + { url = "https://files.pythonhosted.org/packages/a4/b4/ee5bb2537fb9430fd2ef30a616c3672b991a4129bb1c7dcc42aa0abbe5d7/numpy-2.3.5-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:afaffc4393205524af9dfa400fa250143a6c3bc646c08c9f5e25a9f4b4d6a903", size = 6622990, upload-time = "2025-11-16T22:50:26.47Z" }, + { url = "https://files.pythonhosted.org/packages/95/03/dc0723a013c7d7c19de5ef29e932c3081df1c14ba582b8b86b5de9db7f0f/numpy-2.3.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c75442b2209b8470d6d5d8b1c25714270686f14c749028d2199c54e29f20b4d", size = 14248902, upload-time = "2025-11-16T22:50:28.861Z" }, + { url = "https://files.pythonhosted.org/packages/f5/10/ca162f45a102738958dcec8023062dad0cbc17d1ab99d68c4e4a6c45fb2b/numpy-2.3.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11e06aa0af8c0f05104d56450d6093ee639e15f24ecf62d417329d06e522e017", size = 16597430, upload-time = "2025-11-16T22:50:31.56Z" }, + { url = "https://files.pythonhosted.org/packages/2a/51/c1e29be863588db58175175f057286900b4b3327a1351e706d5e0f8dd679/numpy-2.3.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed89927b86296067b4f81f108a2271d8926467a8868e554eaf370fc27fa3ccaf", size = 16024551, upload-time = "2025-11-16T22:50:34.242Z" }, + { url = "https://files.pythonhosted.org/packages/83/68/8236589d4dbb87253d28259d04d9b814ec0ecce7cb1c7fed29729f4c3a78/numpy-2.3.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51c55fe3451421f3a6ef9a9c1439e82101c57a2c9eab9feb196a62b1a10b58ce", size = 18533275, upload-time = "2025-11-16T22:50:37.651Z" }, + { url = "https://files.pythonhosted.org/packages/40/56/2932d75b6f13465239e3b7b7e511be27f1b8161ca2510854f0b6e521c395/numpy-2.3.5-cp313-cp313-win32.whl", hash = "sha256:1978155dd49972084bd6ef388d66ab70f0c323ddee6f693d539376498720fb7e", size = 6277637, upload-time = "2025-11-16T22:50:40.11Z" }, + { url = "https://files.pythonhosted.org/packages/0c/88/e2eaa6cffb115b85ed7c7c87775cb8bcf0816816bc98ca8dbfa2ee33fe6e/numpy-2.3.5-cp313-cp313-win_amd64.whl", hash = "sha256:00dc4e846108a382c5869e77c6ed514394bdeb3403461d25a829711041217d5b", size = 12779090, upload-time = "2025-11-16T22:50:42.503Z" }, + { url = "https://files.pythonhosted.org/packages/8f/88/3f41e13a44ebd4034ee17baa384acac29ba6a4fcc2aca95f6f08ca0447d1/numpy-2.3.5-cp313-cp313-win_arm64.whl", hash = "sha256:0472f11f6ec23a74a906a00b48a4dcf3849209696dff7c189714511268d103ae", size = 10194710, upload-time = "2025-11-16T22:50:44.971Z" }, + { url = "https://files.pythonhosted.org/packages/13/cb/71744144e13389d577f867f745b7df2d8489463654a918eea2eeb166dfc9/numpy-2.3.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:414802f3b97f3c1eef41e530aaba3b3c1620649871d8cb38c6eaff034c2e16bd", size = 16827292, upload-time = "2025-11-16T22:50:47.715Z" }, + { url = "https://files.pythonhosted.org/packages/71/80/ba9dc6f2a4398e7f42b708a7fdc841bb638d353be255655498edbf9a15a8/numpy-2.3.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5ee6609ac3604fa7780e30a03e5e241a7956f8e2fcfe547d51e3afa5247ac47f", size = 12378897, upload-time = "2025-11-16T22:50:51.327Z" }, + { url = "https://files.pythonhosted.org/packages/2e/6d/db2151b9f64264bcceccd51741aa39b50150de9b602d98ecfe7e0c4bff39/numpy-2.3.5-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:86d835afea1eaa143012a2d7a3f45a3adce2d7adc8b4961f0b362214d800846a", size = 5207391, upload-time = "2025-11-16T22:50:54.542Z" }, + { url = "https://files.pythonhosted.org/packages/80/ae/429bacace5ccad48a14c4ae5332f6aa8ab9f69524193511d60ccdfdc65fa/numpy-2.3.5-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:30bc11310e8153ca664b14c5f1b73e94bd0503681fcf136a163de856f3a50139", size = 6721275, upload-time = "2025-11-16T22:50:56.794Z" }, + { url = "https://files.pythonhosted.org/packages/74/5b/1919abf32d8722646a38cd527bc3771eb229a32724ee6ba340ead9b92249/numpy-2.3.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1062fde1dcf469571705945b0f221b73928f34a20c904ffb45db101907c3454e", size = 14306855, upload-time = "2025-11-16T22:50:59.208Z" }, + { url = "https://files.pythonhosted.org/packages/a5/87/6831980559434973bebc30cd9c1f21e541a0f2b0c280d43d3afd909b66d0/numpy-2.3.5-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce581db493ea1a96c0556360ede6607496e8bf9b3a8efa66e06477267bc831e9", size = 16657359, upload-time = "2025-11-16T22:51:01.991Z" }, + { url = "https://files.pythonhosted.org/packages/dd/91/c797f544491ee99fd00495f12ebb7802c440c1915811d72ac5b4479a3356/numpy-2.3.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:cc8920d2ec5fa99875b670bb86ddeb21e295cb07aa331810d9e486e0b969d946", size = 16093374, upload-time = "2025-11-16T22:51:05.291Z" }, + { url = "https://files.pythonhosted.org/packages/74/a6/54da03253afcbe7a72785ec4da9c69fb7a17710141ff9ac5fcb2e32dbe64/numpy-2.3.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9ee2197ef8c4f0dfe405d835f3b6a14f5fee7782b5de51ba06fb65fc9b36e9f1", size = 18594587, upload-time = "2025-11-16T22:51:08.585Z" }, + { url = "https://files.pythonhosted.org/packages/80/e9/aff53abbdd41b0ecca94285f325aff42357c6b5abc482a3fcb4994290b18/numpy-2.3.5-cp313-cp313t-win32.whl", hash = "sha256:70b37199913c1bd300ff6e2693316c6f869c7ee16378faf10e4f5e3275b299c3", size = 6405940, upload-time = "2025-11-16T22:51:11.541Z" }, + { url = "https://files.pythonhosted.org/packages/d5/81/50613fec9d4de5480de18d4f8ef59ad7e344d497edbef3cfd80f24f98461/numpy-2.3.5-cp313-cp313t-win_amd64.whl", hash = "sha256:b501b5fa195cc9e24fe102f21ec0a44dffc231d2af79950b451e0d99cea02234", size = 12920341, upload-time = "2025-11-16T22:51:14.312Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ab/08fd63b9a74303947f34f0bd7c5903b9c5532c2d287bead5bdf4c556c486/numpy-2.3.5-cp313-cp313t-win_arm64.whl", hash = "sha256:a80afd79f45f3c4a7d341f13acbe058d1ca8ac017c165d3fa0d3de6bc1a079d7", size = 10262507, upload-time = "2025-11-16T22:51:16.846Z" }, + { url = "https://files.pythonhosted.org/packages/ba/97/1a914559c19e32d6b2e233cf9a6a114e67c856d35b1d6babca571a3e880f/numpy-2.3.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:bf06bc2af43fa8d32d30fae16ad965663e966b1a3202ed407b84c989c3221e82", size = 16735706, upload-time = "2025-11-16T22:51:19.558Z" }, + { url = "https://files.pythonhosted.org/packages/57/d4/51233b1c1b13ecd796311216ae417796b88b0616cfd8a33ae4536330748a/numpy-2.3.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:052e8c42e0c49d2575621c158934920524f6c5da05a1d3b9bab5d8e259e045f0", size = 12264507, upload-time = "2025-11-16T22:51:22.492Z" }, + { url = "https://files.pythonhosted.org/packages/45/98/2fe46c5c2675b8306d0b4a3ec3494273e93e1226a490f766e84298576956/numpy-2.3.5-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:1ed1ec893cff7040a02c8aa1c8611b94d395590d553f6b53629a4461dc7f7b63", size = 5093049, upload-time = "2025-11-16T22:51:25.171Z" }, + { url = "https://files.pythonhosted.org/packages/ce/0e/0698378989bb0ac5f1660c81c78ab1fe5476c1a521ca9ee9d0710ce54099/numpy-2.3.5-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:2dcd0808a421a482a080f89859a18beb0b3d1e905b81e617a188bd80422d62e9", size = 6626603, upload-time = "2025-11-16T22:51:27Z" }, + { url = "https://files.pythonhosted.org/packages/5e/a6/9ca0eecc489640615642a6cbc0ca9e10df70df38c4d43f5a928ff18d8827/numpy-2.3.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:727fd05b57df37dc0bcf1a27767a3d9a78cbbc92822445f32cc3436ba797337b", size = 14262696, upload-time = "2025-11-16T22:51:29.402Z" }, + { url = "https://files.pythonhosted.org/packages/c8/f6/07ec185b90ec9d7217a00eeeed7383b73d7e709dae2a9a021b051542a708/numpy-2.3.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fffe29a1ef00883599d1dc2c51aa2e5d80afe49523c261a74933df395c15c520", size = 16597350, upload-time = "2025-11-16T22:51:32.167Z" }, + { url = "https://files.pythonhosted.org/packages/75/37/164071d1dde6a1a84c9b8e5b414fa127981bad47adf3a6b7e23917e52190/numpy-2.3.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f7f0e05112916223d3f438f293abf0727e1181b5983f413dfa2fefc4098245c", size = 16040190, upload-time = "2025-11-16T22:51:35.403Z" }, + { url = "https://files.pythonhosted.org/packages/08/3c/f18b82a406b04859eb026d204e4e1773eb41c5be58410f41ffa511d114ae/numpy-2.3.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2e2eb32ddb9ccb817d620ac1d8dae7c3f641c1e5f55f531a33e8ab97960a75b8", size = 18536749, upload-time = "2025-11-16T22:51:39.698Z" }, + { url = "https://files.pythonhosted.org/packages/40/79/f82f572bf44cf0023a2fe8588768e23e1592585020d638999f15158609e1/numpy-2.3.5-cp314-cp314-win32.whl", hash = "sha256:66f85ce62c70b843bab1fb14a05d5737741e74e28c7b8b5a064de10142fad248", size = 6335432, upload-time = "2025-11-16T22:51:42.476Z" }, + { url = "https://files.pythonhosted.org/packages/a3/2e/235b4d96619931192c91660805e5e49242389742a7a82c27665021db690c/numpy-2.3.5-cp314-cp314-win_amd64.whl", hash = "sha256:e6a0bc88393d65807d751a614207b7129a310ca4fe76a74e5c7da5fa5671417e", size = 12919388, upload-time = "2025-11-16T22:51:45.275Z" }, + { url = "https://files.pythonhosted.org/packages/07/2b/29fd75ce45d22a39c61aad74f3d718e7ab67ccf839ca8b60866054eb15f8/numpy-2.3.5-cp314-cp314-win_arm64.whl", hash = "sha256:aeffcab3d4b43712bb7a60b65f6044d444e75e563ff6180af8f98dd4b905dfd2", size = 10476651, upload-time = "2025-11-16T22:51:47.749Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/f6a721234ebd4d87084cfa68d081bcba2f5cfe1974f7de4e0e8b9b2a2ba1/numpy-2.3.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17531366a2e3a9e30762c000f2c43a9aaa05728712e25c11ce1dbe700c53ad41", size = 16834503, upload-time = "2025-11-16T22:51:50.443Z" }, + { url = "https://files.pythonhosted.org/packages/5c/1c/baf7ffdc3af9c356e1c135e57ab7cf8d247931b9554f55c467efe2c69eff/numpy-2.3.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d21644de1b609825ede2f48be98dfde4656aefc713654eeee280e37cadc4e0ad", size = 12381612, upload-time = "2025-11-16T22:51:53.609Z" }, + { url = "https://files.pythonhosted.org/packages/74/91/f7f0295151407ddc9ba34e699013c32c3c91944f9b35fcf9281163dc1468/numpy-2.3.5-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:c804e3a5aba5460c73955c955bdbd5c08c354954e9270a2c1565f62e866bdc39", size = 5210042, upload-time = "2025-11-16T22:51:56.213Z" }, + { url = "https://files.pythonhosted.org/packages/2e/3b/78aebf345104ec50dd50a4d06ddeb46a9ff5261c33bcc58b1c4f12f85ec2/numpy-2.3.5-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:cc0a57f895b96ec78969c34f682c602bf8da1a0270b09bc65673df2e7638ec20", size = 6724502, upload-time = "2025-11-16T22:51:58.584Z" }, + { url = "https://files.pythonhosted.org/packages/02/c6/7c34b528740512e57ef1b7c8337ab0b4f0bddf34c723b8996c675bc2bc91/numpy-2.3.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:900218e456384ea676e24ea6a0417f030a3b07306d29d7ad843957b40a9d8d52", size = 14308962, upload-time = "2025-11-16T22:52:01.698Z" }, + { url = "https://files.pythonhosted.org/packages/80/35/09d433c5262bc32d725bafc619e095b6a6651caf94027a03da624146f655/numpy-2.3.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:09a1bea522b25109bf8e6f3027bd810f7c1085c64a0c7ce050c1676ad0ba010b", size = 16655054, upload-time = "2025-11-16T22:52:04.267Z" }, + { url = "https://files.pythonhosted.org/packages/7a/ab/6a7b259703c09a88804fa2430b43d6457b692378f6b74b356155283566ac/numpy-2.3.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04822c00b5fd0323c8166d66c701dc31b7fbd252c100acd708c48f763968d6a3", size = 16091613, upload-time = "2025-11-16T22:52:08.651Z" }, + { url = "https://files.pythonhosted.org/packages/c2/88/330da2071e8771e60d1038166ff9d73f29da37b01ec3eb43cb1427464e10/numpy-2.3.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d6889ec4ec662a1a37eb4b4fb26b6100841804dac55bd9df579e326cdc146227", size = 18591147, upload-time = "2025-11-16T22:52:11.453Z" }, + { url = "https://files.pythonhosted.org/packages/51/41/851c4b4082402d9ea860c3626db5d5df47164a712cb23b54be028b184c1c/numpy-2.3.5-cp314-cp314t-win32.whl", hash = "sha256:93eebbcf1aafdf7e2ddd44c2923e2672e1010bddc014138b229e49725b4d6be5", size = 6479806, upload-time = "2025-11-16T22:52:14.641Z" }, + { url = "https://files.pythonhosted.org/packages/90/30/d48bde1dfd93332fa557cff1972fbc039e055a52021fbef4c2c4b1eefd17/numpy-2.3.5-cp314-cp314t-win_amd64.whl", hash = "sha256:c8a9958e88b65c3b27e22ca2a076311636850b612d6bbfb76e8d156aacde2aaf", size = 13105760, upload-time = "2025-11-16T22:52:17.975Z" }, + { url = "https://files.pythonhosted.org/packages/2d/fd/4b5eb0b3e888d86aee4d198c23acec7d214baaf17ea93c1adec94c9518b9/numpy-2.3.5-cp314-cp314t-win_arm64.whl", hash = "sha256:6203fdf9f3dc5bdaed7319ad8698e685c7a3be10819f41d32a0723e611733b42", size = 10545459, upload-time = "2025-11-16T22:52:20.55Z" }, +] + +[[package]] +name = "nvidia-cublas-cu12" +version = "12.8.4.1" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/61/e24b560ab2e2eaeb3c839129175fb330dfcfc29e5203196e5541a4c44682/nvidia_cublas_cu12-12.8.4.1-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:8ac4e771d5a348c551b2a426eda6193c19aa630236b418086020df5ba9667142", size = 594346921, upload-time = "2025-03-07T01:44:31.254Z" }, +] + +[[package]] +name = "nvidia-cuda-cupti-cu12" +version = "12.8.90" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/02/2adcaa145158bf1a8295d83591d22e4103dbfd821bcaf6f3f53151ca4ffa/nvidia_cuda_cupti_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ea0cb07ebda26bb9b29ba82cda34849e73c166c18162d3913575b0c9db9a6182", size = 10248621, upload-time = "2025-03-07T01:40:21.213Z" }, +] + +[[package]] +name = "nvidia-cuda-nvrtc-cu12" +version = "12.8.93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/6b/32f747947df2da6994e999492ab306a903659555dddc0fbdeb9d71f75e52/nvidia_cuda_nvrtc_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:a7756528852ef889772a84c6cd89d41dfa74667e24cca16bb31f8f061e3e9994", size = 88040029, upload-time = "2025-03-07T01:42:13.562Z" }, +] + +[[package]] +name = "nvidia-cuda-runtime-cu12" +version = "12.8.90" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/9b/a997b638fcd068ad6e4d53b8551a7d30fe8b404d6f1804abf1df69838932/nvidia_cuda_runtime_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adade8dcbd0edf427b7204d480d6066d33902cab2a4707dcfc48a2d0fd44ab90", size = 954765, upload-time = "2025-03-07T01:40:01.615Z" }, +] + +[[package]] +name = "nvidia-cudnn-cu12" +version = "9.10.2.21" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas-cu12" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/51/e123d997aa098c61d029f76663dedbfb9bc8dcf8c60cbd6adbe42f76d049/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:949452be657fa16687d0930933f032835951ef0892b37d2d53824d1a84dc97a8", size = 706758467, upload-time = "2025-06-06T21:54:08.597Z" }, +] + +[[package]] +name = "nvidia-cufft-cu12" +version = "11.3.3.83" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink-cu12" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d2dd21ec0b88cf61b62e6b43564355e5222e4a3fb394cac0db101f2dd0d4f74", size = 193118695, upload-time = "2025-03-07T01:45:27.821Z" }, +] + +[[package]] +name = "nvidia-cufile-cu12" +version = "1.13.1.3" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/fe/1bcba1dfbfb8d01be8d93f07bfc502c93fa23afa6fd5ab3fc7c1df71038a/nvidia_cufile_cu12-1.13.1.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1d069003be650e131b21c932ec3d8969c1715379251f8d23a1860554b1cb24fc", size = 1197834, upload-time = "2025-03-07T01:45:50.723Z" }, +] + +[[package]] +name = "nvidia-curand-cu12" +version = "10.3.9.90" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/aa/6584b56dc84ebe9cf93226a5cde4d99080c8e90ab40f0c27bda7a0f29aa1/nvidia_curand_cu12-10.3.9.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:b32331d4f4df5d6eefa0554c565b626c7216f87a06a4f56fab27c3b68a830ec9", size = 63619976, upload-time = "2025-03-07T01:46:23.323Z" }, +] + +[[package]] +name = "nvidia-cusolver-cu12" +version = "11.7.3.90" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas-cu12" }, + { name = "nvidia-cusparse-cu12" }, + { name = "nvidia-nvjitlink-cu12" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/48/9a13d2975803e8cf2777d5ed57b87a0b6ca2cc795f9a4f59796a910bfb80/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4376c11ad263152bd50ea295c05370360776f8c3427b30991df774f9fb26c450", size = 267506905, upload-time = "2025-03-07T01:47:16.273Z" }, +] + +[[package]] +name = "nvidia-cusparse-cu12" +version = "12.5.8.93" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink-cu12" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/f5/e1854cb2f2bcd4280c44736c93550cc300ff4b8c95ebe370d0aa7d2b473d/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ec05d76bbbd8b61b06a80e1eaf8cf4959c3d4ce8e711b65ebd0443bb0ebb13b", size = 288216466, upload-time = "2025-03-07T01:48:13.779Z" }, +] + +[[package]] +name = "nvidia-cusparselt-cu12" +version = "0.7.1" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/79/12978b96bd44274fe38b5dde5cfb660b1d114f70a65ef962bcbbed99b549/nvidia_cusparselt_cu12-0.7.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f1bb701d6b930d5a7cea44c19ceb973311500847f81b634d802b7b539dc55623", size = 287193691, upload-time = "2025-02-26T00:15:44.104Z" }, +] + +[[package]] +name = "nvidia-nccl-cu12" +version = "2.27.5" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6e/89/f7a07dc961b60645dbbf42e80f2bc85ade7feb9a491b11a1e973aa00071f/nvidia_nccl_cu12-2.27.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ad730cf15cb5d25fe849c6e6ca9eb5b76db16a80f13f425ac68d8e2e55624457", size = 322348229, upload-time = "2025-06-26T04:11:28.385Z" }, +] + +[[package]] +name = "nvidia-nvjitlink-cu12" +version = "12.8.93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f6/74/86a07f1d0f42998ca31312f998bd3b9a7eff7f52378f4f270c8679c77fb9/nvidia_nvjitlink_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:81ff63371a7ebd6e6451970684f916be2eab07321b73c9d244dc2b4da7f73b88", size = 39254836, upload-time = "2025-03-07T01:49:55.661Z" }, +] + +[[package]] +name = "nvidia-nvshmem-cu12" +version = "3.3.20" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/6c/99acb2f9eb85c29fc6f3a7ac4dccfd992e22666dd08a642b303311326a97/nvidia_nvshmem_cu12-3.3.20-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d00f26d3f9b2e3c3065be895e3059d6479ea5c638a3f38c9fec49b1b9dd7c1e5", size = 124657145, upload-time = "2025-08-04T20:25:19.995Z" }, +] + +[[package]] +name = "nvidia-nvtx-cu12" +version = "12.8.90" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/eb/86626c1bbc2edb86323022371c39aa48df6fd8b0a1647bc274577f72e90b/nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b17e2001cc0d751a5bc2c6ec6d26ad95913324a4adb86788c944f8ce9ba441f", size = 89954, upload-time = "2025-03-07T01:42:44.131Z" }, +] + +[[package]] +name = "pillow" +version = "12.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/cace85a1b0c9775a9f8f5d5423c8261c858760e2466c79b2dd184638b056/pillow-12.0.0.tar.gz", hash = "sha256:87d4f8125c9988bfbed67af47dd7a953e2fc7b0cc1e7800ec6d2080d490bb353", size = 47008828, upload-time = "2025-10-15T18:24:14.008Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/90/4fcce2c22caf044e660a198d740e7fbc14395619e3cb1abad12192c0826c/pillow-12.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:53561a4ddc36facb432fae7a9d8afbfaf94795414f5cdc5fc52f28c1dca90371", size = 5249377, upload-time = "2025-10-15T18:22:05.993Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e0/ed960067543d080691d47d6938ebccbf3976a931c9567ab2fbfab983a5dd/pillow-12.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:71db6b4c1653045dacc1585c1b0d184004f0d7e694c7b34ac165ca70c0838082", size = 4650343, upload-time = "2025-10-15T18:22:07.718Z" }, + { url = "https://files.pythonhosted.org/packages/e7/a1/f81fdeddcb99c044bf7d6faa47e12850f13cee0849537a7d27eeab5534d4/pillow-12.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2fa5f0b6716fc88f11380b88b31fe591a06c6315e955c096c35715788b339e3f", size = 6232981, upload-time = "2025-10-15T18:22:09.287Z" }, + { url = "https://files.pythonhosted.org/packages/88/e1/9098d3ce341a8750b55b0e00c03f1630d6178f38ac191c81c97a3b047b44/pillow-12.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:82240051c6ca513c616f7f9da06e871f61bfd7805f566275841af15015b8f98d", size = 8041399, upload-time = "2025-10-15T18:22:10.872Z" }, + { url = "https://files.pythonhosted.org/packages/a7/62/a22e8d3b602ae8cc01446d0c57a54e982737f44b6f2e1e019a925143771d/pillow-12.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55f818bd74fe2f11d4d7cbc65880a843c4075e0ac7226bc1a23261dbea531953", size = 6347740, upload-time = "2025-10-15T18:22:12.769Z" }, + { url = "https://files.pythonhosted.org/packages/4f/87/424511bdcd02c8d7acf9f65caa09f291a519b16bd83c3fb3374b3d4ae951/pillow-12.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b87843e225e74576437fd5b6a4c2205d422754f84a06942cfaf1dc32243e45a8", size = 7040201, upload-time = "2025-10-15T18:22:14.813Z" }, + { url = "https://files.pythonhosted.org/packages/dc/4d/435c8ac688c54d11755aedfdd9f29c9eeddf68d150fe42d1d3dbd2365149/pillow-12.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c607c90ba67533e1b2355b821fef6764d1dd2cbe26b8c1005ae84f7aea25ff79", size = 6462334, upload-time = "2025-10-15T18:22:16.375Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f2/ad34167a8059a59b8ad10bc5c72d4d9b35acc6b7c0877af8ac885b5f2044/pillow-12.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:21f241bdd5080a15bc86d3466a9f6074a9c2c2b314100dd896ac81ee6db2f1ba", size = 7134162, upload-time = "2025-10-15T18:22:17.996Z" }, + { url = "https://files.pythonhosted.org/packages/0c/b1/a7391df6adacf0a5c2cf6ac1cf1fcc1369e7d439d28f637a847f8803beb3/pillow-12.0.0-cp312-cp312-win32.whl", hash = "sha256:dd333073e0cacdc3089525c7df7d39b211bcdf31fc2824e49d01c6b6187b07d0", size = 6298769, upload-time = "2025-10-15T18:22:19.923Z" }, + { url = "https://files.pythonhosted.org/packages/a2/0b/d87733741526541c909bbf159e338dcace4f982daac6e5a8d6be225ca32d/pillow-12.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9fe611163f6303d1619bbcb653540a4d60f9e55e622d60a3108be0d5b441017a", size = 7001107, upload-time = "2025-10-15T18:22:21.644Z" }, + { url = "https://files.pythonhosted.org/packages/bc/96/aaa61ce33cc98421fb6088af2a03be4157b1e7e0e87087c888e2370a7f45/pillow-12.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:7dfb439562f234f7d57b1ac6bc8fe7f838a4bd49c79230e0f6a1da93e82f1fad", size = 2436012, upload-time = "2025-10-15T18:22:23.621Z" }, + { url = "https://files.pythonhosted.org/packages/62/f2/de993bb2d21b33a98d031ecf6a978e4b61da207bef02f7b43093774c480d/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0869154a2d0546545cde61d1789a6524319fc1897d9ee31218eae7a60ccc5643", size = 4045493, upload-time = "2025-10-15T18:22:25.758Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b6/bc8d0c4c9f6f111a783d045310945deb769b806d7574764234ffd50bc5ea/pillow-12.0.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a7921c5a6d31b3d756ec980f2f47c0cfdbce0fc48c22a39347a895f41f4a6ea4", size = 4120461, upload-time = "2025-10-15T18:22:27.286Z" }, + { url = "https://files.pythonhosted.org/packages/5d/57/d60d343709366a353dc56adb4ee1e7d8a2cc34e3fbc22905f4167cfec119/pillow-12.0.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:1ee80a59f6ce048ae13cda1abf7fbd2a34ab9ee7d401c46be3ca685d1999a399", size = 3576912, upload-time = "2025-10-15T18:22:28.751Z" }, + { url = "https://files.pythonhosted.org/packages/a4/a4/a0a31467e3f83b94d37568294b01d22b43ae3c5d85f2811769b9c66389dd/pillow-12.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c50f36a62a22d350c96e49ad02d0da41dbd17ddc2e29750dbdba4323f85eb4a5", size = 5249132, upload-time = "2025-10-15T18:22:30.641Z" }, + { url = "https://files.pythonhosted.org/packages/83/06/48eab21dd561de2914242711434c0c0eb992ed08ff3f6107a5f44527f5e9/pillow-12.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5193fde9a5f23c331ea26d0cf171fbf67e3f247585f50c08b3e205c7aeb4589b", size = 4650099, upload-time = "2025-10-15T18:22:32.73Z" }, + { url = "https://files.pythonhosted.org/packages/fc/bd/69ed99fd46a8dba7c1887156d3572fe4484e3f031405fcc5a92e31c04035/pillow-12.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bde737cff1a975b70652b62d626f7785e0480918dece11e8fef3c0cf057351c3", size = 6230808, upload-time = "2025-10-15T18:22:34.337Z" }, + { url = "https://files.pythonhosted.org/packages/ea/94/8fad659bcdbf86ed70099cb60ae40be6acca434bbc8c4c0d4ef356d7e0de/pillow-12.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a6597ff2b61d121172f5844b53f21467f7082f5fb385a9a29c01414463f93b07", size = 8037804, upload-time = "2025-10-15T18:22:36.402Z" }, + { url = "https://files.pythonhosted.org/packages/20/39/c685d05c06deecfd4e2d1950e9a908aa2ca8bc4e6c3b12d93b9cafbd7837/pillow-12.0.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b817e7035ea7f6b942c13aa03bb554fc44fea70838ea21f8eb31c638326584e", size = 6345553, upload-time = "2025-10-15T18:22:38.066Z" }, + { url = "https://files.pythonhosted.org/packages/38/57/755dbd06530a27a5ed74f8cb0a7a44a21722ebf318edbe67ddbd7fb28f88/pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344", size = 7037729, upload-time = "2025-10-15T18:22:39.769Z" }, + { url = "https://files.pythonhosted.org/packages/ca/b6/7e94f4c41d238615674d06ed677c14883103dce1c52e4af16f000338cfd7/pillow-12.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e51b71417049ad6ab14c49608b4a24d8fb3fe605e5dfabfe523b58064dc3d27", size = 6459789, upload-time = "2025-10-15T18:22:41.437Z" }, + { url = "https://files.pythonhosted.org/packages/9c/14/4448bb0b5e0f22dd865290536d20ec8a23b64e2d04280b89139f09a36bb6/pillow-12.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d120c38a42c234dc9a8c5de7ceaaf899cf33561956acb4941653f8bdc657aa79", size = 7130917, upload-time = "2025-10-15T18:22:43.152Z" }, + { url = "https://files.pythonhosted.org/packages/dd/ca/16c6926cc1c015845745d5c16c9358e24282f1e588237a4c36d2b30f182f/pillow-12.0.0-cp313-cp313-win32.whl", hash = "sha256:4cc6b3b2efff105c6a1656cfe59da4fdde2cda9af1c5e0b58529b24525d0a098", size = 6302391, upload-time = "2025-10-15T18:22:44.753Z" }, + { url = "https://files.pythonhosted.org/packages/6d/2a/dd43dcfd6dae9b6a49ee28a8eedb98c7d5ff2de94a5d834565164667b97b/pillow-12.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:4cf7fed4b4580601c4345ceb5d4cbf5a980d030fd5ad07c4d2ec589f95f09905", size = 7007477, upload-time = "2025-10-15T18:22:46.838Z" }, + { url = "https://files.pythonhosted.org/packages/77/f0/72ea067f4b5ae5ead653053212af05ce3705807906ba3f3e8f58ddf617e6/pillow-12.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:9f0b04c6b8584c2c193babcccc908b38ed29524b29dd464bc8801bf10d746a3a", size = 2435918, upload-time = "2025-10-15T18:22:48.399Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5e/9046b423735c21f0487ea6cb5b10f89ea8f8dfbe32576fe052b5ba9d4e5b/pillow-12.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7fa22993bac7b77b78cae22bad1e2a987ddf0d9015c63358032f84a53f23cdc3", size = 5251406, upload-time = "2025-10-15T18:22:49.905Z" }, + { url = "https://files.pythonhosted.org/packages/12/66/982ceebcdb13c97270ef7a56c3969635b4ee7cd45227fa707c94719229c5/pillow-12.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f135c702ac42262573fe9714dfe99c944b4ba307af5eb507abef1667e2cbbced", size = 4653218, upload-time = "2025-10-15T18:22:51.587Z" }, + { url = "https://files.pythonhosted.org/packages/16/b3/81e625524688c31859450119bf12674619429cab3119eec0e30a7a1029cb/pillow-12.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c85de1136429c524e55cfa4e033b4a7940ac5c8ee4d9401cc2d1bf48154bbc7b", size = 6266564, upload-time = "2025-10-15T18:22:53.215Z" }, + { url = "https://files.pythonhosted.org/packages/98/59/dfb38f2a41240d2408096e1a76c671d0a105a4a8471b1871c6902719450c/pillow-12.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38df9b4bfd3db902c9c2bd369bcacaf9d935b2fff73709429d95cc41554f7b3d", size = 8069260, upload-time = "2025-10-15T18:22:54.933Z" }, + { url = "https://files.pythonhosted.org/packages/dc/3d/378dbea5cd1874b94c312425ca77b0f47776c78e0df2df751b820c8c1d6c/pillow-12.0.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d87ef5795da03d742bf49439f9ca4d027cde49c82c5371ba52464aee266699a", size = 6379248, upload-time = "2025-10-15T18:22:56.605Z" }, + { url = "https://files.pythonhosted.org/packages/84/b0/d525ef47d71590f1621510327acec75ae58c721dc071b17d8d652ca494d8/pillow-12.0.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aff9e4d82d082ff9513bdd6acd4f5bd359f5b2c870907d2b0a9c5e10d40c88fe", size = 7066043, upload-time = "2025-10-15T18:22:58.53Z" }, + { url = "https://files.pythonhosted.org/packages/61/2c/aced60e9cf9d0cde341d54bf7932c9ffc33ddb4a1595798b3a5150c7ec4e/pillow-12.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8d8ca2b210ada074d57fcee40c30446c9562e542fc46aedc19baf758a93532ee", size = 6490915, upload-time = "2025-10-15T18:23:00.582Z" }, + { url = "https://files.pythonhosted.org/packages/ef/26/69dcb9b91f4e59f8f34b2332a4a0a951b44f547c4ed39d3e4dcfcff48f89/pillow-12.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:99a7f72fb6249302aa62245680754862a44179b545ded638cf1fef59befb57ef", size = 7157998, upload-time = "2025-10-15T18:23:02.627Z" }, + { url = "https://files.pythonhosted.org/packages/61/2b/726235842220ca95fa441ddf55dd2382b52ab5b8d9c0596fe6b3f23dafe8/pillow-12.0.0-cp313-cp313t-win32.whl", hash = "sha256:4078242472387600b2ce8d93ade8899c12bf33fa89e55ec89fe126e9d6d5d9e9", size = 6306201, upload-time = "2025-10-15T18:23:04.709Z" }, + { url = "https://files.pythonhosted.org/packages/c0/3d/2afaf4e840b2df71344ababf2f8edd75a705ce500e5dc1e7227808312ae1/pillow-12.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2c54c1a783d6d60595d3514f0efe9b37c8808746a66920315bfd34a938d7994b", size = 7013165, upload-time = "2025-10-15T18:23:06.46Z" }, + { url = "https://files.pythonhosted.org/packages/6f/75/3fa09aa5cf6ed04bee3fa575798ddf1ce0bace8edb47249c798077a81f7f/pillow-12.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:26d9f7d2b604cd23aba3e9faf795787456ac25634d82cd060556998e39c6fa47", size = 2437834, upload-time = "2025-10-15T18:23:08.194Z" }, + { url = "https://files.pythonhosted.org/packages/54/2a/9a8c6ba2c2c07b71bec92cf63e03370ca5e5f5c5b119b742bcc0cde3f9c5/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:beeae3f27f62308f1ddbcfb0690bf44b10732f2ef43758f169d5e9303165d3f9", size = 4045531, upload-time = "2025-10-15T18:23:10.121Z" }, + { url = "https://files.pythonhosted.org/packages/84/54/836fdbf1bfb3d66a59f0189ff0b9f5f666cee09c6188309300df04ad71fa/pillow-12.0.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:d4827615da15cd59784ce39d3388275ec093ae3ee8d7f0c089b76fa87af756c2", size = 4120554, upload-time = "2025-10-15T18:23:12.14Z" }, + { url = "https://files.pythonhosted.org/packages/0d/cd/16aec9f0da4793e98e6b54778a5fbce4f375c6646fe662e80600b8797379/pillow-12.0.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:3e42edad50b6909089750e65c91aa09aaf1e0a71310d383f11321b27c224ed8a", size = 3576812, upload-time = "2025-10-15T18:23:13.962Z" }, + { url = "https://files.pythonhosted.org/packages/f6/b7/13957fda356dc46339298b351cae0d327704986337c3c69bb54628c88155/pillow-12.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e5d8efac84c9afcb40914ab49ba063d94f5dbdf5066db4482c66a992f47a3a3b", size = 5252689, upload-time = "2025-10-15T18:23:15.562Z" }, + { url = "https://files.pythonhosted.org/packages/fc/f5/eae31a306341d8f331f43edb2e9122c7661b975433de5e447939ae61c5da/pillow-12.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:266cd5f2b63ff316d5a1bba46268e603c9caf5606d44f38c2873c380950576ad", size = 4650186, upload-time = "2025-10-15T18:23:17.379Z" }, + { url = "https://files.pythonhosted.org/packages/86/62/2a88339aa40c4c77e79108facbd307d6091e2c0eb5b8d3cf4977cfca2fe6/pillow-12.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58eea5ebe51504057dd95c5b77d21700b77615ab0243d8152793dc00eb4faf01", size = 6230308, upload-time = "2025-10-15T18:23:18.971Z" }, + { url = "https://files.pythonhosted.org/packages/c7/33/5425a8992bcb32d1cb9fa3dd39a89e613d09a22f2c8083b7bf43c455f760/pillow-12.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f13711b1a5ba512d647a0e4ba79280d3a9a045aaf7e0cc6fbe96b91d4cdf6b0c", size = 8039222, upload-time = "2025-10-15T18:23:20.909Z" }, + { url = "https://files.pythonhosted.org/packages/d8/61/3f5d3b35c5728f37953d3eec5b5f3e77111949523bd2dd7f31a851e50690/pillow-12.0.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6846bd2d116ff42cba6b646edf5bf61d37e5cbd256425fa089fee4ff5c07a99e", size = 6346657, upload-time = "2025-10-15T18:23:23.077Z" }, + { url = "https://files.pythonhosted.org/packages/3a/be/ee90a3d79271227e0f0a33c453531efd6ed14b2e708596ba5dd9be948da3/pillow-12.0.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c98fa880d695de164b4135a52fd2e9cd7b7c90a9d8ac5e9e443a24a95ef9248e", size = 7038482, upload-time = "2025-10-15T18:23:25.005Z" }, + { url = "https://files.pythonhosted.org/packages/44/34/a16b6a4d1ad727de390e9bd9f19f5f669e079e5826ec0f329010ddea492f/pillow-12.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa3ed2a29a9e9d2d488b4da81dcb54720ac3104a20bf0bd273f1e4648aff5af9", size = 6461416, upload-time = "2025-10-15T18:23:27.009Z" }, + { url = "https://files.pythonhosted.org/packages/b6/39/1aa5850d2ade7d7ba9f54e4e4c17077244ff7a2d9e25998c38a29749eb3f/pillow-12.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d034140032870024e6b9892c692fe2968493790dd57208b2c37e3fb35f6df3ab", size = 7131584, upload-time = "2025-10-15T18:23:29.752Z" }, + { url = "https://files.pythonhosted.org/packages/bf/db/4fae862f8fad0167073a7733973bfa955f47e2cac3dc3e3e6257d10fab4a/pillow-12.0.0-cp314-cp314-win32.whl", hash = "sha256:1b1b133e6e16105f524a8dec491e0586d072948ce15c9b914e41cdadd209052b", size = 6400621, upload-time = "2025-10-15T18:23:32.06Z" }, + { url = "https://files.pythonhosted.org/packages/2b/24/b350c31543fb0107ab2599464d7e28e6f856027aadda995022e695313d94/pillow-12.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:8dc232e39d409036af549c86f24aed8273a40ffa459981146829a324e0848b4b", size = 7142916, upload-time = "2025-10-15T18:23:34.71Z" }, + { url = "https://files.pythonhosted.org/packages/0f/9b/0ba5a6fd9351793996ef7487c4fdbde8d3f5f75dbedc093bb598648fddf0/pillow-12.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:d52610d51e265a51518692045e372a4c363056130d922a7351429ac9f27e70b0", size = 2523836, upload-time = "2025-10-15T18:23:36.967Z" }, + { url = "https://files.pythonhosted.org/packages/f5/7a/ceee0840aebc579af529b523d530840338ecf63992395842e54edc805987/pillow-12.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1979f4566bb96c1e50a62d9831e2ea2d1211761e5662afc545fa766f996632f6", size = 5255092, upload-time = "2025-10-15T18:23:38.573Z" }, + { url = "https://files.pythonhosted.org/packages/44/76/20776057b4bfd1aef4eeca992ebde0f53a4dce874f3ae693d0ec90a4f79b/pillow-12.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b2e4b27a6e15b04832fe9bf292b94b5ca156016bbc1ea9c2c20098a0320d6cf6", size = 4653158, upload-time = "2025-10-15T18:23:40.238Z" }, + { url = "https://files.pythonhosted.org/packages/82/3f/d9ff92ace07be8836b4e7e87e6a4c7a8318d47c2f1463ffcf121fc57d9cb/pillow-12.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fb3096c30df99fd01c7bf8e544f392103d0795b9f98ba71a8054bcbf56b255f1", size = 6267882, upload-time = "2025-10-15T18:23:42.434Z" }, + { url = "https://files.pythonhosted.org/packages/9f/7a/4f7ff87f00d3ad33ba21af78bfcd2f032107710baf8280e3722ceec28cda/pillow-12.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7438839e9e053ef79f7112c881cef684013855016f928b168b81ed5835f3e75e", size = 8071001, upload-time = "2025-10-15T18:23:44.29Z" }, + { url = "https://files.pythonhosted.org/packages/75/87/fcea108944a52dad8cca0715ae6247e271eb80459364a98518f1e4f480c1/pillow-12.0.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d5c411a8eaa2299322b647cd932586b1427367fd3184ffbb8f7a219ea2041ca", size = 6380146, upload-time = "2025-10-15T18:23:46.065Z" }, + { url = "https://files.pythonhosted.org/packages/91/52/0d31b5e571ef5fd111d2978b84603fce26aba1b6092f28e941cb46570745/pillow-12.0.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7e091d464ac59d2c7ad8e7e08105eaf9dafbc3883fd7265ffccc2baad6ac925", size = 7067344, upload-time = "2025-10-15T18:23:47.898Z" }, + { url = "https://files.pythonhosted.org/packages/7b/f4/2dd3d721f875f928d48e83bb30a434dee75a2531bca839bb996bb0aa5a91/pillow-12.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:792a2c0be4dcc18af9d4a2dfd8a11a17d5e25274a1062b0ec1c2d79c76f3e7f8", size = 6491864, upload-time = "2025-10-15T18:23:49.607Z" }, + { url = "https://files.pythonhosted.org/packages/30/4b/667dfcf3d61fc309ba5a15b141845cece5915e39b99c1ceab0f34bf1d124/pillow-12.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:afbefa430092f71a9593a99ab6a4e7538bc9eabbf7bf94f91510d3503943edc4", size = 7158911, upload-time = "2025-10-15T18:23:51.351Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2f/16cabcc6426c32218ace36bf0d55955e813f2958afddbf1d391849fee9d1/pillow-12.0.0-cp314-cp314t-win32.whl", hash = "sha256:3830c769decf88f1289680a59d4f4c46c72573446352e2befec9a8512104fa52", size = 6408045, upload-time = "2025-10-15T18:23:53.177Z" }, + { url = "https://files.pythonhosted.org/packages/35/73/e29aa0c9c666cf787628d3f0dcf379f4791fba79f4936d02f8b37165bdf8/pillow-12.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:905b0365b210c73afb0ebe9101a32572152dfd1c144c7e28968a331b9217b94a", size = 7148282, upload-time = "2025-10-15T18:23:55.316Z" }, + { url = "https://files.pythonhosted.org/packages/c1/70/6b41bdcddf541b437bbb9f47f94d2db5d9ddef6c37ccab8c9107743748a4/pillow-12.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:99353a06902c2e43b43e8ff74ee65a7d90307d82370604746738a1e0661ccca7", size = 2525630, upload-time = "2025-10-15T18:23:57.149Z" }, +] + +[[package]] +name = "setuptools" +version = "80.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, +] + +[[package]] +name = "sympy" +version = "1.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mpmath" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, +] + +[[package]] +name = "torch" +version = "2.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, + { name = "fsspec" }, + { name = "jinja2" }, + { name = "networkx" }, + { name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-cupti-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-nvrtc-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-runtime-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cudnn-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cufft-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cufile-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-curand-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusolver-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusparselt-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvshmem-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "setuptools" }, + { name = "sympy" }, + { name = "triton", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "typing-extensions" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/27/07c645c7673e73e53ded71705045d6cb5bae94c4b021b03aa8d03eee90ab/torch-2.9.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:da5f6f4d7f4940a173e5572791af238cb0b9e21b1aab592bd8b26da4c99f1cd6", size = 104126592, upload-time = "2025-11-12T15:20:41.62Z" }, + { url = "https://files.pythonhosted.org/packages/19/17/e377a460603132b00760511299fceba4102bd95db1a0ee788da21298ccff/torch-2.9.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:27331cd902fb4322252657f3902adf1c4f6acad9dcad81d8df3ae14c7c4f07c4", size = 899742281, upload-time = "2025-11-12T15:22:17.602Z" }, + { url = "https://files.pythonhosted.org/packages/b1/1a/64f5769025db846a82567fa5b7d21dba4558a7234ee631712ee4771c436c/torch-2.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:81a285002d7b8cfd3fdf1b98aa8df138d41f1a8334fd9ea37511517cedf43083", size = 110940568, upload-time = "2025-11-12T15:21:18.689Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ab/07739fd776618e5882661d04c43f5b5586323e2f6a2d7d84aac20d8f20bd/torch-2.9.1-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:c0d25d1d8e531b8343bea0ed811d5d528958f1dcbd37e7245bc686273177ad7e", size = 74479191, upload-time = "2025-11-12T15:21:25.816Z" }, + { url = "https://files.pythonhosted.org/packages/20/60/8fc5e828d050bddfab469b3fe78e5ab9a7e53dda9c3bdc6a43d17ce99e63/torch-2.9.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c29455d2b910b98738131990394da3e50eea8291dfeb4b12de71ecf1fdeb21cb", size = 104135743, upload-time = "2025-11-12T15:21:34.936Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b7/6d3f80e6918213babddb2a37b46dbb14c15b14c5f473e347869a51f40e1f/torch-2.9.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:524de44cd13931208ba2c4bde9ec7741fd4ae6bfd06409a604fc32f6520c2bc9", size = 899749493, upload-time = "2025-11-12T15:24:36.356Z" }, + { url = "https://files.pythonhosted.org/packages/a6/47/c7843d69d6de8938c1cbb1eba426b1d48ddf375f101473d3e31a5fc52b74/torch-2.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:545844cc16b3f91e08ce3b40e9c2d77012dd33a48d505aed34b7740ed627a1b2", size = 110944162, upload-time = "2025-11-12T15:21:53.151Z" }, + { url = "https://files.pythonhosted.org/packages/28/0e/2a37247957e72c12151b33a01e4df651d9d155dd74d8cfcbfad15a79b44a/torch-2.9.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5be4bf7496f1e3ffb1dd44b672adb1ac3f081f204c5ca81eba6442f5f634df8e", size = 74830751, upload-time = "2025-11-12T15:21:43.792Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f7/7a18745edcd7b9ca2381aa03353647bca8aace91683c4975f19ac233809d/torch-2.9.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:30a3e170a84894f3652434b56d59a64a2c11366b0ed5776fab33c2439396bf9a", size = 104142929, upload-time = "2025-11-12T15:21:48.319Z" }, + { url = "https://files.pythonhosted.org/packages/f4/dd/f1c0d879f2863ef209e18823a988dc7a1bf40470750e3ebe927efdb9407f/torch-2.9.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:8301a7b431e51764629208d0edaa4f9e4c33e6df0f2f90b90e261d623df6a4e2", size = 899748978, upload-time = "2025-11-12T15:23:04.568Z" }, + { url = "https://files.pythonhosted.org/packages/1f/9f/6986b83a53b4d043e36f3f898b798ab51f7f20fdf1a9b01a2720f445043d/torch-2.9.1-cp313-cp313t-win_amd64.whl", hash = "sha256:2e1c42c0ae92bf803a4b2409fdfed85e30f9027a66887f5e7dcdbc014c7531db", size = 111176995, upload-time = "2025-11-12T15:22:01.618Z" }, + { url = "https://files.pythonhosted.org/packages/40/60/71c698b466dd01e65d0e9514b5405faae200c52a76901baf6906856f17e4/torch-2.9.1-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:2c14b3da5df416cf9cb5efab83aa3056f5b8cd8620b8fde81b4987ecab730587", size = 74480347, upload-time = "2025-11-12T15:21:57.648Z" }, + { url = "https://files.pythonhosted.org/packages/48/50/c4b5112546d0d13cc9eaa1c732b823d676a9f49ae8b6f97772f795874a03/torch-2.9.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1edee27a7c9897f4e0b7c14cfc2f3008c571921134522d5b9b5ec4ebbc69041a", size = 74433245, upload-time = "2025-11-12T15:22:39.027Z" }, + { url = "https://files.pythonhosted.org/packages/81/c9/2628f408f0518b3bae49c95f5af3728b6ab498c8624ab1e03a43dd53d650/torch-2.9.1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:19d144d6b3e29921f1fc70503e9f2fc572cde6a5115c0c0de2f7ca8b1483e8b6", size = 104134804, upload-time = "2025-11-12T15:22:35.222Z" }, + { url = "https://files.pythonhosted.org/packages/28/fc/5bc91d6d831ae41bf6e9e6da6468f25330522e92347c9156eb3f1cb95956/torch-2.9.1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:c432d04376f6d9767a9852ea0def7b47a7bbc8e7af3b16ac9cf9ce02b12851c9", size = 899747132, upload-time = "2025-11-12T15:23:36.068Z" }, + { url = "https://files.pythonhosted.org/packages/63/5d/e8d4e009e52b6b2cf1684bde2a6be157b96fb873732542fb2a9a99e85a83/torch-2.9.1-cp314-cp314-win_amd64.whl", hash = "sha256:d187566a2cdc726fc80138c3cdb260970fab1c27e99f85452721f7759bbd554d", size = 110934845, upload-time = "2025-11-12T15:22:48.367Z" }, + { url = "https://files.pythonhosted.org/packages/bd/b2/2d15a52516b2ea3f414643b8de68fa4cb220d3877ac8b1028c83dc8ca1c4/torch-2.9.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:cb10896a1f7fedaddbccc2017ce6ca9ecaaf990f0973bdfcf405439750118d2c", size = 74823558, upload-time = "2025-11-12T15:22:43.392Z" }, + { url = "https://files.pythonhosted.org/packages/86/5c/5b2e5d84f5b9850cd1e71af07524d8cbb74cba19379800f1f9f7c997fc70/torch-2.9.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:0a2bd769944991c74acf0c4ef23603b9c777fdf7637f115605a4b2d8023110c7", size = 104145788, upload-time = "2025-11-12T15:23:52.109Z" }, + { url = "https://files.pythonhosted.org/packages/a9/8c/3da60787bcf70add986c4ad485993026ac0ca74f2fc21410bc4eb1bb7695/torch-2.9.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:07c8a9660bc9414c39cac530ac83b1fb1b679d7155824144a40a54f4a47bfa73", size = 899735500, upload-time = "2025-11-12T15:24:08.788Z" }, + { url = "https://files.pythonhosted.org/packages/db/2b/f7818f6ec88758dfd21da46b6cd46af9d1b3433e53ddbb19ad1e0da17f9b/torch-2.9.1-cp314-cp314t-win_amd64.whl", hash = "sha256:c88d3299ddeb2b35dcc31753305612db485ab6f1823e37fb29451c8b2732b87e", size = 111163659, upload-time = "2025-11-12T15:23:20.009Z" }, +] + +[[package]] +name = "torchvision" +version = "0.24.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "pillow" }, + { name = "torch" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/af/18e2c6b9538a045f60718a0c5a058908ccb24f88fde8e6f0fc12d5ff7bd3/torchvision-0.24.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e48bf6a8ec95872eb45763f06499f87bd2fb246b9b96cb00aae260fda2f96193", size = 1891433, upload-time = "2025-11-12T15:25:03.232Z" }, + { url = "https://files.pythonhosted.org/packages/9d/43/600e5cfb0643d10d633124f5982d7abc2170dfd7ce985584ff16edab3e76/torchvision-0.24.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:7fb7590c737ebe3e1c077ad60c0e5e2e56bb26e7bccc3b9d04dbfc34fd09f050", size = 2386737, upload-time = "2025-11-12T15:25:08.288Z" }, + { url = "https://files.pythonhosted.org/packages/93/b1/db2941526ecddd84884132e2742a55c9311296a6a38627f9e2627f5ac889/torchvision-0.24.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:66a98471fc18cad9064123106d810a75f57f0838eee20edc56233fd8484b0cc7", size = 8049868, upload-time = "2025-11-12T15:25:13.058Z" }, + { url = "https://files.pythonhosted.org/packages/69/98/16e583f59f86cd59949f59d52bfa8fc286f86341a229a9d15cbe7a694f0c/torchvision-0.24.1-cp312-cp312-win_amd64.whl", hash = "sha256:4aa6cb806eb8541e92c9b313e96192c6b826e9eb0042720e2fa250d021079952", size = 4302006, upload-time = "2025-11-12T15:25:16.184Z" }, + { url = "https://files.pythonhosted.org/packages/e4/97/ab40550f482577f2788304c27220e8ba02c63313bd74cf2f8920526aac20/torchvision-0.24.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:8a6696db7fb71eadb2c6a48602106e136c785642e598eb1533e0b27744f2cce6", size = 1891435, upload-time = "2025-11-12T15:25:28.642Z" }, + { url = "https://files.pythonhosted.org/packages/30/65/ac0a3f9be6abdbe4e1d82c915d7e20de97e7fd0e9a277970508b015309f3/torchvision-0.24.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:db2125c46f9cb25dc740be831ce3ce99303cfe60439249a41b04fd9f373be671", size = 2338718, upload-time = "2025-11-12T15:25:26.19Z" }, + { url = "https://files.pythonhosted.org/packages/10/b5/5bba24ff9d325181508501ed7f0c3de8ed3dd2edca0784d48b144b6c5252/torchvision-0.24.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:f035f0cacd1f44a8ff6cb7ca3627d84c54d685055961d73a1a9fb9827a5414c8", size = 8049661, upload-time = "2025-11-12T15:25:22.558Z" }, + { url = "https://files.pythonhosted.org/packages/5c/ec/54a96ae9ab6a0dd66d4bba27771f892e36478a9c3489fa56e51c70abcc4d/torchvision-0.24.1-cp313-cp313-win_amd64.whl", hash = "sha256:16274823b93048e0a29d83415166a2e9e0bf4e1b432668357b657612a4802864", size = 4319808, upload-time = "2025-11-12T15:25:17.318Z" }, + { url = "https://files.pythonhosted.org/packages/d5/f3/a90a389a7e547f3eb8821b13f96ea7c0563cdefbbbb60a10e08dda9720ff/torchvision-0.24.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e3f96208b4bef54cd60e415545f5200346a65024e04f29a26cd0006dbf9e8e66", size = 2005342, upload-time = "2025-11-12T15:25:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/a9/fe/ff27d2ed1b524078164bea1062f23d2618a5fc3208e247d6153c18c91a76/torchvision-0.24.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:f231f6a4f2aa6522713326d0d2563538fa72d613741ae364f9913027fa52ea35", size = 2341708, upload-time = "2025-11-12T15:25:25.08Z" }, + { url = "https://files.pythonhosted.org/packages/b1/b9/d6c903495cbdfd2533b3ef6f7b5643ff589ea062f8feb5c206ee79b9d9e5/torchvision-0.24.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:1540a9e7f8cf55fe17554482f5a125a7e426347b71de07327d5de6bfd8d17caa", size = 8177239, upload-time = "2025-11-12T15:25:18.554Z" }, + { url = "https://files.pythonhosted.org/packages/4f/2b/ba02e4261369c3798310483028495cf507e6cb3f394f42e4796981ecf3a7/torchvision-0.24.1-cp313-cp313t-win_amd64.whl", hash = "sha256:d83e16d70ea85d2f196d678bfb702c36be7a655b003abed84e465988b6128938", size = 4251604, upload-time = "2025-11-12T15:25:34.069Z" }, + { url = "https://files.pythonhosted.org/packages/42/84/577b2cef8f32094add5f52887867da4c2a3e6b4261538447e9b48eb25812/torchvision-0.24.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cccf4b4fec7fdfcd3431b9ea75d1588c0a8596d0333245dafebee0462abe3388", size = 2005319, upload-time = "2025-11-12T15:25:23.827Z" }, + { url = "https://files.pythonhosted.org/packages/5f/34/ecb786bffe0159a3b49941a61caaae089853132f3cd1e8f555e3621f7e6f/torchvision-0.24.1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:1b495edd3a8f9911292424117544f0b4ab780452e998649425d1f4b2bed6695f", size = 2338844, upload-time = "2025-11-12T15:25:32.625Z" }, + { url = "https://files.pythonhosted.org/packages/51/99/a84623786a6969504c87f2dc3892200f586ee13503f519d282faab0bb4f0/torchvision-0.24.1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:ab211e1807dc3e53acf8f6638df9a7444c80c0ad050466e8d652b3e83776987b", size = 8175144, upload-time = "2025-11-12T15:25:31.355Z" }, + { url = "https://files.pythonhosted.org/packages/6d/ba/8fae3525b233e109317ce6a9c1de922ab2881737b029a7e88021f81e068f/torchvision-0.24.1-cp314-cp314-win_amd64.whl", hash = "sha256:18f9cb60e64b37b551cd605a3d62c15730c086362b40682d23e24b616a697d41", size = 4234459, upload-time = "2025-11-12T15:25:19.859Z" }, + { url = "https://files.pythonhosted.org/packages/50/33/481602c1c72d0485d4b3a6b48c9534b71c2957c9d83bf860eb837bf5a620/torchvision-0.24.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ec9d7379c519428395e4ffda4dbb99ec56be64b0a75b95989e00f9ec7ae0b2d7", size = 2005336, upload-time = "2025-11-12T15:25:27.225Z" }, + { url = "https://files.pythonhosted.org/packages/d0/7f/372de60bf3dd8f5593bd0d03f4aecf0d1fd58f5bc6943618d9d913f5e6d5/torchvision-0.24.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:af9201184c2712d808bd4eb656899011afdfce1e83721c7cb08000034df353fe", size = 2341704, upload-time = "2025-11-12T15:25:29.857Z" }, + { url = "https://files.pythonhosted.org/packages/36/9b/0f3b9ff3d0225ee2324ec663de0e7fb3eb855615ca958ac1875f22f1f8e5/torchvision-0.24.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:9ef95d819fd6df81bc7cc97b8f21a15d2c0d3ac5dbfaab5cbc2d2ce57114b19e", size = 8177422, upload-time = "2025-11-12T15:25:37.357Z" }, + { url = "https://files.pythonhosted.org/packages/d6/ab/e2bcc7c2f13d882a58f8b30ff86f794210b075736587ea50f8c545834f8a/torchvision-0.24.1-cp314-cp314t-win_amd64.whl", hash = "sha256:480b271d6edff83ac2e8d69bbb4cf2073f93366516a50d48f140ccfceedb002e", size = 4335190, upload-time = "2025-11-12T15:25:35.745Z" }, +] + +[[package]] +name = "triton" +version = "3.5.1" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/50/9a8358d3ef58162c0a415d173cfb45b67de60176e1024f71fbc4d24c0b6d/triton-3.5.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d2c6b915a03888ab931a9fd3e55ba36785e1fe70cbea0b40c6ef93b20fc85232", size = 170470207, upload-time = "2025-11-11T17:41:00.253Z" }, + { url = "https://files.pythonhosted.org/packages/27/46/8c3bbb5b0a19313f50edcaa363b599e5a1a5ac9683ead82b9b80fe497c8d/triton-3.5.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3f4346b6ebbd4fad18773f5ba839114f4826037c9f2f34e0148894cd5dd3dba", size = 170470410, upload-time = "2025-11-11T17:41:06.319Z" }, + { url = "https://files.pythonhosted.org/packages/37/92/e97fcc6b2c27cdb87ce5ee063d77f8f26f19f06916aa680464c8104ef0f6/triton-3.5.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0b4d2c70127fca6a23e247f9348b8adde979d2e7a20391bfbabaac6aebc7e6a8", size = 170579924, upload-time = "2025-11-11T17:41:12.455Z" }, + { url = "https://files.pythonhosted.org/packages/a4/e6/c595c35e5c50c4bc56a7bac96493dad321e9e29b953b526bbbe20f9911d0/triton-3.5.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0637b1efb1db599a8e9dc960d53ab6e4637db7d4ab6630a0974705d77b14b60", size = 170480488, upload-time = "2025-11-11T17:41:18.222Z" }, + { url = "https://files.pythonhosted.org/packages/16/b5/b0d3d8b901b6a04ca38df5e24c27e53afb15b93624d7fd7d658c7cd9352a/triton-3.5.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bac7f7d959ad0f48c0e97d6643a1cc0fd5786fe61cb1f83b537c6b2d54776478", size = 170582192, upload-time = "2025-11-11T17:41:23.963Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +]