# Notebook from georgegoldberg1/recipe_nutrition_scraper
Path: Analysis Ipad version.ipynb

import pandas as pd
import json
import matplotlib.pyplot as plt
import seaborn as sns_____no_output_____#IMPORT FILE AND FORMAT DATA
df = pd.read_csv('recipe_data.csv')
df.rename(columns={'Unnamed: 0':'Name'},inplace=True)

#GET nutrition data
nutrition_keys = list(json.loads(df['nutrition'][0].replace("'",'"')).keys())
nutrition_full = [json.loads(x.replace("'",'"').replace('g','')) for x in df['nutrition']]
for i in range(0,len(nutrition_keys)):
    df[nutrition_keys[i]] = [None]*len(df)
    for j in df.T:
        df.iloc[j][nutrition_keys[i]] = nutrition_full[j].get(nutrition_keys[i])

#format nutrition data as numbers
for key in nutrition_keys:
    df[key] = df[key].apply(lambda x:float(x) if x!=None else float(0))
df.drop(columns=['dietary_req','nutrition'],inplace=True)
df['Calories'] = df['Calories'].apply(lambda x:int(x) if x!=None else x)

#get rid of messy html
def clean_cooking_method(x):
    return x.replace('
\n
','') \
    .replace('
','')[4:-1] \
    .replace('','').replace('','').replace('
','') \
    .replace('
','\n\n')
df['method'] = df['method'].apply(lambda x:clean_cooking_method(x))
df = df.rename(columns={'method':'Method'})

#remove invalid portion size data (eg 'enough for a few of your mates')
failed_ = df[df['Calories'].isna()]['Name']
failed2_ = df[(df['portions'] == [x for x in df['portions'] if 'enough' in x][0]) | \
                  (df['portions'] == [x for x in df['portions'] if 'enough' in x][1])]
excluding_blanks = list(set(df.index)-set(failed_.index)-set(failed2_.index))
df = df.iloc[excluding_blanks]

#convert portion size data to numbers
df['portions'] = df['portions'].apply(lambda x:int(x) if str(x).isdigit() else x)
df['portions'] = df['portions'].apply(lambda x:int(x.split('to')[0]) if (str(x).find('to') != -1)&(str(x).find('to')<3) else x)
df['portions'] = df['portions'].apply(lambda x:int(x.split('-')[0]) if (str(x).find('-') != -1)&(str(x).find('-')<3) else x)
df['portions'] = df['portions'].apply(lambda x:int(x.split('–')[0]) if (str(x).find('–') != -1)&(str(x).find('–')<3) else x)
df = df.iloc[[x for x,y in enumerate([type(x) for x in df['portions']]) if y==int]]

#calculate the combined calories
df['total_cals'] = df['Calories']*df['portions']
_____no_output_____#Use nutrition data to work out which meals have the healthiest macro ratios
#protein distancefrom ideal
df['prot_pct'] = (df['Protein']*4)/df['Calories']
df["Protein_balance"] = df.prot_pct - 0.3 #30% CALS FROM PROTEIN IS CONSIDERED IDEAL
#carbs distancefrom ideal
df['carb_pct'] = (df['Carbs']*4)/df['Calories']
df['Carbs_balance'] = df.carb_pct - 0.5 #50% CALS FROM CARBS IS CONSIDERED IDEAL
#fats distancefrom ideal
df['fat_pct'] = (df['Fat']*9)/df['Calories']
df['Fat_balance'] = df.fat_pct - 0.2 #20% CALS FROM FAT IS CONSIDERED IDEAL

ideal = ['30%','50%','20%']
for each in ["Protein","Carbs","Fat"]:
    plt.figure(figsize=(15,6))
    nutrient = plt.bar(df[df["Calories"]>100]['Calories'],height=df[df["Calories"]>100][f"{each}_balance"],label=f'{each}')
    plt.title(f'How does {each} deviate from the ideal?',fontdict={'size':'16'})
    plt.xlabel('Calories per portion',fontdict={'size':'14'})
    plt.ylabel(f'Deviation from ideal ({ideal[["Protein","Carbs","Fat"].index(each)]})',fontdict={'size':'14'})
    plt.xticks(fontsize=14)
    plt.yticks(fontsize=14)
   # plt.legend(handles=nutrient,bbox_to_anchor=(1,1),fontsize='large')
    plt.show()_____no_output_____

# Most meals overdo the fat and underdo the carbs and protein._____no_output_____

#Print out the top performing
recipe_links = pd.read_csv("recipe_list.csv")[['recipe_name','recipe_link']]

#incase it gets deleted above:
#df["prot_balance"] = (df['Protein']*4)/df['Calories']-0.3 #30% CALS FROM PROTEIN IS CONSIDERED IDEAL
##carbs distancefrom ideal
#df['carb_balance'] = (df['Carbs']*4)/df['Calories']-0.5 #50% CALS FROM CARBS IS CONSIDERED IDEAL
##fats distancefrom ideal
#df['fat_balance'] = (df['Fat']*9)/df['Calories']-0.2 #20% CALS FROM FAT IS CONSIDERED IDEAL

tolerance = 10 #percent above or below allocated macros split for that nutrient

#remove meals that fall outside the tolerence window
best = df[ \
   (df["Calories"]>300) \
   &(df["Protein_balance"]<(tolerance/100)) \
   &(-(tolerance/100)<df["Protein_balance"]) \
   &(df["Carbs_balance"]<(tolerance/100)) \
   &(-(tolerance/100)<df["Carbs_balance"]) \
   &(df["Fat_balance"]<(tolerance/100)) \
   &(-(tolerance/100)<df["Fat_balance"]) \
  ][["Protein_balance","Carbs_balance","Fat_balance"]]

top_macros = abs(best).loc[abs(best).mean(axis=1).sort_values(0).index].index

tmp = df.loc[top_macros]

print("\nFoods with ideal macro-nutrient ratios ~(50% Carbs, 30% Protein, 20% Fat)\n")
for i in range(len(df.loc[top_macros])):
    num = df.loc[top_macros].index[i]
    name = tmp.iloc[i]['Name']
    link = recipe_links[recipe_links['recipe_name']==name]['recipe_link'].values[0]
    portions = tmp.iloc[i]['portions']
    cals = tmp.iloc[i]['Calories']
    pro = tmp.iloc[i]['Protein']
    carb = tmp.iloc[i]['Carbs']
    fat = tmp.iloc[i]['Fat']
    propct = tmp.iloc[i].prot_pct
    carbpct = tmp.iloc[i].carb_pct
    fatpct = tmp.iloc[i].fat_pct
    takes = tmp.iloc[i]['cooking_time']
    print("\n",i+1,
          f"""{name}\n   Calories: {cals}\n   Protein: {pro}g Carbs:{carb}g Fat: {fat}g
\tP {propct:.0%}\t C {carbpct:.0%}\t F {fatpct:.0%}
    Takes:    {takes}\n   Serves:   {portions}\n   ref:{num}\n   {link}""")
Foods with ideal macro-nutrient ratios ~(50% Carbs, 30% Protein, 20% Fat)

 1 Roasted veg vindaloo with golden gnarly chicken skewers
   Calories: 544
   Protein: 37.7g Carbs:66.8g Fat: 11.6g
	P 28%	 C 49%	 F 19%
    Takes:    1H30M
   Serves:   6
   ref:780
   https://www.jamieoliver.com/recipes/chicken-recipes/roasted-veg-vindaloo-with-golden-gnarly-chicken-skewers/

 2 Grilled steak ratatouille & saffron rice
   Calories: 593
   Protein: 42.3g Carbs:71.3g Fat: 13.7g
	P 29%	 C 48%	 F 21%
    Takes:    15minutes
   Serves:   4
   ref:420
   https://www.jamieoliver.com/recipes/beef-recipes/grilled-steak-ratatouille-saffron-rice/

 3 Gorgeous Greek chicken
   Calories: 676
   Protein: 45.9g Carbs:84.0g Fat: 13.5g
	P 27%	 C 50%	 F 18%
    Takes:    30minutes
   Serves:   2
   ref:390
   https://www.jamieoliver.com/recipes/chicken-recipes/gorgeous-greek-chicken/

 4 Spicy 'nduja vongole
   Calories: 556
   Protein: 41.9g Carbs:62.5g Fat: 12.5g
	P 30%	 C 45%	 F 20%
    Takes:    15minutes
   Serves:   2
   ref:899
   https://www.jamieoliver.com/recipes/seafood-recipes/spicy-nduja-vongole/

 5 Chicken milanese with spaghetti
   Calories: 965
   Protein: 68.8g Carbs:126.8g Fat: 24.1g
	P 29%	 C 53%	 F 22%
    Takes:    45minutes
   Serves:   2
   ref:199
   https://www.jamieoliver.com/recipes/chicken-recipes/chicken-milanese-with-spaghetti/

 6 Southern Italian-style chicken
   Calories: 617
   Protein: 43.3g Carbs:80.1g Fat: 16.3g
	P 28%	 C 52%	 F 24%
    Takes:    1H10M
   Serves:   4
   ref:882
   https://www.jamieoliver.com/recipes/chicken-recipes/southern-italian-style-chicken/

 7 Crab rigatoni
   Calories: 483
   Protein: 31.0g Carbs:56.6g Fat: 11.1g
	P 26%	 C 47%	 F 21%
    Takes:    35minutes
   Serves:   4
   ref:257
   https://www.jamieoliver.com/recipes/pasta-recipes/crab-rigatoni/

 8 Steamed Thai-style sea bass and rice
   Calories: 649
   Protein: 43.8g Carbs:87.3g Fat: 13.1g
	P 27%	 C 54%	 F 18%
    Takes:    40minutes
   Serves:   4
   ref:936
   https://www.jamieoliver.com/recipes/fish-recipes/steamed-thai-style-sea-bass-and-rice/

 9 Amanda's linguine vongole
   Calories: 568
   Protein: 40.4g Carbs:62.8g Fat: 13.6g
	P 28%	 C 44%	 F 22%
    Takes:    15minutes
   Serves:   2
   ref:11
   https://www.jamieoliver.com/recipes/pasta-recipes/amanda-s-linguine-vongole/

 10 Balinese chicken curry
   Calories: 551
   Protein: 36.6g Carbs:74.9g Fat: 13.7g
	P 27%	 C 54%	 F 22%
    Takes:    1hour
   Serves:   6
   ref:71
   https://www.jamieoliver.com/recipes/curry-recipes/balinese-chicken-curry/

 11 Tasty fish tacos
   Calories: 418
   Protein: 35.2g Carbs:48.3g Fat: 10.6g
	P 34%	 C 46%	 F 23%
    Takes:    35minutes
   Serves:   2
   ref:992
   https://www.jamieoliver.com/recipes/fish-recipes/tasty-fish-tacos/

 12 Winter pasta salad
   Calories: 481
   Protein: 29.8g Carbs:59.1g Fat: 13.0g
	P 25%	 C 49%	 F 24%
    Takes:    30minutes
   Serves:   6
   ref:1098
   https://www.jamieoliver.com/recipes/pasta-recipes/winter-pasta-salad/

 13 Aegean kakavia (Beautiful fish stew)
   Calories: 589
   Protein: 43.7g Carbs:84.3g Fat: 10.8g
	P 30%	 C 57%	 F 17%
    Takes:    1hour
   Serves:   4
   ref:6
   https://www.jamieoliver.com/recipes/fish-recipes/aegean-kakavia-beautiful-fish-stew/

 14 The best fish baps
   Calories: 665
   Protein: 50.0g Carbs:71.4g Fat: 17.8g
	P 30%	 C 43%	 F 24%
    Takes:    15minutes
   Serves:   4
   ref:1007
   https://www.jamieoliver.com/recipes/fish-recipes/the-best-fish-baps-with-mushy-peas-tartare-sauce/

 15 Sri Lankan-style monkfish curry
   Calories: 398
   Protein: 27.0g Carbs:57.3g Fat: 9.3g
	P 27%	 C 58%	 F 21%
    Takes:    55minutes
   Serves:   4
   ref:931
   https://www.jamieoliver.com/recipes/fish-recipes/sri-lankan-style-monkfish-curry/

 16 One-pan fabulous fish
   Calories: 484
   Protein: 31.2g Carbs:66.7g Fat: 12.0g
	P 26%	 C 55%	 F 22%
    Takes:    15minutes
   Serves:   4
   ref:626
   https://www.jamieoliver.com/recipes/fish-recipes/one-pan-fabulous-fish/

 17 Mighty mackerel
   Calories: 431
   Protein: 30.0g Carbs:48.2g Fat: 11.7g
	P 28%	 C 45%	 F 24%
    Takes:    15minutes
   Serves:   4
   ref:586
   https://www.jamieoliver.com/recipes/fish-recipes/mighty-mackerel-with-mixed-tomato-quinoa-salad/

 18 Family spaghetti Bolognese
   Calories: 511
   Protein: 38.6g Carbs:73.7g Fat: 9.1g
	P 30%	 C 58%	 F 16%
    Takes:    2hours
   Serves:   6
   ref:322
   https://www.jamieoliver.com/recipes/pasta-recipes/family-spaghetti-bolognese/

 19 Mexican chicken chilli
   Calories: 547
   Protein: 46.0g Carbs:69.3g Fat: 7.4g
	P 34%	 C 51%	 F 12%
    Takes:    1hour
   Serves:   4
   ref:562
   https://www.jamieoliver.com/recipes/chicken-recipes/mexican-chicken-chilli/

 20 Rescue me kedgeree
   Calories: 494
   Protein: 36.6g Carbs:54.6g Fat: 14.4g
	P 30%	 C 44%	 F 26%
    Takes:    35minutes
   Serves:   4
   ref:730
   https://www.jamieoliver.com/recipes/fish-recipes/rescue-me-kedgeree/

 21 Spiced beef & rice hot pot
   Calories: 501
   Protein: 29.7g Carbs:61.9g Fat: 14.9g
	P 24%	 C 49%	 F 27%
    Takes:    1H55M
   Serves:   4
   ref:895
   https://www.jamieoliver.com/recipes/beef-recipes/spiced-beef-rice-hot-pot/

 22 Helen’s tuna pasta
   Calories: 433
   Protein: 29.4g Carbs:63.4g Fat: 8.5g
	P 27%	 C 59%	 F 18%
    Takes:    NotAvailable
   Serves:   4
   ref:439
   https://www.jamieoliver.com/recipes/pasta-recipes/helen-s-tuna-pasta/

 23 Sesame butterflied chicken
   Calories: 489
   Protein: 40.0g Carbs:52.0g Fat: 12.9g
	P 33%	 C 43%	 F 24%
    Takes:    18minutes
   Serves:   2
   ref:824
   https://www.jamieoliver.com/recipes/chicken-recipes/sesame-butterflied-chicken/

 24 Sloppy Joe
   Calories: 418
   Protein: 38.9g Carbs:53.8g Fat: 6.8g
	P 37%	 C 51%	 F 15%
    Takes:    35minutes
   Serves:   4
   ref:857
   https://www.jamieoliver.com/recipes/beef-recipes/sloppy-joe/

 25 Early autumn minestrone (Minestrone d'inizio autunno)
   Calories: 321
   Protein: 17.2g Carbs:36.9g Fat: 6.6g
	P 21%	 C 46%	 F 19%
    Takes:    1H5M
   Serves:   4
   ref:301
   https://www.jamieoliver.com/recipes/vegetables-recipes/early-autumn-minestrone-minestrone-d-inizio-autunno/

 26 Falafel wraps
   Calories: 602
   Protein: 32.4g Carbs:79.5g Fat: 15.5g
	P 22%	 C 53%	 F 23%
    Takes:    15minutes
   Serves:   4
   ref:321
   https://www.jamieoliver.com/recipes/vegetables-recipes/falafel-wraps-with-grilled-veg-salsa/

 27 Super-tasty miso broth
   Calories: 521
   Protein: 45.1g Carbs:70.4g Fat: 8.1g
	P 35%	 C 54%	 F 14%
    Takes:    40minutes
   Serves:   2
   ref:969
   https://www.jamieoliver.com/recipes/chicken-recipes/super-tasty-miso-broth/

 28 Grandad's mussel linguine (Linguine con cozze di Nonno)
   Calories: 680
   Protein: 49.0g Carbs:73.0g Fat: 20.0g
	P 29%	 C 43%	 F 26%
    Takes:    10minutes
   Serves:   2
   ref:395
   https://www.jamieoliver.com/recipes/pasta-recipes/grandad-s-mussel-linguine-linguine-con-cozze-di-nonno/

 29 Kerryann’s tuna pasta bake
   Calories: 514
   Protein: 31.0g Carbs:64.1g Fat: 16.8g
	P 24%	 C 50%	 F 29%
    Takes:    1hour
   Serves:   6
   ref:508
   https://www.jamieoliver.com/recipes/pasta-recipes/kerryann-s-tuna-pasta-bake/

 30 Chicken fajitas with guacamole
   Calories: 480
   Protein: 32.0g Carbs:56.6g Fat: 15.6g
	P 27%	 C 47%	 F 29%
    Takes:    30minutes
   Serves:   4
   ref:192
   https://www.jamieoliver.com/recipes/chicken-recipes/chicken-fajitas-with-guacamole/

 31 Baked rice with chicken & chorizo
   Calories: 590
   Protein: 40.0g Carbs:68.0g Fat: 19.0g
	P 27%	 C 46%	 F 29%
    Takes:    2hours
   Serves:   4
   ref:64
   https://www.jamieoliver.com/recipes/rice-recipes/baked-rice-with-chicken-chorizo/

 32 Pukka yellow curry
   Calories: 572
   Protein: 33.8g Carbs:74.9g Fat: 17.2g
	P 24%	 C 52%	 F 27%
    Takes:    1H15M
   Serves:   4
   ref:696
   https://www.jamieoliver.com/recipes/chicken-recipes/pukka-yellow-curry/

 33 Kerryann’s homemade fish fingers & minty smashed peas
   Calories: 388
   Protein: 36.3g Carbs:42.3g Fat: 9.5g
	P 37%	 C 44%	 F 22%
    Takes:    30minutes
   Serves:   4
   ref:507
   https://www.jamieoliver.com/recipes/fish-recipes/kerryann-s-homemade-fish-fingers-minty-smashed-peas/

 34 Wicked chicken with coleslaw
   Calories: 388
   Protein: 22.6g Carbs:49.9g Fat: 12.1g
	P 23%	 C 51%	 F 28%
    Takes:    50minutesplusmarinatingtime
   Serves:   4
   ref:1093
   https://www.jamieoliver.com/recipes/chicken-recipes/wicked-chicken-with-coleslaw/

 35 Chicken salpicao sub
   Calories: 509
   Protein: 32.2g Carbs:76.2g Fat: 10.1g
	P 25%	 C 60%	 F 18%
    Takes:    20minutes
   Serves:   4
   ref:206
   https://www.jamieoliver.com/recipes/chicken-recipes/chicken-salpicao-sub/

 36 Easy curried fish stew
   Calories: 454
   Protein: 30.9g Carbs:51.7g Fat: 15.1g
	P 27%	 C 46%	 F 30%
    Takes:    50minutes
   Serves:   6
   ref:304
   https://www.jamieoliver.com/recipes/fish-recipes/easy-curried-fish-stew/

 37 Jools' sweet pea & prawn pasta shells
   Calories: 418
   Protein: 26.1g Carbs:60.3g Fat: 7.2g
	P 25%	 C 58%	 F 16%
    Takes:    15minutes
   Serves:   4
   ref:487
   https://www.jamieoliver.com/recipes/pasta-recipes/jools-sweet-pea-prawn-pasta-shells/

 38 Little sole goujons with a quick lemon and caper sauce
   Calories: 470
   Protein: 31.6g Carbs:49.7g Fat: 14.0g
	P 27%	 C 42%	 F 27%
    Takes:    40minutes
   Serves:   4
   ref:532
   https://www.jamieoliver.com/recipes/fish-recipes/little-sole-goujons-with-a-quick-lemon-and-caper-sauce/

 39 Barbecued chicken dim sum
   Calories: 355
   Protein: 18.0g Carbs:47.9g Fat: 9.5g
	P 20%	 C 54%	 F 24%
    Takes:    NotAvailable
   Serves:   8
   ref:75
   https://www.jamieoliver.com/recipes/chicken-recipes/barbecued-chicken-dim-sum/

 40 Roasted chicken breast with lemony Bombay potatoes
   Calories: 349
   Protein: 33.6g Carbs:37.4g Fat: 8.7g
	P 39%	 C 43%	 F 22%
    Takes:    55minutes
   Serves:   1
   ref:764
   https://www.jamieoliver.com/recipes/chicken-recipes/roasted-chicken-breast-with-lemony-bombay-potatoes/

 41 Super-quick salmon gravadlax
   Calories: 457
   Protein: 25.6g Carbs:55.7g Fat: 14.9g
	P 22%	 C 49%	 F 29%
    Takes:    30minutespluscuringtime
   Serves:   4
   ref:966
   https://www.jamieoliver.com/recipes/fish-recipes/super-quick-salmon-gravadlax/

 42 Crab & fennel spaghetti
   Calories: 464
   Protein: 26.1g Carbs:63.9g Fat: 13.2g
	P 22%	 C 55%	 F 26%
    Takes:    18minutes
   Serves:   2
   ref:256
   https://www.jamieoliver.com/recipes/pasta-recipes/crab-fennel-spaghetti/

 43 Beef kofta curry
   Calories: 706
   Protein: 41.3g Carbs:79.8g Fat: 21.1g
	P 23%	 C 45%	 F 27%
    Takes:    15minutes
   Serves:   4
   ref:92
   https://www.jamieoliver.com/recipes/beef-recipes/beef-kofta-curry-with-fluffy-rice-beans-peas/

 44 Super-simple chicken curry traybake
   Calories: 553
   Protein: 31.8g Carbs:80.3g Fat: 14.4g
	P 23%	 C 58%	 F 23%
    Takes:    1H45M
   Serves:   6
   ref:967
   https://www.jamieoliver.com/recipes/chicken-recipes/super-simple-chicken-curry-traybake/

 45 Chicken noodle stir-fry
   Calories: 579
   Protein: 45.5g Carbs:60.7g Fat: 18.7g
	P 31%	 C 42%	 F 29%
    Takes:    16minutes
   Serves:   2
   ref:202
   https://www.jamieoliver.com/recipes/chicken-recipes/quick-and-easy-chicken-noodle-stir-fry/

 46 Vietnamese fish hot pot (Ca kho to)
   Calories: 336
   Protein: 31.2g Carbs:43.5g Fat: 3.8g
	P 37%	 C 52%	 F 10%
    Takes:    45minutes
   Serves:   4
   ref:1075
   https://www.jamieoliver.com/recipes/fish-recipes/vietnamese-fish-hot-pot-ca-kho-to/

 47 Meatballs & pasta
   Calories: 732
   Protein: 44.2g Carbs:84.4g Fat: 24.0g
	P 24%	 C 46%	 F 30%
    Takes:    45minutes
   Serves:   4
   ref:550
   https://www.jamieoliver.com/recipes/pasta-recipes/meatballs-and-pasta/

 48 Chicken & squash cacciatore
   Calories: 421
   Protein: 25.2g Carbs:45.1g Fat: 12.2g
	P 24%	 C 43%	 F 26%
    Takes:    1H20M
   Serves:   4
   ref:185
   https://www.jamieoliver.com/recipes/chicken-recipes/chicken-squash-cacciatore/

 49 Skinny carbonara
   Calories: 493
   Protein: 27.0g Carbs:63.6g Fat: 16.4g
	P 22%	 C 52%	 F 30%
    Takes:    20minutes
   Serves:   2
   ref:853
   https://www.jamieoliver.com/recipes/pasta-recipes/skinny-carbonara/

 50 Lobster mac 'n' cheese
   Calories: 849
   Protein: 43.7g Carbs:112.5g Fat: 25.7g
	P 21%	 C 53%	 F 27%
    Takes:    2hours
   Serves:   6
   ref:533
   https://www.jamieoliver.com/recipes/pasta-recipes/lobster-mac-n-cheese/

 51 Simple sushi salad
   Calories: 379
   Protein: 22.0g Carbs:42.7g Fat: 12.0g
	P 23%	 C 45%	 F 28%
    Takes:    35minutes
   Serves:   2
   ref:846
   https://www.jamieoliver.com/recipes/fish-recipes/simple-sushi-salad/

 52 Piri piri chicken
   Calories: 514
   Protein: 40.7g Carbs:52.9g Fat: 17.0g
	P 32%	 C 41%	 F 30%
    Takes:    1H15Mplusmarinating
   Serves:   4
   ref:667
   https://www.jamieoliver.com/recipes/chicken-recipes/piri-piri-chicken/

 53 Gallo pinto
   Calories: 394
   Protein: 21.1g Carbs:46.5g Fat: 12.8g
	P 21%	 C 47%	 F 29%
    Takes:    45minutes
   Serves:   4
   ref:353
   https://www.jamieoliver.com/recipes/eggs-recipes/gallo-pinto/

 54 Asian noodle broth with fish
   Calories: 636
   Protein: 39.7g Carbs:70.6g Fat: 21.2g
	P 25%	 C 44%	 F 30%
    Takes:    30minutes
   Serves:   4
   ref:23
   https://www.jamieoliver.com/recipes/fish-recipes/asian-noodle-broth-with-fish/

 55 Chicken & garlic bread kebabs
   Calories: 444
   Protein: 39.2g Carbs:45.0g Fat: 12.8g
	P 35%	 C 41%	 F 26%
    Takes:    30minutes
   Serves:   2
   ref:177
   https://www.jamieoliver.com/recipes/chicken-recipes/chicken-garlic-bread-kebabs/

 56 Southern fried chicken
   Calories: 523
   Protein: 27.0g Carbs:76.1g Fat: 13.9g
	P 21%	 C 58%	 F 24%
    Takes:    2H15Mplusbrining&tenderising
   Serves:   4
   ref:883
   https://www.jamieoliver.com/recipes/chicken-recipes/southern-fried-chicken/

 57 Mushroom & cauliflower penne
   Calories: 616
   Protein: 31.7g Carbs:82.5g Fat: 20.0g
	P 21%	 C 54%	 F 29%
    Takes:    25minutes
   Serves:   2
   ref:601
   https://www.jamieoliver.com/recipes/pasta-recipes/mushroom-cauliflower-penne/
tmp.head(2).T_____no_output_____tmp.iloc[1].ingredients_____no_output_____


# Notebook from gvvynplaine/lessons
Path: notebooks/02_Basics/04_Data_and_Models/04_PT_Data_and_Models.ipynb

# Data and Models
In the subsequent lessons, we will continue to learn deep learning. But we've ignored a fundamental concept about data and modeling: quality and quantity._____no_output_____

_____no_output_____In a nutshell, a machine learning model consumes input data and produces predictions. The quality of the predictions directly corresponds to the quality and quantity of data you train the model with; **garbage in, garbage out**. Check out this [article](https://venturebeat.com/2018/06/30/understanding-the-practical-applications-of-business-ai/) on where it makes sense to use AI and how to properly apply it._____no_output_____We're going to go through all the concepts with concrete code examples and some synthesized data to train our models on. The task is to determine whether a tumor will be benign (harmless) or malignant (harmful) based on leukocyte (white blood cells) count and blood pressure. This is a synethic dataset that we created and has no clinical relevance._____no_output_____# Full dataset_____no_output_____We'll first train a model with the entire dataset. Later we'll remove a subset of the dataset and see the effect it has on our model._____no_output_____## Data_____no_output_____### Load data_____no_output_____

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from pandas.plotting import scatter_matrix
import urllib_____no_output_____SEED = 1234
DATA_FILE = 'tumors.csv'_____no_output_____# Set seed for reproducibility
np.random.seed(SEED)_____no_output_____# Load data from GitHub to this notebook's local drive
url = "https://raw.githubusercontent.com/madewithml/lessons/master/data/tumors.csv"
response = urllib.request.urlopen(url)
html = response.read()
with open(DATA_FILE, 'wb') as fp:
    fp.write(html)_____no_output_____# Raw data
df = pd.read_csv(DATA_FILE, header=0)
df.head()_____no_output_____# Define X and y
X = df[['leukocyte_count', 'blood_pressure']].values
y = df['tumor_class'].values_____no_output_____# Plot data
colors = {'benign': 'red', 'malignant': 'blue'}
plt.scatter(X[:, 0], X[:, 1], c=[colors[_y] for _y in y], s=25, edgecolors='k')
plt.xlabel('leukocyte count')
plt.ylabel('blood pressure')
plt.legend(['malignant ', 'benign'], loc="upper right")
plt.show()_____no_output_____

We want to choose features that have strong predictive signal for our task. If you want to improve performance, you need to continuously do feature engineering by collecting and adding new signals. So you may run into a new feature that has high correlation (orthogonal signal) with your existing features but it may still possess some unique signal to boost your predictive performance. _____no_output_____

# Correlation matrix
scatter_matrix(df, figsize=(5, 5));
df.corr()_____no_output_____

### Split data_____no_output_____

import collections
from sklearn.model_selection import train_test_split_____no_output_____TRAIN_SIZE = 0.70
VAL_SIZE = 0.15
TEST_SIZE = 0.15
SHUFFLE = True_____no_output_____def train_val_test_split(X, y, val_size, test_size, shuffle):
    """Split data into train/val/test datasets.
    """
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=test_size, stratify=y, shuffle=shuffle)
    X_train, X_val, y_train, y_val = train_test_split(
        X_train, y_train, test_size=val_size, stratify=y_train, shuffle=shuffle)
    return X_train, X_val, X_test, y_train, y_val, y_test_____no_output_____# Create data splits
X_train, X_val, X_test, y_train, y_val, y_test = train_val_test_split(
    X=X, y=y, val_size=VAL_SIZE, test_size=TEST_SIZE, shuffle=SHUFFLE)
class_counts = dict(collections.Counter(y))
print (f"X_train: {X_train.shape}, y_train: {y_train.shape}")
print (f"X_val: {X_val.shape}, y_val: {y_val.shape}")
print (f"X_test: {X_test.shape}, y_test: {y_test.shape}")
print (f"Sample point: {X_train[0]} → {y_train[0]}")
print (f"Classes: {class_counts}")X_train: (722, 2), y_train: (722,)
X_val: (128, 2), y_val: (128,)
X_test: (150, 2), y_test: (150,)
Sample point: [18.01865938 15.48133647] → benign
Classes: {'malignant': 611, 'benign': 389}

### Label encoder_____no_output_____

from sklearn.preprocessing import LabelEncoder_____no_output_____# Output vectorizer
y_tokenizer = LabelEncoder()_____no_output_____# Fit on train data
y_tokenizer = y_tokenizer.fit(y_train)
classes = list(y_tokenizer.classes_)
print (f"classes: {classes}")classes: ['benign', 'malignant']
# Convert labels to tokens
print (f"y_train[0]: {y_train[0]}")
y_train = y_tokenizer.transform(y_train)
y_val = y_tokenizer.transform(y_val)
y_test = y_tokenizer.transform(y_test)
print (f"y_train[0]: {y_train[0]}")y_train[0]: benign
y_train[0]: 0
# Class weights
counts = collections.Counter(y_train)
class_weights = {_class: 1.0/count for _class, count in counts.items()}
print (f"class counts: {counts},\nclass weights: {class_weights}")class counts: Counter({1: 441, 0: 281}),
class weights: {0: 0.0035587188612099642, 1: 0.0022675736961451248}

### Standardize data_____no_output_____

from sklearn.preprocessing import StandardScaler_____no_output_____# Standardize the data (mean=0, std=1) using training data
X_scaler = StandardScaler().fit(X_train)_____no_output_____# Apply scaler on training and test data (don't standardize outputs for classification)
X_train = X_scaler.transform(X_train)
X_val = X_scaler.transform(X_val)
X_test = X_scaler.transform(X_test)_____no_output_____# Check (means should be ~0 and std should be ~1)
print (f"X_train[0]: mean: {np.mean(X_train[:, 0], axis=0):.1f}, std: {np.std(X_train[:, 0], axis=0):.1f}")
print (f"X_train[1]: mean: {np.mean(X_train[:, 1], axis=0):.1f}, std: {np.std(X_train[:, 1], axis=0):.1f}")
print (f"X_val[0]: mean: {np.mean(X_val[:, 0], axis=0):.1f}, std: {np.std(X_val[:, 0], axis=0):.1f}")
print (f"X_val[1]: mean: {np.mean(X_val[:, 1], axis=0):.1f}, std: {np.std(X_val[:, 1], axis=0):.1f}")
print (f"X_test[0]: mean: {np.mean(X_test[:, 0], axis=0):.1f}, std: {np.std(X_test[:, 0], axis=0):.1f}")
print (f"X_test[1]: mean: {np.mean(X_test[:, 1], axis=0):.1f}, std: {np.std(X_test[:, 1], axis=0):.1f}")X_train[0]: mean: 0.0, std: 1.0
X_train[1]: mean: -0.0, std: 1.0
X_val[0]: mean: 0.1, std: 1.0
X_val[1]: mean: 0.1, std: 1.0
X_test[0]: mean: -0.1, std: 1.0
X_test[1]: mean: -0.1, std: 1.0

## Modeling_____no_output_____

import torch_____no_output_____# Set seed for reproducibility
torch.manual_seed(SEED)_____no_output_____

### Model_____no_output_____

from torch import nn
import torch.nn.functional as F
from torchsummary import summary_____no_output_____INPUT_DIM = 2 # X is 2-dimensional
HIDDEN_DIM = 100
NUM_CLASSES = 2_____no_output_____class MLP(nn.Module):
    def __init__(self, input_dim, hidden_dim, num_classes):
        super(MLP, self).__init__()
        self.fc1 = nn.Linear(input_dim, hidden_dim)
        self.fc2 = nn.Linear(hidden_dim, num_classes)

    def forward(self, x_in, apply_softmax=False):
        z = F.relu(self.fc1(x_in)) # ReLU activaton function added!
        y_pred = self.fc2(z)
        if apply_softmax:
            y_pred = F.softmax(y_pred, dim=1)
        return y_pred_____no_output_____# Initialize model
model = MLP(input_dim=INPUT_DIM, hidden_dim=HIDDEN_DIM, num_classes=NUM_CLASSES)
print (model.named_parameters)
summary(model, input_size=(INPUT_DIM,))<bound method Module.named_parameters of MLP(
  (fc1): Linear(in_features=2, out_features=100, bias=True)
  (fc2): Linear(in_features=100, out_features=2, bias=True)
)>
----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Linear-1                  [-1, 100]             300
            Linear-2                    [-1, 2]             202
================================================================
Total params: 502
Trainable params: 502
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.00
Forward/backward pass size (MB): 0.00
Params size (MB): 0.00
Estimated Total Size (MB): 0.00
----------------------------------------------------------------

### Training_____no_output_____

from torch.optim import Adam_____no_output_____LEARNING_RATE = 1e-3
NUM_EPOCHS = 5
BATCH_SIZE = 32_____no_output_____# Loss
weights = torch.Tensor([class_weights[key] for key in sorted(class_weights.keys())])
loss_fn = nn.CrossEntropyLoss(weight=weights)_____no_output_____# Accuracy
def accuracy_fn(y_pred, y_true):
    n_correct = torch.eq(y_pred, y_true).sum().item()
    accuracy = (n_correct / len(y_pred)) * 100
    return accuracy_____no_output_____# Optimizer
optimizer = Adam(model.parameters(), lr=LEARNING_RATE) _____no_output_____# Convert data to tensors
X_train = torch.Tensor(X_train)
y_train = torch.LongTensor(y_train)
X_val = torch.Tensor(X_val)
y_val = torch.LongTensor(y_val)
X_test = torch.Tensor(X_test)
y_test = torch.LongTensor(y_test)_____no_output_____# Training
for epoch in range(NUM_EPOCHS*10):
    # Forward pass
    y_pred = model(X_train)

    # Loss
    loss = loss_fn(y_pred, y_train)

    # Zero all gradients
    optimizer.zero_grad()

    # Backward pass
    loss.backward()

    # Update weights
    optimizer.step()

    if epoch%10==0:
        predictions = y_pred.max(dim=1)[1] # class
        accuracy = accuracy_fn(y_pred=predictions, y_true=y_train)
        print (f"Epoch: {epoch} | loss: {loss:.2f}, accuracy: {accuracy:.1f}")Epoch: 0 | loss: 0.70, accuracy: 48.8
Epoch: 10 | loss: 0.55, accuracy: 91.7
Epoch: 20 | loss: 0.43, accuracy: 97.6
Epoch: 30 | loss: 0.36, accuracy: 98.2
Epoch: 40 | loss: 0.30, accuracy: 98.2

### Evaluation_____no_output_____

import itertools
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix_____no_output_____def plot_multiclass_decision_boundary(model, X, y):
    x_min, x_max = X[:, 0].min() - 0.1, X[:, 0].max() + 0.1
    y_min, y_max = X[:, 1].min() - 0.1, X[:, 1].max() + 0.1
    xx, yy = np.meshgrid(np.linspace(x_min, x_max, 101), np.linspace(y_min, y_max, 101))
    cmap = plt.cm.Spectral

    X_test = torch.from_numpy(np.c_[xx.ravel(), yy.ravel()]).float()
    y_pred = model(X_test, apply_softmax=True)
    _, y_pred = y_pred.max(dim=1)
    y_pred = y_pred.reshape(xx.shape)
    plt.contourf(xx, yy, y_pred, cmap=plt.cm.Spectral, alpha=0.8)
    plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.RdYlBu)
    plt.xlim(xx.min(), xx.max())
    plt.ylim(yy.min(), yy.max())_____no_output_____# Predictions
pred_train = model(X_train, apply_softmax=True)
pred_test = model(X_test, apply_softmax=True)
print (f"sample probability: {pred_test[0]}")
pred_train = pred_train.max(dim=1)[1]
pred_test = pred_test.max(dim=1)[1]
print (f"sample class: {pred_test[0]}")sample probability: tensor([0.3269, 0.6731], grad_fn=<SelectBackward>)
sample class: 1
# Accuracy
train_acc = accuracy_score(y_train, pred_train)
test_acc = accuracy_score(y_test, pred_test)
print (f"train acc: {train_acc:.2f}, test acc: {test_acc:.2f}")train acc: 0.98, test acc: 0.94

We're going to plot a white point, which we know belongs to the malignant tumor class. Our well trained model here would accurately predict that it is indeed a malignant tumor!_____no_output_____

# Visualize the decision boundary
plt.figure(figsize=(8,5))
plt.title("Test")
plot_multiclass_decision_boundary(model=model, X=X_test, y=y_test)

# Sample point near the decision boundary
mean_leukocyte_count, mean_blood_pressure = X_scaler.transform(
    [[np.mean(df.leukocyte_count), np.mean(df.blood_pressure)]])[0]
plt.scatter(mean_leukocyte_count+0.05, mean_blood_pressure-0.05, s=200,
            c='b', edgecolor='w', linewidth=2)

# Annotate
plt.annotate('true: malignant,\npred: malignant',
             color='white',
             xy=(mean_leukocyte_count, mean_blood_pressure),
             xytext=(0.4, 0.65),
             textcoords='figure fraction',
             fontsize=16,
             arrowprops=dict(facecolor='white', shrink=0.1))
plt.show()_____no_output_____

Great! We received great performances on both our train and test data splits. We're going to use this dataset to show the importance of data quality and quantity._____no_output_____# Reduced dataset_____no_output_____Let's remove some training data near the decision boundary and see how robust the model is now._____no_output_____## Data_____no_output_____### Load data_____no_output_____

REDUCED_DATA_FILE = 'tumors_reduced.csv'_____no_output_____# Load data from GitHub to this notebook's local drive
url = "https://raw.githubusercontent.com/madewithml/lessons/master/data/tumors_reduced.csv"
response = urllib.request.urlopen(url)
html = response.read()
with open(REDUCED_DATA_FILE, 'wb') as fp:
    fp.write(html)_____no_output_____# Raw reduced data
df_reduced = pd.read_csv(REDUCED_DATA_FILE, header=0)
df_reduced.head()_____no_output_____# Define X and y
X = df_reduced[['leukocyte_count', 'blood_pressure']].values
y = df_reduced['tumor_class'].values_____no_output_____# Plot data
colors = {'benign': 'red', 'malignant': 'blue'}
plt.scatter(X[:, 0], X[:, 1], c=[colors[_y] for _y in y], s=25, edgecolors='k')
plt.xlabel('leukocyte count')
plt.ylabel('blood pressure')
plt.legend(['malignant ', 'benign'], loc="upper right")
plt.show()_____no_output_____

### Split data_____no_output_____

# Create data splits
X_train, X_val, X_test, y_train, y_val, y_test = train_val_test_split(
    X, y, val_size=VAL_SIZE, test_size=TEST_SIZE, shuffle=SHUFFLE)
class_counts = dict(collections.Counter(y_train))
print (f"X_train: {X_train.shape}, y_train: {y_train.shape}")
print (f"X_val: {X_val.shape}, y_val: {y_val.shape}")
print (f"X_test: {X_test.shape}, y_test: {y_test.shape}")
print (f"Sample point: {X_train[0]} → {y_train[0]}")
print (f"Classes: {class_counts}")X_train: (520, 2), y_train: (520,)
X_val: (92, 2), y_val: (92,)
X_test: (108, 2), y_test: (108,)
Sample point: [14.4110029  13.14842457] → benign
Classes: {'benign': 281, 'malignant': 239}

### Label encoder_____no_output_____

# Encode class labels
y_tokenizer = LabelEncoder()
y_tokenizer = y_tokenizer.fit(y_train)
num_classes = len(y_tokenizer.classes_)
y_train = y_tokenizer.transform(y_train)
y_val = y_tokenizer.transform(y_val)
y_test = y_tokenizer.transform(y_test)_____no_output_____# Class weights
counts = collections.Counter(y_train)
class_weights = {_class: 1.0/count for _class, count in counts.items()}
print (f"class counts: {counts},\nclass weights: {class_weights}")class counts: Counter({0: 281, 1: 239}),
class weights: {0: 0.0035587188612099642, 1: 0.0041841004184100415}

### Standardize data_____no_output_____

# Standardize inputs using training data
X_scaler = StandardScaler().fit(X_train)
X_train = X_scaler.transform(X_train)
X_val = X_scaler.transform(X_val)
X_test = X_scaler.transform(X_test)_____no_output_____

## Modeling_____no_output_____### Model_____no_output_____

# Initialize model
model = MLP(input_dim=INPUT_DIM, hidden_dim=HIDDEN_DIM, num_classes=NUM_CLASSES)_____no_output_____

### Training_____no_output_____

# Optimizer
optimizer = Adam(model.parameters(), lr=LEARNING_RATE) _____no_output_____# Convert data to tensors
X_train = torch.Tensor(X_train)
y_train = torch.LongTensor(y_train)
X_val = torch.Tensor(X_val)
y_val = torch.LongTensor(y_val)
X_test = torch.Tensor(X_test)
y_test = torch.LongTensor(y_test)_____no_output_____# Training
for epoch in range(NUM_EPOCHS*10):
    # Forward pass
    y_pred = model(X_train)

    # Loss
    loss = loss_fn(y_pred, y_train)

    # Zero all gradients
    optimizer.zero_grad()

    # Backward pass
    loss.backward()

    # Update weights
    optimizer.step()

    if epoch%10==0:
        predictions = y_pred.max(dim=1)[1] # class
        accuracy = accuracy_fn(y_pred=predictions, y_true=y_train)
        print (f"Epoch: {epoch} | loss: {loss:.2f}, accuracy: {accuracy:.1f}")Epoch: 0 | loss: 0.70, accuracy: 49.6
Epoch: 10 | loss: 0.54, accuracy: 88.7
Epoch: 20 | loss: 0.42, accuracy: 97.3
Epoch: 30 | loss: 0.34, accuracy: 99.6
Epoch: 40 | loss: 0.27, accuracy: 100.0

### Evaluation_____no_output_____

# Predictions
pred_train = model(X_train, apply_softmax=True)
pred_test = model(X_test, apply_softmax=True)
print (f"sample probability: {pred_test[0]}")
pred_train = pred_train.max(dim=1)[1]
pred_test = pred_test.max(dim=1)[1]
print (f"sample class: {pred_test[0]}")sample probability: tensor([0.9436, 0.0564], grad_fn=<SelectBackward>)
sample class: 0
# Accuracy
train_acc = accuracy_score(y_train, pred_train)
test_acc = accuracy_score(y_test, pred_test)
print (f"train acc: {train_acc:.2f}, test acc: {test_acc:.2f}")train acc: 1.00, test acc: 1.00
# Visualize the decision boundary
plt.figure(figsize=(8,5))
plt.title("Test")
plot_multiclass_decision_boundary(model=model, X=X_test, y=y_test)

# Sample point near the decision boundary (same point as before)
plt.scatter(mean_leukocyte_count+0.05, mean_blood_pressure-0.05, s=200,
            c='b', edgecolor='w', linewidth=2)

# Annotate
plt.annotate('true: malignant,\npred: benign',
             color='white',
             xy=(mean_leukocyte_count, mean_blood_pressure),
             xytext=(0.45, 0.60),
             textcoords='figure fraction',
             fontsize=16,
             arrowprops=dict(facecolor='white', shrink=0.1))
plt.show()_____no_output_____

This is a very scary but highly realistic scenario. Based on our reduced synthetic dataset, we have achieved a model that generalized really well on the test data. But when we ask for the prediction for the same point tested earlier (which we known is malignant), the prediction is now a benign tumor. We would have completely missed the tumor. To mitigate this, we can:
1. Get more data around the space we are concerned about
2. Consume predictions with caution when they are close to the decision boundary_____no_output_____# Takeaway_____no_output_____Models are not crystal balls. So it's important that before any machine learning, we really look at our data and ask ourselves if it is truly representative for the task we want to solve. The model itself may fit really well and generalize well on your data but if the data is of poor quality to begin with, the model cannot be trusted._____no_output_____Once you are confident that your data is of good quality and quantity, you can finally start thinking about modeling. The type of model you choose depends on many factors, including the task, type of data, complexity required, etc.

So once you figure out what type of model your task needs, start with simple models and then slowly add complexity. You don’t want to start with neural networks right away because that may not be right model for your data and task. Striking this balance in model complexity is one of the key tasks of your data scientists. **simple models → complex models**

_____no_output_____---
Share and discover ML projects at Made With ML.

             _____no_output_____


# Notebook from jadetangyy0820/CLIP
Path: notebooks/Prompt_Engineering_for_ImageNet.ipynb

# Preparation for Colab

Make sure you're running a GPU runtime; if not, select "GPU" as the hardware accelerator in Runtime > Change Runtime Type in the menu. The next cells will install the `clip` package and its dependencies, and check if PyTorch 1.7.1 or later is installed._____no_output_____

! pip install ftfy regex tqdm
! pip install git+https://github.com/openai/CLIP.gitCollecting ftfy
  Downloading ftfy-6.0.3.tar.gz (64 kB)

     |█████                           | 10 kB 14.9 MB/s eta 0:00:01
     |██████████▏                     | 20 kB 18.7 MB/s eta 0:00:01
     |███████████████▎                | 30 kB 9.0 MB/s eta 0:00:01
     |████████████████████▍           | 40 kB 4.1 MB/s eta 0:00:01
     |█████████████████████████▌      | 51 kB 4.6 MB/s eta 0:00:01
     |██████████████████████████████▋ | 61 kB 4.7 MB/s eta 0:00:01
     |████████████████████████████████| 64 kB 1.3 MB/s
Requirement already satisfied: regex in /usr/local/lib/python3.7/dist-packages (2019.12.20)
Requirement already satisfied: tqdm in /usr/local/lib/python3.7/dist-packages (4.41.1)
Requirement already satisfied: wcwidth in /usr/local/lib/python3.7/dist-packages (from ftfy) (0.2.5)
Building wheels for collected packages: ftfy
  Building wheel for ftfy (setup.py) ... done
  Created wheel for ftfy: filename=ftfy-6.0.3-py3-none-any.whl size=41934 sha256=90ec193331444b2c4ff1cd81935e7de42065b89d304db7efac67bcfd87c27873
  Stored in directory: /root/.cache/pip/wheels/19/f5/38/273eb3b5e76dfd850619312f693716ac4518b498f5ffb6f56d
Successfully built ftfy
Installing collected packages: ftfy
Successfully installed ftfy-6.0.3
Collecting git+https://github.com/openai/CLIP.git
  Cloning https://github.com/openai/CLIP.git to /tmp/pip-req-build-hqnbveqi
  Running command git clone -q https://github.com/openai/CLIP.git /tmp/pip-req-build-hqnbveqi
Requirement already satisfied: ftfy in /usr/local/lib/python3.7/dist-packages (from clip==1.0) (6.0.3)
Requirement already satisfied: regex in /usr/local/lib/python3.7/dist-packages (from clip==1.0) (2019.12.20)
Requirement already satisfied: tqdm in /usr/local/lib/python3.7/dist-packages (from clip==1.0) (4.41.1)
Requirement already satisfied: torch in /usr/local/lib/python3.7/dist-packages (from clip==1.0) (1.9.0+cu102)
Requirement already satisfied: torchvision in /usr/local/lib/python3.7/dist-packages (from clip==1.0) (0.10.0+cu102)
Requirement already satisfied: wcwidth in /usr/local/lib/python3.7/dist-packages (from ftfy->clip==1.0) (0.2.5)
Requirement already satisfied: typing-extensions in /usr/local/lib/python3.7/dist-packages (from torch->clip==1.0) (3.7.4.3)
Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from torchvision->clip==1.0) (1.19.5)
Requirement already satisfied: pillow>=5.3.0 in /usr/local/lib/python3.7/dist-packages (from torchvision->clip==1.0) (7.1.2)
Building wheels for collected packages: clip
  Building wheel for clip (setup.py) ... done
  Created wheel for clip: filename=clip-1.0-py3-none-any.whl size=1369080 sha256=fda43d2b80cfb2b33c2d43e23ea5f53293a9a8b48d5f9e341de527f6adfbf5a3
  Stored in directory: /tmp/pip-ephem-wheel-cache-kmmplf44/wheels/fd/b9/c3/5b4470e35ed76e174bff77c92f91da82098d5e35fd5bc8cdac
