3v324v23 commited on
Commit
bf56825
·
1 Parent(s): c2b848d

Commit : 103

Browse files
BirdOrForest.ipynb ADDED
@@ -0,0 +1,386 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 2,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "from fastbook import *"
10
+ ]
11
+ },
12
+ {
13
+ "cell_type": "code",
14
+ "execution_count": 2,
15
+ "metadata": {},
16
+ "outputs": [],
17
+ "source": [
18
+ "Search_Words = [\"bird\", \"forest\"]\n",
19
+ "path = Path(\"images\")\n",
20
+ "Search_Num = 10\n",
21
+ "\n",
22
+ "# to make sure that the file is empty\n",
23
+ "!rm -r images\n",
24
+ "\n",
25
+ "for W in Search_Words:\n",
26
+ " dest = path/W\n",
27
+ " dest.mkdir(exist_ok=True, parents=True)\n",
28
+ " download_images(dest, urls=search_images_ddg(f'{W} photo', max_images=Search_Num))\n",
29
+ " time.sleep(5)\n",
30
+ " resize_images(path/W, max_size=400, dest=path/W)"
31
+ ]
32
+ },
33
+ {
34
+ "cell_type": "code",
35
+ "execution_count": 1,
36
+ "metadata": {},
37
+ "outputs": [
38
+ {
39
+ "ename": "NameError",
40
+ "evalue": "name 'DataBlock' is not defined",
41
+ "output_type": "error",
42
+ "traceback": [
43
+ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
44
+ "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
45
+ "Cell \u001b[1;32mIn[1], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m dls \u001b[38;5;241m=\u001b[39m \u001b[43mDataBlock\u001b[49m(\n\u001b[0;32m 2\u001b[0m blocks\u001b[38;5;241m=\u001b[39m(ImageBlock, CategoryBlock),\n\u001b[0;32m 3\u001b[0m get_items\u001b[38;5;241m=\u001b[39mget_image_files,\n\u001b[0;32m 4\u001b[0m splitter\u001b[38;5;241m=\u001b[39mRandomSplitter(valid_pct\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m0.2\u001b[39m, seed\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m30\u001b[39m),\n\u001b[0;32m 5\u001b[0m get_y\u001b[38;5;241m=\u001b[39mparent_label,\n\u001b[0;32m 6\u001b[0m item_tfms\u001b[38;5;241m=\u001b[39m[Resize(\u001b[38;5;241m192\u001b[39m, method\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124msquish\u001b[39m\u001b[38;5;124m'\u001b[39m)]\n\u001b[0;32m 7\u001b[0m )\u001b[38;5;241m.\u001b[39mdataloaders(path, bs\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m6\u001b[39m)\n\u001b[0;32m 9\u001b[0m dls\u001b[38;5;241m.\u001b[39mshow_batch(max_n\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m6\u001b[39m)\n",
46
+ "\u001b[1;31mNameError\u001b[0m: name 'DataBlock' is not defined"
47
+ ]
48
+ }
49
+ ],
50
+ "source": [
51
+ "dls = DataBlock(\n",
52
+ " blocks=(ImageBlock, CategoryBlock),\n",
53
+ " get_items=get_image_files,\n",
54
+ " splitter=RandomSplitter(valid_pct=0.2, seed=30),\n",
55
+ " get_y=parent_label,\n",
56
+ " item_tfms=[Resize(192, method='squish')]\n",
57
+ ").dataloaders(path, bs=6)\n",
58
+ "\n",
59
+ "dls.show_batch(max_n=6)"
60
+ ]
61
+ },
62
+ {
63
+ "cell_type": "code",
64
+ "execution_count": 8,
65
+ "metadata": {},
66
+ "outputs": [
67
+ {
68
+ "data": {
69
+ "text/html": [
70
+ "\n",
71
+ "<style>\n",
72
+ " /* Turns off some styling */\n",
73
+ " progress {\n",
74
+ " /* gets rid of default border in Firefox and Opera. */\n",
75
+ " border: none;\n",
76
+ " /* Needs to be in here for Safari polyfill so background images work as expected. */\n",
77
+ " background-size: auto;\n",
78
+ " }\n",
79
+ " progress:not([value]), progress:not([value])::-webkit-progress-bar {\n",
80
+ " background: repeating-linear-gradient(45deg, #7e7e7e, #7e7e7e 10px, #5c5c5c 10px, #5c5c5c 20px);\n",
81
+ " }\n",
82
+ " .progress-bar-interrupted, .progress-bar-interrupted::-webkit-progress-bar {\n",
83
+ " background: #F44336;\n",
84
+ " }\n",
85
+ "</style>\n"
86
+ ],
87
+ "text/plain": [
88
+ "<IPython.core.display.HTML object>"
89
+ ]
90
+ },
91
+ "metadata": {},
92
+ "output_type": "display_data"
93
+ },
94
+ {
95
+ "data": {
96
+ "text/html": [
97
+ "<table border=\"1\" class=\"dataframe\">\n",
98
+ " <thead>\n",
99
+ " <tr style=\"text-align: left;\">\n",
100
+ " <th>epoch</th>\n",
101
+ " <th>train_loss</th>\n",
102
+ " <th>valid_loss</th>\n",
103
+ " <th>error_rate</th>\n",
104
+ " <th>time</th>\n",
105
+ " </tr>\n",
106
+ " </thead>\n",
107
+ " <tbody>\n",
108
+ " <tr>\n",
109
+ " <td>0</td>\n",
110
+ " <td>1.553634</td>\n",
111
+ " <td>0.449045</td>\n",
112
+ " <td>0.333333</td>\n",
113
+ " <td>00:01</td>\n",
114
+ " </tr>\n",
115
+ " </tbody>\n",
116
+ "</table>"
117
+ ],
118
+ "text/plain": [
119
+ "<IPython.core.display.HTML object>"
120
+ ]
121
+ },
122
+ "metadata": {},
123
+ "output_type": "display_data"
124
+ },
125
+ {
126
+ "data": {
127
+ "text/html": [
128
+ "\n",
129
+ "<style>\n",
130
+ " /* Turns off some styling */\n",
131
+ " progress {\n",
132
+ " /* gets rid of default border in Firefox and Opera. */\n",
133
+ " border: none;\n",
134
+ " /* Needs to be in here for Safari polyfill so background images work as expected. */\n",
135
+ " background-size: auto;\n",
136
+ " }\n",
137
+ " progress:not([value]), progress:not([value])::-webkit-progress-bar {\n",
138
+ " background: repeating-linear-gradient(45deg, #7e7e7e, #7e7e7e 10px, #5c5c5c 10px, #5c5c5c 20px);\n",
139
+ " }\n",
140
+ " .progress-bar-interrupted, .progress-bar-interrupted::-webkit-progress-bar {\n",
141
+ " background: #F44336;\n",
142
+ " }\n",
143
+ "</style>\n"
144
+ ],
145
+ "text/plain": [
146
+ "<IPython.core.display.HTML object>"
147
+ ]
148
+ },
149
+ "metadata": {},
150
+ "output_type": "display_data"
151
+ },
152
+ {
153
+ "data": {
154
+ "text/html": [
155
+ "<table border=\"1\" class=\"dataframe\">\n",
156
+ " <thead>\n",
157
+ " <tr style=\"text-align: left;\">\n",
158
+ " <th>epoch</th>\n",
159
+ " <th>train_loss</th>\n",
160
+ " <th>valid_loss</th>\n",
161
+ " <th>error_rate</th>\n",
162
+ " <th>time</th>\n",
163
+ " </tr>\n",
164
+ " </thead>\n",
165
+ " <tbody>\n",
166
+ " <tr>\n",
167
+ " <td>0</td>\n",
168
+ " <td>0.675821</td>\n",
169
+ " <td>0.164133</td>\n",
170
+ " <td>0.000000</td>\n",
171
+ " <td>00:01</td>\n",
172
+ " </tr>\n",
173
+ " <tr>\n",
174
+ " <td>1</td>\n",
175
+ " <td>0.426282</td>\n",
176
+ " <td>0.027100</td>\n",
177
+ " <td>0.000000</td>\n",
178
+ " <td>00:01</td>\n",
179
+ " </tr>\n",
180
+ " <tr>\n",
181
+ " <td>2</td>\n",
182
+ " <td>0.395531</td>\n",
183
+ " <td>0.013128</td>\n",
184
+ " <td>0.000000</td>\n",
185
+ " <td>00:01</td>\n",
186
+ " </tr>\n",
187
+ " </tbody>\n",
188
+ "</table>"
189
+ ],
190
+ "text/plain": [
191
+ "<IPython.core.display.HTML object>"
192
+ ]
193
+ },
194
+ "metadata": {},
195
+ "output_type": "display_data"
196
+ }
197
+ ],
198
+ "source": [
199
+ "learn = vision_learner(dls, resnet18, metrics=error_rate)\n",
200
+ "learn.fine_tune(3)"
201
+ ]
202
+ },
203
+ {
204
+ "cell_type": "code",
205
+ "execution_count": 14,
206
+ "metadata": {},
207
+ "outputs": [
208
+ {
209
+ "data": {
210
+ "text/html": [
211
+ "\n",
212
+ "<style>\n",
213
+ " /* Turns off some styling */\n",
214
+ " progress {\n",
215
+ " /* gets rid of default border in Firefox and Opera. */\n",
216
+ " border: none;\n",
217
+ " /* Needs to be in here for Safari polyfill so background images work as expected. */\n",
218
+ " background-size: auto;\n",
219
+ " }\n",
220
+ " progress:not([value]), progress:not([value])::-webkit-progress-bar {\n",
221
+ " background: repeating-linear-gradient(45deg, #7e7e7e, #7e7e7e 10px, #5c5c5c 10px, #5c5c5c 20px);\n",
222
+ " }\n",
223
+ " .progress-bar-interrupted, .progress-bar-interrupted::-webkit-progress-bar {\n",
224
+ " background: #F44336;\n",
225
+ " }\n",
226
+ "</style>\n"
227
+ ],
228
+ "text/plain": [
229
+ "<IPython.core.display.HTML object>"
230
+ ]
231
+ },
232
+ "metadata": {},
233
+ "output_type": "display_data"
234
+ },
235
+ {
236
+ "data": {
237
+ "text/html": [],
238
+ "text/plain": [
239
+ "<IPython.core.display.HTML object>"
240
+ ]
241
+ },
242
+ "metadata": {},
243
+ "output_type": "display_data"
244
+ },
245
+ {
246
+ "name": "stdout",
247
+ "output_type": "stream",
248
+ "text": [
249
+ "This is a: bird.\n",
250
+ "Probability it's a bird: 0.998842179775238\n"
251
+ ]
252
+ }
253
+ ],
254
+ "source": [
255
+ "is_it,_,probs = learn.predict(PILImage.create('Examples/1.jpg'))\n",
256
+ "print(f\"This is a: {is_it}.\")\n",
257
+ "print(f\"Probability it's a {is_it}: {max(probs[0], probs[1])}\")"
258
+ ]
259
+ },
260
+ {
261
+ "cell_type": "code",
262
+ "execution_count": 15,
263
+ "metadata": {},
264
+ "outputs": [
265
+ {
266
+ "data": {
267
+ "text/html": [
268
+ "\n",
269
+ "<style>\n",
270
+ " /* Turns off some styling */\n",
271
+ " progress {\n",
272
+ " /* gets rid of default border in Firefox and Opera. */\n",
273
+ " border: none;\n",
274
+ " /* Needs to be in here for Safari polyfill so background images work as expected. */\n",
275
+ " background-size: auto;\n",
276
+ " }\n",
277
+ " progress:not([value]), progress:not([value])::-webkit-progress-bar {\n",
278
+ " background: repeating-linear-gradient(45deg, #7e7e7e, #7e7e7e 10px, #5c5c5c 10px, #5c5c5c 20px);\n",
279
+ " }\n",
280
+ " .progress-bar-interrupted, .progress-bar-interrupted::-webkit-progress-bar {\n",
281
+ " background: #F44336;\n",
282
+ " }\n",
283
+ "</style>\n"
284
+ ],
285
+ "text/plain": [
286
+ "<IPython.core.display.HTML object>"
287
+ ]
288
+ },
289
+ "metadata": {},
290
+ "output_type": "display_data"
291
+ },
292
+ {
293
+ "data": {
294
+ "text/html": [],
295
+ "text/plain": [
296
+ "<IPython.core.display.HTML object>"
297
+ ]
298
+ },
299
+ "metadata": {},
300
+ "output_type": "display_data"
301
+ },
302
+ {
303
+ "data": {
304
+ "text/html": [
305
+ "\n",
306
+ "<style>\n",
307
+ " /* Turns off some styling */\n",
308
+ " progress {\n",
309
+ " /* gets rid of default border in Firefox and Opera. */\n",
310
+ " border: none;\n",
311
+ " /* Needs to be in here for Safari polyfill so background images work as expected. */\n",
312
+ " background-size: auto;\n",
313
+ " }\n",
314
+ " progress:not([value]), progress:not([value])::-webkit-progress-bar {\n",
315
+ " background: repeating-linear-gradient(45deg, #7e7e7e, #7e7e7e 10px, #5c5c5c 10px, #5c5c5c 20px);\n",
316
+ " }\n",
317
+ " .progress-bar-interrupted, .progress-bar-interrupted::-webkit-progress-bar {\n",
318
+ " background: #F44336;\n",
319
+ " }\n",
320
+ "</style>\n"
321
+ ],
322
+ "text/plain": [
323
+ "<IPython.core.display.HTML object>"
324
+ ]
325
+ },
326
+ "metadata": {},
327
+ "output_type": "display_data"
328
+ },
329
+ {
330
+ "data": {
331
+ "text/html": [],
332
+ "text/plain": [
333
+ "<IPython.core.display.HTML object>"
334
+ ]
335
+ },
336
+ "metadata": {},
337
+ "output_type": "display_data"
338
+ },
339
+ {
340
+ "data": {
341
+ "image/png": "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",
342
+ "text/plain": [
343
+ "<Figure size 640x480 with 1 Axes>"
344
+ ]
345
+ },
346
+ "metadata": {},
347
+ "output_type": "display_data"
348
+ }
349
+ ],
350
+ "source": [
351
+ "interp = ClassificationInterpretation.from_learner(learn)\n",
352
+ "interp.plot_confusion_matrix()"
353
+ ]
354
+ },
355
+ {
356
+ "cell_type": "code",
357
+ "execution_count": 16,
358
+ "metadata": {},
359
+ "outputs": [],
360
+ "source": [
361
+ "learn.export('BirdOrForest.pkl')"
362
+ ]
363
+ }
364
+ ],
365
+ "metadata": {
366
+ "kernelspec": {
367
+ "display_name": "Python 3",
368
+ "language": "python",
369
+ "name": "python3"
370
+ },
371
+ "language_info": {
372
+ "codemirror_mode": {
373
+ "name": "ipython",
374
+ "version": 3
375
+ },
376
+ "file_extension": ".py",
377
+ "mimetype": "text/x-python",
378
+ "name": "python",
379
+ "nbconvert_exporter": "python",
380
+ "pygments_lexer": "ipython3",
381
+ "version": "3.12.3"
382
+ }
383
+ },
384
+ "nbformat": 4,
385
+ "nbformat_minor": 2
386
+ }
BirdOrForest.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3ccd989e1a51db855cf465dd7c34b7e0bfa3d00e90d491c1e54ece215db32188
3
+ size 46963431
Examples/1.jpg ADDED
Examples/2.jpg ADDED
Examples/3.jpg ADDED
Examples/4.jpg ADDED
app.py CHANGED
@@ -1,7 +1,18 @@
1
  import gradio as gr
 
