chriskok3 commited on
Commit
1e786c4
·
verified ·
1 Parent(s): 0026e41

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +102 -142
app.py CHANGED
@@ -1,147 +1,107 @@
1
- import io
2
- import random
3
- from typing import List, Tuple
4
-
5
- import aiohttp
6
  import panel as pn
7
- from PIL import Image
8
- from transformers import CLIPModel, CLIPProcessor
9
-
10
- pn.extension(design="bootstrap", sizing_mode="stretch_width")
11
-
12
- ICON_URLS = {
13
- "brand-github": "https://github.com/holoviz/panel",
14
- "brand-twitter": "https://twitter.com/Panel_Org",
15
- "brand-linkedin": "https://www.linkedin.com/company/panel-org",
16
- "message-circle": "https://discourse.holoviz.org/",
17
- "brand-discord": "https://discord.gg/AXRHnJU6sP",
18
- }
19
-
20
-
21
- async def random_url(_):
22
- pet = random.choice(["cat", "dog"])
23
- api_url = f"https://api.the{pet}api.com/v1/images/search"
24
- async with aiohttp.ClientSession() as session:
25
- async with session.get(api_url) as resp:
26
- return (await resp.json())[0]["url"]
27
-
28
-
29
- @pn.cache
30
- def load_processor_model(
31
- processor_name: str, model_name: str
32
- ) -> Tuple[CLIPProcessor, CLIPModel]:
33
- processor = CLIPProcessor.from_pretrained(processor_name)
34
- model = CLIPModel.from_pretrained(model_name)
35
- return processor, model
36
-
37
-
38
- async def open_image_url(image_url: str) -> Image:
39
- async with aiohttp.ClientSession() as session:
40
- async with session.get(image_url) as resp:
41
- return Image.open(io.BytesIO(await resp.read()))
42
-
43
-
44
- def get_similarity_scores(class_items: List[str], image: Image) -> List[float]:
45
- processor, model = load_processor_model(
46
- "openai/clip-vit-base-patch32", "openai/clip-vit-base-patch32"
47
- )
48
- inputs = processor(
49
- text=class_items,
50
- images=[image],
51
- return_tensors="pt", # pytorch tensors
52
- )
53
- outputs = model(**inputs)
54
- logits_per_image = outputs.logits_per_image
55
- class_likelihoods = logits_per_image.softmax(dim=1).detach().numpy()
56
- return class_likelihoods[0]
57
 
58
-
59
- async def process_inputs(class_names: List[str], image_url: str):
60
- """
61
- High level function that takes in the user inputs and returns the
62
- classification results as panel objects.
63
- """
64
- try:
65
- main.disabled = True
66
- if not image_url:
67
- yield "##### ⚠️ Provide an image URL"
68
- return
69
-
70
- yield "##### ⚙ Fetching image and running model..."
71
- try:
72
- pil_img = await open_image_url(image_url)
73
- img = pn.pane.Image(pil_img, height=400, align="center")
74
- except Exception as e:
75
- yield f"##### 😔 Something went wrong, please try a different URL!"
76
- return
77
 
78
- class_items = class_names.split(",")
79
- class_likelihoods = get_similarity_scores(class_items, pil_img)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
- # build the results column
82
- results = pn.Column("##### 🎉 Here are the results!", img)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
- for class_item, class_likelihood in zip(class_items, class_likelihoods):
85
- row_label = pn.widgets.StaticText(
86
- name=class_item.strip(), value=f"{class_likelihood:.2%}", align="center"
87
- )
88
- row_bar = pn.indicators.Progress(
89
- value=int(class_likelihood * 100),
90
- sizing_mode="stretch_width",
91
- bar_color="secondary",
92
- margin=(0, 10),
93
- design=pn.theme.Material,
94
- )
95
- results.append(pn.Column(row_label, row_bar))
96
- yield results
97
- finally:
98
- main.disabled = False
99
-
100
-
101
- # create widgets
102
- randomize_url = pn.widgets.Button(name="Randomize URL", align="end")
103
-
104
- image_url = pn.widgets.TextInput(
105
- name="Image URL to classify",
106
- value=pn.bind(random_url, randomize_url),
107
- )
108
- class_names = pn.widgets.TextInput(
109
- name="Comma separated class names",
110
- placeholder="Enter possible class names, e.g. cat, dog",
111
- value="cat, dog, parrot",
112
- )
113
-
114
- input_widgets = pn.Column(
115
- "##### 😊 Click randomize or paste a URL to start classifying!",
116
- pn.Row(image_url, randomize_url),
117
- class_names,
118
- )
119
-
120
- # add interactivity
121
- interactive_result = pn.panel(
122
- pn.bind(process_inputs, image_url=image_url, class_names=class_names),
123
- height=600,
124
- )
125
-
126
- # add footer
127
- footer_row = pn.Row(pn.Spacer(), align="center")
128
- for icon, url in ICON_URLS.items():
129
- href_button = pn.widgets.Button(icon=icon, width=35, height=35)
130
- href_button.js_on_click(code=f"window.open('{url}')")
131
- footer_row.append(href_button)
132
- footer_row.append(pn.Spacer())
133
-
134
- # create dashboard
135
- main = pn.WidgetBox(
136
- input_widgets,
137
- interactive_result,
138
- footer_row,
139
- )
140
-
141
- title = "Panel Demo - Image Classification"
142
- pn.template.BootstrapTemplate(
143
- title=title,
144
- main=main,
145
- main_max_width="min(50%, 698px)",
146
- header_background="#F08080",
147
- ).servable(title=title)
 
 
 
 
 
 
1
  import panel as pn