Successfully built clip
Installing collected packages: clip
Successfully installed clip-1.0
import numpy as np
import torch
import clip
from tqdm.notebook import tqdm

print("Torch version:", torch.__version__)

assert torch.__version__.split(".") >= ["1", "7", "1"], "PyTorch 1.7.1 or later is required"Torch version: 1.9.0+cu102

# Loading the model

Download and instantiate a CLIP model using the `clip` module that we just installed._____no_output_____

clip.available_models()_____no_output_____model, preprocess = clip.load("ViT-B/32")100%|███████████████████████████████████████| 338M/338M [00:05<00:00, 63.6MiB/s]
input_resolution = model.visual.input_resolution
context_length = model.context_length
vocab_size = model.vocab_size

print("Model parameters:", f"{np.sum([int(np.prod(p.shape)) for p in model.parameters()]):,}")
print("Input resolution:", input_resolution)
print("Context length:", context_length)
print("Vocab size:", vocab_size)Model parameters: 151,277,313
Input resolution: 224
Context length: 77
Vocab size: 49408

# Preparing ImageNet labels and prompts

The following cell contains the 1,000 labels for the ImageNet dataset, followed by the text templates we'll use as "prompt engineering"._____no_output_____

imagenet_classes = ["tench", "goldfish", "great white shark", "tiger shark", "hammerhead shark", "electric ray", "stingray", "rooster", "hen", "ostrich", "brambling", "goldfinch", "house finch", "junco", "indigo bunting", "American robin", "bulbul", "jay", "magpie", "chickadee", "American dipper", "kite (bird of prey)", "bald eagle", "vulture", "great grey owl", "fire salamander", "smooth newt", "newt", "spotted salamander", "axolotl", "American bullfrog", "tree frog", "tailed frog", "loggerhead sea turtle", "leatherback sea turtle", "mud turtle", "terrapin", "box turtle", "banded gecko", "green iguana", "Carolina anole", "desert grassland whiptail lizard", "agama", "frilled-necked lizard", "alligator lizard", "Gila monster", "European green lizard", "chameleon", "Komodo dragon", "Nile crocodile", "American alligator", "triceratops", "worm snake", "ring-necked snake", "eastern hog-nosed snake", "smooth green snake", "kingsnake", "garter snake", "water snake", "vine snake", "night snake", "boa constrictor", "African rock python", "Indian cobra", "green mamba", "sea snake", "Saharan horned viper", "eastern diamondback rattlesnake", "sidewinder rattlesnake", "trilobite", "harvestman", "scorpion", "yellow garden spider", "barn spider", "European garden spider", "southern black widow", "tarantula", "wolf spider", "tick", "centipede", "black grouse", "ptarmigan", "ruffed grouse", "prairie grouse", "peafowl", "quail", "partridge", "african grey parrot", "macaw", "sulphur-crested cockatoo", "lorikeet", "coucal", "bee eater", "hornbill", "hummingbird", "jacamar", "toucan", "duck", "red-breasted merganser", "goose", "black swan", "tusker", "echidna", "platypus", "wallaby", "koala", "wombat", "jellyfish", "sea anemone", "brain coral", "flatworm", "nematode", "conch", "snail", "slug", "sea slug", "chiton", "chambered nautilus", "Dungeness crab", "rock crab", "fiddler crab", "red king crab", "American lobster", "spiny lobster", "crayfish", "hermit crab", "isopod", "white stork", "black stork", "spoonbill", "flamingo", "little blue heron", "great egret", "bittern bird", "crane bird", "limpkin", "common gallinule", "American coot", "bustard", "ruddy turnstone", "dunlin", "common redshank", "dowitcher", "oystercatcher", "pelican", "king penguin", "albatross", "grey whale", "killer whale", "dugong", "sea lion", "Chihuahua", "Japanese Chin", "Maltese", "Pekingese", "Shih Tzu", "King Charles Spaniel", "Papillon", "toy terrier", "Rhodesian Ridgeback", "Afghan Hound", "Basset Hound", "Beagle", "Bloodhound", "Bluetick Coonhound", "Black and Tan Coonhound", "Treeing Walker Coonhound", "English foxhound", "Redbone Coonhound", "borzoi", "Irish Wolfhound", "Italian Greyhound", "Whippet", "Ibizan Hound", "Norwegian Elkhound", "Otterhound", "Saluki", "Scottish Deerhound", "Weimaraner", "Staffordshire Bull Terrier", "American Staffordshire Terrier", "Bedlington Terrier", "Border Terrier", "Kerry Blue Terrier", "Irish Terrier", "Norfolk Terrier", "Norwich Terrier", "Yorkshire Terrier", "Wire Fox Terrier", "Lakeland Terrier", "Sealyham Terrier", "Airedale Terrier", "Cairn Terrier", "Australian Terrier", "Dandie Dinmont Terrier", "Boston Terrier", "Miniature Schnauzer", "Giant Schnauzer", "Standard Schnauzer", "Scottish Terrier", "Tibetan Terrier", "Australian Silky Terrier", "Soft-coated Wheaten Terrier", "West Highland White Terrier", "Lhasa Apso", "Flat-Coated Retriever", "Curly-coated Retriever", "Golden Retriever", "Labrador Retriever", "Chesapeake Bay Retriever", "German Shorthaired Pointer", "Vizsla", "English Setter", "Irish Setter", "Gordon Setter", "Brittany dog", "Clumber Spaniel", "English Springer Spaniel", "Welsh Springer Spaniel", "Cocker Spaniel", "Sussex Spaniel", "Irish Water Spaniel", "Kuvasz", "Schipperke", "Groenendael dog", "Malinois", "Briard", "Australian Kelpie", "Komondor", "Old English Sheepdog", "Shetland Sheepdog", "collie", "Border Collie", "Bouvier des Flandres dog", "Rottweiler", "German Shepherd Dog", "Dobermann", "Miniature Pinscher", "Greater Swiss Mountain Dog", "Bernese Mountain Dog", "Appenzeller Sennenhund", "Entlebucher Sennenhund", "Boxer", "Bullmastiff", "Tibetan Mastiff", "French Bulldog", "Great Dane", "St. Bernard", "husky", "Alaskan Malamute", "Siberian Husky", "Dalmatian", "Affenpinscher", "Basenji", "pug", "Leonberger", "Newfoundland dog", "Great Pyrenees dog", "Samoyed", "Pomeranian", "Chow Chow", "Keeshond", "brussels griffon", "Pembroke Welsh Corgi", "Cardigan Welsh Corgi", "Toy Poodle", "Miniature Poodle", "Standard Poodle", "Mexican hairless dog (xoloitzcuintli)", "grey wolf", "Alaskan tundra wolf", "red wolf or maned wolf", "coyote", "dingo", "dhole", "African wild dog", "hyena", "red fox", "kit fox", "Arctic fox", "grey fox", "tabby cat", "tiger cat", "Persian cat", "Siamese cat", "Egyptian Mau", "cougar", "lynx", "leopard", "snow leopard", "jaguar", "lion", "tiger", "cheetah", "brown bear", "American black bear", "polar bear", "sloth bear", "mongoose", "meerkat", "tiger beetle", "ladybug", "ground beetle", "longhorn beetle", "leaf beetle", "dung beetle", "rhinoceros beetle", "weevil", "fly", "bee", "ant", "grasshopper", "cricket insect", "stick insect", "cockroach", "praying mantis", "cicada", "leafhopper", "lacewing", "dragonfly", "damselfly", "red admiral butterfly", "ringlet butterfly", "monarch butterfly", "small white butterfly", "sulphur butterfly", "gossamer-winged butterfly", "starfish", "sea urchin", "sea cucumber", "cottontail rabbit", "hare", "Angora rabbit", "hamster", "porcupine", "fox squirrel", "marmot", "beaver", "guinea pig", "common sorrel horse", "zebra", "pig", "wild boar", "warthog", "hippopotamus", "ox", "water buffalo", "bison", "ram (adult male sheep)", "bighorn sheep", "Alpine ibex", "hartebeest", "impala (antelope)", "gazelle", "arabian camel", "llama", "weasel", "mink", "European polecat", "black-footed ferret", "otter", "skunk", "badger", "armadillo", "three-toed sloth", "orangutan", "gorilla", "chimpanzee", "gibbon", "siamang", "guenon", "patas monkey", "baboon", "macaque", "langur", "black-and-white colobus", "proboscis monkey", "marmoset", "white-headed capuchin", "howler monkey", "titi monkey", "Geoffroy's spider monkey", "common squirrel monkey", "ring-tailed lemur", "indri", "Asian elephant", "African bush elephant", "red panda", "giant panda", "snoek fish", "eel", "silver salmon", "rock beauty fish", "clownfish", "sturgeon", "gar fish", "lionfish", "pufferfish", "abacus", "abaya", "academic gown", "accordion", "acoustic guitar", "aircraft carrier", "airliner", "airship", "altar", "ambulance", "amphibious vehicle", "analog clock", "apiary", "apron", "trash can", "assault rifle", "backpack", "bakery", "balance beam", "balloon", "ballpoint pen", "Band-Aid", "banjo", "baluster / handrail", "barbell", "barber chair", "barbershop", "barn", "barometer", "barrel", "wheelbarrow", "baseball", "basketball", "bassinet", "bassoon", "swimming cap", "bath towel", "bathtub", "station wagon", "lighthouse", "beaker", "military hat (bearskin or shako)", "beer bottle", "beer glass", "bell tower", "baby bib", "tandem bicycle", "bikini", "ring binder", "binoculars", "birdhouse", "boathouse", "bobsleigh", "bolo tie", "poke bonnet", "bookcase", "bookstore", "bottle cap", "hunting bow", "bow tie", "brass memorial plaque", "bra", "breakwater", "breastplate", "broom", "bucket", "buckle", "bulletproof vest", "high-speed train", "butcher shop", "taxicab", "cauldron", "candle", "cannon", "canoe", "can opener", "cardigan", "car mirror", "carousel", "tool kit", "cardboard box / carton", "car wheel", "automated teller machine", "cassette", "cassette player", "castle", "catamaran", "CD player", "cello", "mobile phone", "chain", "chain-link fence", "chain mail", "chainsaw", "storage chest", "chiffonier", "bell or wind chime", "china cabinet", "Christmas stocking", "church", "movie theater", "cleaver", "cliff dwelling", "cloak", "clogs", "cocktail shaker", "coffee mug", "coffeemaker", "spiral or coil", "combination lock", "computer keyboard", "candy store", "container ship", "convertible", "corkscrew", "cornet", "cowboy boot", "cowboy hat", "cradle", "construction crane", "crash helmet", "crate", "infant bed", "Crock Pot", "croquet ball", "crutch", "cuirass", "dam", "desk", "desktop computer", "rotary dial telephone", "diaper", "digital clock", "digital watch", "dining table", "dishcloth", "dishwasher", "disc brake", "dock", "dog sled", "dome", "doormat", "drilling rig", "drum", "drumstick", "dumbbell", "Dutch oven", "electric fan", "electric guitar", "electric locomotive", "entertainment center", "envelope", "espresso machine", "face powder", "feather boa", "filing cabinet", "fireboat", "fire truck", "fire screen", "flagpole", "flute", "folding chair", "football helmet", "forklift", "fountain", "fountain pen", "four-poster bed", "freight car", "French horn", "frying pan", "fur coat", "garbage truck", "gas mask or respirator", "gas pump", "goblet", "go-kart", "golf ball", "golf cart", "gondola", "gong", "gown", "grand piano", "greenhouse", "radiator grille", "grocery store", "guillotine", "hair clip", "hair spray", "half-track", "hammer", "hamper", "hair dryer", "hand-held computer", "handkerchief", "hard disk drive", "harmonica", "harp", "combine harvester", "hatchet", "holster", "home theater", "honeycomb", "hook", "hoop skirt", "gymnastic horizontal bar", "horse-drawn vehicle", "hourglass", "iPod", "clothes iron", "carved pumpkin", "jeans", "jeep", "T-shirt", "jigsaw puzzle", "rickshaw", "joystick", "kimono", "knee pad", "knot", "lab coat", "ladle", "lampshade", "laptop computer", "lawn mower", "lens cap", "letter opener", "library", "lifeboat", "lighter", "limousine", "ocean liner", "lipstick", "slip-on shoe", "lotion", "music speaker", "loupe magnifying glass", "sawmill", "magnetic compass", "messenger bag", "mailbox", "tights", "one-piece bathing suit", "manhole cover", "maraca", "marimba", "mask", "matchstick", "maypole", "maze", "measuring cup", "medicine cabinet", "megalith", "microphone", "microwave oven", "military uniform", "milk can", "minibus", "miniskirt", "minivan", "missile", "mitten", "mixing bowl", "mobile home", "ford model t", "modem", "monastery", "monitor", "moped", "mortar and pestle", "graduation cap", "mosque", "mosquito net", "vespa", "mountain bike", "tent", "computer mouse", "mousetrap", "moving van", "muzzle", "metal nail", "neck brace", "necklace", "baby pacifier", "notebook computer", "obelisk", "oboe", "ocarina", "odometer", "oil filter", "pipe organ", "oscilloscope", "overskirt", "bullock cart", "oxygen mask", "product packet / packaging", "paddle", "paddle wheel", "padlock", "paintbrush", "pajamas", "palace", "pan flute", "paper towel", "parachute", "parallel bars", "park bench", "parking meter", "railroad car", "patio", "payphone", "pedestal", "pencil case", "pencil sharpener", "perfume", "Petri dish", "photocopier", "plectrum", "Pickelhaube", "picket fence", "pickup truck", "pier", "piggy bank", "pill bottle", "pillow", "ping-pong ball", "pinwheel", "pirate ship", "drink pitcher", "block plane", "planetarium", "plastic bag", "plate rack", "farm plow", "plunger", "Polaroid camera", "pole", "police van", "poncho", "pool table", "soda bottle", "plant pot", "potter's wheel", "power drill", "prayer rug", "printer", "prison", "missile", "projector", "hockey puck", "punching bag", "purse", "quill", "quilt", "race car", "racket", "radiator", "radio", "radio telescope", "rain barrel", "recreational vehicle", "fishing casting reel", "reflex camera", "refrigerator", "remote control", "restaurant", "revolver", "rifle", "rocking chair", "rotisserie", "eraser", "rugby ball", "ruler measuring stick", "sneaker", "safe", "safety pin", "salt shaker", "sandal", "sarong", "saxophone", "scabbard", "weighing scale", "school bus", "schooner", "scoreboard", "CRT monitor", "screw", "screwdriver", "seat belt", "sewing machine", "shield", "shoe store", "shoji screen / room divider", "shopping basket", "shopping cart", "shovel", "shower cap", "shower curtain", "ski", "balaclava ski mask", "sleeping bag", "slide rule", "sliding door", "slot machine", "snorkel", "snowmobile", "snowplow", "soap dispenser", "soccer ball", "sock", "solar thermal collector", "sombrero", "soup bowl", "keyboard space bar", "space heater", "space shuttle", "spatula", "motorboat", "spider web", "spindle", "sports car", "spotlight", "stage", "steam locomotive", "through arch bridge", "steel drum", "stethoscope", "scarf", "stone wall", "stopwatch", "stove", "strainer", "tram", "stretcher", "couch", "stupa", "submarine", "suit", "sundial", "sunglasses", "sunglasses", "sunscreen", "suspension bridge", "mop", "sweatshirt", "swim trunks / shorts", "swing", "electrical switch", "syringe", "table lamp", "tank", "tape player", "teapot", "teddy bear", "television", "tennis ball", "thatched roof", "front curtain", "thimble", "threshing machine", "throne", "tile roof", "toaster", "tobacco shop", "toilet seat", "torch", "totem pole", "tow truck", "toy store", "tractor", "semi-trailer truck", "tray", "trench coat", "tricycle", "trimaran", "tripod", "triumphal arch", "trolleybus", "trombone", "hot tub", "turnstile", "typewriter keyboard", "umbrella", "unicycle", "upright piano", "vacuum cleaner", "vase", "vaulted or arched ceiling", "velvet fabric", "vending machine", "vestment", "viaduct", "violin", "volleyball", "waffle iron", "wall clock", "wallet", "wardrobe", "military aircraft", "sink", "washing machine", "water bottle", "water jug", "water tower", "whiskey jug", "whistle", "hair wig", "window screen", "window shade", "Windsor tie", "wine bottle", "airplane wing", "wok", "wooden spoon", "wool", "split-rail fence", "shipwreck", "sailboat", "yurt", "website", "comic book", "crossword", "traffic or street sign", "traffic light", "dust jacket", "menu", "plate", "guacamole", "consomme", "hot pot", "trifle", "ice cream", "popsicle", "baguette", "bagel", "pretzel", "cheeseburger", "hot dog", "mashed potatoes", "cabbage", "broccoli", "cauliflower", "zucchini", "spaghetti squash", "acorn squash", "butternut squash", "cucumber", "artichoke", "bell pepper", "cardoon", "mushroom", "Granny Smith apple", "strawberry", "orange", "lemon", "fig", "pineapple", "banana", "jackfruit", "cherimoya (custard apple)", "pomegranate", "hay", "carbonara", "chocolate syrup", "dough", "meatloaf", "pizza", "pot pie", "burrito", "red wine", "espresso", "tea cup", "eggnog", "mountain", "bubble", "cliff", "coral reef", "geyser", "lakeshore", "promontory", "sandbar", "beach", "valley", "volcano", "baseball player", "bridegroom", "scuba diver", "rapeseed", "daisy", "yellow lady's slipper", "corn", "acorn", "rose hip", "horse chestnut seed", "coral fungus", "agaric", "gyromitra", "stinkhorn mushroom", "earth star fungus", "hen of the woods mushroom", "bolete", "corn cob", "toilet paper"]_____no_output_____