2
 
3
- def greet(name):
4
- return "Hello " + name + "!!"
5
 
6
- demo = gr.Interface(fn=greet, inputs="text", outputs="text")
7
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
+ from fastbook import *
3
 
 
 
4
 
5
+ learn = load_learner('BirdOrForest.pkl')
6
+
7
+
8
+ image = gr.inputs.Image(shape=(224, 224))
9
+ label = gr.outputs.Label()
10
+ path = Path("Examples")
11
+ examples = [[path/"1.jpg"], [path/"2.jpg"], [path/"3.jpg"], [path/"4.jpg"]]
12
+
13
+
14
+ def prediction(img):
15
+ return
16
+
17
+ demo = gr.Interface(fn=prediction, inputs=image, outputs=label, examples=examples)
18
+ demo.launch(inline = False)
g CHANGED
@@ -1,5 +1,5 @@
1
  #!/bin/bash
2
- #this is a shortcut for pushing alx project to github
3
  loober=$(cat ~/counter.txt)
4
  commit_message="Commit : $loober"
5
  git add .
 
1
  #!/bin/bash
2
+ #this is a shortcut for pushing project to github
3
  loober=$(cat ~/counter.txt)
4
  commit_message="Commit : $loober"
5
  git add .
images/bird/04560e85-0b49-41ff-a45e-dbf958389e33.jpg ADDED
images/bird/2015b31e-26fb-4a01-800b-0966fd4bffe6.jpg ADDED
images/bird/26a70e86-0a6e-4f56-a999-d82b154a64b0.jpg ADDED
images/bird/65a8f3e5-13ca-4ae8-afc1-4b8af210ebeb.jpg ADDED
images/bird/769cafa8-9b76-4dc4-99c5-2cd8539e904e.jpg ADDED
images/bird/b70b4a36-2862-4034-869c-5373c29457b6.jpg ADDED
images/bird/d971b2e4-f2b2-421b-9597-17acbc81ae02.jpg ADDED
images/bird/e32922ed-fbdd-45de-92cd-7e89f487f0a4.jpg ADDED
images/forest/1649db2c-236c-4359-ad85-9f395d26c932.jpg ADDED
images/forest/30e2174c-2449-4b5e-8781-8a52781df862.jpg ADDED
images/forest/4bb2a2bf-bcee-4ee3-8574-20e3208a1232.jpg ADDED
images/forest/9bdf9c94-7f11-4f59-a1fb-8e54925580ba.jpeg ADDED
images/forest/a99d97fd-ec3b-4bc5-a2e3-a01a171490f0.jpg ADDED
images/forest/ad1abb9f-4b66-47b7-a701-d6fe813c5e3d.jpg ADDED
images/forest/c68b5998-44f7-43e4-9116-0c88b49a76a4.jpg ADDED
images/forest/f6aba4ba-e52b-4e43-b648-9803614cb352.jpg ADDED
pythonfile.ipynb DELETED
@@ -1,69 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "code",
5
- "execution_count": 2,
6
- "metadata": {},
7
- "outputs": [
8
- {
9
- "name": "stdout",
10
- "output_type": "stream",
11
- "text": [
12
- "5\n"
13
- ]
14
- }
15
- ],
16
- "source": [
17
- "print(2+3)"
18
- ]
19
- },
20
- {
21
- "cell_type": "code",
22
- "execution_count": 4,
23
- "metadata": {},
24
- "outputs": [
25
- {
26
- "data": {
27
- "text/plain": [
28
- "5"
29
- ]
30
- },
31
- "execution_count": 4,
32
- "metadata": {},
33
- "output_type": "execute_result"
34
- }
35
- ],
36
- "source": [
37
- "2+3"
38
- ]
39
- },
40
- {
41
- "cell_type": "code",
42
- "execution_count": null,
43
- "metadata": {},
44
- "outputs": [],
45
- "source": []
46
- }
47
- ],
48
- "metadata": {
49
- "kernelspec": {
50
- "display_name": "Python 3",
51
- "language": "python",
52
- "name": "python3"
53
- },
54
- "language_info": {
55
- "codemirror_mode": {
56
- "name": "ipython",
57
- "version": 3
58
- },
59
- "file_extension": ".py",
60
- "mimetype": "text/x-python",
61
- "name": "python",
62
- "nbconvert_exporter": "python",
63
- "pygments_lexer": "ipython3",
64
- "version": "3.12.3"
65
- }
66
- },
67
- "nbformat": 4,
68
- "nbformat_minor": 2
69
- }