Commit
·
06282d7
1
Parent(s):
384c66d
Upload 7 files
Browse files- Flickr_8k.testImages.txt +1000 -0
- captions.txt +0 -0
- descriptions.txt +0 -0
- descriptions1.txt +0 -0
- features.pkl +3 -0
- notebooks/Img-captioning-project.ipynb +869 -0
- notebooks/img_captioning_project.py +581 -0
Flickr_8k.testImages.txt
ADDED
|
@@ -0,0 +1,1000 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
3385593926_d3e9c21170.jpg
|
| 2 |
+
2677656448_6b7e7702af.jpg
|
| 3 |
+
311146855_0b65fdb169.jpg
|
| 4 |
+
1258913059_07c613f7ff.jpg
|
| 5 |
+
241347760_d44c8d3a01.jpg
|
| 6 |
+
2654514044_a70a6e2c21.jpg
|
| 7 |
+
2339106348_2df90aa6a9.jpg
|
| 8 |
+
256085101_2c2617c5d0.jpg
|
| 9 |
+
280706862_14c30d734a.jpg
|
| 10 |
+
3072172967_630e9c69d0.jpg
|
| 11 |
+
3482062809_3b694322c4.jpg
|
| 12 |
+
1167669558_87a8a467d6.jpg
|
| 13 |
+
2847615962_c330bded6e.jpg
|
| 14 |
+
3344233740_c010378da7.jpg
|
| 15 |
+
2435685480_a79d42e564.jpg
|
| 16 |
+
3110649716_c17e14670e.jpg
|
| 17 |
+
2511019188_ca71775f2d.jpg
|
| 18 |
+
2521770311_3086ca90de.jpg
|
| 19 |
+
2723477522_d89f5ac62b.jpg
|
| 20 |
+
2218609886_892dcd6915.jpg
|
| 21 |
+
3745451546_fc8ec70cbd.jpg
|
| 22 |
+
2844018783_524b08e5aa.jpg
|
| 23 |
+
3100251515_c68027cc22.jpg
|
| 24 |
+
2207244634_1db1a1890b.jpg
|
| 25 |
+
2943023421_e297f05e11.jpg
|
| 26 |
+
3286822339_5535af6b93.jpg
|
| 27 |
+
2479652566_8f9fac8af5.jpg
|
| 28 |
+
1394368714_3bc7c19969.jpg
|
| 29 |
+
872622575_ba1d3632cc.jpg
|
| 30 |
+
2309860995_c2e2a0feeb.jpg
|
| 31 |
+
241347204_007d83e252.jpg
|
| 32 |
+
3502343542_f9b46688e5.jpg
|
| 33 |
+
757332692_6866ae545c.jpg
|
| 34 |
+
2748729903_3c7c920c4d.jpg
|
| 35 |
+
494792770_2c5f767ac0.jpg
|
| 36 |
+
3213992947_3f3f967a9f.jpg
|
| 37 |
+
2295750198_6d152d7ceb.jpg
|
| 38 |
+
2358898017_24496b80e8.jpg
|
| 39 |
+
3222055946_45f7293bb2.jpg
|
| 40 |
+
444481722_690d0cadcf.jpg
|
| 41 |
+
2647049174_0fb47cee2e.jpg
|
| 42 |
+
1174629344_a2e1a2bdbf.jpg
|
| 43 |
+
2921094201_2ed70a7963.jpg
|
| 44 |
+
2553550034_5901aa9d6c.jpg
|
| 45 |
+
3045613316_4e88862836.jpg
|
| 46 |
+
2706766641_a9df81969d.jpg
|
| 47 |
+
510531976_90bbee22a2.jpg
|
| 48 |
+
485245061_5a5de43e20.jpg
|
| 49 |
+
3070011270_390e597783.jpg
|
| 50 |
+
1352410176_af6b139734.jpg
|
| 51 |
+
1131932671_c8d17751b3.jpg
|
| 52 |
+
3155451946_c0862c70cb.jpg
|
| 53 |
+
2762301555_48a0d0aa24.jpg
|
| 54 |
+
3442242092_e579538d82.jpg
|
| 55 |
+
2415803492_56a673dc25.jpg
|
| 56 |
+
2884301336_dc8e974431.jpg
|
| 57 |
+
3453259666_9ecaa8bb4b.jpg
|
| 58 |
+
3016606751_0e8be20abd.jpg
|
| 59 |
+
3642220260_3aa8a52670.jpg
|
| 60 |
+
2612488996_9450de0e54.jpg
|
| 61 |
+
1499581619_a5f65a882c.jpg
|
| 62 |
+
1427391496_ea512cbe7f.jpg
|
| 63 |
+
3601843201_4809e66909.jpg
|
| 64 |
+
3584561689_b6eb24dd70.jpg
|
| 65 |
+
138718600_f430ebca17.jpg
|
| 66 |
+
3220126881_b0a4f7cccb.jpg
|
| 67 |
+
300314926_0b2e4b64f5.jpg
|
| 68 |
+
3128164023_ebe8da4c32.jpg
|
| 69 |
+
324208502_674488bcea.jpg
|
| 70 |
+
3647750811_395fbd397e.jpg
|
| 71 |
+
3458211052_bb73084398.jpg
|
| 72 |
+
2414397449_2ac3b78e0d.jpg
|
| 73 |
+
3085226474_62aba51179.jpg
|
| 74 |
+
968081289_cdba83ce2e.jpg
|
| 75 |
+
2436081047_bca044c1d3.jpg
|
| 76 |
+
2813992915_f732cf8539.jpg
|
| 77 |
+
3627011534_485f667b10.jpg
|
| 78 |
+
3214237686_6566b8b52f.jpg
|
| 79 |
+
1248940539_46d33ed487.jpg
|
| 80 |
+
2064790732_219e52e19c.jpg
|
| 81 |
+
544576742_283b65fa0d.jpg
|
| 82 |
+
2731171552_4a808c7d5a.jpg
|
| 83 |
+
3609032038_005c789f64.jpg
|
| 84 |
+
3119875880_22f9129a1c.jpg
|
| 85 |
+
3339140382_2e49bc324a.jpg
|
| 86 |
+
2712787899_d85048eb6a.jpg
|
| 87 |
+
3655155990_b0e201dd3c.jpg
|
| 88 |
+
3325497914_f9014d615b.jpg
|
| 89 |
+
468310111_d9396abcbd.jpg
|
| 90 |
+
747921928_48eb02aab2.jpg
|
| 91 |
+
3639967449_137f48b43d.jpg
|
| 92 |
+
2374652725_32f90fa15c.jpg
|
| 93 |
+
3363750526_efcedc47a9.jpg
|
| 94 |
+
2689001252_e0016c89f0.jpg
|
| 95 |
+
3154641421_d1b9b8c24c.jpg
|
| 96 |
+
2631300484_be8621d17b.jpg
|
| 97 |
+
3677318686_b018862bb7.jpg
|
| 98 |
+
405615014_03be7ef618.jpg
|
| 99 |
+
533979933_a95b03323b.jpg
|
| 100 |
+
3437654963_c4fdc17e8b.jpg
|
| 101 |
+
3462454965_a481809cea.jpg
|
| 102 |
+
2256133102_e2c8314ecb.jpg
|
| 103 |
+
3186412658_2ab2ebd397.jpg
|
| 104 |
+
3554634863_5f6f616639.jpg
|
| 105 |
+
3223055565_68973f5d20.jpg
|
| 106 |
+
1554713437_61b64527dd.jpg
|
| 107 |
+
3150742439_b8a352e1e0.jpg
|
| 108 |
+
2238019823_79318d1f11.jpg
|
| 109 |
+
3484832904_08619300d9.jpg
|
| 110 |
+
3365783912_e12c3510d8.jpg
|
| 111 |
+
3185409663_95f6b958d8.jpg
|
| 112 |
+
3207358897_bfa61fa3c6.jpg
|
| 113 |
+
3263497678_8bb688ca01.jpg
|
| 114 |
+
1897025969_0c41688fa6.jpg
|
| 115 |
+
3657016761_d553e514d9.jpg
|
| 116 |
+
3537400880_8f410d747d.jpg
|
| 117 |
+
2419221084_01a14176b4.jpg
|
| 118 |
+
172097782_f0844ec317.jpg
|
| 119 |
+
244571201_0339d8e8d1.jpg
|
| 120 |
+
3467219837_7d62213dec.jpg
|
| 121 |
+
2928152792_b16c73434a.jpg
|
| 122 |
+
401079494_562454c4d6.jpg
|
| 123 |
+
2396691909_6b8c2f7c44.jpg
|
| 124 |
+
3243588540_b418ac7eda.jpg
|
| 125 |
+
3592992234_6d3fe58a70.jpg
|
| 126 |
+
1417031097_ab656bc4bd.jpg
|
| 127 |
+
1122944218_8eb3607403.jpg
|
| 128 |
+
3149919755_f9272b10b3.jpg
|
| 129 |
+
2682382530_f9f8fd1e89.jpg
|
| 130 |
+
2453971388_76616b6a82.jpg
|
| 131 |
+
3079787482_0757e9d167.jpg
|
| 132 |
+
2900274587_f2cbca4c58.jpg
|
| 133 |
+
3301859683_2d5e4b40a3.jpg
|
| 134 |
+
1287073593_f3d2a62455.jpg
|
| 135 |
+
2718495608_d8533e3ac5.jpg
|
| 136 |
+
2054869561_ff723e9eab.jpg
|
| 137 |
+
3567061016_62768dcce1.jpg
|
| 138 |
+
3221036999_3f7b152d8a.jpg
|
| 139 |
+
2554081584_233bdf289a.jpg
|
| 140 |
+
3250695024_93e8ab7305.jpg
|
| 141 |
+
3630332976_fdba22c50b.jpg
|
| 142 |
+
2902269566_419d9f1d8e.jpg
|
| 143 |
+
2544182005_3aa1332bf9.jpg
|
| 144 |
+
2999730677_0cfa1c146e.jpg
|
| 145 |
+
3354883962_170d19bfe4.jpg
|
| 146 |
+
2346401538_f5e8da66fc.jpg
|
| 147 |
+
3605676864_0fb491267e.jpg
|
| 148 |
+
3658427967_6e2e57458d.jpg
|
| 149 |
+
2868575889_2c030aa8ae.jpg
|
| 150 |
+
3494394662_3edfd4a34c.jpg
|
| 151 |
+
3452127051_fa54a902b3.jpg
|
| 152 |
+
3143155555_32b6d24f34.jpg
|
| 153 |
+
470373679_98dceb19e7.jpg
|
| 154 |
+
542317719_ed4dd95dc2.jpg
|
| 155 |
+
2844641033_dab3715a99.jpg
|
| 156 |
+
2588927489_f4da2f11ec.jpg
|
| 157 |
+
2041867793_552819a40b.jpg
|
| 158 |
+
2594042571_2e4666507e.jpg
|
| 159 |
+
493109089_468e105233.jpg
|
| 160 |
+
3109704348_c6416244ce.jpg
|
| 161 |
+
241345811_46b5f157d4.jpg
|
| 162 |
+
3457045393_2bbbb4e941.jpg
|
| 163 |
+
2797149878_bb8e27ecf9.jpg
|
| 164 |
+
543007912_23fc735b99.jpg
|
| 165 |
+
3364026240_645d533fda.jpg
|
| 166 |
+
466956209_2ffcea3941.jpg
|
| 167 |
+
2300168895_a9b83e16fc.jpg
|
| 168 |
+
106490881_5a2dd9b7bd.jpg
|
| 169 |
+
3694991841_141804da1f.jpg
|
| 170 |
+
1523984678_edd68464da.jpg
|
| 171 |
+
2529116152_4331dabf50.jpg
|
| 172 |
+
1773928579_5664a810dc.jpg
|
| 173 |
+
191003285_edd8d0cf58.jpg
|
| 174 |
+
1392272228_cf104086e6.jpg
|
| 175 |
+
2910758605_73a3f5a5c2.jpg
|
| 176 |
+
3507076266_8b17993fbb.jpg
|
| 177 |
+
535830521_aa971319fc.jpg
|
| 178 |
+
70995350_75d0698839.jpg
|
| 179 |
+
909808296_23c427022d.jpg
|
| 180 |
+
3364861247_d590fa170d.jpg
|
| 181 |
+
3545652636_0746537307.jpg
|
| 182 |
+
2869491449_1041485a6b.jpg
|
| 183 |
+
2901074943_041aba4607.jpg
|
| 184 |
+
3480051754_18e5802558.jpg
|
| 185 |
+
3234401637_84e0d14414.jpg
|
| 186 |
+
1317292658_ba29330a0b.jpg
|
| 187 |
+
2140182410_8e2a06fbda.jpg
|
| 188 |
+
3095225232_2e6e6dc92e.jpg
|
| 189 |
+
2280525192_81911f2b00.jpg
|
| 190 |
+
2763044275_aa498eb88b.jpg
|
| 191 |
+
2559503010_84f20b3bc9.jpg
|
| 192 |
+
496110746_a93ca191ae.jpg
|
| 193 |
+
468608014_09fd20eb9b.jpg
|
| 194 |
+
398662202_97e5819b79.jpg
|
| 195 |
+
3141293960_74459f0a24.jpg
|
| 196 |
+
2271755053_e1b1ec8442.jpg
|
| 197 |
+
3181701312_70a379ab6e.jpg
|
| 198 |
+
3523471597_87e0bf3b21.jpg
|
| 199 |
+
2083434441_a93bc6306b.jpg
|
| 200 |
+
54501196_a9ac9d66f2.jpg
|
| 201 |
+
751109943_2a7f8e117f.jpg
|
| 202 |
+
3121521593_18f0ec14f7.jpg
|
| 203 |
+
1432179046_8e3d75cf81.jpg
|
| 204 |
+
3234115903_f4dfc8fc75.jpg
|
| 205 |
+
3497224764_6e17544e0d.jpg
|
| 206 |
+
2878272032_fda05ffac7.jpg
|
| 207 |
+
1536774449_e16b1b6382.jpg
|
| 208 |
+
2228022180_9597b2a458.jpg
|
| 209 |
+
2708686056_1b8f356264.jpg
|
| 210 |
+
1402640441_81978e32a9.jpg
|
| 211 |
+
3437147889_4cf26dd525.jpg
|
| 212 |
+
448658518_eec0b648a6.jpg
|
| 213 |
+
211295363_49010ca38d.jpg
|
| 214 |
+
583174725_6b522b621f.jpg
|
| 215 |
+
2830869109_c4e403eae6.jpg
|
| 216 |
+
488590040_35a3e96c89.jpg
|
| 217 |
+
3217266166_4e0091860b.jpg
|
| 218 |
+
3246991821_750a3097e2.jpg
|
| 219 |
+
3048597471_5697538daf.jpg
|
| 220 |
+
2854959952_3991a385ab.jpg
|
| 221 |
+
2084217208_7bd9bc85e5.jpg
|
| 222 |
+
435827376_4384c3005a.jpg
|
| 223 |
+
2944362789_aebbc22db4.jpg
|
| 224 |
+
2497420371_74788d7ba1.jpg
|
| 225 |
+
309687244_4bdf3b591f.jpg
|
| 226 |
+
3433982387_3fa993cf5a.jpg
|
| 227 |
+
2782433864_5a0c311d87.jpg
|
| 228 |
+
136552115_6dc3e7231c.jpg
|
| 229 |
+
1679617928_a73c1769be.jpg
|
| 230 |
+
352981175_16ff5c07e4.jpg
|
| 231 |
+
1808370027_2088394eb4.jpg
|
| 232 |
+
3651971126_309e6a5e22.jpg
|
| 233 |
+
3708177171_529bb4ff1d.jpg
|
| 234 |
+
2450299735_62c095f40e.jpg
|
| 235 |
+
1387785218_cee67735f5.jpg
|
| 236 |
+
224369028_b1ac40d1fa.jpg
|
| 237 |
+
464251704_b0f0c4c87a.jpg
|
| 238 |
+
2648165716_02e2e74fd6.jpg
|
| 239 |
+
3085667767_66041b202e.jpg
|
| 240 |
+
3211556865_d1d9becf69.jpg
|
| 241 |
+
3503689049_63212220be.jpg
|
| 242 |
+
1107246521_d16a476380.jpg
|
| 243 |
+
3201427741_3033f5b625.jpg
|
| 244 |
+
3540416981_4e74f08cbb.jpg
|
| 245 |
+
410453140_5401bf659a.jpg
|
| 246 |
+
3702436188_2c26192fd0.jpg
|
| 247 |
+
2216695423_1362cb25f3.jpg
|
| 248 |
+
2345984157_724823b1e4.jpg
|
| 249 |
+
3317073508_7e13565c1b.jpg
|
| 250 |
+
2101457132_69c950bc45.jpg
|
| 251 |
+
3285993030_87b0f1d202.jpg
|
| 252 |
+
3220161734_77f42734b9.jpg
|
| 253 |
+
2393264648_a280744f97.jpg
|
| 254 |
+
506367606_7cca2bba9b.jpg
|
| 255 |
+
422763475_0bc814dac6.jpg
|
| 256 |
+
1982852140_56425fa7a2.jpg
|
| 257 |
+
2929506802_5432054d77.jpg
|
| 258 |
+
541063517_35044c554a.jpg
|
| 259 |
+
2595186208_9b16fa0ee3.jpg
|
| 260 |
+
2922973230_5a769ef92a.jpg
|
| 261 |
+
166507476_9be5b9852a.jpg
|
| 262 |
+
114051287_dd85625a04.jpg
|
| 263 |
+
3582742297_1daa29968e.jpg
|
| 264 |
+
396360611_941e5849a3.jpg
|
| 265 |
+
3504881781_6a842e043b.jpg
|
| 266 |
+
3558370311_5734a15890.jpg
|
| 267 |
+
2542662402_d781dd7f7c.jpg
|
| 268 |
+
3532205154_5674b628ea.jpg
|
| 269 |
+
2675685200_0913d84d9b.jpg
|
| 270 |
+
3565598162_56044bc2f7.jpg
|
| 271 |
+
3024172109_a10198e1dd.jpg
|
| 272 |
+
3116769029_f5a76f04ba.jpg
|
| 273 |
+
2061354254_faa5bd294b.jpg
|
| 274 |
+
3576259024_9c05b163aa.jpg
|
| 275 |
+
476759700_8911f087f8.jpg
|
| 276 |
+
2932740428_b15384f389.jpg
|
| 277 |
+
3348385580_10b53391f9.jpg
|
| 278 |
+
2510020918_b2ca0fb2aa.jpg
|
| 279 |
+
1517721825_10176d0683.jpg
|
| 280 |
+
2788945468_74a9618cfa.jpg
|
| 281 |
+
2608289957_044849f73e.jpg
|
| 282 |
+
3328646934_5cca4cebce.jpg
|
| 283 |
+
537532165_e4b7c0e61a.jpg
|
| 284 |
+
2933637854_984614e18b.jpg
|
| 285 |
+
3080056515_3013830309.jpg
|
| 286 |
+
1425069308_488e5fcf9d.jpg
|
| 287 |
+
261490838_2f3ac98b12.jpg
|
| 288 |
+
2926233397_71e617f3a3.jpg
|
| 289 |
+
2963573792_dd51b5fbfb.jpg
|
| 290 |
+
3416091866_a96003d652.jpg
|
| 291 |
+
2431470169_0eeba7d602.jpg
|
| 292 |
+
3099923914_fd450f6d51.jpg
|
| 293 |
+
524105255_b346f288be.jpg
|
| 294 |
+
56489627_e1de43de34.jpg
|
| 295 |
+
2587818583_4aa8e7b174.jpg
|
| 296 |
+
460935487_75b2da7854.jpg
|
| 297 |
+
3316725440_9ccd9b5417.jpg
|
| 298 |
+
2573625591_70291c894a.jpg
|
| 299 |
+
3030566410_393c36a6c5.jpg
|
| 300 |
+
1131800850_89c7ffd477.jpg
|
| 301 |
+
3375549004_beee810e60.jpg
|
| 302 |
+
2470486377_c3a39ccb7b.jpg
|
| 303 |
+
436009777_440c7679a1.jpg
|
| 304 |
+
2862004252_53894bb28b.jpg
|
| 305 |
+
3361990489_92244a58ef.jpg
|
| 306 |
+
293879742_5fe0ffd894.jpg
|
| 307 |
+
3203453897_6317aac6ff.jpg
|
| 308 |
+
1772859261_236c09b861.jpg
|
| 309 |
+
509123893_07b8ea82a9.jpg
|
| 310 |
+
3168123064_d1983b8f92.jpg
|
| 311 |
+
2238759450_6475641bdb.jpg
|
| 312 |
+
246055693_ccb69ac5c6.jpg
|
| 313 |
+
3521374954_37371b49a4.jpg
|
| 314 |
+
3143982558_9e2d44c155.jpg
|
| 315 |
+
3119076670_64b5340530.jpg
|
| 316 |
+
2502905671_c6039804ab.jpg
|
| 317 |
+
1267711451_e2a754b4f8.jpg
|
| 318 |
+
2683963310_20dcd5e566.jpg
|
| 319 |
+
302983277_69a4e732e4.jpg
|
| 320 |
+
3584534971_b44f82c4b9.jpg
|
| 321 |
+
143688283_a96ded20f1.jpg
|
| 322 |
+
1282392036_5a0328eb86.jpg
|
| 323 |
+
2704934519_457dc38986.jpg
|
| 324 |
+
3499720588_c32590108e.jpg
|
| 325 |
+
506738508_327efdf9c3.jpg
|
| 326 |
+
512101751_05a6d93e19.jpg
|
| 327 |
+
2317714088_bcd081f926.jpg
|
| 328 |
+
3275704430_a75828048f.jpg
|
| 329 |
+
2518508760_68d8df7365.jpg
|
| 330 |
+
3254817653_632e840423.jpg
|
| 331 |
+
3113322995_13781860f2.jpg
|
| 332 |
+
2103568100_5d018c495b.jpg
|
| 333 |
+
3518126579_e70e0cbb2b.jpg
|
| 334 |
+
2192131110_8a40e7c028.jpg
|
| 335 |
+
2581066814_179d28f306.jpg
|
| 336 |
+
480505313_2dc686e5db.jpg
|
| 337 |
+
1056338697_4f7d7ce270.jpg
|
| 338 |
+
532457586_bddfc5251d.jpg
|
| 339 |
+
3471841031_a949645ba8.jpg
|
| 340 |
+
3295680663_af21ea648b.jpg
|
| 341 |
+
415793623_6c1225ae27.jpg
|
| 342 |
+
2666205903_8d287669e1.jpg
|
| 343 |
+
3323988406_e3c8fce690.jpg
|
| 344 |
+
3347666612_659e6e2207.jpg
|
| 345 |
+
3439382048_d2e23b2b4c.jpg
|
| 346 |
+
2522297487_57edf117f7.jpg
|
| 347 |
+
3003691049_f4363c2d5c.jpg
|
| 348 |
+
2472980433_210ec62874.jpg
|
| 349 |
+
2307118114_c258e3a47e.jpg
|
| 350 |
+
2410320522_d967f0b75c.jpg
|
| 351 |
+
1408958345_68eea9a4e4.jpg
|
| 352 |
+
498444334_a680d318a1.jpg
|
| 353 |
+
3596131692_91b8a05606.jpg
|
| 354 |
+
2208310655_a3d83080c5.jpg
|
| 355 |
+
2340206885_58754a799a.jpg
|
| 356 |
+
2968182121_b3b491df85.jpg
|
| 357 |
+
3514019869_7de4ece2a5.jpg
|
| 358 |
+
2162564553_96de62c7e6.jpg
|
| 359 |
+
766099402_cdda6964f0.jpg
|
| 360 |
+
3593392955_a4125087f6.jpg
|
| 361 |
+
1472230829_803818a383.jpg
|
| 362 |
+
2774554310_007e980a90.jpg
|
| 363 |
+
2289068031_fe26990183.jpg
|
| 364 |
+
3411393875_a9ff73c67a.jpg
|
| 365 |
+
3406930103_4db7b4dde0.jpg
|
| 366 |
+
497791037_93499238d8.jpg
|
| 367 |
+
3255482333_5bcee79f7e.jpg
|
| 368 |
+
3040033126_9f4b88261b.jpg
|
| 369 |
+
2354540393_a149722680.jpg
|
| 370 |
+
2739331794_4ae78f69a0.jpg
|
| 371 |
+
241346508_0b3907a95b.jpg
|
| 372 |
+
2877503811_4e311253ec.jpg
|
| 373 |
+
3484649669_7bfe62080b.jpg
|
| 374 |
+
1084040636_97d9633581.jpg
|
| 375 |
+
3027397797_4f1d305ced.jpg
|
| 376 |
+
2398605966_1d0c9e6a20.jpg
|
| 377 |
+
2533424347_cf2f84872b.jpg
|
| 378 |
+
189721896_1ffe76d89e.jpg
|
| 379 |
+
2089426086_7acc98a3a8.jpg
|
| 380 |
+
2718024196_3ff660416a.jpg
|
| 381 |
+
3072114570_e1c0127529.jpg
|
| 382 |
+
3516825206_5750824874.jpg
|
| 383 |
+
3224227640_31865b3651.jpg
|
| 384 |
+
200771289_31902164a7.jpg
|
| 385 |
+
3502993968_4ee36afb0e.jpg
|
| 386 |
+
3692593096_fbaea67476.jpg
|
| 387 |
+
447111935_5af98563e3.jpg
|
| 388 |
+
3568197730_a071d7595b.jpg
|
| 389 |
+
3569979711_6507841268.jpg
|
| 390 |
+
180506881_de0f59770f.jpg
|
| 391 |
+
3017521547_f5ef8848e3.jpg
|
| 392 |
+
3503623999_bbd5dcfb18.jpg
|
| 393 |
+
3301811927_a2797339e5.jpg
|
| 394 |
+
3592968286_b63c81bcd2.jpg
|
| 395 |
+
2311690895_0d6efe11c8.jpg
|
| 396 |
+
452419961_6d42ab7000.jpg
|
| 397 |
+
2641770481_c98465ff35.jpg
|
| 398 |
+
2878190821_6e4e03dc5f.jpg
|
| 399 |
+
3725202807_12fbfdd207.jpg
|
| 400 |
+
2938747424_64e64784f0.jpg
|
| 401 |
+
1322323208_c7ecb742c6.jpg
|
| 402 |
+
2458269558_277012780d.jpg
|
| 403 |
+
2985679744_75a7102aab.jpg
|
| 404 |
+
317383917_d8bfa350b6.jpg
|
| 405 |
+
2482629385_f370b290d1.jpg
|
| 406 |
+
293327462_20dee0de56.jpg
|
| 407 |
+
359837950_9e22ffe6c2.jpg
|
| 408 |
+
354642192_3b7666a2dd.jpg
|
| 409 |
+
1786425974_c7c5ad6aa1.jpg
|
| 410 |
+
3767841911_6678052eb6.jpg
|
| 411 |
+
2884420269_225d27f242.jpg
|
| 412 |
+
2715035273_8fc8b1291c.jpg
|
| 413 |
+
3123463486_f5b36a3624.jpg
|
| 414 |
+
2194286203_5dc620006a.jpg
|
| 415 |
+
2815256108_fc1302117d.jpg
|
| 416 |
+
1348304997_afe60a61df.jpg
|
| 417 |
+
888425986_e4b6c12324.jpg
|
| 418 |
+
3485425825_c2f3446e73.jpg
|
| 419 |
+
3217187564_0ffd89dec1.jpg
|
| 420 |
+
3589895574_ee08207d26.jpg
|
| 421 |
+
317109978_cb557802e1.jpg
|
| 422 |
+
2224450291_4c133fabe8.jpg
|
| 423 |
+
3155390408_8e1a81efb2.jpg
|
| 424 |
+
3562050678_4196a7fff3.jpg
|
| 425 |
+
2696866120_254a0345bc.jpg
|
| 426 |
+
3114944484_28b5bb9842.jpg
|
| 427 |
+
751737218_b89839a311.jpg
|
| 428 |
+
352382023_7605223d1c.jpg
|
| 429 |
+
247704641_d883902277.jpg
|
| 430 |
+
3461041826_0e24cdf597.jpg
|
| 431 |
+
3358558292_6ab14193ed.jpg
|
| 432 |
+
525863257_053333e612.jpg
|
| 433 |
+
2112921744_92bf706805.jpg
|
| 434 |
+
375392855_54d46ed5c8.jpg
|
| 435 |
+
1917265421_aeccf1ca38.jpg
|
| 436 |
+
1659358141_0433c9bf99.jpg
|
| 437 |
+
2533642917_a5eace85e6.jpg
|
| 438 |
+
2204550058_2707d92338.jpg
|
| 439 |
+
2764178773_d63b502812.jpg
|
| 440 |
+
180094434_b0f244832d.jpg
|
| 441 |
+
2308978137_bfe776d541.jpg
|
| 442 |
+
3358682439_be4b83544c.jpg
|
| 443 |
+
2602085456_d1beebcb29.jpg
|
| 444 |
+
2589241160_3832440850.jpg
|
| 445 |
+
421322723_3470543368.jpg
|
| 446 |
+
2124040721_bffc0a091a.jpg
|
| 447 |
+
3145967309_b33abe4d84.jpg
|
| 448 |
+
300550441_f44ec3701a.jpg
|
| 449 |
+
1584315962_5b0b45d02d.jpg
|
| 450 |
+
2460797929_66446c13db.jpg
|
| 451 |
+
2909875716_25c8652614.jpg
|
| 452 |
+
3085667865_fa001816be.jpg
|
| 453 |
+
3624327440_bef4f33f32.jpg
|
| 454 |
+
979383193_0a542a059d.jpg
|
| 455 |
+
3009644534_992e9ea2a7.jpg
|
| 456 |
+
561940436_64d6fc125d.jpg
|
| 457 |
+
3393926562_66cc01b001.jpg
|
| 458 |
+
3299820401_c2589186c5.jpg
|
| 459 |
+
3545586120_283d728a97.jpg
|
| 460 |
+
1467533293_a2656cc000.jpg
|
| 461 |
+
373394550_1b2296b8c4.jpg
|
| 462 |
+
539751252_2bd88c456b.jpg
|
| 463 |
+
2621415349_ef1a7e73be.jpg
|
| 464 |
+
2077079696_03380d218b.jpg
|
| 465 |
+
566397227_a469e9e415.jpg
|
| 466 |
+
115684808_cb01227802.jpg
|
| 467 |
+
3387542157_81bfd00072.jpg
|
| 468 |
+
2646116932_232573f030.jpg
|
| 469 |
+
307327914_f98f576adb.jpg
|
| 470 |
+
3044536048_e615466e7f.jpg
|
| 471 |
+
3053743109_a2d780c0d2.jpg
|
| 472 |
+
2265096094_8cc34d669c.jpg
|
| 473 |
+
2283966256_70317e1759.jpg
|
| 474 |
+
3609645320_815c294b65.jpg
|
| 475 |
+
3047264346_e24601bfbf.jpg
|
| 476 |
+
439037721_cdf1fc7358.jpg
|
| 477 |
+
2594902417_f65d8866a8.jpg
|
| 478 |
+
533483374_86c5d4c13e.jpg
|
| 479 |
+
2991575785_bd4868e215.jpg
|
| 480 |
+
3295391572_cbfde03a10.jpg
|
| 481 |
+
3217620013_8b17873273.jpg
|
| 482 |
+
2526041608_a9775ab8d7.jpg
|
| 483 |
+
3028969146_26929ae0e8.jpg
|
| 484 |
+
254295381_d98fa049f4.jpg
|
| 485 |
+
2148916767_644ea6a7fa.jpg
|
| 486 |
+
3200120942_59cfbb3437.jpg
|
| 487 |
+
3591458156_f1a9a33918.jpg
|
| 488 |
+
3354330935_de75be9d2f.jpg
|
| 489 |
+
3320356356_1497e53f80.jpg
|
| 490 |
+
353180303_6a24179c50.jpg
|
| 491 |
+
3064383768_f6838f57da.jpg
|
| 492 |
+
154871781_ae77696b77.jpg
|
| 493 |
+
2616643090_4f2d2d1a44.jpg
|
| 494 |
+
2049051050_20359a434a.jpg
|
| 495 |
+
1472882567_33dc14c8b6.jpg
|
| 496 |
+
170100272_d820db2199.jpg
|
| 497 |
+
2096771662_984441d20d.jpg
|
| 498 |
+
363617160_6cb0c723be.jpg
|
| 499 |
+
3523474077_16e14bc54c.jpg
|
| 500 |
+
3506468593_7e41a6d9f1.jpg
|
| 501 |
+
1446053356_a924b4893f.jpg
|
| 502 |
+
3123351642_3794f2f601.jpg
|
| 503 |
+
523985664_c866af4850.jpg
|
| 504 |
+
3251976937_20625dc2b8.jpg
|
| 505 |
+
2078311270_f01c9eaf4c.jpg
|
| 506 |
+
350443876_c9769f5734.jpg
|
| 507 |
+
2649406158_ded6be38de.jpg
|
| 508 |
+
215214751_e913b6ff09.jpg
|
| 509 |
+
2926595608_69b22be8d4.jpg
|
| 510 |
+
3310067561_b92017acab.jpg
|
| 511 |
+
997722733_0cb5439472.jpg
|
| 512 |
+
1389264266_8170bc1c54.jpg
|
| 513 |
+
2774430374_fee1d793e7.jpg
|
| 514 |
+
3384314832_dffc944152.jpg
|
| 515 |
+
3251648670_9339943ba2.jpg
|
| 516 |
+
2933912528_52b05f84a1.jpg
|
| 517 |
+
3694093650_547259731e.jpg
|
| 518 |
+
2197275664_fabcf3424b.jpg
|
| 519 |
+
2505988632_9541f15583.jpg
|
| 520 |
+
3477715432_79d82487bb.jpg
|
| 521 |
+
241031254_0c6f30e3d1.jpg
|
| 522 |
+
2575647360_f5de38c751.jpg
|
| 523 |
+
3539767254_c598b8e6c7.jpg
|
| 524 |
+
3182121297_38c99b2769.jpg
|
| 525 |
+
1682079482_9a72fa57fa.jpg
|
| 526 |
+
3247052319_da8aba1983.jpg
|
| 527 |
+
249394748_2e4acfbbb5.jpg
|
| 528 |
+
2461616306_3ee7ac1b4b.jpg
|
| 529 |
+
929679367_ff8c7df2ee.jpg
|
| 530 |
+
468102269_135938e209.jpg
|
| 531 |
+
771048251_602e5e8f45.jpg
|
| 532 |
+
2384353160_f395e9a54b.jpg
|
| 533 |
+
3245912109_fdeef6b456.jpg
|
| 534 |
+
3613955682_3860e116cf.jpg
|
| 535 |
+
2866254827_9a8f592017.jpg
|
| 536 |
+
160792599_6a7ec52516.jpg
|
| 537 |
+
3108732084_565b423162.jpg
|
| 538 |
+
2991994607_06f24ec7a6.jpg
|
| 539 |
+
542179694_e170e9e465.jpg
|
| 540 |
+
136644343_0e2b423829.jpg
|
| 541 |
+
3605061440_1d08c80a57.jpg
|
| 542 |
+
2358554995_54ed3baa83.jpg
|
| 543 |
+
3138399980_d6ab8b2272.jpg
|
| 544 |
+
2944836001_b38b516286.jpg
|
| 545 |
+
2949982320_c704b31626.jpg
|
| 546 |
+
2544426580_317b1f1f73.jpg
|
| 547 |
+
3006093003_c211737232.jpg
|
| 548 |
+
2370481277_a3085614c9.jpg
|
| 549 |
+
2707873672_15e6b5d54b.jpg
|
| 550 |
+
3427118504_93126c83e0.jpg
|
| 551 |
+
3203908917_53e53c03d1.jpg
|
| 552 |
+
1415591512_a84644750c.jpg
|
| 553 |
+
2757803246_8aa3499d26.jpg
|
| 554 |
+
2061144717_5b3a1864f0.jpg
|
| 555 |
+
3393343330_b13df4d8ec.jpg
|
| 556 |
+
3569406219_f37ebf7b92.jpg
|
| 557 |
+
3353036763_4cbeba03b2.jpg
|
| 558 |
+
3498327617_d2e3db3ee3.jpg
|
| 559 |
+
1343426964_cde3fb54e8.jpg
|
| 560 |
+
3425851292_de92a072ee.jpg
|
| 561 |
+
3630641436_8f9ac5b9b2.jpg
|
| 562 |
+
2901880865_3fd7b66a45.jpg
|
| 563 |
+
2445283938_ff477c7952.jpg
|
| 564 |
+
3315616181_15dd137e27.jpg
|
| 565 |
+
1572532018_64c030c974.jpg
|
| 566 |
+
2308271254_27fb466eb4.jpg
|
| 567 |
+
2498897831_0bbb5d5b51.jpg
|
| 568 |
+
2170222061_e8bce4a32d.jpg
|
| 569 |
+
2534502836_7a75305655.jpg
|
| 570 |
+
534875358_6ea30d3091.jpg
|
| 571 |
+
370614351_98b8a166b9.jpg
|
| 572 |
+
3429956016_3c7e3096c2.jpg
|
| 573 |
+
514990193_2d2422af2c.jpg
|
| 574 |
+
1287475186_2dee85f1a5.jpg
|
| 575 |
+
2966552760_e65b22cd26.jpg
|
| 576 |
+
486712504_36be449055.jpg
|
| 577 |
+
3015863181_92ff43f4d8.jpg
|
| 578 |
+
348380010_33bb0599ef.jpg
|
| 579 |
+
3670907052_c827593564.jpg
|
| 580 |
+
1626754053_81126b67b6.jpg
|
| 581 |
+
3716244806_97d5a1fb61.jpg
|
| 582 |
+
3641022607_e7a5455d6c.jpg
|
| 583 |
+
2950905787_f2017d3e49.jpg
|
| 584 |
+
3482974845_db4f16befa.jpg
|
| 585 |
+
2883099128_0b056eed9e.jpg
|
| 586 |
+
2310126952_7dc86d88f6.jpg
|
| 587 |
+
2479162876_a5ce3306af.jpg
|
| 588 |
+
3498997518_c2b16f0a0e.jpg
|
| 589 |
+
3232470286_903a61ea16.jpg
|
| 590 |
+
2183227136_8bb657846b.jpg
|
| 591 |
+
2120383553_5825333a3f.jpg
|
| 592 |
+
3544793763_b38546a5e8.jpg
|
| 593 |
+
1404832008_68e432665b.jpg
|
| 594 |
+
3541474181_489f19fae7.jpg
|
| 595 |
+
3042380610_c5ea61eef8.jpg
|
| 596 |
+
486917990_72bd4069af.jpg
|
| 597 |
+
2599444370_9e40103027.jpg
|
| 598 |
+
3468694409_a51571d621.jpg
|
| 599 |
+
494921598_af73bda568.jpg
|
| 600 |
+
197107117_4b438b1872.jpg
|
| 601 |
+
3019842612_8501c1791e.jpg
|
| 602 |
+
909191414_1cf5d85821.jpg
|
| 603 |
+
2945036454_280fa5b29f.jpg
|
| 604 |
+
2666179615_f05a9d8331.jpg
|
| 605 |
+
3030294889_78b2ccbe51.jpg
|
| 606 |
+
509778093_21236bb64d.jpg
|
| 607 |
+
3245070961_8977fdd548.jpg
|
| 608 |
+
533713007_bf9f3e25b4.jpg
|
| 609 |
+
2922222717_12195af92d.jpg
|
| 610 |
+
3191135894_2b4bdabb6d.jpg
|
| 611 |
+
700884207_d3ec546494.jpg
|
| 612 |
+
2196846255_2c1635359a.jpg
|
| 613 |
+
3474406285_01f3d24b71.jpg
|
| 614 |
+
448252603_7d928c900e.jpg
|
| 615 |
+
2860872588_f2c7b30e1a.jpg
|
| 616 |
+
880220939_0ef1c37f1f.jpg
|
| 617 |
+
820169182_f5e78d7d19.jpg
|
| 618 |
+
3436063693_15c8d377a2.jpg
|
| 619 |
+
1262583859_653f1469a9.jpg
|
| 620 |
+
3185371756_ff4e9fa8a6.jpg
|
| 621 |
+
3591462960_86045906bd.jpg
|
| 622 |
+
3619416477_9d18580a14.jpg
|
| 623 |
+
3459156091_c1879ebe28.jpg
|
| 624 |
+
537559285_29be110134.jpg
|
| 625 |
+
3052196390_c59dd24ca8.jpg
|
| 626 |
+
2490768374_45d94fc658.jpg
|
| 627 |
+
150387174_24825cf871.jpg
|
| 628 |
+
1962729184_6996e128e7.jpg
|
| 629 |
+
2306674172_dc07c7f847.jpg
|
| 630 |
+
2086513494_dbbcb583e7.jpg
|
| 631 |
+
2652522323_9218afd8c2.jpg
|
| 632 |
+
3399284917_721aefe2a7.jpg
|
| 633 |
+
370713359_7560808550.jpg
|
| 634 |
+
2843695880_eeea6c67db.jpg
|
| 635 |
+
2676764246_c58205a365.jpg
|
| 636 |
+
3107513635_fe8a21f148.jpg
|
| 637 |
+
2885387575_9127ea10f1.jpg
|
| 638 |
+
3223224391_be50bf4f43.jpg
|
| 639 |
+
1461667284_041c8a2475.jpg
|
| 640 |
+
2196316998_3b2d63f01f.jpg
|
| 641 |
+
1998457059_c9ac9a1e1a.jpg
|
| 642 |
+
3294209955_a1f1e2cc19.jpg
|
| 643 |
+
488408004_a1e26d4886.jpg
|
| 644 |
+
3135504530_0f4130d8f8.jpg
|
| 645 |
+
3217910740_d1d61c08ab.jpg
|
| 646 |
+
3602838407_bf13e49243.jpg
|
| 647 |
+
2984174290_a915748d77.jpg
|
| 648 |
+
424779662_568f9606d0.jpg
|
| 649 |
+
2431832075_00aa1a4457.jpg
|
| 650 |
+
624742559_ff467d8ebc.jpg
|
| 651 |
+
3157847991_463e006a28.jpg
|
| 652 |
+
2893374123_087f98d58a.jpg
|
| 653 |
+
3359551687_68f2f0212a.jpg
|
| 654 |
+
3070031806_3d587c2a66.jpg
|
| 655 |
+
2480850054_de3433b54a.jpg
|
| 656 |
+
3216926094_bc975e84b9.jpg
|
| 657 |
+
3449114979_6cdc3e8da8.jpg
|
| 658 |
+
2543589122_ec3e55f434.jpg
|
| 659 |
+
3530843182_35af2c821c.jpg
|
| 660 |
+
3472364264_dbde5a8d0a.jpg
|
| 661 |
+
3715469645_6d1dc019b3.jpg
|
| 662 |
+
2196107384_361d73a170.jpg
|
| 663 |
+
1561658940_a947f2446a.jpg
|
| 664 |
+
3655074079_7df3812bc5.jpg
|
| 665 |
+
3004823335_9b82cbd8a7.jpg
|
| 666 |
+
2495931537_9b8d4474b6.jpg
|
| 667 |
+
293881927_ac62900fd4.jpg
|
| 668 |
+
3162045919_c2decbb69b.jpg
|
| 669 |
+
505929313_7668f021ab.jpg
|
| 670 |
+
3244470342_c08f6bb17e.jpg
|
| 671 |
+
3655964639_21e76383d0.jpg
|
| 672 |
+
3718964174_cb2dc1615e.jpg
|
| 673 |
+
3388330419_85d72f7cda.jpg
|
| 674 |
+
2128119486_4407061c40.jpg
|
| 675 |
+
917574521_74fab68514.jpg
|
| 676 |
+
400851260_5911898657.jpg
|
| 677 |
+
270816949_ffad112278.jpg
|
| 678 |
+
421730441_6b2267fd31.jpg
|
| 679 |
+
429851331_b248ca01cd.jpg
|
| 680 |
+
241345905_5826a72da1.jpg
|
| 681 |
+
2102360862_264452db8e.jpg
|
| 682 |
+
3051384385_c5c850c1f8.jpg
|
| 683 |
+
3500136982_bf7a85531e.jpg
|
| 684 |
+
416788726_5b4eb1466e.jpg
|
| 685 |
+
245895500_a4eb97af02.jpg
|
| 686 |
+
3259002340_707ce96858.jpg
|
| 687 |
+
2796801478_8ebd7e550b.jpg
|
| 688 |
+
57422853_b5f6366081.jpg
|
| 689 |
+
1311388430_4ab0cd1a1f.jpg
|
| 690 |
+
522063319_33827f1627.jpg
|
| 691 |
+
384577800_fc325af410.jpg
|
| 692 |
+
3159995270_17334ccb5b.jpg
|
| 693 |
+
2229179070_dc8ea8582e.jpg
|
| 694 |
+
1764955991_5e53a28c87.jpg
|
| 695 |
+
670609997_5c7fdb3f0b.jpg
|
| 696 |
+
86412576_c53392ef80.jpg
|
| 697 |
+
260828892_7925d27865.jpg
|
| 698 |
+
3737539561_d1dc161040.jpg
|
| 699 |
+
3262075846_5695021d84.jpg
|
| 700 |
+
3227148358_f152303584.jpg
|
| 701 |
+
2373234213_4ebe9c4ee5.jpg
|
| 702 |
+
2914206497_5e36ac6324.jpg
|
| 703 |
+
488356951_b3b77ad832.jpg
|
| 704 |
+
2105756457_a100d8434e.jpg
|
| 705 |
+
3506560025_8d0f4f9ac4.jpg
|
| 706 |
+
3456362961_d8f7e347a8.jpg
|
| 707 |
+
3044500219_778f9f2b71.jpg
|
| 708 |
+
2301525531_edde12d673.jpg
|
| 709 |
+
3280052365_c4644bf0a5.jpg
|
| 710 |
+
3640422448_a0f42e4559.jpg
|
| 711 |
+
2396025708_e4a72e2558.jpg
|
| 712 |
+
1433142189_cda8652603.jpg
|
| 713 |
+
3214573346_d3a57f0328.jpg
|
| 714 |
+
3218480482_66af7587c8.jpg
|
| 715 |
+
2021613437_d99731f986.jpg
|
| 716 |
+
2525270674_4ab536e7ec.jpg
|
| 717 |
+
3470951932_27ed74eb0b.jpg
|
| 718 |
+
2870875612_2cbb9e4a3c.jpg
|
| 719 |
+
2541104331_a2d65cfa54.jpg
|
| 720 |
+
444057017_f1e0fcaef7.jpg
|
| 721 |
+
3597326009_3678a98a43.jpg
|
| 722 |
+
3360930596_1e75164ce6.jpg
|
| 723 |
+
247637795_fdf26a03cf.jpg
|
| 724 |
+
3696698390_989f1488e7.jpg
|
| 725 |
+
3421789737_f625dd17ed.jpg
|
| 726 |
+
53043785_c468d6f931.jpg
|
| 727 |
+
3058439373_9276a4702a.jpg
|
| 728 |
+
2100816230_ff866fb352.jpg
|
| 729 |
+
2729655904_1dd01922fb.jpg
|
| 730 |
+
3270691950_88583c3524.jpg
|
| 731 |
+
3729525173_7f984ed776.jpg
|
| 732 |
+
540721368_12ac732c6c.jpg
|
| 733 |
+
3686924335_3c51e8834a.jpg
|
| 734 |
+
2295216243_0712928988.jpg
|
| 735 |
+
3450874870_c4dcf58fb3.jpg
|
| 736 |
+
3061481868_d1e00b1f2e.jpg
|
| 737 |
+
308487515_7852928f90.jpg
|
| 738 |
+
263854883_0f320c1562.jpg
|
| 739 |
+
3549583146_3e8bb2f7e9.jpg
|
| 740 |
+
3542484764_77d8920ec9.jpg
|
| 741 |
+
3208074567_ac44aeb3f3.jpg
|
| 742 |
+
3167365436_c379bda282.jpg
|
| 743 |
+
2693425189_47740c22ed.jpg
|
| 744 |
+
434792818_56375e203f.jpg
|
| 745 |
+
3635577874_48ebaac734.jpg
|
| 746 |
+
3413571342_b9855795e2.jpg
|
| 747 |
+
2475162978_2c51048dca.jpg
|
| 748 |
+
2160266952_a2ab39191b.jpg
|
| 749 |
+
463978865_c87c6ca84c.jpg
|
| 750 |
+
3585487286_ef9a8d4c56.jpg
|
| 751 |
+
3239021459_a6b71bb400.jpg
|
| 752 |
+
2662845514_8620aaee96.jpg
|
| 753 |
+
3044746136_8b89da5f40.jpg
|
| 754 |
+
343218198_1ca90e0734.jpg
|
| 755 |
+
2924259848_effb4dcb82.jpg
|
| 756 |
+
3720366614_dfa8fe1088.jpg
|
| 757 |
+
1356796100_b265479721.jpg
|
| 758 |
+
2905942129_2b4bf59bc0.jpg
|
| 759 |
+
2660008870_b672a4c76a.jpg
|
| 760 |
+
2274992140_bb9e868bb8.jpg
|
| 761 |
+
3538213870_9856a76b2a.jpg
|
| 762 |
+
2206960564_325ed0c7ae.jpg
|
| 763 |
+
2839038702_e168128665.jpg
|
| 764 |
+
424416723_19c56cb365.jpg
|
| 765 |
+
2876993733_cb26107d18.jpg
|
| 766 |
+
223299142_521aedf9e7.jpg
|
| 767 |
+
3347798761_5c5260b000.jpg
|
| 768 |
+
1220401002_3f44b1f3f7.jpg
|
| 769 |
+
3564543247_05cdbc31cf.jpg
|
| 770 |
+
3385246141_a263d1053e.jpg
|
| 771 |
+
3334537556_a2cf4e9b9a.jpg
|
| 772 |
+
2909955251_4b326a46a7.jpg
|
| 773 |
+
2247889670_413db8094b.jpg
|
| 774 |
+
3186073578_6e115f45f5.jpg
|
| 775 |
+
3192069971_83c5a90b4c.jpg
|
| 776 |
+
3422458549_f3f3878dbf.jpg
|
| 777 |
+
2891617125_f939f604c7.jpg
|
| 778 |
+
279728508_6bd7281f3c.jpg
|
| 779 |
+
2913965136_2d00136697.jpg
|
| 780 |
+
3692892751_f6574e2700.jpg
|
| 781 |
+
2288099178_41091aa00c.jpg
|
| 782 |
+
476233374_e1396998ef.jpg
|
| 783 |
+
2559921948_06af25d566.jpg
|
| 784 |
+
2189995738_352607a63b.jpg
|
| 785 |
+
3359530430_249f51972c.jpg
|
| 786 |
+
317488612_70ac35493b.jpg
|
| 787 |
+
2842865689_e37256d9ce.jpg
|
| 788 |
+
2225231022_1632d0a5aa.jpg
|
| 789 |
+
327415627_6313d32a64.jpg
|
| 790 |
+
2292406847_f366350600.jpg
|
| 791 |
+
3571147934_d1c8af1d6e.jpg
|
| 792 |
+
2607462776_78e639d891.jpg
|
| 793 |
+
801607443_f15956d1ce.jpg
|
| 794 |
+
2176980976_7054c99621.jpg
|
| 795 |
+
3523559027_a65619a34b.jpg
|
| 796 |
+
1329832826_432538d331.jpg
|
| 797 |
+
260520547_944f9f4c91.jpg
|
| 798 |
+
2473738924_eca928d12f.jpg
|
| 799 |
+
1765164972_92dac06fa9.jpg
|
| 800 |
+
2806710650_e201acd913.jpg
|
| 801 |
+
2501595799_6316001e89.jpg
|
| 802 |
+
3697359692_8a5cdbe4fe.jpg
|
| 803 |
+
3688858505_e8afd1475d.jpg
|
| 804 |
+
3396157719_6807d52a81.jpg
|
| 805 |
+
473220329_819a913bbb.jpg
|
| 806 |
+
3228069008_edb2961fc4.jpg
|
| 807 |
+
2861932486_52befd8592.jpg
|
| 808 |
+
758921886_55a351dd67.jpg
|
| 809 |
+
791338571_7f38510bf7.jpg
|
| 810 |
+
3435035138_af32890a4c.jpg
|
| 811 |
+
1339596997_8ac29c1841.jpg
|
| 812 |
+
3245460937_2710a82709.jpg
|
| 813 |
+
3256275785_9c3af57576.jpg
|
| 814 |
+
2856080862_95d793fa9d.jpg
|
| 815 |
+
3179336562_c3d0c0a3bd.jpg
|
| 816 |
+
430173345_86388d8822.jpg
|
| 817 |
+
1096395242_fc69f0ae5a.jpg
|
| 818 |
+
2378149488_648e5deeac.jpg
|
| 819 |
+
2358561039_e215a8d6cd.jpg
|
| 820 |
+
2667015110_1670324a33.jpg
|
| 821 |
+
500446858_125702b296.jpg
|
| 822 |
+
226607225_44d696db6b.jpg
|
| 823 |
+
2496370758_a3fbc49837.jpg
|
| 824 |
+
3259991972_fce3ab18b2.jpg
|
| 825 |
+
229862312_1a0ba19dab.jpg
|
| 826 |
+
3333921867_6cc7d7c73d.jpg
|
| 827 |
+
2248487950_c62d0c81a9.jpg
|
| 828 |
+
3074842262_62b1b2168c.jpg
|
| 829 |
+
561417861_8e25d0c0e8.jpg
|
| 830 |
+
2646046871_c3a5dbb971.jpg
|
| 831 |
+
2944952557_8484f0da8f.jpg
|
| 832 |
+
3244747165_17028936e0.jpg
|
| 833 |
+
2285570521_05015cbf4b.jpg
|
| 834 |
+
315880837_90db309bab.jpg
|
| 835 |
+
3375070563_3c290a7991.jpg
|
| 836 |
+
1298295313_db1f4c6522.jpg
|
| 837 |
+
3585598356_8ce815bbb9.jpg
|
| 838 |
+
2473689180_e9d8fd656a.jpg
|
| 839 |
+
3258874419_23fec1bdc1.jpg
|
| 840 |
+
1237985362_dbafc59280.jpg
|
| 841 |
+
3290105461_7590f23371.jpg
|
| 842 |
+
2644430445_47c985a2ee.jpg
|
| 843 |
+
732468337_a37075225e.jpg
|
| 844 |
+
113678030_87a6a6e42e.jpg
|
| 845 |
+
2120411340_104eb610b1.jpg
|
| 846 |
+
2450453051_f1d4a78ab4.jpg
|
| 847 |
+
2831217847_555b2f95ca.jpg
|
| 848 |
+
3192266178_f9bf5d3dba.jpg
|
| 849 |
+
326456451_effadbbe49.jpg
|
| 850 |
+
2663794355_e726ec7e05.jpg
|
| 851 |
+
3364151356_eecd07a23e.jpg
|
| 852 |
+
2251747182_6b67a3ab8b.jpg
|
| 853 |
+
3139160252_75109e9e05.jpg
|
| 854 |
+
219070971_ae43410b9e.jpg
|
| 855 |
+
1674612291_7154c5ab61.jpg
|
| 856 |
+
136886677_6026c622eb.jpg
|
| 857 |
+
3398746625_5199beea71.jpg
|
| 858 |
+
3220650628_4ed964e5b4.jpg
|
| 859 |
+
1082379191_ec1e53f996.jpg
|
| 860 |
+
3741462565_cc35966b7a.jpg
|
| 861 |
+
1174525839_7c1e6cfa86.jpg
|
| 862 |
+
3572267708_9d8a81d4a4.jpg
|
| 863 |
+
1509786421_f03158adfc.jpg
|
| 864 |
+
3155987659_b9ea318dd3.jpg
|
| 865 |
+
925491651_57df3a5b36.jpg
|
| 866 |
+
2735558076_0d7bbc18fc.jpg
|
| 867 |
+
300922408_05a4f9938c.jpg
|
| 868 |
+
1490670858_e122df2560.jpg
|
| 869 |
+
2953015871_cae796b6e7.jpg
|
| 870 |
+
524282699_71e678a6bd.jpg
|
| 871 |
+
2890113532_ab2003d74e.jpg
|
| 872 |
+
1456393634_74022d9056.jpg
|
| 873 |
+
2813033949_e19fa08805.jpg
|
| 874 |
+
745880539_cd3f948837.jpg
|
| 875 |
+
2480327661_fb69829f57.jpg
|
| 876 |
+
3125309108_1011486589.jpg
|
| 877 |
+
3287549827_04dec6fb6e.jpg
|
| 878 |
+
391579205_c8373b5411.jpg
|
| 879 |
+
2610447973_89227ff978.jpg
|
| 880 |
+
2698666984_13e17236ae.jpg
|
| 881 |
+
339350939_6643bfb270.jpg
|
| 882 |
+
127490019_7c5c08cb11.jpg
|
| 883 |
+
1714316707_8bbaa2a2ba.jpg
|
| 884 |
+
3556598205_86c180769d.jpg
|
| 885 |
+
757046028_ff5999f91b.jpg
|
| 886 |
+
132489044_3be606baf7.jpg
|
| 887 |
+
3613800013_5a54968ab0.jpg
|
| 888 |
+
2577972703_a22c5f2a87.jpg
|
| 889 |
+
2073964624_52da3a0fc4.jpg
|
| 890 |
+
2194494220_bb2178832c.jpg
|
| 891 |
+
2215136723_960edfea49.jpg
|
| 892 |
+
2759860913_f75b39d783.jpg
|
| 893 |
+
3225310099_d8e419ba56.jpg
|
| 894 |
+
2938120171_970564e3d8.jpg
|
| 895 |
+
754852108_72f80d421f.jpg
|
| 896 |
+
3187395715_f2940c2b72.jpg
|
| 897 |
+
3281078518_630a7a7f4f.jpg
|
| 898 |
+
3071676551_a65741e372.jpg
|
| 899 |
+
3106026005_473a7b1c8c.jpg
|
| 900 |
+
3523874798_9ba2fa46e3.jpg
|
| 901 |
+
245252561_4f20f1c89e.jpg
|
| 902 |
+
3685328542_ab999b83bb.jpg
|
| 903 |
+
3613424631_3ae537624f.jpg
|
| 904 |
+
3584930205_a3f58a4b7c.jpg
|
| 905 |
+
127488876_f2d2a89588.jpg
|
| 906 |
+
3578841731_f775cab089.jpg
|
| 907 |
+
2934359101_cdf57442dc.jpg
|
| 908 |
+
339658315_fbb178c252.jpg
|
| 909 |
+
2991994415_504d1c0a03.jpg
|
| 910 |
+
3349451628_4249a21c8f.jpg
|
| 911 |
+
3197917064_e679a44b8e.jpg
|
| 912 |
+
2657484284_daa07a3a1b.jpg
|
| 913 |
+
2894217628_f1a4153dca.jpg
|
| 914 |
+
3424424006_98f9d1921c.jpg
|
| 915 |
+
2526585002_10987a63f3.jpg
|
| 916 |
+
1836335410_de8313a64e.jpg
|
| 917 |
+
2443380641_7b38d18f5b.jpg
|
| 918 |
+
2208067635_39a03834ca.jpg
|
| 919 |
+
3427233064_6af01bfc5c.jpg
|
| 920 |
+
799486353_f665d7b0f0.jpg
|
| 921 |
+
3741827382_71e93298d0.jpg
|
| 922 |
+
3578914491_36019ba703.jpg
|
| 923 |
+
3197981073_3156963446.jpg
|
| 924 |
+
416960865_048fd3f294.jpg
|
| 925 |
+
197504190_fd1fc3d4b7.jpg
|
| 926 |
+
2484190118_e89363c465.jpg
|
| 927 |
+
2602258549_7401a3cdae.jpg
|
| 928 |
+
493621130_152bdd4e91.jpg
|
| 929 |
+
3332467180_d72f9b067d.jpg
|
| 930 |
+
2981702521_2459f2c1c4.jpg
|
| 931 |
+
461505235_590102a5bf.jpg
|
| 932 |
+
1490213660_9ea45550cf.jpg
|
| 933 |
+
300577375_26cc2773a1.jpg
|
| 934 |
+
2549968784_39bfbe44f9.jpg
|
| 935 |
+
2075321027_c8fcbaf581.jpg
|
| 936 |
+
1547883892_e29b3db42e.jpg
|
| 937 |
+
2886411666_72d8b12ce4.jpg
|
| 938 |
+
2239938351_43c73c887c.jpg
|
| 939 |
+
2918769188_565dd48060.jpg
|
| 940 |
+
3610683688_bbe6d725ed.jpg
|
| 941 |
+
3025549604_38b86198f5.jpg
|
| 942 |
+
2073105823_6dacade004.jpg
|
| 943 |
+
2447284966_d6bbdb4b6e.jpg
|
| 944 |
+
2600867924_cd502fc911.jpg
|
| 945 |
+
2333288869_8c01e4c859.jpg
|
| 946 |
+
3589367895_5d3729e3ea.jpg
|
| 947 |
+
96420612_feb18fc6c6.jpg
|
| 948 |
+
3375991133_87d7c40925.jpg
|
| 949 |
+
3320032226_63390d74a6.jpg
|
| 950 |
+
2971431335_e192613db4.jpg
|
| 951 |
+
219301555_17883a51bd.jpg
|
| 952 |
+
3222041930_f642f49d28.jpg
|
| 953 |
+
3187492926_8aa85f80c6.jpg
|
| 954 |
+
3673165148_67f217064f.jpg
|
| 955 |
+
270724499_107481c88f.jpg
|
| 956 |
+
2182488373_df73c7cc09.jpg
|
| 957 |
+
2421446839_fe7d46c177.jpg
|
| 958 |
+
2603792708_18a97bac97.jpg
|
| 959 |
+
2822290399_97c809d43b.jpg
|
| 960 |
+
1332722096_1e3de8ae70.jpg
|
| 961 |
+
3694064560_467683205b.jpg
|
| 962 |
+
3263395801_5e4cee2b9e.jpg
|
| 963 |
+
3701291852_373ea46bb6.jpg
|
| 964 |
+
2343525685_3eba3b6686.jpg
|
| 965 |
+
416106657_cab2a107a5.jpg
|
| 966 |
+
387830531_e89c192b92.jpg
|
| 967 |
+
2892995070_39f3c9a56e.jpg
|
| 968 |
+
3432550415_e7b77232de.jpg
|
| 969 |
+
3564312955_716e86c48b.jpg
|
| 970 |
+
3238951136_2a99f1a1a8.jpg
|
| 971 |
+
3595643050_d312e4b652.jpg
|
| 972 |
+
3139876823_859c7d7c23.jpg
|
| 973 |
+
3473264983_67917a931f.jpg
|
| 974 |
+
2994179598_a45c2732b5.jpg
|
| 975 |
+
491405109_798222cfd0.jpg
|
| 976 |
+
3115174046_9e96b9ce47.jpg
|
| 977 |
+
3631986552_944ea208fc.jpg
|
| 978 |
+
3350786891_6d39b234e9.jpg
|
| 979 |
+
3062173277_bfb5ef4c45.jpg
|
| 980 |
+
3108197858_441ff38565.jpg
|
| 981 |
+
1224851143_33bcdd299c.jpg
|
| 982 |
+
3458559770_12cf9f134e.jpg
|
| 983 |
+
3425835357_204e620a66.jpg
|
| 984 |
+
3214885227_2be09e7cfb.jpg
|
| 985 |
+
2854207034_1f00555703.jpg
|
| 986 |
+
2167644298_100ca79f54.jpg
|
| 987 |
+
241346971_c100650320.jpg
|
| 988 |
+
1386964743_9e80d96b05.jpg
|
| 989 |
+
3397220683_4aca010f86.jpg
|
| 990 |
+
2473791980_805c819bd4.jpg
|
| 991 |
+
241345844_69e1c22464.jpg
|
| 992 |
+
3256043809_47258e0b3e.jpg
|
| 993 |
+
2351479551_e8820a1ff3.jpg
|
| 994 |
+
3514179514_cbc3371b92.jpg
|
| 995 |
+
1119015538_e8e796281e.jpg
|
| 996 |
+
3727752439_907795603b.jpg
|
| 997 |
+
3430607596_7e4f74e3ff.jpg
|
| 998 |
+
3259666643_ae49524c81.jpg
|
| 999 |
+
2623930900_b9df917b82.jpg
|
| 1000 |
+
3490736665_38710f4b91.jpg
|
captions.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
descriptions.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
descriptions1.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
features.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:542f8e7bcb742c8eda9eb4df8c0d26a4a82feed966ad045a7ebec1bc5505826a
|
| 3 |
+
size 32852115
|
notebooks/Img-captioning-project.ipynb
ADDED
|
@@ -0,0 +1,869 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "code",
|
| 5 |
+
"execution_count": 64,
|
| 6 |
+
"id": "029e3b0a",
|
| 7 |
+
"metadata": {},
|
| 8 |
+
"outputs": [],
|
| 9 |
+
"source": [
|
| 10 |
+
"from os import listdir\n",
|
| 11 |
+
"from pickle import dump\n",
|
| 12 |
+
"from keras.applications.vgg16 import VGG16, preprocess_input\n",
|
| 13 |
+
"from tensorflow.keras.preprocessing.image import img_to_array, load_img\n",
|
| 14 |
+
"from keras.models import Model"
|
| 15 |
+
]
|
| 16 |
+
},
|
| 17 |
+
{
|
| 18 |
+
"cell_type": "code",
|
| 19 |
+
"execution_count": 299,
|
| 20 |
+
"id": "bec9f820",
|
| 21 |
+
"metadata": {},
|
| 22 |
+
"outputs": [],
|
| 23 |
+
"source": [
|
| 24 |
+
"# extract feature from each photo in directory\n",
|
| 25 |
+
"def extract_feature(directory):\n",
|
| 26 |
+
" model = VGG16()\n",
|
| 27 |
+
" #restructure model, here we remove last softmax layer from this model\n",
|
| 28 |
+
" model.layers.pop\n",
|
| 29 |
+
" model = Model(inputs=model.inputs, outputs=model.layers[-1].output)\n",
|
| 30 |
+
" print(model.summary)\n",
|
| 31 |
+
" \n",
|
| 32 |
+
" #extract feature from each photo\n",
|
| 33 |
+
" feature = dict()\n",
|
| 34 |
+
" for name in listdir(directory):\n",
|
| 35 |
+
" filename = directory + '/' + name\n",
|
| 36 |
+
" image = load_img(filename, target_size=(224,224))\n",
|
| 37 |
+
" #convert img pixels to numpy array\n",
|
| 38 |
+
" image = img_to_array(image)\n",
|
| 39 |
+
" #reshape data for the model\n",
|
| 40 |
+
" image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))\n",
|
| 41 |
+
" #preprocess img for preprocess model\n",
|
| 42 |
+
" image = preprocess_input(image)\n",
|
| 43 |
+
" #get features\n",
|
| 44 |
+
" features = model.predict(image, verbose=0)\n",
|
| 45 |
+
" #get img id\n",
|
| 46 |
+
" img_id = name.split('.')[0]\n",
|
| 47 |
+
" #storing features\n",
|
| 48 |
+
" feature[img_id] = features\n",
|
| 49 |
+
" print(\">%s\" % name)\n",
|
| 50 |
+
" return feature"
|
| 51 |
+
]
|
| 52 |
+
},
|
| 53 |
+
{
|
| 54 |
+
"cell_type": "code",
|
| 55 |
+
"execution_count": null,
|
| 56 |
+
"id": "035ed4b2",
|
| 57 |
+
"metadata": {},
|
| 58 |
+
"outputs": [],
|
| 59 |
+
"source": [
|
| 60 |
+
"directory = \"img_captioning_dataset/Images\"\n",
|
| 61 |
+
"features = extract_feature(directory)\n",
|
| 62 |
+
"# print(\"Extracted Features: %d\" %len(features))\n",
|
| 63 |
+
"# dump(features, open('img_captioning_features/features.pkl', 'wb'))"
|
| 64 |
+
]
|
| 65 |
+
},
|
| 66 |
+
{
|
| 67 |
+
"cell_type": "code",
|
| 68 |
+
"execution_count": 385,
|
| 69 |
+
"id": "89135fbf",
|
| 70 |
+
"metadata": {},
|
| 71 |
+
"outputs": [],
|
| 72 |
+
"source": [
|
| 73 |
+
"import string\n",
|
| 74 |
+
"from nltk.tokenize import word_tokenize\n",
|
| 75 |
+
"\n",
|
| 76 |
+
"def load_doc(filename):\n",
|
| 77 |
+
" # open the file as read only\n",
|
| 78 |
+
" file = open(filename, 'r')\n",
|
| 79 |
+
" # read all text\n",
|
| 80 |
+
" text = file.read()\n",
|
| 81 |
+
" # close the file\n",
|
| 82 |
+
" file.close()\n",
|
| 83 |
+
" return text\n",
|
| 84 |
+
"\n",
|
| 85 |
+
"#extract description of image\n",
|
| 86 |
+
"def load_description(doc):\n",
|
| 87 |
+
" mapping = dict()\n",
|
| 88 |
+
" for line in doc.split('\\n'):\n",
|
| 89 |
+
" token = word_tokenize(line)\n",
|
| 90 |
+
" if len(line) < 2:\n",
|
| 91 |
+
" continue\n",
|
| 92 |
+
" image_id, image_desc = token[0], token[1:]\n",
|
| 93 |
+
" image_id = image_id.split('.')[0]\n",
|
| 94 |
+
" image_desc = ' '.join(image_desc)\n",
|
| 95 |
+
" if image_id not in mapping:\n",
|
| 96 |
+
" mapping[image_id] = list()\n",
|
| 97 |
+
" mapping[image_id].append(image_desc)\n",
|
| 98 |
+
" return mapping"
|
| 99 |
+
]
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"cell_type": "code",
|
| 103 |
+
"execution_count": 386,
|
| 104 |
+
"id": "74ffda4f",
|
| 105 |
+
"metadata": {},
|
| 106 |
+
"outputs": [],
|
| 107 |
+
"source": [
|
| 108 |
+
"def clean_descriptions(descriptions):\n",
|
| 109 |
+
" # prepare translation table for removing punctuation\n",
|
| 110 |
+
" table = str.maketrans('', '', string.punctuation)\n",
|
| 111 |
+
" for key, desc_list in descriptions.items():\n",
|
| 112 |
+
" for i in range(len(desc_list)):\n",
|
| 113 |
+
" desc = desc_list[i]\n",
|
| 114 |
+
" # tokenize\n",
|
| 115 |
+
" desc = desc.split()\n",
|
| 116 |
+
" # convert to lower case\n",
|
| 117 |
+
" desc = [word.lower() for word in desc]\n",
|
| 118 |
+
" # remove punctuation from each token\n",
|
| 119 |
+
" desc = [w.translate(table) for w in desc]\n",
|
| 120 |
+
" # remove hanging 's' and 'a'\n",
|
| 121 |
+
" desc = [word for word in desc if len(word)>1]\n",
|
| 122 |
+
" # remove tokens with numbers in them\n",
|
| 123 |
+
" desc = [word for word in desc if word.isalpha()]\n",
|
| 124 |
+
" # store as string\n",
|
| 125 |
+
" desc_list[i] = ' '.join(desc)\n",
|
| 126 |
+
"def to_vocabulary(descriptions):\n",
|
| 127 |
+
" # build a list of all description strings\n",
|
| 128 |
+
" all_desc = set()\n",
|
| 129 |
+
" for key in descriptions.keys():\n",
|
| 130 |
+
" [all_desc.update(d.split()) for d in descriptions[key]]\n",
|
| 131 |
+
" return all_desc"
|
| 132 |
+
]
|
| 133 |
+
},
|
| 134 |
+
{
|
| 135 |
+
"cell_type": "code",
|
| 136 |
+
"execution_count": 387,
|
| 137 |
+
"id": "6ae0e204",
|
| 138 |
+
"metadata": {},
|
| 139 |
+
"outputs": [],
|
| 140 |
+
"source": [
|
| 141 |
+
"def save_descriptions(descriptions, filename):\n",
|
| 142 |
+
" lines = list()\n",
|
| 143 |
+
" for key, desc_list in descriptions.items():\n",
|
| 144 |
+
" for desc in desc_list:\n",
|
| 145 |
+
" lines.append(key + \" \" + desc)\n",
|
| 146 |
+
" data = '\\n'.join(lines)\n",
|
| 147 |
+
" file = open(filename, 'w')\n",
|
| 148 |
+
" file.write(data)\n",
|
| 149 |
+
" file.close()"
|
| 150 |
+
]
|
| 151 |
+
},
|
| 152 |
+
{
|
| 153 |
+
"cell_type": "code",
|
| 154 |
+
"execution_count": 388,
|
| 155 |
+
"id": "ad625117",
|
| 156 |
+
"metadata": {},
|
| 157 |
+
"outputs": [
|
| 158 |
+
{
|
| 159 |
+
"name": "stdout",
|
| 160 |
+
"output_type": "stream",
|
| 161 |
+
"text": [
|
| 162 |
+
"Loaded: 8092\n"
|
| 163 |
+
]
|
| 164 |
+
}
|
| 165 |
+
],
|
| 166 |
+
"source": [
|
| 167 |
+
"filename = \"Flickr8k.token.txt\"\n",
|
| 168 |
+
"doc = load_doc(filename)\n",
|
| 169 |
+
"descriptions = load_description(doc)\n",
|
| 170 |
+
"print(\"Loaded: %d\" %len(descriptions))"
|
| 171 |
+
]
|
| 172 |
+
},
|
| 173 |
+
{
|
| 174 |
+
"cell_type": "code",
|
| 175 |
+
"execution_count": 389,
|
| 176 |
+
"id": "7b06b1b5",
|
| 177 |
+
"metadata": {},
|
| 178 |
+
"outputs": [
|
| 179 |
+
{
|
| 180 |
+
"name": "stdout",
|
| 181 |
+
"output_type": "stream",
|
| 182 |
+
"text": [
|
| 183 |
+
"Vocab size: 8761\n"
|
| 184 |
+
]
|
| 185 |
+
}
|
| 186 |
+
],
|
| 187 |
+
"source": [
|
| 188 |
+
"#clean desc\n",
|
| 189 |
+
"clean_descriptions(descriptions)\n",
|
| 190 |
+
"vocab = to_vocabulary(descriptions)\n",
|
| 191 |
+
"print(\"Vocab size: %d\" %len(vocab))"
|
| 192 |
+
]
|
| 193 |
+
},
|
| 194 |
+
{
|
| 195 |
+
"cell_type": "code",
|
| 196 |
+
"execution_count": 390,
|
| 197 |
+
"id": "c4c867ea",
|
| 198 |
+
"metadata": {},
|
| 199 |
+
"outputs": [],
|
| 200 |
+
"source": [
|
| 201 |
+
"save_descriptions(descriptions, \"another-way/descriptions1.txt\")"
|
| 202 |
+
]
|
| 203 |
+
},
|
| 204 |
+
{
|
| 205 |
+
"cell_type": "markdown",
|
| 206 |
+
"id": "d4079267",
|
| 207 |
+
"metadata": {},
|
| 208 |
+
"source": [
|
| 209 |
+
"### Extract Identifier"
|
| 210 |
+
]
|
| 211 |
+
},
|
| 212 |
+
{
|
| 213 |
+
"cell_type": "code",
|
| 214 |
+
"execution_count": 281,
|
| 215 |
+
"id": "898c84a0",
|
| 216 |
+
"metadata": {},
|
| 217 |
+
"outputs": [],
|
| 218 |
+
"source": [
|
| 219 |
+
"from pickle import dump"
|
| 220 |
+
]
|
| 221 |
+
},
|
| 222 |
+
{
|
| 223 |
+
"cell_type": "code",
|
| 224 |
+
"execution_count": 391,
|
| 225 |
+
"id": "dd687334",
|
| 226 |
+
"metadata": {},
|
| 227 |
+
"outputs": [],
|
| 228 |
+
"source": [
|
| 229 |
+
"#load into memory\n",
|
| 230 |
+
"def load_doc(filename):\n",
|
| 231 |
+
" with open(filename, 'r') as f:\n",
|
| 232 |
+
" content = f.read()\n",
|
| 233 |
+
" return content\n",
|
| 234 |
+
"#pre-defined list of photo identifier\n",
|
| 235 |
+
"def load_set(filename):\n",
|
| 236 |
+
" doc = load_doc(filename)\n",
|
| 237 |
+
" dataset = list()\n",
|
| 238 |
+
" for line in doc.split(\"\\n\"):\n",
|
| 239 |
+
" if len(line) < 1:\n",
|
| 240 |
+
" continue\n",
|
| 241 |
+
" identifier = line.split('.')[0]\n",
|
| 242 |
+
" dataset.append(identifier)\n",
|
| 243 |
+
" return set(dataset)"
|
| 244 |
+
]
|
| 245 |
+
},
|
| 246 |
+
{
|
| 247 |
+
"cell_type": "code",
|
| 248 |
+
"execution_count": 392,
|
| 249 |
+
"id": "2c612418",
|
| 250 |
+
"metadata": {},
|
| 251 |
+
"outputs": [],
|
| 252 |
+
"source": [
|
| 253 |
+
"def load_clean_descripitions(filename, dataset):\n",
|
| 254 |
+
" doc = load_doc(filename)\n",
|
| 255 |
+
" descriptions = dict()\n",
|
| 256 |
+
" for line in doc.split('\\n'):\n",
|
| 257 |
+
" tokens = word_tokenize(line)\n",
|
| 258 |
+
" image_id, image_desc = tokens[0], tokens[1:]\n",
|
| 259 |
+
" if image_id in dataset:\n",
|
| 260 |
+
" if image_id not in descriptions:\n",
|
| 261 |
+
" descriptions[image_id] = list()\n",
|
| 262 |
+
" #wrap description in token\n",
|
| 263 |
+
" desc = 'startseq ' + ' '.join(image_desc) + ' endseq'\n",
|
| 264 |
+
" descriptions[image_id].append(desc)\n",
|
| 265 |
+
" return descriptions"
|
| 266 |
+
]
|
| 267 |
+
},
|
| 268 |
+
{
|
| 269 |
+
"cell_type": "code",
|
| 270 |
+
"execution_count": 393,
|
| 271 |
+
"id": "4d22db3e",
|
| 272 |
+
"metadata": {},
|
| 273 |
+
"outputs": [],
|
| 274 |
+
"source": [
|
| 275 |
+
"def load_photo_features(features, dataset):\n",
|
| 276 |
+
" all_features = load(open(features, 'rb'))\n",
|
| 277 |
+
" features = {k: all_features[k] for k in dataset if k in all_features}\n",
|
| 278 |
+
" return features"
|
| 279 |
+
]
|
| 280 |
+
},
|
| 281 |
+
{
|
| 282 |
+
"cell_type": "code",
|
| 283 |
+
"execution_count": 394,
|
| 284 |
+
"id": "0c3a8e25",
|
| 285 |
+
"metadata": {},
|
| 286 |
+
"outputs": [
|
| 287 |
+
{
|
| 288 |
+
"name": "stdout",
|
| 289 |
+
"output_type": "stream",
|
| 290 |
+
"text": [
|
| 291 |
+
"dataset: 6000\n",
|
| 292 |
+
"Descriptions: train=6000\n",
|
| 293 |
+
"Photos: train=6000\n"
|
| 294 |
+
]
|
| 295 |
+
}
|
| 296 |
+
],
|
| 297 |
+
"source": [
|
| 298 |
+
"from pickle import load\n",
|
| 299 |
+
"\n",
|
| 300 |
+
"features = \"Flickr_8k.trainImages.txt\"\n",
|
| 301 |
+
"train = load_set(features)\n",
|
| 302 |
+
"print(\"dataset: %d\" %len(train))\n",
|
| 303 |
+
"train_descriptions = load_clean_descripitions(\"descriptions1.txt\", train)\n",
|
| 304 |
+
"print(\"Descriptions: train=%d\" %len(train_descriptions))\n",
|
| 305 |
+
"train_features = load_photo_features(\"features.pkl\", train)\n",
|
| 306 |
+
"print('Photos: train=%d' % len(train_features))"
|
| 307 |
+
]
|
| 308 |
+
},
|
| 309 |
+
{
|
| 310 |
+
"cell_type": "code",
|
| 311 |
+
"execution_count": 444,
|
| 312 |
+
"id": "437278aa",
|
| 313 |
+
"metadata": {},
|
| 314 |
+
"outputs": [
|
| 315 |
+
{
|
| 316 |
+
"data": {
|
| 317 |
+
"text/plain": [
|
| 318 |
+
"{'1191338263_a4fa073154': ['startseq little old lady sitting next to an advertisement endseq',\n",
|
| 319 |
+
" 'startseq an asian woman waiting at an underground train stop endseq',\n",
|
| 320 |
+
" 'startseq an old woman sits in transit station next to backlit advertisement endseq',\n",
|
| 321 |
+
" 'startseq woman sits in subway station endseq',\n",
|
| 322 |
+
" 'startseq woman with an umbrella is sitting at station with an aquos commercial on the wall endseq'],\n",
|
| 323 |
+
" '218342358_1755a9cce1': ['startseq cyclist wearing red helmet is riding on the pavement endseq',\n",
|
| 324 |
+
" 'startseq girl is riding bike on the street while wearing red helmet endseq',\n",
|
| 325 |
+
" 'startseq person on bike wearing red helmet riding down street endseq',\n",
|
| 326 |
+
" 'startseq woman wears red helmet and blue shirt as she goes for bike ride in the shade endseq',\n",
|
| 327 |
+
" 'startseq person in blue shirt and red helmet riding bike down the road endseq'],\n",
|
| 328 |
+
" '2187222896_c206d63396': ['startseq boy in red shirt in front of long blue wall raises his eyebrow at the camera endseq',\n",
|
| 329 |
+
" 'startseq boy in red shirt with stripes standing near blue brick wall with handicap signs endseq',\n",
|
| 330 |
+
" 'startseq an african american boy stands in front of blue building in the handicapped space endseq',\n",
|
| 331 |
+
" 'startseq the boy in the orange shirt looks backwards endseq',\n",
|
| 332 |
+
" 'startseq the boy in the red shirt is next to blue wall endseq'],\n",
|
| 333 |
+
" '2276499757_b44dc6f8ce': ['startseq dog looks warily at the brown dog investigating his area endseq',\n",
|
| 334 |
+
" 'startseq large brown dog is looking at medium sized black dog endseq',\n",
|
| 335 |
+
" 'startseq small black dog looks at larger brown dog in grassy field endseq',\n",
|
| 336 |
+
" 'startseq the big brown dog looks at the small black dog in tall grass endseq',\n",
|
| 337 |
+
" 'startseq there is big dog looking at little dog endseq'],\n",
|
| 338 |
+
" '2294598473_40637b5c04': ['startseq dog catches frisbee in midair endseq',\n",
|
| 339 |
+
" 'startseq dog catching frisbee endseq',\n",
|
| 340 |
+
" 'startseq terrier mix catches frisbee in the air endseq',\n",
|
| 341 |
+
" 'startseq white and black dog catching frisbee endseq',\n",
|
| 342 |
+
" 'startseq white dog is leaping in the air with green object in its mouth endseq'],\n",
|
| 343 |
+
" '2380765956_6313d8cae3': ['startseq blond girl wearing green jacket walks on trail along side metal fence endseq',\n",
|
| 344 |
+
" 'startseq girl in green coat walks down rural road playing flute endseq',\n",
|
| 345 |
+
" 'startseq young girl in parka playing flute while walking by fenced in field endseq',\n",
|
| 346 |
+
" 'startseq girl in green and blue jacket walking past an enclosed field endseq',\n",
|
| 347 |
+
" 'startseq girl playing flute as she walks by fence in rural area endseq'],\n",
|
| 348 |
+
" '2501968935_02f2cd8079': ['startseq man dressed in purple shirt and red bandanna smiles at the people watching him endseq',\n",
|
| 349 |
+
" 'startseq man on the street wearing leather chaps and chainmail codpiece endseq',\n",
|
| 350 |
+
" 'startseq man wearing purple shirt and black leather chaps poses for the camera endseq',\n",
|
| 351 |
+
" 'startseq man dressed in leather chaps and purple shirt stands in front of onlookers endseq',\n",
|
| 352 |
+
" 'startseq there is man in purple shirt leather chaps and red bandanna standing near other men endseq'],\n",
|
| 353 |
+
" '2506892928_7e79bec613': ['startseq three children in field with white flowers endseq',\n",
|
| 354 |
+
" 'startseq three children one with stuffed kitten in field of flowers endseq',\n",
|
| 355 |
+
" 'startseq three children play in the garden endseq',\n",
|
| 356 |
+
" 'startseq three children pose among wildflowers endseq',\n",
|
| 357 |
+
" 'startseq three kids palying with toy cat in garden endseq'],\n",
|
| 358 |
+
" '2513260012_03d33305cf': ['startseq black dog is running after white dog in the snow endseq',\n",
|
| 359 |
+
" 'startseq black dog chasing brown dog through snow endseq',\n",
|
| 360 |
+
" 'startseq two dogs chase each other across the snowy ground endseq',\n",
|
| 361 |
+
" 'startseq two dogs play together in the snow endseq',\n",
|
| 362 |
+
" 'startseq two dogs running through low lying body of water endseq'],\n",
|
| 363 |
+
" '2638369467_8fc251595b': ['startseq girl in white dress endseq',\n",
|
| 364 |
+
" 'startseq little girl in white is looking back at the camera while carrying water grenade endseq',\n",
|
| 365 |
+
" 'startseq smiling young girl in braids is playing ball endseq',\n",
|
| 366 |
+
" 'startseq young girl wearing white looks at the camera as she plays endseq',\n",
|
| 367 |
+
" 'startseq the girl is holding green ball endseq'],\n",
|
| 368 |
+
" '2644326817_8f45080b87': ['startseq black and white dog with red frisbee standing on sandy beach endseq',\n",
|
| 369 |
+
" 'startseq dog drops red disc on beach endseq',\n",
|
| 370 |
+
" 'startseq dog with red frisbee flying in the air endseq',\n",
|
| 371 |
+
" 'startseq dog catching red frisbee endseq',\n",
|
| 372 |
+
" 'startseq the black dog is dropping red disc on beach endseq'],\n",
|
| 373 |
+
" '2699342860_5288e203ea': ['startseq boy wearing red tshirt is running through woodland endseq',\n",
|
| 374 |
+
" 'startseq child runs near some trees endseq',\n",
|
| 375 |
+
" 'startseq young boy is dancing around endseq',\n",
|
| 376 |
+
" 'startseq young boy with red short sleeved shirt and jeans runs by some trees endseq',\n",
|
| 377 |
+
" 'startseq the little boy in the red shirt stops to smile for the camera endseq'],\n",
|
| 378 |
+
" '2851304910_b5721199bc': ['startseq photographer looks over the hills endseq',\n",
|
| 379 |
+
" 'startseq woman in red jacket is videotaping natural landscape endseq',\n",
|
| 380 |
+
" 'startseq woman with camera looks out over rolling hills endseq',\n",
|
| 381 |
+
" 'startseq woman with camera on tripod is looking at the view endseq',\n",
|
| 382 |
+
" 'startseq lady in red shirt has her camera set up in the field to record something endseq'],\n",
|
| 383 |
+
" '2903617548_d3e38d7f88': ['startseq little baby plays croquet endseq',\n",
|
| 384 |
+
" 'startseq little girl plays croquet next to truck endseq',\n",
|
| 385 |
+
" 'startseq the child is playing croquette by the truck endseq',\n",
|
| 386 |
+
" 'startseq the kid is in front of car with put and ball endseq',\n",
|
| 387 |
+
" 'startseq the little boy is playing with croquet hammer and ball beside the car endseq'],\n",
|
| 388 |
+
" '2926786902_815a99a154': ['startseq skier in yellow jacket is airborne above the mountains endseq',\n",
|
| 389 |
+
" 'startseq skier jumps high in the air with view of the mountains endseq',\n",
|
| 390 |
+
" 'startseq skiing man in fluorescent jacket jumps very high and it looks as though he is flying endseq',\n",
|
| 391 |
+
" 'startseq somone is high in the air doing ski jump endseq',\n",
|
| 392 |
+
" 'startseq the skier in the green jacket and white pants appears to almost fly into the sky endseq'],\n",
|
| 393 |
+
" '3119887967_271a097464': ['startseq man in sweater pointing at the camera endseq',\n",
|
| 394 |
+
" 'startseq one man is posing with arms outstretched and finger pointed while another stares from behind him endseq',\n",
|
| 395 |
+
" 'startseq the man in the black hat stands behind the man who is pointing his finger endseq',\n",
|
| 396 |
+
" 'startseq two men look toward the camera while the one in front points his index finger endseq',\n",
|
| 397 |
+
" 'startseq two men one wearing black hat while the one in front points standing in hallway endseq'],\n",
|
| 398 |
+
" '3197891333_b1b0fd1702': ['startseq family of nine people including four children pose in front of brick fireplace with white mantle endseq',\n",
|
| 399 |
+
" 'startseq family poses in front of the fireplace and christmas tree endseq',\n",
|
| 400 |
+
" 'startseq family posing by the mantle and christmas tree endseq',\n",
|
| 401 |
+
" 'startseq happy family poses by the fireplace endseq',\n",
|
| 402 |
+
" 'startseq two couples and four kids pose for family picture endseq'],\n",
|
| 403 |
+
" '3338291921_fe7ae0c8f8': ['startseq brown dog in the snow has something hot pink in its mouth endseq',\n",
|
| 404 |
+
" 'startseq brown dog in the snow holding pink hat endseq',\n",
|
| 405 |
+
" 'startseq brown dog is holding pink shirt in the snow endseq',\n",
|
| 406 |
+
" 'startseq dog is carrying something pink in its mouth while walking through the snow endseq',\n",
|
| 407 |
+
" 'startseq dog with something pink in its mouth is looking forward endseq'],\n",
|
| 408 |
+
" '3356369156_074750c6cc': ['startseq blue boat with yellow canopy is floating on calm waters endseq',\n",
|
| 409 |
+
" 'startseq boat in the water endseq',\n",
|
| 410 |
+
" 'startseq boat with roof on green water endseq',\n",
|
| 411 |
+
" 'startseq the boat is in the middle of the water endseq',\n",
|
| 412 |
+
" 'startseq the solitude boat floats on the lake endseq'],\n",
|
| 413 |
+
" '3423802527_94bd2b23b0': ['startseq bunch of girls in cheerleader outfits endseq',\n",
|
| 414 |
+
" 'startseq large group of cheerleaders walking in parade endseq',\n",
|
| 415 |
+
" 'startseq cheerleaders perform endseq',\n",
|
| 416 |
+
" 'startseq many cheerleaders wearing black walk down the street endseq',\n",
|
| 417 |
+
" 'startseq parade of cheerleaders wearing black pink and white uniforms endseq'],\n",
|
| 418 |
+
" '488416045_1c6d903fe0': ['startseq brown dog is running along beach endseq',\n",
|
| 419 |
+
" 'startseq brown dog wearing black collar running across the beach endseq',\n",
|
| 420 |
+
" 'startseq dog walks on the sand near the water endseq',\n",
|
| 421 |
+
" 'startseq brown dog running on the beach endseq',\n",
|
| 422 |
+
" 'startseq the large brown dog is running on the beach by the ocean endseq']}"
|
| 423 |
+
]
|
| 424 |
+
},
|
| 425 |
+
"execution_count": 444,
|
| 426 |
+
"metadata": {},
|
| 427 |
+
"output_type": "execute_result"
|
| 428 |
+
}
|
| 429 |
+
],
|
| 430 |
+
"source": [
|
| 431 |
+
"train_descriptions"
|
| 432 |
+
]
|
| 433 |
+
},
|
| 434 |
+
{
|
| 435 |
+
"cell_type": "markdown",
|
| 436 |
+
"id": "b80bb437",
|
| 437 |
+
"metadata": {},
|
| 438 |
+
"source": [
|
| 439 |
+
"### Now going to use keras tokenizer to change text to numeric form"
|
| 440 |
+
]
|
| 441 |
+
},
|
| 442 |
+
{
|
| 443 |
+
"cell_type": "code",
|
| 444 |
+
"execution_count": 396,
|
| 445 |
+
"id": "c7e2130c",
|
| 446 |
+
"metadata": {},
|
| 447 |
+
"outputs": [],
|
| 448 |
+
"source": [
|
| 449 |
+
"# dict to clean list\n",
|
| 450 |
+
"def to_lines(descriptions):\n",
|
| 451 |
+
" all_desc = list()\n",
|
| 452 |
+
" for key in descriptions.keys():\n",
|
| 453 |
+
" [all_desc.append(d) for d in descriptions[key]]\n",
|
| 454 |
+
" return all_desc"
|
| 455 |
+
]
|
| 456 |
+
},
|
| 457 |
+
{
|
| 458 |
+
"cell_type": "code",
|
| 459 |
+
"execution_count": 397,
|
| 460 |
+
"id": "a91092cf",
|
| 461 |
+
"metadata": {},
|
| 462 |
+
"outputs": [],
|
| 463 |
+
"source": [
|
| 464 |
+
"def create_tokenizer(descriptions):\n",
|
| 465 |
+
" lines = to_lines(descriptions)\n",
|
| 466 |
+
" tokenizer = Tokenizer()\n",
|
| 467 |
+
" tokenizer.fit_on_texts(lines)\n",
|
| 468 |
+
" return tokenizer"
|
| 469 |
+
]
|
| 470 |
+
},
|
| 471 |
+
{
|
| 472 |
+
"cell_type": "code",
|
| 473 |
+
"execution_count": 398,
|
| 474 |
+
"id": "69996870",
|
| 475 |
+
"metadata": {},
|
| 476 |
+
"outputs": [
|
| 477 |
+
{
|
| 478 |
+
"name": "stdout",
|
| 479 |
+
"output_type": "stream",
|
| 480 |
+
"text": [
|
| 481 |
+
"Vocabulary Size: 7577\n"
|
| 482 |
+
]
|
| 483 |
+
}
|
| 484 |
+
],
|
| 485 |
+
"source": [
|
| 486 |
+
"tokenizer = create_tokenizer(train_descriptions)\n",
|
| 487 |
+
"vocab_size = len(tokenizer.word_index) + 1\n",
|
| 488 |
+
"print('Vocabulary Size: %d' % vocab_size)"
|
| 489 |
+
]
|
| 490 |
+
},
|
| 491 |
+
{
|
| 492 |
+
"cell_type": "code",
|
| 493 |
+
"execution_count": 399,
|
| 494 |
+
"id": "9f0b5246",
|
| 495 |
+
"metadata": {},
|
| 496 |
+
"outputs": [],
|
| 497 |
+
"source": [
|
| 498 |
+
"#len of description\n",
|
| 499 |
+
"def max_length(description):\n",
|
| 500 |
+
" lines = to_lines(description)\n",
|
| 501 |
+
" return max(len(d.split()) for d in lines)"
|
| 502 |
+
]
|
| 503 |
+
},
|
| 504 |
+
{
|
| 505 |
+
"cell_type": "code",
|
| 506 |
+
"execution_count": 462,
|
| 507 |
+
"id": "191d71d6",
|
| 508 |
+
"metadata": {},
|
| 509 |
+
"outputs": [],
|
| 510 |
+
"source": [
|
| 511 |
+
"# create input and output sequence\n",
|
| 512 |
+
"def create_sequences(tokenizer, max_length, desc_list, photo):\n",
|
| 513 |
+
" X1, X2, y = list(), list(), list()\n",
|
| 514 |
+
" # walk through each description for the image\n",
|
| 515 |
+
" for desc in desc_list:\n",
|
| 516 |
+
" # encode the sequence\n",
|
| 517 |
+
" seq = tokenizer.texts_to_sequences([desc])[0]\n",
|
| 518 |
+
" # split one sequence into multiple X,y pairs\n",
|
| 519 |
+
" for i in range(1, len(seq)):\n",
|
| 520 |
+
" # split into input and output pair\n",
|
| 521 |
+
" in_seq, out_seq = seq[:i], seq[i]\n",
|
| 522 |
+
" # pad input sequence\n",
|
| 523 |
+
" in_seq = pad_sequences([in_seq], maxlen=max_length)[0]\n",
|
| 524 |
+
" # encode output sequence\n",
|
| 525 |
+
" out_seq = to_categorical([out_seq], num_classes=vocab_size)[0]\n",
|
| 526 |
+
" # store\n",
|
| 527 |
+
" X1.append(photo)\n",
|
| 528 |
+
" X2.append(in_seq)\n",
|
| 529 |
+
" y.append(out_seq)\n",
|
| 530 |
+
" return array(X1), array(X2), array(y)"
|
| 531 |
+
]
|
| 532 |
+
},
|
| 533 |
+
{
|
| 534 |
+
"cell_type": "code",
|
| 535 |
+
"execution_count": 401,
|
| 536 |
+
"id": "4e3e04fa",
|
| 537 |
+
"metadata": {},
|
| 538 |
+
"outputs": [],
|
| 539 |
+
"source": [
|
| 540 |
+
"from numpy import array\n",
|
| 541 |
+
"from tensorflow.keras.preprocessing.text import Tokenizer\n",
|
| 542 |
+
"from tensorflow.keras.preprocessing.sequence import pad_sequences\n",
|
| 543 |
+
"from tensorflow.keras.utils import to_categorical, plot_model\n",
|
| 544 |
+
"from keras.models import Model\n",
|
| 545 |
+
"from keras.layers import Input, Dense, Activation, Dropout, Embedding,LSTM, Bidirectional, BatchNormalization\n",
|
| 546 |
+
"from keras.layers.merging import add\n",
|
| 547 |
+
"from keras.callbacks import ModelCheckpoint"
|
| 548 |
+
]
|
| 549 |
+
},
|
| 550 |
+
{
|
| 551 |
+
"cell_type": "markdown",
|
| 552 |
+
"id": "45c2cfe9",
|
| 553 |
+
"metadata": {},
|
| 554 |
+
"source": [
|
| 555 |
+
"### Model creation"
|
| 556 |
+
]
|
| 557 |
+
},
|
| 558 |
+
{
|
| 559 |
+
"cell_type": "code",
|
| 560 |
+
"execution_count": null,
|
| 561 |
+
"id": "93f8f578",
|
| 562 |
+
"metadata": {},
|
| 563 |
+
"outputs": [],
|
| 564 |
+
"source": []
|
| 565 |
+
},
|
| 566 |
+
{
|
| 567 |
+
"cell_type": "code",
|
| 568 |
+
"execution_count": 467,
|
| 569 |
+
"id": "22c7799b",
|
| 570 |
+
"metadata": {},
|
| 571 |
+
"outputs": [],
|
| 572 |
+
"source": [
|
| 573 |
+
"def define_model(vocab_size, max_length):\n",
|
| 574 |
+
" # feature extractor model\n",
|
| 575 |
+
" inputs1 = Input(shape=(1000,))\n",
|
| 576 |
+
" fe1 = Dropout(0.5)(inputs1)\n",
|
| 577 |
+
" fe2 = Dense(256, activation='relu')(fe1)\n",
|
| 578 |
+
" # sequence model\n",
|
| 579 |
+
" inputs2 = Input(shape=(max_length,))\n",
|
| 580 |
+
" se1 = Embedding(vocab_size,output_dim=256, mask_zero=True)(inputs2)\n",
|
| 581 |
+
" se2 = Dropout(0.5)(se1)\n",
|
| 582 |
+
" se3 = LSTM(256)(se2)\n",
|
| 583 |
+
" # decoder model\n",
|
| 584 |
+
" decoder1 = concatenate([fe2, se3])\n",
|
| 585 |
+
" decoder2 = Dense(256, activation='relu')(decoder1)\n",
|
| 586 |
+
" outputs = Dense(vocab_size, activation='softmax')(decoder2)\n",
|
| 587 |
+
" # tie it together [image, seq] [word]\n",
|
| 588 |
+
" model = Model(inputs=[inputs1, inputs2], outputs=outputs)\n",
|
| 589 |
+
" model.compile(loss='categorical_crossentropy', optimizer='adam')\n",
|
| 590 |
+
" # summarize model\n",
|
| 591 |
+
" print(model.summary())\n",
|
| 592 |
+
" return model"
|
| 593 |
+
]
|
| 594 |
+
},
|
| 595 |
+
{
|
| 596 |
+
"cell_type": "code",
|
| 597 |
+
"execution_count": 463,
|
| 598 |
+
"id": "6ad11b1d",
|
| 599 |
+
"metadata": {},
|
| 600 |
+
"outputs": [],
|
| 601 |
+
"source": [
|
| 602 |
+
"# load batch of data\n",
|
| 603 |
+
"def data_generator(descriptions, photos, tokenizer, max_length):\n",
|
| 604 |
+
" # loop for ever over images\n",
|
| 605 |
+
" while 1:\n",
|
| 606 |
+
" for key, desc_list in descriptions.items():\n",
|
| 607 |
+
" # retrieve the photo feature\n",
|
| 608 |
+
" photo = photos[key][0]\n",
|
| 609 |
+
" in_img, in_seq, out_word = create_sequences(tokenizer, max_length, desc_list, photo)\n",
|
| 610 |
+
" yield [[in_img, in_seq], out_word]"
|
| 611 |
+
]
|
| 612 |
+
},
|
| 613 |
+
{
|
| 614 |
+
"cell_type": "code",
|
| 615 |
+
"execution_count": 464,
|
| 616 |
+
"id": "a999a0db",
|
| 617 |
+
"metadata": {},
|
| 618 |
+
"outputs": [
|
| 619 |
+
{
|
| 620 |
+
"name": "stdout",
|
| 621 |
+
"output_type": "stream",
|
| 622 |
+
"text": [
|
| 623 |
+
"Dataset: 6000\n",
|
| 624 |
+
"train_descriptions= 6000\n",
|
| 625 |
+
"photos: train= 6000\n",
|
| 626 |
+
"Vocab size: 7577\n",
|
| 627 |
+
"Description Length: 34\n"
|
| 628 |
+
]
|
| 629 |
+
}
|
| 630 |
+
],
|
| 631 |
+
"source": [
|
| 632 |
+
"#load train dataset\n",
|
| 633 |
+
"import tensorflow as tf\n",
|
| 634 |
+
"filename = \"Flickr_8k.trainImages.txt\"\n",
|
| 635 |
+
"train = load_set(filename)\n",
|
| 636 |
+
"print(\"Dataset: %d\" %len(train))\n",
|
| 637 |
+
"\n",
|
| 638 |
+
"train_descriptions = load_clean_descripitions(\"descriptions1.txt\", train)\n",
|
| 639 |
+
"print(\"train_descriptions= %d\" %len(train_descriptions))\n",
|
| 640 |
+
"\n",
|
| 641 |
+
"train_feature = load_photo_features(\"features.pkl\", train)\n",
|
| 642 |
+
"print(\"photos: train= %d\" %len(train_feature))\n",
|
| 643 |
+
"\n",
|
| 644 |
+
"tokenizer = create_tokenizer(train_descriptions)\n",
|
| 645 |
+
"vocab_size = len(tokenizer.word_index)+1\n",
|
| 646 |
+
"print(\"Vocab size: %d\" %vocab_size)\n",
|
| 647 |
+
"\n",
|
| 648 |
+
"max_len = max_length(train_descriptions)\n",
|
| 649 |
+
"print('Description Length: %d' % max_len)"
|
| 650 |
+
]
|
| 651 |
+
},
|
| 652 |
+
{
|
| 653 |
+
"cell_type": "code",
|
| 654 |
+
"execution_count": 468,
|
| 655 |
+
"id": "9936fc7f",
|
| 656 |
+
"metadata": {
|
| 657 |
+
"scrolled": false
|
| 658 |
+
},
|
| 659 |
+
"outputs": [
|
| 660 |
+
{
|
| 661 |
+
"name": "stdout",
|
| 662 |
+
"output_type": "stream",
|
| 663 |
+
"text": [
|
| 664 |
+
"Model: \"model_47\"\n",
|
| 665 |
+
"__________________________________________________________________________________________________\n",
|
| 666 |
+
" Layer (type) Output Shape Param # Connected to \n",
|
| 667 |
+
"==================================================================================================\n",
|
| 668 |
+
" input_121 (InputLayer) [(None, 34)] 0 [] \n",
|
| 669 |
+
" \n",
|
| 670 |
+
" input_120 (InputLayer) [(None, 1000)] 0 [] \n",
|
| 671 |
+
" \n",
|
| 672 |
+
" embedding_52 (Embedding) (None, 34, 256) 1939712 ['input_121[0][0]'] \n",
|
| 673 |
+
" \n",
|
| 674 |
+
" dropout_109 (Dropout) (None, 1000) 0 ['input_120[0][0]'] \n",
|
| 675 |
+
" \n",
|
| 676 |
+
" dropout_110 (Dropout) (None, 34, 256) 0 ['embedding_52[0][0]'] \n",
|
| 677 |
+
" \n",
|
| 678 |
+
" dense_151 (Dense) (None, 256) 256256 ['dropout_109[0][0]'] \n",
|
| 679 |
+
" \n",
|
| 680 |
+
" lstm_52 (LSTM) (None, 256) 525312 ['dropout_110[0][0]'] \n",
|
| 681 |
+
" \n",
|
| 682 |
+
" concatenate_8 (Concatenate) (None, 512) 0 ['dense_151[0][0]', \n",
|
| 683 |
+
" 'lstm_52[0][0]'] \n",
|
| 684 |
+
" \n",
|
| 685 |
+
" dense_152 (Dense) (None, 256) 131328 ['concatenate_8[0][0]'] \n",
|
| 686 |
+
" \n",
|
| 687 |
+
" dense_153 (Dense) (None, 7577) 1947289 ['dense_152[0][0]'] \n",
|
| 688 |
+
" \n",
|
| 689 |
+
"==================================================================================================\n",
|
| 690 |
+
"Total params: 4,799,897\n",
|
| 691 |
+
"Trainable params: 4,799,897\n",
|
| 692 |
+
"Non-trainable params: 0\n",
|
| 693 |
+
"__________________________________________________________________________________________________\n",
|
| 694 |
+
"None\n"
|
| 695 |
+
]
|
| 696 |
+
}
|
| 697 |
+
],
|
| 698 |
+
"source": [
|
| 699 |
+
"#train model\n",
|
| 700 |
+
"model = define_model(vocab_size, max_len)\n",
|
| 701 |
+
"epochs = 10\n",
|
| 702 |
+
"steps = len(train_descriptions)"
|
| 703 |
+
]
|
| 704 |
+
},
|
| 705 |
+
{
|
| 706 |
+
"cell_type": "code",
|
| 707 |
+
"execution_count": 469,
|
| 708 |
+
"id": "6d10533f",
|
| 709 |
+
"metadata": {},
|
| 710 |
+
"outputs": [
|
| 711 |
+
{
|
| 712 |
+
"name": "stdout",
|
| 713 |
+
"output_type": "stream",
|
| 714 |
+
"text": [
|
| 715 |
+
" 514/6000 [=>............................] - ETA: 25:52 - loss: 5.8238"
|
| 716 |
+
]
|
| 717 |
+
},
|
| 718 |
+
{
|
| 719 |
+
"ename": "KeyboardInterrupt",
|
| 720 |
+
"evalue": "",
|
| 721 |
+
"output_type": "error",
|
| 722 |
+
"traceback": [
|
| 723 |
+
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
| 724 |
+
"\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
|
| 725 |
+
"Cell \u001b[1;32mIn[469], line 4\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(epochs):\n\u001b[0;32m 2\u001b[0m \u001b[38;5;66;03m#create data generator\u001b[39;00m\n\u001b[0;32m 3\u001b[0m generator \u001b[38;5;241m=\u001b[39m data_generator(train_descriptions, train_feature, tokenizer, max_len)\n\u001b[1;32m----> 4\u001b[0m \u001b[43mmodel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mgenerator\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mepochs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msteps_per_epoch\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[43msteps\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m 5\u001b[0m model\u001b[38;5;241m.\u001b[39msave(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmodel_\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(i) \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mh5\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
|
| 726 |
+
"File \u001b[1;32m~\\miniconda3\\lib\\site-packages\\keras\\utils\\traceback_utils.py:65\u001b[0m, in \u001b[0;36mfilter_traceback.<locals>.error_handler\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 63\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 64\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m---> 65\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m fn(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 66\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m 67\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m _process_traceback_frames(e\u001b[38;5;241m.\u001b[39m__traceback__)\n",
|
| 727 |
+
"File \u001b[1;32m~\\miniconda3\\lib\\site-packages\\keras\\engine\\training.py:1685\u001b[0m, in \u001b[0;36mModel.fit\u001b[1;34m(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_batch_size, validation_freq, max_queue_size, workers, use_multiprocessing)\u001b[0m\n\u001b[0;32m 1677\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m tf\u001b[38;5;241m.\u001b[39mprofiler\u001b[38;5;241m.\u001b[39mexperimental\u001b[38;5;241m.\u001b[39mTrace(\n\u001b[0;32m 1678\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtrain\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m 1679\u001b[0m epoch_num\u001b[38;5;241m=\u001b[39mepoch,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 1682\u001b[0m _r\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1\u001b[39m,\n\u001b[0;32m 1683\u001b[0m ):\n\u001b[0;32m 1684\u001b[0m callbacks\u001b[38;5;241m.\u001b[39mon_train_batch_begin(step)\n\u001b[1;32m-> 1685\u001b[0m tmp_logs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtrain_function\u001b[49m\u001b[43m(\u001b[49m\u001b[43miterator\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1686\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m data_handler\u001b[38;5;241m.\u001b[39mshould_sync:\n\u001b[0;32m 1687\u001b[0m context\u001b[38;5;241m.\u001b[39masync_wait()\n",
|
| 728 |
+
"File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python310\\site-packages\\tensorflow\\python\\util\\traceback_utils.py:150\u001b[0m, in \u001b[0;36mfilter_traceback.<locals>.error_handler\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 148\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 149\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 150\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m fn(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 151\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m 152\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m _process_traceback_frames(e\u001b[38;5;241m.\u001b[39m__traceback__)\n",
|
| 729 |
+
"File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python310\\site-packages\\tensorflow\\python\\eager\\polymorphic_function\\polymorphic_function.py:894\u001b[0m, in \u001b[0;36mFunction.__call__\u001b[1;34m(self, *args, **kwds)\u001b[0m\n\u001b[0;32m 891\u001b[0m compiler \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mxla\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_jit_compile \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnonXla\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 893\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m OptionalXlaContext(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_jit_compile):\n\u001b[1;32m--> 894\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwds)\n\u001b[0;32m 896\u001b[0m new_tracing_count \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mexperimental_get_tracing_count()\n\u001b[0;32m 897\u001b[0m without_tracing \u001b[38;5;241m=\u001b[39m (tracing_count \u001b[38;5;241m==\u001b[39m new_tracing_count)\n",
|
| 730 |
+
"File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python310\\site-packages\\tensorflow\\python\\eager\\polymorphic_function\\polymorphic_function.py:926\u001b[0m, in \u001b[0;36mFunction._call\u001b[1;34m(self, *args, **kwds)\u001b[0m\n\u001b[0;32m 923\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock\u001b[38;5;241m.\u001b[39mrelease()\n\u001b[0;32m 924\u001b[0m \u001b[38;5;66;03m# In this case we have created variables on the first call, so we run the\u001b[39;00m\n\u001b[0;32m 925\u001b[0m \u001b[38;5;66;03m# defunned version which is guaranteed to never create variables.\u001b[39;00m\n\u001b[1;32m--> 926\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_no_variable_creation_fn(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwds) \u001b[38;5;66;03m# pylint: disable=not-callable\u001b[39;00m\n\u001b[0;32m 927\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_variable_creation_fn \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 928\u001b[0m \u001b[38;5;66;03m# Release the lock early so that multiple threads can perform the call\u001b[39;00m\n\u001b[0;32m 929\u001b[0m \u001b[38;5;66;03m# in parallel.\u001b[39;00m\n\u001b[0;32m 930\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock\u001b[38;5;241m.\u001b[39mrelease()\n",
|
| 731 |
+
"File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python310\\site-packages\\tensorflow\\python\\eager\\polymorphic_function\\tracing_compiler.py:143\u001b[0m, in \u001b[0;36mTracingCompiler.__call__\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 140\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock:\n\u001b[0;32m 141\u001b[0m (concrete_function,\n\u001b[0;32m 142\u001b[0m filtered_flat_args) \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_maybe_define_function(args, kwargs)\n\u001b[1;32m--> 143\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mconcrete_function\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call_flat\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 144\u001b[0m \u001b[43m \u001b[49m\u001b[43mfiltered_flat_args\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcaptured_inputs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mconcrete_function\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcaptured_inputs\u001b[49m\u001b[43m)\u001b[49m\n",
|
| 732 |
+
"File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python310\\site-packages\\tensorflow\\python\\eager\\polymorphic_function\\monomorphic_function.py:1757\u001b[0m, in \u001b[0;36mConcreteFunction._call_flat\u001b[1;34m(self, args, captured_inputs, cancellation_manager)\u001b[0m\n\u001b[0;32m 1753\u001b[0m possible_gradient_type \u001b[38;5;241m=\u001b[39m gradients_util\u001b[38;5;241m.\u001b[39mPossibleTapeGradientTypes(args)\n\u001b[0;32m 1754\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m (possible_gradient_type \u001b[38;5;241m==\u001b[39m gradients_util\u001b[38;5;241m.\u001b[39mPOSSIBLE_GRADIENT_TYPES_NONE\n\u001b[0;32m 1755\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m executing_eagerly):\n\u001b[0;32m 1756\u001b[0m \u001b[38;5;66;03m# No tape is watching; skip to running the function.\u001b[39;00m\n\u001b[1;32m-> 1757\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_build_call_outputs(\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_inference_function\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcall\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 1758\u001b[0m \u001b[43m \u001b[49m\u001b[43mctx\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcancellation_manager\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcancellation_manager\u001b[49m\u001b[43m)\u001b[49m)\n\u001b[0;32m 1759\u001b[0m forward_backward \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_select_forward_and_backward_functions(\n\u001b[0;32m 1760\u001b[0m args,\n\u001b[0;32m 1761\u001b[0m possible_gradient_type,\n\u001b[0;32m 1762\u001b[0m executing_eagerly)\n\u001b[0;32m 1763\u001b[0m forward_function, args_with_tangents \u001b[38;5;241m=\u001b[39m forward_backward\u001b[38;5;241m.\u001b[39mforward()\n",
|
| 733 |
+
"File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python310\\site-packages\\tensorflow\\python\\eager\\polymorphic_function\\monomorphic_function.py:381\u001b[0m, in \u001b[0;36m_EagerDefinedFunction.call\u001b[1;34m(self, ctx, args, cancellation_manager)\u001b[0m\n\u001b[0;32m 379\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m _InterpolateFunctionError(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m 380\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m cancellation_manager \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m--> 381\u001b[0m outputs \u001b[38;5;241m=\u001b[39m \u001b[43mexecute\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexecute\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 382\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mstr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msignature\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mname\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 383\u001b[0m \u001b[43m \u001b[49m\u001b[43mnum_outputs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_num_outputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 384\u001b[0m \u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 385\u001b[0m \u001b[43m \u001b[49m\u001b[43mattrs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mattrs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 386\u001b[0m \u001b[43m \u001b[49m\u001b[43mctx\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mctx\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 387\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 388\u001b[0m outputs \u001b[38;5;241m=\u001b[39m execute\u001b[38;5;241m.\u001b[39mexecute_with_cancellation(\n\u001b[0;32m 389\u001b[0m \u001b[38;5;28mstr\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msignature\u001b[38;5;241m.\u001b[39mname),\n\u001b[0;32m 390\u001b[0m num_outputs\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_num_outputs,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 393\u001b[0m ctx\u001b[38;5;241m=\u001b[39mctx,\n\u001b[0;32m 394\u001b[0m cancellation_manager\u001b[38;5;241m=\u001b[39mcancellation_manager)\n",
|
| 734 |
+
"File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python310\\site-packages\\tensorflow\\python\\eager\\execute.py:52\u001b[0m, in \u001b[0;36mquick_execute\u001b[1;34m(op_name, num_outputs, inputs, attrs, ctx, name)\u001b[0m\n\u001b[0;32m 50\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 51\u001b[0m ctx\u001b[38;5;241m.\u001b[39mensure_initialized()\n\u001b[1;32m---> 52\u001b[0m tensors \u001b[38;5;241m=\u001b[39m \u001b[43mpywrap_tfe\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mTFE_Py_Execute\u001b[49m\u001b[43m(\u001b[49m\u001b[43mctx\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_handle\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdevice_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mop_name\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 53\u001b[0m \u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mattrs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnum_outputs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 54\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m core\u001b[38;5;241m.\u001b[39m_NotOkStatusException \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m 55\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n",
|
| 735 |
+
"\u001b[1;31mKeyboardInterrupt\u001b[0m: "
|
| 736 |
+
]
|
| 737 |
+
}
|
| 738 |
+
],
|
| 739 |
+
"source": [
|
| 740 |
+
"for i in range(epochs):\n",
|
| 741 |
+
" #create data generator\n",
|
| 742 |
+
" generator = data_generator(train_descriptions, train_feature, tokenizer, max_len)\n",
|
| 743 |
+
" model.fit(generator, epochs=1, steps_per_epoch = steps, verbose=1)\n",
|
| 744 |
+
" model.save(\"model_\" + str(i) + \"h5\")"
|
| 745 |
+
]
|
| 746 |
+
},
|
| 747 |
+
{
|
| 748 |
+
"cell_type": "code",
|
| 749 |
+
"execution_count": null,
|
| 750 |
+
"id": "f4867e1b",
|
| 751 |
+
"metadata": {},
|
| 752 |
+
"outputs": [],
|
| 753 |
+
"source": [
|
| 754 |
+
"# from tensorflow.keras.callbacks import ModelCheckpoint\n",
|
| 755 |
+
"\n",
|
| 756 |
+
"# # Define the number of epochs and steps\n",
|
| 757 |
+
"# epochs = 10\n",
|
| 758 |
+
"# steps_per_epoch = len(train_descriptions)\n",
|
| 759 |
+
"\n",
|
| 760 |
+
"# # Create a data generator\n",
|
| 761 |
+
"# generator = data_generator(train_descriptions, train_feature, tokenizer, max_len)\n",
|
| 762 |
+
"\n",
|
| 763 |
+
"# # Define a checkpoint callback to save the model after each epoch\n",
|
| 764 |
+
"# checkpoint = ModelCheckpoint(filepath=\"model_{epoch}.h5\", save_weights_only=False, save_format=\"h5\")\n",
|
| 765 |
+
"\n",
|
| 766 |
+
"# # Train the model for the specified number of epochs\n",
|
| 767 |
+
"# model.fit(generator, epochs=epochs, steps_per_epoch=steps_per_epoch, verbose=1, callbacks=[checkpoint])"
|
| 768 |
+
]
|
| 769 |
+
},
|
| 770 |
+
{
|
| 771 |
+
"cell_type": "code",
|
| 772 |
+
"execution_count": 2,
|
| 773 |
+
"id": "3a998776",
|
| 774 |
+
"metadata": {},
|
| 775 |
+
"outputs": [],
|
| 776 |
+
"source": [
|
| 777 |
+
"def word_for_id(interger, tokenizer):\n",
|
| 778 |
+
" for word, index in tokenizer.word_index.items():\n",
|
| 779 |
+
" if index==interger:\n",
|
| 780 |
+
" return word\n",
|
| 781 |
+
" return None\n",
|
| 782 |
+
"def generate_desc(model, tokenizer, photo, max_len):\n",
|
| 783 |
+
" in_text = \"start_seq\"\n",
|
| 784 |
+
" for i in range(max_len):\n",
|
| 785 |
+
" sequence = tokenizer.texts_to_sequences([in_text])[0]\n",
|
| 786 |
+
" sequence = pad_sequence([sequence], maxlen = max_len)\n",
|
| 787 |
+
" yhat = model.predict([photo, sequence], verbose=1)\n",
|
| 788 |
+
" yhat = argmax(yhat)\n",
|
| 789 |
+
" word = word_for_id(yhat, tokenizer)\n",
|
| 790 |
+
" if word is None:\n",
|
| 791 |
+
" break\n",
|
| 792 |
+
" in_text += ' '+word\n",
|
| 793 |
+
" if word=='endseq':\n",
|
| 794 |
+
" break\n",
|
| 795 |
+
" return in_text"
|
| 796 |
+
]
|
| 797 |
+
},
|
| 798 |
+
{
|
| 799 |
+
"cell_type": "code",
|
| 800 |
+
"execution_count": 3,
|
| 801 |
+
"id": "9f7dfb85",
|
| 802 |
+
"metadata": {},
|
| 803 |
+
"outputs": [
|
| 804 |
+
{
|
| 805 |
+
"ename": "NameError",
|
| 806 |
+
"evalue": "name 'corpus_bleu' is not defined",
|
| 807 |
+
"output_type": "error",
|
| 808 |
+
"traceback": [
|
| 809 |
+
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
| 810 |
+
"\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
|
| 811 |
+
"Cell \u001b[1;32mIn[3], line 8\u001b[0m\n\u001b[0;32m 6\u001b[0m references \u001b[38;5;241m=\u001b[39m [d\u001b[38;5;241m.\u001b[39msplit() \u001b[38;5;28;01mfor\u001b[39;00m d \u001b[38;5;129;01min\u001b[39;00m desc_list]\n\u001b[0;32m 7\u001b[0m actual\u001b[38;5;241m.\u001b[39mappend(yhat\u001b[38;5;241m.\u001b[39msplit())\n\u001b[1;32m----> 8\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mBLUE-1: \u001b[39m\u001b[38;5;132;01m%f\u001b[39;00m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;241m%\u001b[39m\u001b[43mcorpus_bleu\u001b[49m(actual, predicted, weights\u001b[38;5;241m=\u001b[39m(\u001b[38;5;241m1.0\u001b[39m,\u001b[38;5;241m0\u001b[39m,\u001b[38;5;241m0\u001b[39m,\u001b[38;5;241m0\u001b[39m)))\n\u001b[0;32m 9\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mBLUE-2: \u001b[39m\u001b[38;5;132;01m%f\u001b[39;00m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;241m%\u001b[39mcorpus_bleu(actual, predicted, weights\u001b[38;5;241m=\u001b[39m(\u001b[38;5;241m0.5\u001b[39m,\u001b[38;5;241m0.5\u001b[39m,\u001b[38;5;241m0\u001b[39m,\u001b[38;5;241m0\u001b[39m)))\n\u001b[0;32m 10\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mBLUE-3: \u001b[39m\u001b[38;5;132;01m%f\u001b[39;00m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;241m%\u001b[39mcorpus_bleu(actual, predicted, weights\u001b[38;5;241m=\u001b[39m(\u001b[38;5;241m0.3\u001b[39m,\u001b[38;5;241m0.3\u001b[39m,\u001b[38;5;241m0.3\u001b[39m,\u001b[38;5;241m0\u001b[39m)))\n",
|
| 812 |
+
"\u001b[1;31mNameError\u001b[0m: name 'corpus_bleu' is not defined"
|
| 813 |
+
]
|
| 814 |
+
}
|
| 815 |
+
],
|
| 816 |
+
"source": [
|
| 817 |
+
"# evaluated the skill of model\n",
|
| 818 |
+
"def evaluate_model(model, description, photos, tokenizer, max_length):\n",
|
| 819 |
+
" actual, predicted = list(), list()\n",
|
| 820 |
+
" for key, desc_list in description.items():\n",
|
| 821 |
+
" yhat = generate_desc(model, tokenizer, photos[key], max_length)\n",
|
| 822 |
+
" references = [d.split() for d in desc_list]\n",
|
| 823 |
+
" actual.append(yhat.split())\n",
|
| 824 |
+
" predicted.append(yhat.split())\n",
|
| 825 |
+
"print(\"BLUE-1: %f\" %corpus_bleu(actual, predicted, weights=(1.0,0,0,0)))\n",
|
| 826 |
+
"print(\"BLUE-2: %f\" %corpus_bleu(actual, predicted, weights=(0.5,0.5,0,0)))\n",
|
| 827 |
+
"print(\"BLUE-3: %f\" %corpus_bleu(actual, predicted, weights=(0.3,0.3,0.3,0)))\n",
|
| 828 |
+
"print(\"BLUE-4: %f\" %corpus_bleu(actual, predicted, weights=(0.25,0.25,0.25,0.25)))"
|
| 829 |
+
]
|
| 830 |
+
},
|
| 831 |
+
{
|
| 832 |
+
"cell_type": "code",
|
| 833 |
+
"execution_count": null,
|
| 834 |
+
"id": "d5a1cd9c",
|
| 835 |
+
"metadata": {},
|
| 836 |
+
"outputs": [],
|
| 837 |
+
"source": []
|
| 838 |
+
},
|
| 839 |
+
{
|
| 840 |
+
"cell_type": "code",
|
| 841 |
+
"execution_count": null,
|
| 842 |
+
"id": "c1509cb1",
|
| 843 |
+
"metadata": {},
|
| 844 |
+
"outputs": [],
|
| 845 |
+
"source": []
|
| 846 |
+
}
|
| 847 |
+
],
|
| 848 |
+
"metadata": {
|
| 849 |
+
"kernelspec": {
|
| 850 |
+
"display_name": "Python 3 (ipykernel)",
|
| 851 |
+
"language": "python",
|
| 852 |
+
"name": "python3"
|
| 853 |
+
},
|
| 854 |
+
"language_info": {
|
| 855 |
+
"codemirror_mode": {
|
| 856 |
+
"name": "ipython",
|
| 857 |
+
"version": 3
|
| 858 |
+
},
|
| 859 |
+
"file_extension": ".py",
|
| 860 |
+
"mimetype": "text/x-python",
|
| 861 |
+
"name": "python",
|
| 862 |
+
"nbconvert_exporter": "python",
|
| 863 |
+
"pygments_lexer": "ipython3",
|
| 864 |
+
"version": "3.10.9"
|
| 865 |
+
}
|
| 866 |
+
},
|
| 867 |
+
"nbformat": 4,
|
| 868 |
+
"nbformat_minor": 5
|
| 869 |
+
}
|
notebooks/img_captioning_project.py
ADDED
|
@@ -0,0 +1,581 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- coding: utf-8 -*-
|
| 2 |
+
"""img-captioning-project.ipynb
|
| 3 |
+
|
| 4 |
+
Automatically generated by Colaboratory.
|
| 5 |
+
|
| 6 |
+
Original file is located at
|
| 7 |
+
https://colab.research.google.com/drive/1wZSpAsjNfRWhMdsclYJT6o2B-YBZc1yH
|
| 8 |
+
"""
|
| 9 |
+
|
| 10 |
+
from os import listdir
|
| 11 |
+
from numpy import array
|
| 12 |
+
from keras.models import Model
|
| 13 |
+
from pickle import dump
|
| 14 |
+
from keras.applications.vgg16 import VGG16
|
| 15 |
+
from tensorflow.keras.preprocessing.image import load_img
|
| 16 |
+
from tensorflow.keras.preprocessing.image import img_to_array
|
| 17 |
+
from tensorflow.keras.preprocessing.sequence import pad_sequences
|
| 18 |
+
from keras.preprocessing.text import Tokenizer
|
| 19 |
+
from keras.utils import to_categorical
|
| 20 |
+
from keras.utils import plot_model
|
| 21 |
+
from keras.models import Model
|
| 22 |
+
from keras.layers import Input
|
| 23 |
+
from keras.layers import Dense
|
| 24 |
+
from keras.layers import LSTM
|
| 25 |
+
from keras.layers import Embedding
|
| 26 |
+
from keras.layers import Dropout
|
| 27 |
+
from tensorflow.keras.layers import Add
|
| 28 |
+
from keras.callbacks import ModelCheckpoint
|
| 29 |
+
|
| 30 |
+
from keras.applications.vgg16 import VGG16, preprocess_input
|
| 31 |
+
model = VGG16()
|
| 32 |
+
# re-structure the model
|
| 33 |
+
model.layers.pop()
|
| 34 |
+
model = Model(inputs=model.inputs, outputs=model.layers[-2].output)
|
| 35 |
+
# summarize
|
| 36 |
+
print(model.summary())
|
| 37 |
+
|
| 38 |
+
from os import listdir
|
| 39 |
+
from pickle import dump
|
| 40 |
+
from tensorflow.keras.preprocessing.image import img_to_array, load_img
|
| 41 |
+
from keras.models import Model
|
| 42 |
+
|
| 43 |
+
# extract feature from each photo in directory
|
| 44 |
+
def extract_features(directory):
|
| 45 |
+
# extract features from each photo
|
| 46 |
+
features = dict()
|
| 47 |
+
for name in listdir(directory):
|
| 48 |
+
# load an image from file
|
| 49 |
+
filename = directory + '/' + name
|
| 50 |
+
image = load_img(filename, target_size=(224, 224))
|
| 51 |
+
# convert the image pixels to a numpy array
|
| 52 |
+
image = img_to_array(image)
|
| 53 |
+
# reshape data for the model
|
| 54 |
+
image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
|
| 55 |
+
# prepare the image for the VGG model
|
| 56 |
+
image = preprocess_input(image)
|
| 57 |
+
# get features
|
| 58 |
+
feature = model.predict(image, verbose=0)
|
| 59 |
+
# get image id
|
| 60 |
+
image_id = name.split('.')[0]
|
| 61 |
+
# store feature
|
| 62 |
+
features[image_id] = feature
|
| 63 |
+
print('>%s' % name)
|
| 64 |
+
return features
|
| 65 |
+
|
| 66 |
+
# directory = "/content/drive/MyDrive/Image_Captioning_Project/Images"
|
| 67 |
+
# features = extract_features(directory)
|
| 68 |
+
# dump(features, open('features1.pkl', 'wb'))
|
| 69 |
+
# print("Extracted Features: %d" %len(features))
|
| 70 |
+
|
| 71 |
+
!ls
|
| 72 |
+
|
| 73 |
+
import string
|
| 74 |
+
from nltk.tokenize import word_tokenize
|
| 75 |
+
|
| 76 |
+
def load_doc(filename):
|
| 77 |
+
# open the file as read only
|
| 78 |
+
file = open(filename, 'r')
|
| 79 |
+
# read all text
|
| 80 |
+
text = file.read()
|
| 81 |
+
# close the file
|
| 82 |
+
file.close()
|
| 83 |
+
return text
|
| 84 |
+
|
| 85 |
+
def load_descriptions(doc):
|
| 86 |
+
mapping = dict()
|
| 87 |
+
# process lines
|
| 88 |
+
for line in doc.split('\n'):
|
| 89 |
+
# split line by white space
|
| 90 |
+
tokens = line.split()
|
| 91 |
+
if len(line) < 2:
|
| 92 |
+
continue
|
| 93 |
+
# take the first token as the image id, the rest as the description
|
| 94 |
+
image_id, image_desc = tokens[0], tokens[1:]
|
| 95 |
+
# remove filename from image id
|
| 96 |
+
image_id = image_id.split('.')[0]
|
| 97 |
+
# convert description tokens back to string
|
| 98 |
+
image_desc = ' '.join(image_desc)
|
| 99 |
+
# create the list if needed
|
| 100 |
+
if image_id not in mapping:
|
| 101 |
+
mapping[image_id] = list()
|
| 102 |
+
# store description
|
| 103 |
+
mapping[image_id].append(image_desc)
|
| 104 |
+
return mapping
|
| 105 |
+
|
| 106 |
+
"""## Preprocessing of Text
|
| 107 |
+
|
| 108 |
+
1. Convert all words to lowercase.
|
| 109 |
+
2. Remove all punctuation.
|
| 110 |
+
3. Remove all words that are one character or less in length (e.g. ‘a’).
|
| 111 |
+
4. Remove all words with numbers in them.
|
| 112 |
+
"""
|
| 113 |
+
|
| 114 |
+
def clean_descriptions(descriptions):
|
| 115 |
+
# prepare translation table for removing punctuation
|
| 116 |
+
table = str.maketrans('', '', string.punctuation)
|
| 117 |
+
for key, desc_list in descriptions.items():
|
| 118 |
+
for i in range(len(desc_list)):
|
| 119 |
+
desc = desc_list[i]
|
| 120 |
+
# tokenize
|
| 121 |
+
desc = desc.split()
|
| 122 |
+
# convert to lower case
|
| 123 |
+
desc = [word.lower() for word in desc]
|
| 124 |
+
# remove punctuation from each token
|
| 125 |
+
desc = [w.translate(table) for w in desc]
|
| 126 |
+
# remove hanging 's' and 'a'
|
| 127 |
+
desc = [word for word in desc if len(word)>1]
|
| 128 |
+
# remove tokens with numbers in them
|
| 129 |
+
desc = [word for word in desc if word.isalpha()]
|
| 130 |
+
# store as string
|
| 131 |
+
desc_list[i] = ' '.join(desc)
|
| 132 |
+
def to_vocabulary(descriptions):
|
| 133 |
+
# build a list of all description strings
|
| 134 |
+
all_desc = set()
|
| 135 |
+
for key in descriptions.keys():
|
| 136 |
+
[all_desc.update(d.split()) for d in descriptions[key]]
|
| 137 |
+
return all_desc
|
| 138 |
+
|
| 139 |
+
def save_descriptions(descriptions, filename):
|
| 140 |
+
lines = list()
|
| 141 |
+
for key, desc_list in descriptions.items():
|
| 142 |
+
for desc in desc_list:
|
| 143 |
+
lines.append(key + " " + desc)
|
| 144 |
+
data = '\n'.join(lines)
|
| 145 |
+
file = open(filename, 'w')
|
| 146 |
+
file.write(data)
|
| 147 |
+
file.close()
|
| 148 |
+
|
| 149 |
+
import nltk
|
| 150 |
+
nltk.download('punkt')
|
| 151 |
+
|
| 152 |
+
filename = "/content/drive/MyDrive/Image_Captioning_Project/Flickr8k.token.txt"
|
| 153 |
+
doc = load_doc(filename)
|
| 154 |
+
descriptions = load_descriptions(doc)
|
| 155 |
+
print("Loaded: %d" %len(descriptions))
|
| 156 |
+
|
| 157 |
+
#clean desc
|
| 158 |
+
clean_descriptions(descriptions)
|
| 159 |
+
vocab = to_vocabulary(descriptions)
|
| 160 |
+
print("Vocab size: %d" %len(vocab))
|
| 161 |
+
|
| 162 |
+
# save_descriptions(descriptions, "descriptions2.txt")
|
| 163 |
+
|
| 164 |
+
"""### Developing Deep Learning Model
|
| 165 |
+
|
| 166 |
+
#### This section is divided into the following parts:
|
| 167 |
+
|
| 168 |
+
Loading Data.
|
| 169 |
+
Defining the Model.
|
| 170 |
+
Fitting the Model.
|
| 171 |
+
"""
|
| 172 |
+
|
| 173 |
+
from pickle import dump
|
| 174 |
+
|
| 175 |
+
#load into memory
|
| 176 |
+
def load_doc(filename):
|
| 177 |
+
# open the file as read only
|
| 178 |
+
file = open(filename, 'r')
|
| 179 |
+
# read all text
|
| 180 |
+
text = file.read()
|
| 181 |
+
# close the file
|
| 182 |
+
file.close()
|
| 183 |
+
return text
|
| 184 |
+
|
| 185 |
+
#pre-defined list of photo identifier
|
| 186 |
+
def load_set(filename):
|
| 187 |
+
doc = load_doc(filename)
|
| 188 |
+
dataset = list()
|
| 189 |
+
for line in doc.split("\n"):
|
| 190 |
+
if len(line) < 1:
|
| 191 |
+
continue
|
| 192 |
+
identifier = line.split('.')[0]
|
| 193 |
+
dataset.append(identifier)
|
| 194 |
+
return set(dataset)
|
| 195 |
+
|
| 196 |
+
"""load_clean_descriptions() that loads the cleaned text descriptions from ‘descriptions.txt‘ for a given set of identifiers and returns a dictionary of identifiers to lists of text descriptions.
|
| 197 |
+
|
| 198 |
+
The model we will develop will generate a caption given a photo, and the caption will be generated one word at a time. The sequence of previously generated words will be provided as input. Therefore, we will need a ‘first word’ to kick-off the generation process and a ‘last word‘ to signal the end of the caption.
|
| 199 |
+
|
| 200 |
+
We will use the strings ‘startseq‘ and ‘endseq‘ for this purpose.
|
| 201 |
+
"""
|
| 202 |
+
|
| 203 |
+
def load_photo_features(features, dataset):
|
| 204 |
+
all_features = load(open(features, 'rb'))
|
| 205 |
+
features = {k: all_features[k] for k in dataset}
|
| 206 |
+
return features
|
| 207 |
+
|
| 208 |
+
def load_clean_descriptions(filename, dataset):
|
| 209 |
+
# load document
|
| 210 |
+
doc = load_doc(filename)
|
| 211 |
+
descriptions = dict()
|
| 212 |
+
for line in doc.split('\n'):
|
| 213 |
+
# split line by white space
|
| 214 |
+
tokens = line.split()
|
| 215 |
+
# split id from description
|
| 216 |
+
image_id, image_desc = tokens[0], tokens[1:]
|
| 217 |
+
# skip images not in the set
|
| 218 |
+
if image_id in dataset:
|
| 219 |
+
# create list
|
| 220 |
+
if image_id not in descriptions:
|
| 221 |
+
descriptions[image_id] = list()
|
| 222 |
+
# wrap description in tokens
|
| 223 |
+
desc = 'startseq ' + ' '.join(image_desc) + ' endseq'
|
| 224 |
+
# store
|
| 225 |
+
descriptions[image_id].append(desc)
|
| 226 |
+
return descriptions
|
| 227 |
+
|
| 228 |
+
from pickle import load
|
| 229 |
+
|
| 230 |
+
# load training dataset (6K)
|
| 231 |
+
filename = '/content/drive/MyDrive/Image_Captioning_Project/Flickr_8k.trainImages.txt'
|
| 232 |
+
train = load_set(filename)
|
| 233 |
+
print('Dataset: %d' % len(train))
|
| 234 |
+
# descriptions
|
| 235 |
+
train_descriptions = load_clean_descriptions('/content/drive/MyDrive/Image_Captioning_Project/descriptions1.txt', train)
|
| 236 |
+
print('Descriptions: train=%d' % len(train_descriptions))
|
| 237 |
+
# photo features
|
| 238 |
+
train_features = load_photo_features('/content/drive/MyDrive/Image_Captioning_Project/features.pkl', train)
|
| 239 |
+
print('Photos: train=%d' % len(train_features))
|
| 240 |
+
|
| 241 |
+
def load_doc(filename):
|
| 242 |
+
# open the file as read only
|
| 243 |
+
file = open(filename, 'r')
|
| 244 |
+
# read all text
|
| 245 |
+
text = file.read()
|
| 246 |
+
# close the file
|
| 247 |
+
file.close
|
| 248 |
+
return text
|
| 249 |
+
|
| 250 |
+
def load_set(filename):
|
| 251 |
+
doc = load_doc(filename)
|
| 252 |
+
dataset = list()
|
| 253 |
+
for line in doc.split("\n"):
|
| 254 |
+
if len(line) < 1:
|
| 255 |
+
continue
|
| 256 |
+
identifier = line.split('.')[0]
|
| 257 |
+
dataset.append(identifier)
|
| 258 |
+
return set(dataset)
|
| 259 |
+
|
| 260 |
+
def load_clean_descriptions(filename, dataset):
|
| 261 |
+
# load document
|
| 262 |
+
doc = load_doc(filename)
|
| 263 |
+
descriptions = dict()
|
| 264 |
+
for line in doc.split('\n'):
|
| 265 |
+
# split line by white space
|
| 266 |
+
tokens = line.split()
|
| 267 |
+
# split id from description
|
| 268 |
+
image_id, image_desc = tokens[0], tokens[1:]
|
| 269 |
+
# skip images not in the set
|
| 270 |
+
if image_id in dataset:
|
| 271 |
+
# create list
|
| 272 |
+
if image_id not in descriptions:
|
| 273 |
+
descriptions[image_id] = list()
|
| 274 |
+
# wrap description in tokens
|
| 275 |
+
desc = 'startseq ' + ' '.join(image_desc) + ' endseq'
|
| 276 |
+
# store
|
| 277 |
+
descriptions[image_id].append(desc)
|
| 278 |
+
return descriptions
|
| 279 |
+
|
| 280 |
+
def load_photo_features(filename, dataset):
|
| 281 |
+
# load all features
|
| 282 |
+
all_features = load(open(filename, 'rb'))
|
| 283 |
+
# filter features
|
| 284 |
+
features = {k: all_features[k] for k in dataset}
|
| 285 |
+
return features
|
| 286 |
+
|
| 287 |
+
# dict to clean list
|
| 288 |
+
def to_lines(descriptions):
|
| 289 |
+
all_desc = list()
|
| 290 |
+
for key in descriptions.keys():
|
| 291 |
+
[all_desc.append(d) for d in descriptions[key]]
|
| 292 |
+
return all_desc
|
| 293 |
+
|
| 294 |
+
def create_tokenizer(descriptions):
|
| 295 |
+
lines = to_lines(descriptions)
|
| 296 |
+
tokenizer = Tokenizer()
|
| 297 |
+
tokenizer.fit_on_texts(lines)
|
| 298 |
+
return tokenizer
|
| 299 |
+
|
| 300 |
+
#len of description
|
| 301 |
+
def max_length(description):
|
| 302 |
+
lines = to_lines(description)
|
| 303 |
+
return max(len(d.split()) for d in lines)
|
| 304 |
+
|
| 305 |
+
# create input and output sequence
|
| 306 |
+
def create_sequences(tokenizer, max_length, desc_list, photo):
|
| 307 |
+
X1, X2, y = list(), list(), list()
|
| 308 |
+
# walk through each description for the image
|
| 309 |
+
for desc in desc_list:
|
| 310 |
+
# encode the sequence
|
| 311 |
+
seq = tokenizer.texts_to_sequences([desc])[0]
|
| 312 |
+
# split one sequence into multiple X,y pairs
|
| 313 |
+
for i in range(1, len(seq)):
|
| 314 |
+
# split into input and output pair
|
| 315 |
+
in_seq, out_seq = seq[:i], seq[i]
|
| 316 |
+
# pad input sequence
|
| 317 |
+
in_seq = pad_sequences([in_seq], maxlen=max_length)[0]
|
| 318 |
+
# encode output sequence
|
| 319 |
+
out_seq = to_categorical([out_seq], num_classes=vocab_size)[0]
|
| 320 |
+
# store
|
| 321 |
+
X1.append(photo)
|
| 322 |
+
X2.append(in_seq)
|
| 323 |
+
y.append(out_seq)
|
| 324 |
+
return array(X1), array(X2), array(y)
|
| 325 |
+
|
| 326 |
+
"""## Model building"""
|
| 327 |
+
|
| 328 |
+
from tensorflow.keras.layers import add
|
| 329 |
+
def define_model(vocab_size, max_length):
|
| 330 |
+
# feature extractor model
|
| 331 |
+
inputs1 = Input(shape=(1000,))
|
| 332 |
+
fe1 = Dropout(0.5)(inputs1)
|
| 333 |
+
fe2 = Dense(256, activation='relu')(fe1)
|
| 334 |
+
# sequence model
|
| 335 |
+
inputs2 = Input(shape=(max_length,))
|
| 336 |
+
se1 = Embedding(vocab_size,output_dim=256, mask_zero=True)(inputs2)
|
| 337 |
+
se2 = Dropout(0.5)(se1)
|
| 338 |
+
se3 = LSTM(256)(se2)
|
| 339 |
+
# decoder model
|
| 340 |
+
decoder1 = add([fe2, se3])
|
| 341 |
+
decoder2 = Dense(256, activation='relu')(decoder1)
|
| 342 |
+
outputs = Dense(vocab_size, activation='softmax')(decoder2)
|
| 343 |
+
# tie it together [image, seq] [word]
|
| 344 |
+
model = Model(inputs=[inputs1, inputs2], outputs=outputs)
|
| 345 |
+
model.compile(loss='categorical_crossentropy', optimizer='adam')
|
| 346 |
+
# summarize model
|
| 347 |
+
print(model.summary())
|
| 348 |
+
return model
|
| 349 |
+
|
| 350 |
+
# load batch of data
|
| 351 |
+
def data_generator(descriptions, photos, tokenizer, max_length):
|
| 352 |
+
# loop for ever over images
|
| 353 |
+
while 1:
|
| 354 |
+
for key, desc_list in descriptions.items():
|
| 355 |
+
# retrieve the photo feature
|
| 356 |
+
photo = photos[key][0]
|
| 357 |
+
in_img, in_seq, out_word = create_sequences(tokenizer, max_length, desc_list, photo)
|
| 358 |
+
yield [[in_img, in_seq], out_word]
|
| 359 |
+
|
| 360 |
+
#load train dataset
|
| 361 |
+
import tensorflow as tf
|
| 362 |
+
filename = "/content/drive/MyDrive/Image_Captioning_Project/Flickr_8k.trainImages.txt"
|
| 363 |
+
train = load_set(filename)
|
| 364 |
+
print("Dataset: %d" %len(train))
|
| 365 |
+
|
| 366 |
+
train_descriptions = load_clean_descriptions("/content/drive/MyDrive/Image_Captioning_Project/descriptions1.txt", train)
|
| 367 |
+
print("train_descriptions= %d" %len(train_descriptions))
|
| 368 |
+
|
| 369 |
+
train_feature = load_photo_features("/content/drive/MyDrive/Image_Captioning_Project/features.pkl", train)
|
| 370 |
+
print("photos: train= %d" %len(train_feature))
|
| 371 |
+
|
| 372 |
+
tokenizer = create_tokenizer(train_descriptions)
|
| 373 |
+
vocab_size = len(tokenizer.word_index)+1
|
| 374 |
+
print("Vocab size: %d" %vocab_size)
|
| 375 |
+
|
| 376 |
+
max_length = max_length(train_descriptions)
|
| 377 |
+
print('Description Length: %d' % max_length)
|
| 378 |
+
|
| 379 |
+
import pickle
|
| 380 |
+
|
| 381 |
+
# Dump the tokenizer using pickle
|
| 382 |
+
with open('tokenizer1.pkl', 'wb') as f:
|
| 383 |
+
pickle.dump(tokenizer, f)
|
| 384 |
+
|
| 385 |
+
#train model
|
| 386 |
+
# model = define_model(vocab_size, max_length)
|
| 387 |
+
# filename = "/content/drive/MyDrive/Image_Captioning_Project/model_18.h5"
|
| 388 |
+
# model = load_model(filename)
|
| 389 |
+
# epochs = 4
|
| 390 |
+
# steps = len(train_descriptions)
|
| 391 |
+
# model.summary()
|
| 392 |
+
|
| 393 |
+
# for i in range(epochs):
|
| 394 |
+
# #create data generator
|
| 395 |
+
# generator = data_generator(train_descriptions, train_feature, tokenizer, max_len)
|
| 396 |
+
# model.fit(generator, epochs=1, steps_per_epoch = steps, verbose=1)
|
| 397 |
+
# model.save("model_" + str(i) + ".h5")
|
| 398 |
+
|
| 399 |
+
def load_doc(filename):
|
| 400 |
+
# open the file as read only
|
| 401 |
+
file = open(filename, 'r')
|
| 402 |
+
# read all text
|
| 403 |
+
text = file.read()
|
| 404 |
+
# close the file
|
| 405 |
+
file.close()
|
| 406 |
+
return text
|
| 407 |
+
|
| 408 |
+
# load a pre-defined list of photo identifiers
|
| 409 |
+
def load_set(filename):
|
| 410 |
+
doc = load_doc(filename)
|
| 411 |
+
dataset = list()
|
| 412 |
+
# process line by line
|
| 413 |
+
for line in doc.split('\n'):
|
| 414 |
+
# skip empty lines
|
| 415 |
+
if len(line) < 1:
|
| 416 |
+
continue
|
| 417 |
+
# get the image identifier
|
| 418 |
+
identifier = line.split('.')[0]
|
| 419 |
+
dataset.append(identifier)
|
| 420 |
+
return set(dataset)
|
| 421 |
+
|
| 422 |
+
def load_photo_features(filename, dataset):
|
| 423 |
+
# load all features
|
| 424 |
+
all_features = load(open(filename, 'rb'))
|
| 425 |
+
# filter features
|
| 426 |
+
features = {k: all_features[k] for k in dataset}
|
| 427 |
+
return features
|
| 428 |
+
|
| 429 |
+
# covert a dictionary of clean descriptions to a list of descriptions
|
| 430 |
+
def to_lines(descriptions):
|
| 431 |
+
all_desc = list()
|
| 432 |
+
for key in descriptions.keys():
|
| 433 |
+
[all_desc.append(d) for d in descriptions[key]]
|
| 434 |
+
return all_desc
|
| 435 |
+
|
| 436 |
+
# fit a tokenizer given caption descriptions
|
| 437 |
+
def create_tokenizer(descriptions):
|
| 438 |
+
lines = to_lines(descriptions)
|
| 439 |
+
tokenizer = Tokenizer()
|
| 440 |
+
tokenizer.fit_on_texts(lines)
|
| 441 |
+
return tokenizer
|
| 442 |
+
|
| 443 |
+
# calculate the length of the description with the most words
|
| 444 |
+
def max_length(descriptions):
|
| 445 |
+
lines = to_lines(descriptions)
|
| 446 |
+
return max(len(d.split()) for d in lines)
|
| 447 |
+
|
| 448 |
+
# map an integer to a word
|
| 449 |
+
def word_for_id(integer, tokenizer):
|
| 450 |
+
for word, index in tokenizer.word_index.items():
|
| 451 |
+
if index == integer:
|
| 452 |
+
return word
|
| 453 |
+
return None
|
| 454 |
+
|
| 455 |
+
from tensorflow.keras.preprocessing.sequence import pad_sequences
|
| 456 |
+
import numpy as np
|
| 457 |
+
def generate_desc(model, tokenizer, photo, max_length):
|
| 458 |
+
# seed the generation process
|
| 459 |
+
in_text = 'startseq'
|
| 460 |
+
# iterate over the whole length of the sequence
|
| 461 |
+
for i in range(max_length):
|
| 462 |
+
# integer encode input sequence
|
| 463 |
+
sequence = tokenizer.texts_to_sequences([in_text])[0]
|
| 464 |
+
# pad input
|
| 465 |
+
sequence = pad_sequences([sequence], maxlen=max_length)
|
| 466 |
+
# predict next word
|
| 467 |
+
yhat = model.predict([photo,sequence], verbose=0)
|
| 468 |
+
# convert probability to integer
|
| 469 |
+
yhat = np.argmax(yhat)
|
| 470 |
+
# map integer to word
|
| 471 |
+
word = word_for_id(yhat, tokenizer)
|
| 472 |
+
# stop if we cannot map the word
|
| 473 |
+
if word is None:
|
| 474 |
+
break
|
| 475 |
+
# append as input for generating the next word
|
| 476 |
+
in_text += ' ' + word
|
| 477 |
+
# stop if we predict the end of the sequence
|
| 478 |
+
if word == 'endseq':
|
| 479 |
+
break
|
| 480 |
+
return in_text
|
| 481 |
+
|
| 482 |
+
# evaluated the skill of model
|
| 483 |
+
from nltk.translate.bleu_score import corpus_bleu
|
| 484 |
+
def evaluate_model(model, descriptions, photos, tokenizer, max_length):
|
| 485 |
+
actual, predicted = list(), list()
|
| 486 |
+
# step over the whole set
|
| 487 |
+
for key, desc_list in descriptions.items():
|
| 488 |
+
# generate description
|
| 489 |
+
yhat = generate_desc(model, tokenizer, photos[key], max_length)
|
| 490 |
+
# store actual and predicted
|
| 491 |
+
references = [d.split() for d in desc_list]
|
| 492 |
+
actual.append(references)
|
| 493 |
+
predicted.append(yhat.split())
|
| 494 |
+
# calculate BLEU score
|
| 495 |
+
print('BLEU-1: %f' % corpus_bleu(actual, predicted, weights=(1.0, 0, 0, 0)))
|
| 496 |
+
print('BLEU-2: %f' % corpus_bleu(actual, predicted, weights=(0.5, 0.5, 0, 0)))
|
| 497 |
+
print('BLEU-3: %f' % corpus_bleu(actual, predicted, weights=(0.3, 0.3, 0.3, 0)))
|
| 498 |
+
print('BLEU-4: %f' % corpus_bleu(actual, predicted, weights=(0.25, 0.25, 0.25, 0.25)))
|
| 499 |
+
|
| 500 |
+
#load train dataset
|
| 501 |
+
import tensorflow as tf
|
| 502 |
+
filename = "/content/drive/MyDrive/Image_Captioning_Project/Flickr_8k.trainImages.txt"
|
| 503 |
+
train = load_set(filename)
|
| 504 |
+
print("Dataset: %d" %len(train))
|
| 505 |
+
|
| 506 |
+
train_descriptions = load_clean_descriptions("/content/drive/MyDrive/Image_Captioning_Project/descriptions.txt", train)
|
| 507 |
+
print("train_descriptions= %d" %len(train_descriptions))
|
| 508 |
+
|
| 509 |
+
train_feature = load_photo_features("/content/drive/MyDrive/Image_Captioning_Project/features.pkl", train)
|
| 510 |
+
print("photos: train= %d" %len(train_feature))
|
| 511 |
+
|
| 512 |
+
tokenizer = create_tokenizer(train_descriptions)
|
| 513 |
+
vocab_size = len(tokenizer.word_index)+1
|
| 514 |
+
print("Vocab size: %d" %vocab_size)
|
| 515 |
+
|
| 516 |
+
max_length = max_length(train_descriptions)
|
| 517 |
+
print('Description Length: %d' % max_length)
|
| 518 |
+
|
| 519 |
+
filename = "/content/drive/MyDrive/Image_Captioning_Project/Flickr_8k.testImages.txt"
|
| 520 |
+
test = load_set(filename)
|
| 521 |
+
print("Dataset: %d" %len(test))
|
| 522 |
+
test_description = load_clean_descriptions("/content/drive/MyDrive/Image_Captioning_Project/descriptions.txt", test)
|
| 523 |
+
print("Description= %d" %len(test_description))
|
| 524 |
+
test_features = load_photo_features("/content/drive/MyDrive/Image_Captioning_Project/features.pkl", test)
|
| 525 |
+
print("photos: test=%d" % len(test_features))
|
| 526 |
+
|
| 527 |
+
from keras.models import load_model
|
| 528 |
+
filename = "/content/drive/MyDrive/Image_Captioning_Project/model_18.h5"
|
| 529 |
+
model = load_model(filename)
|
| 530 |
+
|
| 531 |
+
# evaluate_model(model, test_description, test_features, tokenizer, max_length)
|
| 532 |
+
|
| 533 |
+
from pickle import load
|
| 534 |
+
from numpy import argmax
|
| 535 |
+
from tensorflow.keras.preprocessing.sequence import pad_sequences
|
| 536 |
+
from keras.applications.vgg16 import VGG16
|
| 537 |
+
from tensorflow.keras.preprocessing.image import load_img
|
| 538 |
+
from tensorflow.keras.preprocessing.image import img_to_array
|
| 539 |
+
from keras.applications.vgg16 import preprocess_input
|
| 540 |
+
from keras.models import Model
|
| 541 |
+
from keras.models import load_model
|
| 542 |
+
# from keras.preprocessing.text import Tokenizer
|
| 543 |
+
|
| 544 |
+
def extract_features(filename):
|
| 545 |
+
# load the model
|
| 546 |
+
model = VGG16()
|
| 547 |
+
# re-structure the model
|
| 548 |
+
model.layers.pop()
|
| 549 |
+
model = Model(inputs=model.inputs, outputs=model.layers[-2].output)
|
| 550 |
+
# load the photo
|
| 551 |
+
image = load_img(filename, target_size=(224, 224))
|
| 552 |
+
# convert the image pixels to a numpy array
|
| 553 |
+
image = img_to_array(image)
|
| 554 |
+
# reshape data for the model
|
| 555 |
+
image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
|
| 556 |
+
# prepare the image for the VGG model
|
| 557 |
+
image = preprocess_input(image)
|
| 558 |
+
# get features
|
| 559 |
+
feature = model.predict(image, verbose=0)
|
| 560 |
+
return feature
|
| 561 |
+
|
| 562 |
+
from pickle import load
|
| 563 |
+
from tensorflow.keras.preprocessing.text import Tokenizer
|
| 564 |
+
|
| 565 |
+
tokenizer = load(open('/content/tokenizer1.pkl', 'rb'))
|
| 566 |
+
max_len = 34
|
| 567 |
+
model = load_model('/content/drive/MyDrive/Image_Captioning_Project/model_18.h5')
|
| 568 |
+
photo = extract_features("/content/drive/MyDrive/Image_Captioning_Project/Images/101654506_8eb26cfb60.jpg")
|
| 569 |
+
tokenizer.analyzer = None
|
| 570 |
+
description = generate_desc(model, tokenizer, photo, max_len)
|
| 571 |
+
print(description)
|
| 572 |
+
|
| 573 |
+
query = description
|
| 574 |
+
stopwords = ['startseq','endseq']
|
| 575 |
+
querywords = query.split()
|
| 576 |
+
|
| 577 |
+
resultwords = [word for word in querywords if word.lower() not in stopwords]
|
| 578 |
+
result = ' '.join(resultwords)
|
| 579 |
+
|
| 580 |
+
print(result)
|
| 581 |
+
|