A subset of these class names are modified from the default ImageNet class names sourced from Anish Athalye's imagenet-simple-labels.

These edits were made via trial and error and concentrated on the lowest performing classes according to top_1 and top_5 accuracy on the ImageNet training set for the RN50, RN101, and RN50x4 models. These tweaks improve top_1 by 1.5% on ViT-B/32 over using the default class names. Alec got bored somewhere along the way as gains started to diminish and never finished updating / tweaking the list. He also didn't revisit this with the better performing RN50x16, RN50x64, or any of the ViT models. He thinks it's likely another 0.5% to 1% top_1 could be gained from further work here. It'd be interesting to more rigorously study / understand this.

Some examples beyond the crane/crane -> construction crane / bird crane issue mentioned in Section 3.1.4 of the paper include:

- CLIP interprets "nail" as "fingernail" so we changed the label to "metal nail".
- ImageNet kite class refers to the bird of prey, not the flying toy, so we changed "kite" to "kite (bird of prey)"
- The ImageNet class for red wolf seems to include a lot of mislabeled maned wolfs so we changed "red wolf" to "red wolf or maned wolf"_____no_output_____

imagenet_templates = [
    'a bad photo of a {}.',
    'a photo of many {}.',
    'a sculpture of a {}.',
    'a photo of the hard to see {}.',
    'a low resolution photo of the {}.',
    'a rendering of a {}.',
    'graffiti of a {}.',
    'a bad photo of the {}.',
    'a cropped photo of the {}.',
    'a tattoo of a {}.',
    'the embroidered {}.',
    'a photo of a hard to see {}.',
    'a bright photo of a {}.',
    'a photo of a clean {}.',
    'a photo of a dirty {}.',
    'a dark photo of the {}.',
    'a drawing of a {}.',
    'a photo of my {}.',
    'the plastic {}.',
    'a photo of the cool {}.',
    'a close-up photo of a {}.',
    'a black and white photo of the {}.',
    'a painting of the {}.',
    'a painting of a {}.',
    'a pixelated photo of the {}.',
    'a sculpture of the {}.',
    'a bright photo of the {}.',
    'a cropped photo of a {}.',
    'a plastic {}.',
    'a photo of the dirty {}.',
    'a jpeg corrupted photo of a {}.',
    'a blurry photo of the {}.',
    'a photo of the {}.',
    'a good photo of the {}.',
    'a rendering of the {}.',
    'a {} in a video game.',
    'a photo of one {}.',
    'a doodle of a {}.',
    'a close-up photo of the {}.',
    'a photo of a {}.',
    'the origami {}.',
    'the {} in a video game.',
    'a sketch of a {}.',
    'a doodle of the {}.',
    'a origami {}.',
    'a low resolution photo of a {}.',
    'the toy {}.',
    'a rendition of the {}.',
    'a photo of the clean {}.',
    'a photo of a large {}.',
    'a rendition of a {}.',
    'a photo of a nice {}.',
    'a photo of a weird {}.',
    'a blurry photo of a {}.',
    'a cartoon {}.',
    'art of a {}.',
    'a sketch of the {}.',
    'a embroidered {}.',
    'a pixelated photo of a {}.',
    'itap of the {}.',
    'a jpeg corrupted photo of the {}.',
    'a good photo of a {}.',
    'a plushie {}.',
    'a photo of the nice {}.',
    'a photo of the small {}.',
    'a photo of the weird {}.',
    'the cartoon {}.',
    'art of the {}.',
    'a drawing of the {}.',
    'a photo of the large {}.',
    'a black and white photo of a {}.',
    'the plushie {}.',
    'a dark photo of a {}.',
    'itap of a {}.',
    'graffiti of the {}.',
    'a toy {}.',
    'itap of my {}.',
    'a photo of a cool {}.',
    'a photo of a small {}.',
    'a tattoo of the {}.',
]