2
+ import plotly.graph_objects as go
3
+ pn.extension('plotly')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
+ def create_sankey(player='Human', initial_decision='Cooperate'):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
+ source = [0, 0, 1, 1]
8
+ target = [2, 3, 2, 3]
9
+
10
+ # based on the stats above and the current type of player, we get the following value arrays.
11
+ if player == 'Human':
12
+ if initial_decision == 'Cooperate':
13
+ value = [12035, 3173, 4963, 8440]
14
+ else:
15
+ value = [3821, 7686, 3635, 10584]
16
+ elif player == 'ChatGPT-4':
17
+ if initial_decision == 'Cooperate':
18
+ value = [29, 0, 0, 1]
19
+ else:
20
+ value = [0, 26, 1, 3]
21
+ else: # ChatGPT-3
22
+ if initial_decision == 'Cooperate':
23
+ value = [21, 3, 3, 3]
24
+ else:
25
+ value = [7, 15, 4, 4]
26
 
27
+ link_percentages = [value[0]/(value[0]+value[1])*100, value[1]/(value[0]+value[1])*100, value[2]/(value[2]+value[3])*100, value[3]/(value[2]+value[3])*100]
28
+ node_percentages = [(value[0]+value[1])/sum(value)*100, (value[2]+value[3])/sum(value)*100, (value[0]+value[2])/sum(value)*100, (value[1]+value[3])/sum(value)*100]
29
+ node_customdata = [("Cooperate in Round 1", node_percentages[0]), ("Defect in Round 1", node_percentages[1]),
30
+ ("Cooperate in Round 2", node_percentages[2]), ("Defect in Round 2", node_percentages[3])]
31
+
32
+ # Create sankey diagram
33
+ fig = go.Figure(data=[go.Sankey(
34
+ node = dict(
35
+ pad = 15,
36
+ thickness = 20,
37
+ label = ["Cooperate", "Defect", "Cooperate", "Defect"],
38
+ color = ["#B0C5A4", "#D37676", "#B0C5A4", "#D37676"],
39
+ # customdata = ["Cooperate in Round 1", "Defect in Round 1", "Cooperate in Round 2", "Defect in Round 2"],
40
+ customdata = node_customdata,
41
+ hovertemplate='%{value:.0f} players (%{customdata[1]:.02f}%) chose to %{customdata[0]}<extra></extra>',
42
+ ),
43
+ link = dict(
44
+ source = source,
45
+ target = target,
46
+ value = value,
47
+ customdata = link_percentages,
48
+ hovertemplate='Of the %{source.value} players who chose to <br />'+
49
+ '%{source.customdata[0]}, %{value:.0f} (%{customdata:.02f}%) <br />'+
50
+ 'chose to %{target.customdata[0]}<extra></extra>',
51
+ color = ["#B0C5A4", "#B0C5A4", "#D37676", "#D37676"],
52
+ ),
53
+ )])
54
+
55
+ annotations=[
56
+ dict(x=0, y=-0.2, xref='paper', yref='paper', showarrow=False,
57
+ text="Round 1"),
58
+ dict(x=0.5, y=-0.2, xref='paper', yref='paper', showarrow=False,
59
+ text="Other Player Defects in Round 1" if initial_decision == "Defect" else "Other Player Cooperates in Round 1", font=dict(size=14, color='grey')),
60
+ dict(x=1, y=-0.2, xref='paper', yref='paper', showarrow=False,
61
+ text="2")
62
+ ]
63
 
