3v324v23 commited on
Commit
bb27838
·
1 Parent(s): 7971dcf

Commit : 113

Browse files
Files changed (4) hide show
  1. BirdOrForest.ipynb +0 -386
  2. BirdOrForest.pkl +3 -0
  3. app.py +1 -21
  4. predictfile.ipynb +0 -0
BirdOrForest.ipynb DELETED
@@ -1,386 +0,0 @@
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:a212f5f54b91d4a4c50fad5832787e60f0a1600e9a41efde11c8c70e005ee6fe
3
+ size 46963303
app.py CHANGED
@@ -1,27 +1,7 @@
1
  import gradio as gr
2
  from fastbook import *
3
 
4
- Search_Words = ["bird", "forest"]
5
- path = Path("images")
6
- Search_Num = 10
7
-
8
- for W in Search_Words:
9
- dest = path/W
10
- dest.mkdir(exist_ok=True, parents=True)
11
- download_images(dest, urls=search_images_ddg(f'{W} photo', max_images=Search_Num))
12
- time.sleep(5)
13
- resize_images(path/W, max_size=400, dest=path/W)
14
-
15
- dls = DataBlock(
16
- blocks=(ImageBlock, CategoryBlock),
17
- get_items=get_image_files,
18
- splitter=RandomSplitter(valid_pct=0.2, seed=42),
19
- get_y=parent_label,
20
- item_tfms=[Resize(192, method='squish')]
21
- ).dataloaders(path, bs=6)
22
-
23
- learn = vision_learner(dls, resnet18, metrics=error_rate)
24
- learn.fine_tune(3)
25
 
26
  def predict_image(image):
27
  img = PILImage.create(image)
 
1
  import gradio as gr
2
  from fastbook import *
3
 
4
+ learn = load_learner('BirdOrForest.pkl')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
  def predict_image(image):
7
  img = PILImage.create(image)
predictfile.ipynb DELETED
File without changes