print(f"{len(imagenet_classes)} classes, {len(imagenet_templates)} templates")1000 classes, 80 templates

A similar, intuition-guided trial and error based on the ImageNet training set was used for templates. This list is pretty haphazard and was gradually made / expanded over the course of about a year of the project and was revisited / tweaked every few months. A surprising / weird thing was adding templates intended to help ImageNet-R performance (specifying different possible renditions of an object) improved standard ImageNet accuracy too.

After the 80 templates were "locked" for the paper, we ran sequential forward selection over the list of 80 templates. The search terminated after ensembling 7 templates and selected them in the order below.

1. itap of a {}.
2. a bad photo of the {}.
3. a origami {}.
4. a photo of the large {}.
5. a {} in a video game.
6. art of the {}.
7. a photo of the small {}.

Speculating, we think it's interesting to see different scales (large and small), a difficult view (a bad photo), and "abstract" versions (origami, video game, art), were all selected for, but we haven't studied this in any detail. This subset performs a bit better than the full 80 ensemble reported in the paper, especially for the smaller models._____no_output_____# Loading the Images

The ILSVRC2012 datasets are no longer available for download publicly. We instead download the ImageNet-V2 dataset by [Recht et al.](https://arxiv.org/abs/1902.10811).

If you have the ImageNet dataset downloaded, you can replace the dataset with the official torchvision loader, e.g.:

```python
images = torchvision.datasets.ImageNet("path/to/imagenet", split='val', transform=preprocess)
```_____no_output_____

! pip install git+https://github.com/modestyachts/ImageNetV2_pytorch

from imagenetv2_pytorch import ImageNetV2Dataset

images = ImageNetV2Dataset(transform=preprocess)
loader = torch.utils.data.DataLoader(images, batch_size=32, num_workers=2)Collecting git+https://github.com/modestyachts/ImageNetV2_pytorch
  Cloning https://github.com/modestyachts/ImageNetV2_pytorch to /tmp/pip-req-build-0kih0kn2
  Running command git clone -q https://github.com/modestyachts/ImageNetV2_pytorch /tmp/pip-req-build-0kih0kn2
Building wheels for collected packages: imagenetv2-pytorch
  Building wheel for imagenetv2-pytorch (setup.py) ... done
  Created wheel for imagenetv2-pytorch: filename=imagenetv2_pytorch-0.1-py3-none-any.whl size=2663 sha256=ac31e0ed9c61afc5e0271eed315d3a82844a79ae64f8ce43fc1c98928cec129f
  Stored in directory: /tmp/pip-ephem-wheel-cache-745b5n1m/wheels/ab/ee/f4/73bce5c7f68d28ce632ef33ae87ce60aaca021eb2b3b31a6fa
Successfully built imagenetv2-pytorch
Installing collected packages: imagenetv2-pytorch
Successfully installed imagenetv2-pytorch-0.1
Dataset matched-frequency not found on disk, downloading....

# Creating zero-shot classifier weights_____no_output_____

def zeroshot_classifier(classnames, templates):
    with torch.no_grad():
        zeroshot_weights = []
        for classname in tqdm(classnames):
            texts = [template.format(classname) for template in templates] #format with class
            texts = clip.tokenize(texts).cuda() #tokenize
            class_embeddings = model.encode_text(texts) #embed with text encoder
            class_embeddings /= class_embeddings.norm(dim=-1, keepdim=True)
            class_embedding = class_embeddings.mean(dim=0)
            class_embedding /= class_embedding.norm()
            zeroshot_weights.append(class_embedding)
        zeroshot_weights = torch.stack(zeroshot_weights, dim=1).cuda()
    return zeroshot_weights

zeroshot_weights = zeroshot_classifier(imagenet_classes, imagenet_templates)_____no_output_____

# Zero-shot prediction_____no_output_____

def accuracy(output, target, topk=(1,)):
    pred = output.topk(max(topk), 1, True, True)[1].t()
    correct = pred.eq(target.view(1, -1).expand_as(pred))
    return [float(correct[:k].reshape(-1).float().sum(0, keepdim=True).cpu().numpy()) for k in topk]_____no_output_____with torch.no_grad():
    top1, top5, n = 0., 0., 0.
    for i, (images, target) in enumerate(tqdm(loader)):
        images = images.cuda()
        target = target.cuda()

        # predict
        image_features = model.encode_image(images)
        image_features /= image_features.norm(dim=-1, keepdim=True)
        logits = 100. * image_features @ zeroshot_weights

        # measure accuracy
        acc1, acc5 = accuracy(logits, target, topk=(1, 5))
        top1 += acc1
        top5 += acc5
        n += images.size(0)

top1 = (top1 / n) * 100
top5 = (top5 / n) * 100

print(f"Top-1 accuracy: {top1:.2f}")
print(f"Top-5 accuracy: {top5:.2f}")_____no_output_____


# Notebook from GuignardLab/sc3D
Path: Test-embryo.ipynb

import json
from matplotlib import pyplot as plt
import numpy as np
from sc3D import Embryo

corres_tissues = 'data/corresptissues.json'
with open('data/tissuescolor.json') as f:
    colors_paper = json.load(f)
    colors_paper = {eval(k): v for k, v in colors_paper.items()}
%matplotlib inline_____no_output_____

# Setting up parameters
Note that it is necessary to download the E8.5.h5ad dataset!

The dataset can be found [there](https://figshare.com/s/9c73df7fd39e3ca5422d)._____no_output_____

# Path to the input data
data_path = 'data/E8.5.h5ad'
# Path to the output folder
output_folder = 'out/'

# Set of genes that will be interpolated
genes_of_interest = ['T', 'Sox2']

# List of tissues that are ignored to do coverslip registration
tissues_to_ignore = [13, 15, 16, 22, 27, 29, 32, 36, 40, 41]

# Coverslips to ignore
# on the starting side
nb_CS_begin_ignore = 0
# on the ending side
nb_CS_end_ignore = 4

# Gives more weight to some tissues to help the alignment
tissue_weight = {21:2000, 18:2000}
# xy resolution
xy_resolution = .6
# Distance max that two beads can be linked together between coverslips
th_d = 150
# Threshold bellow which the beads will be considered noise.
# Value between 0 (all beads taken) and 1 (almost no beads taken)
outlier_threshold = .6

# Number of interpolated layers between two consecutive coverslips
nb_interp = 5_____no_output_____embryo = Embryo(data_path, tissues_to_ignore, corres_tissues, tissue_weight=tissue_weight,
                xy_resolution=xy_resolution, genes_of_interest=genes_of_interest,
                nb_CS_begin_ignore=nb_CS_begin_ignore, nb_CS_end_ignore=nb_CS_end_ignore,
                store_anndata=True)
embryo.removing_spatial_outliers(th=outlier_threshold)
embryo.reconstruct_intermediate(embryo, th_d=th_d, genes=genes_of_interest)_____no_output_____

## Saving the dataset
The following line allows to save the dataset so you can then open it using our viewer._____no_output_____

embryo.save_anndata(output_folder+'/reconstructed.h5ad')_____no_output_____

# Extracting a plan_____no_output_____## Plotting the tissues
### Tissue color_____no_output_____

origin = np.mean([embryo.final[c] for c in embryo.all_cells if embryo.tissue[c] in [30, 31]], axis=0)
origin = np.hstack([origin, 80])
angles = np.array([-5., 5., 0.])
points_to_plot = embryo.plot_slice(angles, color_map=colors_paper, origin=origin, thickness=30,
                                   tissues=[18, 30, 31], nb_interp=5) _____no_output_____

### Gene colors_____no_output_____

origin = np.mean([embryo.final[c] for c in embryo.all_cells if embryo.tissue[c] in [30, 31]], axis=0)
origin = np.hstack([origin, 80])
angles = np.array([-5., 5., 0.])
points_to_plot = embryo.plot_slice(angles, colors_paper, origin=origin, thickness=30, gene='T',
                                   tissues=[18, 30, 31], nb_interp=5, output_path=output_folder+'test.pdf')_____no_output_____

### 2 Genes colors

Explanation of the 2 colors parameters:

`gene`: can be a single gene (as above) or a list of TWO genes as below

The color combinations availables are:
- Red and Cyan
- Green and Magenta
- Blue and Yellow

The parameter `main_bi_color` allows to choose one of these 3 combinations. `main_bi_color` can have 3 different values: `r`, `g` or `b` respectively referring to red, green and blue the first color of each color combination.

Moreover, 4 different parameters exists to define the upper and lower bounds of the gene expression values:
- `min_g1`: minimum value for the first gene of the list
- `min_g2`: minimum value for the second gene of the list
- `max_g1`: maximum value for the first gene of the list
- `max_g2`: maximum value for the second gene of the list

By default, if no value is provided (or `None`) these values are computed as the bottom and top 2 percent of the respective gene expression distributions.

To look at the color scale for bi-color plots, one can give the path to the image where the scale will be saved using the parameter `path_scale`. For example `path_scale='path/to/folder/scale.pdf'`

Finally, some parameters can be called to change the properties of the scatter plot, some are called in the example bellow:
- `alpha`: sets the transparency (0 being fully transparent, 1 being fully opaque)
- `linewidth`: width of the line around the markers
- `s`: size of the markers

All the possible parameters for the scatter plot can be found [there](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.scatter.html#matplotlib.pyplot.scatter)._____no_output_____

origin = np.mean([embryo.final[c] for c in embryo.all_cells if embryo.tissue[c] in [30, 31]], axis=0)
origin = np.hstack([origin, 80])
angles = np.array([-5., 5., 0.])

# Use the line below before a plot to plot it with dark background
# When using this command line you need to ident the line below
# with plt.style.context('dark_background'):

# Basic plot
points_to_plot = embryo.plot_slice(angles, colors_paper, origin=origin, thickness=30,
                                   gene=['Sox2', 'T'], tissues=[31], nb_interp=5)

# Reducing the min and max values to make the plot less dark
# Changing the alpha to .7, the linewidth to 0 and the dot size to 15
points_to_plot = embryo.plot_slice(angles, colors_paper, origin=origin, thickness=30,
                                   gene=['Sox2', 'T'], tissues=[31], nb_interp=5,
                                   alpha=.7, linewidth=0, main_bi_color='g', s=15, min_g1=-1, min_g2=-1)

# Example changing the main color to red and using a black background
with plt.style.context('dark_background'):
    points_to_plot = embryo.plot_slice(angles, colors_paper, origin=origin, thickness=30,
                                       gene=['T', 'Sox2'], tissues=[31], nb_interp=5,
                                       main_bi_color='r')

# Example with the scale (parameter `path_scale`)
# together with change of the min_g1 and min_g2 to show the difference
# Moreover, because the line is still indented (shifted to the right),
# the dark background is still active
    points_to_plot = embryo.plot_slice(angles, colors_paper, origin=origin, thickness=30,
                                       gene=['T', 'Sox2'], tissues=[31], nb_interp=5,
                                       main_bi_color='b', path_scale=output_folder+'test.pdf',
                                       min_g1=.5, min_g2=.5)

# Back to normal indentation => back to white background
points_to_plot = embryo.plot_slice(angles, colors_paper, origin=origin, thickness=30,
                                   gene=['Sox2', 'T'], tissues=[31], nb_interp=5,
                                   alpha=.7, linewidth=0, main_bi_color='g', s=15, min_g1=-1, min_g2=-1)_____no_output_____

## Saving slice as h5ad_____no_output_____### With interpolated slices but only a subset of genes_____no_output_____

origin = np.mean([embryo.final[c] for c in embryo.all_cells if embryo.tissue[c] in [30, 31]], axis=0)
origin = np.hstack([origin, 80])
angles = np.array([-5., 5., 0.])
points_to_plot = embryo.anndata_slice(output_folder+'slice.h5ad', angles,
                                      gene_list=genes_of_interest, origin=origin,
                                      tissues=[18, 21, 30, 31, 34])/Users/leo.guignard/miniforge3/envs/test-sc3D2/lib/python3.9/site-packages/sc3D/sc3D.py:1022: FutureWarning: X.dtype being converted to np.float32 from float64. In the next version of anndata (0.9) conversion will not be automatic. Pass dtype explicitly to avoid this warning. Pass `AnnData(X, dtype=X.dtype, ...)` to get the future behavour.
  D = anndata.AnnData(df)
/Users/leo.guignard/miniforge3/envs/test-sc3D2/lib/python3.9/site-packages/anndata/_core/anndata.py:121: ImplicitModificationWarning: Transforming to str index.
  warnings.warn("Transforming to str index.", ImplicitModificationWarning)

### Without interpolated slices but with all genes_____no_output_____

origin = np.mean([embryo.final[c] for c in embryo.all_cells if embryo.tissue[c] in [30, 31]], axis=0)
origin = np.hstack([origin, 80])
angles = np.array([-5., 5., 0.])
embryo.anndata_no_extra(output_folder+'all.h5ad', angles, origin=origin)_____no_output_____


# Notebook from sspickle/sci-comp-notebooks
Path: P07-Parameter Estimation (Zipf's Law).ipynb

Power Law Distributions: Zipf's Law
=======================

(Note: Be sure to either download the data that goes with this notebook or uncomment/edit the lines below needed to get your own data before executing the code in this notebook.)

It turns out that "power law" distributions are ubitquitous in nature, see:

1 [http://arxiv.org/abs/cond-mat/0412004](http://arxiv.org/abs/cond-mat/0412004)

2 [https://arxiv.org/abs/1812.09662](https://arxiv.org/abs/1812.09662)

In the next feww cells of this notebook I measure the number of files of different sizes on my hard disk. Then I proceed to quantify (in the simples possible way) the distribution of file sizes in a certain range as a power law distribution.
_____no_output_____

import numpy as np
import matplotlib.pyplot as pl

import pandas as pd                    # pandas is the "python data analysis package"
import os                              # operating system services
from scipy.optimize import curve_fit   # non-linear curve fitting_____no_output_____def getFileSizes(folder, minsize=2000, maxsize=10**9):
    """
    return a list of file sizes in a folder
    """
    sizes = []
    for (path, dirs, files) in os.walk(folder):
        for file in files:
            try:
                filename = os.path.join(path, file)
                size=os.path.getsize(filename)
                if size>minsize and size<maxsize:
                    sizes.append(size)
            except OSError:
                pass
    return sizes_____no_output_____if 0: # set this to "1" to actaully collect data, but edit the paths to match your computer.
    minsize=10**4  # the minimum file size to consider
    maxsize=10**10 # the maximum file size to consider
    sizes = getFileSizes('/Users/steve/Desktop',minsize,maxsize) # <--- edit this to match some folder with a lot of files
    print(len(sizes), 'files between', minsize, 'and', maxsize)_____no_output_____
if 0: # set this to "1" to write the file
    df=pd.DataFrame({'file_sizes':sizes})
    df.to_csv('myData.csv', sep=',')
else: # read the file
    df=pd.read_csv('myData.csv')
    df.head()
    sizes = df.file_sizes_____no_output_____ns,bins,patches = pl.hist(np.log(np.array(sizes)+1),40)_____no_output_____xvals=(bins[:-1]+bins[1:])/2.0
counts=ns+0.5
yvals=np.log(counts)
pl.title("distribution of file sizes")
pl.ylabel("log(count)")
pl.xlabel("log(size)")
pl.plot(xvals,yvals,'b.')_____no_output_____

Uncertainties in the Parameters
-------------------------------

There are a variety of techniques for estimating the uncertainty in the parameters you compute. The approach we'll take is one of the more "brute force" approaches, but it's pretty robust. We're going to fabricate data that has the same statistics as our original data (do the degree that we know and/or care). Then we'll fit the fabricated data many times (1000 times in this case) and we'll look at the statistics of the fit parameters produced. From this we can tell how well our fit has done at narrowing down the parameters we computed.
_____no_output_____

#
# Just to see same data fit using the non-linear scipy package "curve_fit":
#

def fLinear(x, m, b):
    return m*x + b

m0 = (yvals[-1]-yvals[0])/(xvals[-1]-xvals[0])  # estimate slope
b0 = yvals[0] - m0*xvals[0]                     # estimate intercept
sigma=1.0/np.sqrt(np.abs(counts))

popt, pcov = curve_fit(fLinear, xvals, yvals, p0=(m0, b0), sigma=sigma)

m=popt[0]          # slope
dm=np.sqrt(pcov[0,0]) # sqrt(variance(slope))
b=popt[1]          # int
db=np.sqrt(pcov[1,1]) # sqrt(variance(int))
ystar=fLinear(xvals, m, b)

N=1000    # number of samples to take
mList=[]  # keep track of monte-carlo fit parameters
bList=[]

for i in range(N):
    """
    Generate mc data with the same statistical properties as the real data.
    Repeat the fit for each set, and record the parameters.
    """
    mcY = ystar + sigma*np.random.normal(size=len(xvals))  # generate fabricated data to fit
    mcpopt, mcpcov = curve_fit(fLinear, xvals, mcY, p0=(m,b), sigma=sigma)
    mList.append(mcpopt[0])  # store the fit paramters for the fab-data
    bList.append(mcpopt[1])_____no_output_____# check slope histogram

pl.hist(mList)_____no_output_____# check intercept histogram

pl.hist(bList)_____no_output_____#
# Compute the statistics of the mc-results
#

marr=np.array(mList)
barr=np.array(bList)

mAvg = marr.mean()
bAvg = barr.mean()
sigM = marr.std()
sigB = barr.std()

pl.errorbar(xvals, yvals, sigma, fmt='r.')
pl.title("File Sizes on My HD")
pl.ylabel("log(count)")
pl.xlabel("log(size)")
pl.plot(xvals,ystar, 'g-')
print("Slope=", m, '+/-', sigM, "(", m-sigM,",",m+sigM, ")")
print("Intercept=", b, '+/-', sigB, "(", b-db,",",b+sigB, ")")

print() # print a blank link
print("Compare to cov-matrix for fun:")
print("sqsrt(pcov[0,0]) (should be sigma m)", np.sqrt(pcov[0,0]))
print("sqrt(pcov[1,1]) (should be sigma b)", np.sqrt(pcov[1,1]))Slope= -0.4010129725637122 +/- 0.007056226722822071 ( -0.4080691992865343 , -0.39395674584089013 )
Intercept= 10.251110169860413 +/- 0.08162270120288012 ( 9.941549243952434 , 10.332732871063293 )

Compare to cov-matrix for fun:
sqsrt(pcov[0,0]) (should be sigma m) 0.02675033478186744
sqrt(pcov[1,1]) (should be sigma b) 0.30956092590797973

Project 7
=========

See this reference for other systems that exhibit power law behavior:

<http://arxiv.org/abs/cond-mat/0412004>

Or test your intuition and see if it's right. Many system exhibit this behavior!

Get some data, and test your idea. Use the matrix technique to do the fitting._____no_output_____Matrix Approach
--------------------

# WARNING: THE REST OF THIS NOTEBOOK IS OPTIONAL. YOU DO NOT NEED TO READ FURTHER UNLESS YOU ARE CURIOUS/INTERSTED IN THE INNER MACHINERY OF CURVE FITTING

The remainder of this notebook details an approach to parameter estimation
using matrices. If you're interested, you're welcome to use this approach to
fit your data. It has the (minor) advantage that there are no "black boxes"
like `curve_fit`. The underlying mathematics is open for your inspection! However
it's also pretty mathematically "heavy" so, please use `curve_fit` if you prefer.
_____no_output_____Fitting Data with Matrices
===========================

We can see that we have something that looks like it might be a power law. How can we tell? We'll use "linear least squares" analysis.

When fitting some experimental data to a model, there are typically
a set of paramters $(\alpha_1, \alpha_2, \ldots, \alpha_n)$ that
need to be found so that the function $\chi^2$ is a minimum.
We can think of the paramters as an n-vector called $\alpha$. The
data consist of a set of paired numbers $(x_i, y_i)$ and we can
define $\chi^2$ as

\begin{equation}
\chi^2 = \sum_{i=1}^{m} {(y_i - y^\star(x_i,\alpha))^2\over \sigma_i^2},
\end{equation}

where $\sigma_i$ is the uncertainty in $y_i$, and $y^\star$ is the
model value corresponding to $x_i$ (and the value of the parameters
$\alpha$). If the model $y^\star(x,\vec\alpha)$ is *linear* then we
can write $y^\star$ as:

\begin{equation}
y^\star (x) = \alpha_1 X_1(x)+\alpha_2 X_2(x)+\ldots+\alpha_n X_n(x).
\end{equation}

or

\begin{equation}
y^\star(x) = \sum_{j=1}^{n} \alpha_j X_j(x),
\end{equation}

where the $X_j$ are a set of functions that are to be superposed
with coefficients $\alpha_j$ to form the model. A common example
of this would be a straight line fit $y^\star(x) = mx+b$ where the
functions are $x$ and 1 for the paramters $m$ and $b$ respectively.

Notice that, since the $x$'s are at fixed measured values, this whole thing can be
cast into a single matrix equation. If we define the following $M$ matrix:

\begin{equation}
M_{ij} = X_j(x_i)
\end{equation}

and if we think of $y^\star$ as an $m$-vector of model
values evaluated at the $m$ data points $x_i$ and $y$ as an
experimental $m$-vector $y$, then the model vector
can be evaluated by matrix multiplication as:

\begin{equation}
y^\star = M \alpha
\end{equation}

and the difference vector between the model and the data becomes simply

\begin{equation}
y - y^\star = y - M\alpha
\end{equation}

Finally we can write $\chi^2$ as

\begin{equation}
\chi^2 = (y - M\alpha)^T S (y - M\alpha) \,\,\,\,\,\,\,\,(1)
\end{equation}

where $S$ is a diagonal matrix of $1/\sigma_i^2$ and
the $T$ on the left side means "transpose".

Now it is a simple matter to find the values of the paramters that
minimize $\chi^2$. We require that $\nabla_{\alpha}\chi^2 = 0$.
If you play around with this you can convince yourself that this means:

\begin{equation}
M^T S(y - M\alpha) = 0
\end{equation}

and therefore:

\begin{equation}
\alpha = (M^T SM)^{-1}M^T S y.  \,\,\,\,\,\,\,\,(2)
\end{equation}_____no_output_____

#
# define the function values (these are the columns of the "M" matrix
#
# generate arrays that contain "functions" of x that are combined to form the model
#

def doFit(funcs, xvals, yvals, sigma):
    """
    doFit uses matrices to solve for the linear least squares
    fit parameters based on the list of 'funcs', and the x-y values
    and their corresponding uncertainties (sigma).

    returns the array of model parameters
    """
    #
    # define the S matrix in terms of uncertainties
    #

    S=np.diag((1.0/sigma)**2)

    #
    # define the model matrix
    #

    M = np.array(funcs).T
    MtM = M.T.dot(S.dot(M))
    MtMInv = np.linalg.inv(MtM)
    MtY = M.T.dot(S.dot(yvals))
    alpha = MtMInv.dot(MtY)      # see eq 2 above.

    #
    # solve for the parameters, and return
    #
    ystar = M.dot(alpha)

    return (alpha, ystar, MtMInv)

fx1 = np.ones(len(xvals))   # X_1(x) = 1
fx2 = xvals              # X_2(x) = x

sigma=1.0/np.sqrt(np.abs(counts))

alpha, ystar, fcov = doFit([fx1, fx2], xvals, yvals, sigma)

mFit = alpha[1]
bFit = alpha[0]

pl.errorbar(xvals, yvals, sigma, fmt='r.')
pl.title("File Sizes on My HD")
pl.ylabel("log(count)")
pl.xlabel("log(size)")
pl.plot(xvals,ystar, 'g-')
_____no_output_____#
# Now do monte-carlo data fabrication and fit analysis
#

N=1000    # number of samples to take
mList=[]  # keep track of monte-carlo fit parameters
bList=[]

for i in range(N):
    """
    Generate mc data with the same statistical properties as the real data.
    Repeat the fit for each set, and record the parameters.
    """
    mcY = ystar + sigma*np.random.normal(size=len(xvals))
    mcAlpha,mcYstar,mccov = doFit([fx1,fx2],xvals,mcY,sigma)   # repeatedly fit mc data
    mList.append(mcAlpha[1])
    bList.append(mcAlpha[0])

#
# Compute the statistics of the mc-results
#

marr=np.array(mList)
barr=np.array(bList)

mAvg = marr.sum()/N
bAvg = barr.sum()/N
delM = marr-mAvg
delB = barr-bAvg
sigM = np.sqrt((delM*delM).sum()/(N-1))  # sigM is the std-deviation of the m values
sigB = np.sqrt((delB*delB).sum()/(N-1))  # sigB is the std-deviation of the b values

#
# plot the fit
#
print("Slope=", mFit, '+/-', sigM, "(", mFit - sigM,",",mFit + sigM, ")")
print("Intercept=", bFit, '+/-', sigB, "(", bFit - sigB,",",bFit + sigB, ")")

#
# Just for fun print out the diagonals of the covariance matrix.
#
print # print a blank link
print("Compare to cov-matrix for fun:")
print("sqsrt(cov[1,1]) (should be sigma m)", np.sqrt(fcov[1,1]))
print("sqrt(cov[0,0]) (should be sigma b)", np.sqrt(fcov[0,0]))
Slope= -0.40101297210387443 +/- 0.0069164777066884975 ( -0.40792944981056295 , -0.3940964943971859 )
Intercept= 10.251110164592234 +/- 0.07947579449122216 ( 10.171634370101012 , 10.330585959083455 )
Compare to cov-matrix for fun:
sqsrt(cov[1,1]) (should be sigma m) 0.006919937608028965
sqrt(cov[0,0]) (should be sigma b) 0.08007908396499791
pl.hist(marr) # look at the variation in "m" values
print("m average:", mAvg)
print("m sigma:",sigM)m average: -0.4009698835771972
m sigma: 0.0069164777066884975
pl.hist(barr)  # look at the variation in "b" values
print("b average:", bAvg)
print("b sigma:",sigB)b average: 10.250089828310378
b sigma: 0.07947579449122216