64
+ fig.update_layout(hovermode='x', title="Prisoner's Dilemma Decision Flows", annotations=annotations, font_size=14, title_x=0.5)
65
+ return fig
66
+
67
+
68
+ # Interactive widgets for filtering
69
+ select_player = pn.widgets.Select(name='Type of Player', options=['Human', 'ChatGPT-4', 'ChatGPT-3'])
70
+ select_decision = pn.widgets.Select(name='Round 1 Decision by Other Player', options=['Cooperate', 'Defect'])
71
+
72
+ # Textual explanation of each chart based on type of player and round 1 decision (should have 6 scenarios!)
73
+ # https://panel.holoviz.org/reference/widgets/StaticText.html
74
+
75
+
76
+ # Dynamic binding of the sankey diagram function to the widgets' values
77
+ @pn.depends(select_player.param.value, select_decision.param.value)
78
+ def interactive_sankey(chatgpt_version, initial_decision):
79
+ return create_sankey(chatgpt_version, initial_decision)
80
+
81
+ @pn.depends(select_player.param.value, select_decision.param.value)
82
+ def setup_description(chatgpt_version, initial_decision):
83
+ if chatgpt_version == 'Human':
84
+ if initial_decision == 'Cooperate':
85
+ scenario_desc="Here's what happens <b>in reality</b> (for us humans) when the other player <b>cooperates</b> in Round 1! We can see that about 50% of the people start on either side of the coin (cooperate or defect) and then the numbers lean more heavily (around 60%) onto the cooperate side by Round 2. This shows that humans would more naturally lean towards cooperation if the other player does the same. Check out what happens when the other player defects in Round 1 by selecting the <b>Defect</b> option above!"
86
+ else:
87
+ scenario_desc="Here's what happens <b>for humans</b> when the other player <b>defects</b> in Round 1! Just like in the first scenario (other player cooperates) we see that about 50% of the people start on either side of the coin (cooperate or defect). This time, however, the numbers lean MUCH more heavily (around 70%) onto the defect side by Round 2 (especially coming from those who initially cooperated). This shows that humans would more naturally lean towards defecting (moreso than cooperation) if the other player does the same. Now check out how AI would make this decision by selecting either <b>ChatGPT-3 or ChatGPT-4</b> in the options above!"
88
+ elif chatgpt_version == 'ChatGPT-4':
89
+ if initial_decision == 'Cooperate':
90
+ scenario_desc="Here's a peek into <b>ChatGPT-4's</b> world when faced with a <b>cooperating</b> partner in Round 1! ChatGPT-4 shows a strong tendency towards reciprocating cooperation, with ALL of the players who decided to cooperate in the first place (95%) choosing to cooperate again. It appears to demonstrate a high capacity for trust and cooperative behavior, mirroring an ideal strategic participant who values mutual benefit over individual gain. Curious about how ChatGPT-4 reacts to a defect? Switch to the <b>Defect</b> option above to explore further!"
91
+ else:
92
+ scenario_desc="Exploring <b>ChatGPT-4's</b> strategy when the other player decides to <b>defect</b> in Round 1 unveils an interesting approach! Just like humans, when ChatGPT-4 is 'betrayed' in a sense, it goes HEAVILY into defecting (with a total table turning 96% defecting in the second round). It's an intriguing stance that differs only in terms of extremeties compared to human reaction patterns. Now, check how <b>ChatGPT-3</b> handles this by selecting it in the options above!"
93
+ else:
94
+ if initial_decision == 'Cooperate':
95
+ scenario_desc="Diving into <b>ChatGPT-3's</b> choices when the game starts with <b>cooperation</b>, it shows something in between both humans and ChatGPT-4; the exact same amount of responses (80%) end up in cooperation despite there having been some players changing to defecting and some initial defectors changing to cooperation. It is fascinating to see how this earlier version of ChatGPT balances trust and strategy. Want to see what happens when the start is less friendly? Choose the <b>Defect</b> option to discover."
96
+ else:
97
+ scenario_desc="When the initial move is to <b>defect</b>, <b>ChatGPT-3</b> displays a mixed strategy (again, in between humans and ChatGPT-4). Despite starting with more on the cooperation side (~70%), they end up with the majority of players defecting by the second round (63% - which is much closer to the humans which were at 70%). This variance from ChatGPT-4's strategy offers a glimpse into the evolution and differences in approach between the two AI versions. Toggle to <b>ChatGPT-4 or Human</b> to compare both of these to what you found out about ChatGPT-3!"
98
+
99
+ static_text = pn.widgets.StaticText(name='Description', value=f"{scenario_desc}")
100
+ static_text.value = f"{scenario_desc}"
101
+ return static_text
102
+
103
+
104
+ # Layout
105
+ layout = pn.Column(pn.Row(select_player, select_decision), interactive_sankey, setup_description)
106
+
107
+ layout.servable()