clarifai 11.3.0rc2__py3-none-any.whl → 11.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (300) hide show
  1. clarifai/__init__.py +1 -1
  2. clarifai/cli/__main__.py +1 -1
  3. clarifai/cli/base.py +144 -136
  4. clarifai/cli/compute_cluster.py +45 -31
  5. clarifai/cli/deployment.py +93 -76
  6. clarifai/cli/model.py +578 -180
  7. clarifai/cli/nodepool.py +100 -82
  8. clarifai/client/__init__.py +12 -2
  9. clarifai/client/app.py +973 -911
  10. clarifai/client/auth/helper.py +345 -342
  11. clarifai/client/auth/register.py +7 -7
  12. clarifai/client/auth/stub.py +107 -106
  13. clarifai/client/base.py +185 -178
  14. clarifai/client/compute_cluster.py +214 -180
  15. clarifai/client/dataset.py +793 -698
  16. clarifai/client/deployment.py +55 -50
  17. clarifai/client/input.py +1223 -1088
  18. clarifai/client/lister.py +47 -45
  19. clarifai/client/model.py +1939 -1717
  20. clarifai/client/model_client.py +525 -502
  21. clarifai/client/module.py +82 -73
  22. clarifai/client/nodepool.py +358 -213
  23. clarifai/client/runner.py +58 -0
  24. clarifai/client/search.py +342 -309
  25. clarifai/client/user.py +419 -414
  26. clarifai/client/workflow.py +294 -274
  27. clarifai/constants/dataset.py +11 -17
  28. clarifai/constants/model.py +8 -2
  29. clarifai/datasets/export/inputs_annotations.py +233 -217
  30. clarifai/datasets/upload/base.py +63 -51
  31. clarifai/datasets/upload/features.py +43 -38
  32. clarifai/datasets/upload/image.py +237 -207
  33. clarifai/datasets/upload/loaders/coco_captions.py +34 -32
  34. clarifai/datasets/upload/loaders/coco_detection.py +72 -65
  35. clarifai/datasets/upload/loaders/imagenet_classification.py +57 -53
  36. clarifai/datasets/upload/loaders/xview_detection.py +274 -132
  37. clarifai/datasets/upload/multimodal.py +55 -46
  38. clarifai/datasets/upload/text.py +55 -47
  39. clarifai/datasets/upload/utils.py +250 -234
  40. clarifai/errors.py +51 -50
  41. clarifai/models/api.py +260 -238
  42. clarifai/modules/css.py +50 -50
  43. clarifai/modules/pages.py +33 -33
  44. clarifai/rag/rag.py +312 -288
  45. clarifai/rag/utils.py +91 -84
  46. clarifai/runners/models/model_builder.py +906 -802
  47. clarifai/runners/models/model_class.py +370 -331
  48. clarifai/runners/models/model_run_locally.py +459 -419
  49. clarifai/runners/models/model_runner.py +170 -162
  50. clarifai/runners/models/model_servicer.py +78 -70
  51. clarifai/runners/server.py +111 -101
  52. clarifai/runners/utils/code_script.py +225 -187
  53. clarifai/runners/utils/const.py +4 -1
  54. clarifai/runners/utils/data_types/__init__.py +12 -0
  55. clarifai/runners/utils/data_types/data_types.py +598 -0
  56. clarifai/runners/utils/data_utils.py +387 -440
  57. clarifai/runners/utils/loader.py +247 -227
  58. clarifai/runners/utils/method_signatures.py +411 -386
  59. clarifai/runners/utils/openai_convertor.py +108 -109
  60. clarifai/runners/utils/serializers.py +175 -179
  61. clarifai/runners/utils/url_fetcher.py +35 -35
  62. clarifai/schema/search.py +56 -63
  63. clarifai/urls/helper.py +125 -102
  64. clarifai/utils/cli.py +129 -123
  65. clarifai/utils/config.py +127 -87
  66. clarifai/utils/constants.py +49 -0
  67. clarifai/utils/evaluation/helpers.py +503 -466
  68. clarifai/utils/evaluation/main.py +431 -393
  69. clarifai/utils/evaluation/testset_annotation_parser.py +154 -144
  70. clarifai/utils/logging.py +324 -306
  71. clarifai/utils/misc.py +60 -56
  72. clarifai/utils/model_train.py +165 -146
  73. clarifai/utils/protobuf.py +126 -103
  74. clarifai/versions.py +3 -1
  75. clarifai/workflows/export.py +48 -50
  76. clarifai/workflows/utils.py +39 -36
  77. clarifai/workflows/validate.py +55 -43
  78. {clarifai-11.3.0rc2.dist-info → clarifai-11.4.0.dist-info}/METADATA +16 -6
  79. clarifai-11.4.0.dist-info/RECORD +109 -0
  80. {clarifai-11.3.0rc2.dist-info → clarifai-11.4.0.dist-info}/WHEEL +1 -1
  81. clarifai/__pycache__/__init__.cpython-310.pyc +0 -0
  82. clarifai/__pycache__/__init__.cpython-311.pyc +0 -0
  83. clarifai/__pycache__/__init__.cpython-39.pyc +0 -0
  84. clarifai/__pycache__/errors.cpython-310.pyc +0 -0
  85. clarifai/__pycache__/errors.cpython-311.pyc +0 -0
  86. clarifai/__pycache__/versions.cpython-310.pyc +0 -0
  87. clarifai/__pycache__/versions.cpython-311.pyc +0 -0
  88. clarifai/cli/__pycache__/__init__.cpython-310.pyc +0 -0
  89. clarifai/cli/__pycache__/__init__.cpython-311.pyc +0 -0
  90. clarifai/cli/__pycache__/base.cpython-310.pyc +0 -0
  91. clarifai/cli/__pycache__/base.cpython-311.pyc +0 -0
  92. clarifai/cli/__pycache__/base_cli.cpython-310.pyc +0 -0
  93. clarifai/cli/__pycache__/compute_cluster.cpython-310.pyc +0 -0
  94. clarifai/cli/__pycache__/compute_cluster.cpython-311.pyc +0 -0
  95. clarifai/cli/__pycache__/deployment.cpython-310.pyc +0 -0
  96. clarifai/cli/__pycache__/deployment.cpython-311.pyc +0 -0
  97. clarifai/cli/__pycache__/model.cpython-310.pyc +0 -0
  98. clarifai/cli/__pycache__/model.cpython-311.pyc +0 -0
  99. clarifai/cli/__pycache__/model_cli.cpython-310.pyc +0 -0
  100. clarifai/cli/__pycache__/nodepool.cpython-310.pyc +0 -0
  101. clarifai/cli/__pycache__/nodepool.cpython-311.pyc +0 -0
  102. clarifai/client/__pycache__/__init__.cpython-310.pyc +0 -0
  103. clarifai/client/__pycache__/__init__.cpython-311.pyc +0 -0
  104. clarifai/client/__pycache__/__init__.cpython-39.pyc +0 -0
  105. clarifai/client/__pycache__/app.cpython-310.pyc +0 -0
  106. clarifai/client/__pycache__/app.cpython-311.pyc +0 -0
  107. clarifai/client/__pycache__/app.cpython-39.pyc +0 -0
  108. clarifai/client/__pycache__/base.cpython-310.pyc +0 -0
  109. clarifai/client/__pycache__/base.cpython-311.pyc +0 -0
  110. clarifai/client/__pycache__/compute_cluster.cpython-310.pyc +0 -0
  111. clarifai/client/__pycache__/compute_cluster.cpython-311.pyc +0 -0
  112. clarifai/client/__pycache__/dataset.cpython-310.pyc +0 -0
  113. clarifai/client/__pycache__/dataset.cpython-311.pyc +0 -0
  114. clarifai/client/__pycache__/deployment.cpython-310.pyc +0 -0
  115. clarifai/client/__pycache__/deployment.cpython-311.pyc +0 -0
  116. clarifai/client/__pycache__/input.cpython-310.pyc +0 -0
  117. clarifai/client/__pycache__/input.cpython-311.pyc +0 -0
  118. clarifai/client/__pycache__/lister.cpython-310.pyc +0 -0
  119. clarifai/client/__pycache__/lister.cpython-311.pyc +0 -0
  120. clarifai/client/__pycache__/model.cpython-310.pyc +0 -0
  121. clarifai/client/__pycache__/model.cpython-311.pyc +0 -0
  122. clarifai/client/__pycache__/module.cpython-310.pyc +0 -0
  123. clarifai/client/__pycache__/module.cpython-311.pyc +0 -0
  124. clarifai/client/__pycache__/nodepool.cpython-310.pyc +0 -0
  125. clarifai/client/__pycache__/nodepool.cpython-311.pyc +0 -0
  126. clarifai/client/__pycache__/search.cpython-310.pyc +0 -0
  127. clarifai/client/__pycache__/search.cpython-311.pyc +0 -0
  128. clarifai/client/__pycache__/user.cpython-310.pyc +0 -0
  129. clarifai/client/__pycache__/user.cpython-311.pyc +0 -0
  130. clarifai/client/__pycache__/workflow.cpython-310.pyc +0 -0
  131. clarifai/client/__pycache__/workflow.cpython-311.pyc +0 -0
  132. clarifai/client/auth/__pycache__/__init__.cpython-310.pyc +0 -0
  133. clarifai/client/auth/__pycache__/__init__.cpython-311.pyc +0 -0
  134. clarifai/client/auth/__pycache__/helper.cpython-310.pyc +0 -0
  135. clarifai/client/auth/__pycache__/helper.cpython-311.pyc +0 -0
  136. clarifai/client/auth/__pycache__/register.cpython-310.pyc +0 -0
  137. clarifai/client/auth/__pycache__/register.cpython-311.pyc +0 -0
  138. clarifai/client/auth/__pycache__/stub.cpython-310.pyc +0 -0
  139. clarifai/client/auth/__pycache__/stub.cpython-311.pyc +0 -0
  140. clarifai/client/cli/__init__.py +0 -0
  141. clarifai/client/cli/__pycache__/__init__.cpython-310.pyc +0 -0
  142. clarifai/client/cli/__pycache__/base_cli.cpython-310.pyc +0 -0
  143. clarifai/client/cli/__pycache__/model_cli.cpython-310.pyc +0 -0
  144. clarifai/client/cli/base_cli.py +0 -88
  145. clarifai/client/cli/model_cli.py +0 -29
  146. clarifai/constants/__pycache__/base.cpython-310.pyc +0 -0
  147. clarifai/constants/__pycache__/base.cpython-311.pyc +0 -0
  148. clarifai/constants/__pycache__/dataset.cpython-310.pyc +0 -0
  149. clarifai/constants/__pycache__/dataset.cpython-311.pyc +0 -0
  150. clarifai/constants/__pycache__/input.cpython-310.pyc +0 -0
  151. clarifai/constants/__pycache__/input.cpython-311.pyc +0 -0
  152. clarifai/constants/__pycache__/model.cpython-310.pyc +0 -0
  153. clarifai/constants/__pycache__/model.cpython-311.pyc +0 -0
  154. clarifai/constants/__pycache__/rag.cpython-310.pyc +0 -0
  155. clarifai/constants/__pycache__/rag.cpython-311.pyc +0 -0
  156. clarifai/constants/__pycache__/search.cpython-310.pyc +0 -0
  157. clarifai/constants/__pycache__/search.cpython-311.pyc +0 -0
  158. clarifai/constants/__pycache__/workflow.cpython-310.pyc +0 -0
  159. clarifai/constants/__pycache__/workflow.cpython-311.pyc +0 -0
  160. clarifai/datasets/__pycache__/__init__.cpython-310.pyc +0 -0
  161. clarifai/datasets/__pycache__/__init__.cpython-311.pyc +0 -0
  162. clarifai/datasets/__pycache__/__init__.cpython-39.pyc +0 -0
  163. clarifai/datasets/export/__pycache__/__init__.cpython-310.pyc +0 -0
  164. clarifai/datasets/export/__pycache__/__init__.cpython-311.pyc +0 -0
  165. clarifai/datasets/export/__pycache__/__init__.cpython-39.pyc +0 -0
  166. clarifai/datasets/export/__pycache__/inputs_annotations.cpython-310.pyc +0 -0
  167. clarifai/datasets/export/__pycache__/inputs_annotations.cpython-311.pyc +0 -0
  168. clarifai/datasets/upload/__pycache__/__init__.cpython-310.pyc +0 -0
  169. clarifai/datasets/upload/__pycache__/__init__.cpython-311.pyc +0 -0
  170. clarifai/datasets/upload/__pycache__/__init__.cpython-39.pyc +0 -0
  171. clarifai/datasets/upload/__pycache__/base.cpython-310.pyc +0 -0
  172. clarifai/datasets/upload/__pycache__/base.cpython-311.pyc +0 -0
  173. clarifai/datasets/upload/__pycache__/features.cpython-310.pyc +0 -0
  174. clarifai/datasets/upload/__pycache__/features.cpython-311.pyc +0 -0
  175. clarifai/datasets/upload/__pycache__/image.cpython-310.pyc +0 -0
  176. clarifai/datasets/upload/__pycache__/image.cpython-311.pyc +0 -0
  177. clarifai/datasets/upload/__pycache__/multimodal.cpython-310.pyc +0 -0
  178. clarifai/datasets/upload/__pycache__/multimodal.cpython-311.pyc +0 -0
  179. clarifai/datasets/upload/__pycache__/text.cpython-310.pyc +0 -0
  180. clarifai/datasets/upload/__pycache__/text.cpython-311.pyc +0 -0
  181. clarifai/datasets/upload/__pycache__/utils.cpython-310.pyc +0 -0
  182. clarifai/datasets/upload/__pycache__/utils.cpython-311.pyc +0 -0
  183. clarifai/datasets/upload/loaders/__pycache__/__init__.cpython-311.pyc +0 -0
  184. clarifai/datasets/upload/loaders/__pycache__/__init__.cpython-39.pyc +0 -0
  185. clarifai/datasets/upload/loaders/__pycache__/coco_detection.cpython-311.pyc +0 -0
  186. clarifai/datasets/upload/loaders/__pycache__/imagenet_classification.cpython-311.pyc +0 -0
  187. clarifai/models/__pycache__/__init__.cpython-39.pyc +0 -0
  188. clarifai/modules/__pycache__/__init__.cpython-39.pyc +0 -0
  189. clarifai/rag/__pycache__/__init__.cpython-310.pyc +0 -0
  190. clarifai/rag/__pycache__/__init__.cpython-311.pyc +0 -0
  191. clarifai/rag/__pycache__/__init__.cpython-39.pyc +0 -0
  192. clarifai/rag/__pycache__/rag.cpython-310.pyc +0 -0
  193. clarifai/rag/__pycache__/rag.cpython-311.pyc +0 -0
  194. clarifai/rag/__pycache__/rag.cpython-39.pyc +0 -0
  195. clarifai/rag/__pycache__/utils.cpython-310.pyc +0 -0
  196. clarifai/rag/__pycache__/utils.cpython-311.pyc +0 -0
  197. clarifai/runners/__pycache__/__init__.cpython-310.pyc +0 -0
  198. clarifai/runners/__pycache__/__init__.cpython-311.pyc +0 -0
  199. clarifai/runners/__pycache__/__init__.cpython-39.pyc +0 -0
  200. clarifai/runners/dockerfile_template/Dockerfile.cpu.template +0 -31
  201. clarifai/runners/dockerfile_template/Dockerfile.cuda.template +0 -42
  202. clarifai/runners/dockerfile_template/Dockerfile.nim +0 -71
  203. clarifai/runners/models/__pycache__/__init__.cpython-310.pyc +0 -0
  204. clarifai/runners/models/__pycache__/__init__.cpython-311.pyc +0 -0
  205. clarifai/runners/models/__pycache__/__init__.cpython-39.pyc +0 -0
  206. clarifai/runners/models/__pycache__/base_typed_model.cpython-310.pyc +0 -0
  207. clarifai/runners/models/__pycache__/base_typed_model.cpython-311.pyc +0 -0
  208. clarifai/runners/models/__pycache__/base_typed_model.cpython-39.pyc +0 -0
  209. clarifai/runners/models/__pycache__/model_builder.cpython-311.pyc +0 -0
  210. clarifai/runners/models/__pycache__/model_class.cpython-310.pyc +0 -0
  211. clarifai/runners/models/__pycache__/model_class.cpython-311.pyc +0 -0
  212. clarifai/runners/models/__pycache__/model_run_locally.cpython-310-pytest-7.1.2.pyc +0 -0
  213. clarifai/runners/models/__pycache__/model_run_locally.cpython-310.pyc +0 -0
  214. clarifai/runners/models/__pycache__/model_run_locally.cpython-311.pyc +0 -0
  215. clarifai/runners/models/__pycache__/model_runner.cpython-310.pyc +0 -0
  216. clarifai/runners/models/__pycache__/model_runner.cpython-311.pyc +0 -0
  217. clarifai/runners/models/__pycache__/model_upload.cpython-310.pyc +0 -0
  218. clarifai/runners/models/base_typed_model.py +0 -238
  219. clarifai/runners/models/model_class_refract.py +0 -80
  220. clarifai/runners/models/model_upload.py +0 -607
  221. clarifai/runners/models/temp.py +0 -25
  222. clarifai/runners/utils/__pycache__/__init__.cpython-310.pyc +0 -0
  223. clarifai/runners/utils/__pycache__/__init__.cpython-311.pyc +0 -0
  224. clarifai/runners/utils/__pycache__/__init__.cpython-38.pyc +0 -0
  225. clarifai/runners/utils/__pycache__/__init__.cpython-39.pyc +0 -0
  226. clarifai/runners/utils/__pycache__/buffered_stream.cpython-310.pyc +0 -0
  227. clarifai/runners/utils/__pycache__/buffered_stream.cpython-38.pyc +0 -0
  228. clarifai/runners/utils/__pycache__/buffered_stream.cpython-39.pyc +0 -0
  229. clarifai/runners/utils/__pycache__/const.cpython-310.pyc +0 -0
  230. clarifai/runners/utils/__pycache__/const.cpython-311.pyc +0 -0
  231. clarifai/runners/utils/__pycache__/constants.cpython-310.pyc +0 -0
  232. clarifai/runners/utils/__pycache__/constants.cpython-38.pyc +0 -0
  233. clarifai/runners/utils/__pycache__/constants.cpython-39.pyc +0 -0
  234. clarifai/runners/utils/__pycache__/data_handler.cpython-310.pyc +0 -0
  235. clarifai/runners/utils/__pycache__/data_handler.cpython-311.pyc +0 -0
  236. clarifai/runners/utils/__pycache__/data_handler.cpython-38.pyc +0 -0
  237. clarifai/runners/utils/__pycache__/data_handler.cpython-39.pyc +0 -0
  238. clarifai/runners/utils/__pycache__/data_utils.cpython-310.pyc +0 -0
  239. clarifai/runners/utils/__pycache__/data_utils.cpython-311.pyc +0 -0
  240. clarifai/runners/utils/__pycache__/data_utils.cpython-38.pyc +0 -0
  241. clarifai/runners/utils/__pycache__/data_utils.cpython-39.pyc +0 -0
  242. clarifai/runners/utils/__pycache__/grpc_server.cpython-310.pyc +0 -0
  243. clarifai/runners/utils/__pycache__/grpc_server.cpython-38.pyc +0 -0
  244. clarifai/runners/utils/__pycache__/grpc_server.cpython-39.pyc +0 -0
  245. clarifai/runners/utils/__pycache__/health.cpython-310.pyc +0 -0
  246. clarifai/runners/utils/__pycache__/health.cpython-38.pyc +0 -0
  247. clarifai/runners/utils/__pycache__/health.cpython-39.pyc +0 -0
  248. clarifai/runners/utils/__pycache__/loader.cpython-310.pyc +0 -0
  249. clarifai/runners/utils/__pycache__/loader.cpython-311.pyc +0 -0
  250. clarifai/runners/utils/__pycache__/logging.cpython-310.pyc +0 -0
  251. clarifai/runners/utils/__pycache__/logging.cpython-38.pyc +0 -0
  252. clarifai/runners/utils/__pycache__/logging.cpython-39.pyc +0 -0
  253. clarifai/runners/utils/__pycache__/stream_source.cpython-310.pyc +0 -0
  254. clarifai/runners/utils/__pycache__/stream_source.cpython-39.pyc +0 -0
  255. clarifai/runners/utils/__pycache__/url_fetcher.cpython-310.pyc +0 -0
  256. clarifai/runners/utils/__pycache__/url_fetcher.cpython-311.pyc +0 -0
  257. clarifai/runners/utils/__pycache__/url_fetcher.cpython-38.pyc +0 -0
  258. clarifai/runners/utils/__pycache__/url_fetcher.cpython-39.pyc +0 -0
  259. clarifai/runners/utils/data_handler.py +0 -231
  260. clarifai/runners/utils/data_handler_refract.py +0 -213
  261. clarifai/runners/utils/data_types.py +0 -469
  262. clarifai/runners/utils/logger.py +0 -0
  263. clarifai/runners/utils/openai_format.py +0 -87
  264. clarifai/schema/__pycache__/search.cpython-310.pyc +0 -0
  265. clarifai/schema/__pycache__/search.cpython-311.pyc +0 -0
  266. clarifai/urls/__pycache__/helper.cpython-310.pyc +0 -0
  267. clarifai/urls/__pycache__/helper.cpython-311.pyc +0 -0
  268. clarifai/utils/__pycache__/__init__.cpython-310.pyc +0 -0
  269. clarifai/utils/__pycache__/__init__.cpython-311.pyc +0 -0
  270. clarifai/utils/__pycache__/__init__.cpython-39.pyc +0 -0
  271. clarifai/utils/__pycache__/cli.cpython-310.pyc +0 -0
  272. clarifai/utils/__pycache__/cli.cpython-311.pyc +0 -0
  273. clarifai/utils/__pycache__/config.cpython-311.pyc +0 -0
  274. clarifai/utils/__pycache__/constants.cpython-310.pyc +0 -0
  275. clarifai/utils/__pycache__/constants.cpython-311.pyc +0 -0
  276. clarifai/utils/__pycache__/logging.cpython-310.pyc +0 -0
  277. clarifai/utils/__pycache__/logging.cpython-311.pyc +0 -0
  278. clarifai/utils/__pycache__/misc.cpython-310.pyc +0 -0
  279. clarifai/utils/__pycache__/misc.cpython-311.pyc +0 -0
  280. clarifai/utils/__pycache__/model_train.cpython-310.pyc +0 -0
  281. clarifai/utils/__pycache__/model_train.cpython-311.pyc +0 -0
  282. clarifai/utils/__pycache__/protobuf.cpython-311.pyc +0 -0
  283. clarifai/utils/evaluation/__pycache__/__init__.cpython-311.pyc +0 -0
  284. clarifai/utils/evaluation/__pycache__/__init__.cpython-39.pyc +0 -0
  285. clarifai/utils/evaluation/__pycache__/helpers.cpython-311.pyc +0 -0
  286. clarifai/utils/evaluation/__pycache__/main.cpython-311.pyc +0 -0
  287. clarifai/utils/evaluation/__pycache__/main.cpython-39.pyc +0 -0
  288. clarifai/workflows/__pycache__/__init__.cpython-310.pyc +0 -0
  289. clarifai/workflows/__pycache__/__init__.cpython-311.pyc +0 -0
  290. clarifai/workflows/__pycache__/__init__.cpython-39.pyc +0 -0
  291. clarifai/workflows/__pycache__/export.cpython-310.pyc +0 -0
  292. clarifai/workflows/__pycache__/export.cpython-311.pyc +0 -0
  293. clarifai/workflows/__pycache__/utils.cpython-310.pyc +0 -0
  294. clarifai/workflows/__pycache__/utils.cpython-311.pyc +0 -0
  295. clarifai/workflows/__pycache__/validate.cpython-310.pyc +0 -0
  296. clarifai/workflows/__pycache__/validate.cpython-311.pyc +0 -0
  297. clarifai-11.3.0rc2.dist-info/RECORD +0 -322
  298. {clarifai-11.3.0rc2.dist-info → clarifai-11.4.0.dist-info}/entry_points.txt +0 -0
  299. {clarifai-11.3.0rc2.dist-info → clarifai-11.4.0.dist-info/licenses}/LICENSE +0 -0
  300. {clarifai-11.3.0rc2.dist-info → clarifai-11.4.0.dist-info}/top_level.txt +0 -0
@@ -5,57 +5,62 @@ from typing import List, Optional, Union
5
5
 
6
6
  @dataclass
7
7
  class TextFeatures:
8
- """Text classification datasets preprocessing output features."""
9
- text: str
10
- labels: List[Union[str, int]] = None # List[str or int] to cater for multi-class tasks
11
- id: Optional[int] = None # text_id
12
- metadata: Optional[dict] = None
13
- label_ids: Optional[List[str]] = None
8
+ """Text classification datasets preprocessing output features."""
9
+
10
+ text: str
11
+ labels: List[Union[str, int]] = None # List[str or int] to cater for multi-class tasks
12
+ id: Optional[int] = None # text_id
13
+ metadata: Optional[dict] = None
14
+ label_ids: Optional[List[str]] = None
14
15
 
15
16
 
16
17
  @dataclass
17
18
  class VisualClassificationFeatures:
18
- """Image classification datasets preprocessing output features."""
19
- image_path: str
20
- labels: List[Union[str, int]] # List[str or int] to cater for multi-class tasks
21
- geo_info: Optional[List[float]] = None #[Longitude, Latitude]
22
- id: Optional[int] = None # image_id
23
- metadata: Optional[dict] = None
24
- image_bytes: Optional[bytes] = None
25
- label_ids: Optional[List[str]] = None
19
+ """Image classification datasets preprocessing output features."""
20
+
21
+ image_path: str
22
+ labels: List[Union[str, int]] # List[str or int] to cater for multi-class tasks
23
+ geo_info: Optional[List[float]] = None # [Longitude, Latitude]
24
+ id: Optional[int] = None # image_id
25
+ metadata: Optional[dict] = None
26
+ image_bytes: Optional[bytes] = None
27
+ label_ids: Optional[List[str]] = None
26
28
 
27
29
 
28
30
  @dataclass
29
31
  class VisualDetectionFeatures:
30
- """Image Detection datasets preprocessing output features."""
31
- image_path: str
32
- labels: List[Union[str, int]]
33
- bboxes: List[List[float]]
34
- geo_info: Optional[List[float]] = None #[Longitude, Latitude]
35
- id: Optional[int] = None # image_id
36
- metadata: Optional[dict] = None
37
- image_bytes: Optional[bytes] = None
38
- label_ids: Optional[List[str]] = None
32
+ """Image Detection datasets preprocessing output features."""
33
+
34
+ image_path: str
35
+ labels: List[Union[str, int]]
36
+ bboxes: List[List[float]]
37
+ geo_info: Optional[List[float]] = None # [Longitude, Latitude]
38
+ id: Optional[int] = None # image_id
39
+ metadata: Optional[dict] = None
40
+ image_bytes: Optional[bytes] = None
41
+ label_ids: Optional[List[str]] = None
39
42
 
40
43
 
41
44
  @dataclass
42
45
  class VisualSegmentationFeatures:
43
- """Image Segmentation datasets preprocessing output features."""
44
- image_path: str
45
- labels: List[Union[str, int]]
46
- polygons: List[List[List[float]]]
47
- geo_info: Optional[List[float]] = None #[Longitude, Latitude]
48
- id: Optional[int] = None # image_id
49
- metadata: Optional[dict] = None
50
- image_bytes: Optional[bytes] = None
51
- label_ids: Optional[List[str]] = None
46
+ """Image Segmentation datasets preprocessing output features."""
47
+
48
+ image_path: str
49
+ labels: List[Union[str, int]]
50
+ polygons: List[List[List[float]]]
51
+ geo_info: Optional[List[float]] = None # [Longitude, Latitude]
52
+ id: Optional[int] = None # image_id
53
+ metadata: Optional[dict] = None
54
+ image_bytes: Optional[bytes] = None
55
+ label_ids: Optional[List[str]] = None
52
56
 
53
57
 
54
58
  @dataclass
55
59
  class MultiModalFeatures:
56
- """Multi-modal datasets preprocessing output features."""
57
- text: str
58
- image_bytes: str
59
- labels: List[Union[str, int]] = None # List[str or int] to cater for multi-class tasks
60
- id: Optional[int] = None # image_id
61
- metadata: Optional[dict] = None
60
+ """Multi-modal datasets preprocessing output features."""
61
+
62
+ text: str
63
+ image_bytes: str
64
+ labels: List[Union[str, int]] = None # List[str or int] to cater for multi-class tasks
65
+ id: Optional[int] = None # image_id
66
+ metadata: Optional[dict] = None
@@ -11,217 +11,247 @@ from clarifai.utils.misc import get_uuid
11
11
 
12
12
 
13
13
  class VisualClassificationDataset(ClarifaiDataset):
14
+ def __init__(
15
+ self, data_generator: Type[ClarifaiDataLoader], dataset_id: str, max_workers: int = 4
16
+ ) -> None:
17
+ super().__init__(data_generator, dataset_id, max_workers)
14
18
 
15
- def __init__(self,
16
- data_generator: Type[ClarifaiDataLoader],
17
- dataset_id: str,
18
- max_workers: int = 4) -> None:
19
- super().__init__(data_generator, dataset_id, max_workers)
20
-
21
- def _extract_protos(self, batch_input_ids: List[str]
22
- ) -> Tuple[List[resources_pb2.Input], List[resources_pb2.Annotation]]:
23
- """Create input image and annotation protos for batch of input ids.
24
- Args:
25
- batch_input_ids: List of input IDs to retrieve the protos for.
26
- Returns:
27
- input_protos: List of input protos.
28
- annotation_protos: List of annotation protos.
29
- """
30
- input_protos, annotation_protos = [], []
31
-
32
- def process_data_item(id):
33
- data_item = self.data_generator[id]
34
- metadata = Struct()
35
- image_path = data_item.image_path
36
- labels = data_item.labels if isinstance(data_item.labels,
37
- list) else [data_item.labels] # clarifai concept
38
- label_ids = data_item.label_ids
39
- input_id = f"{self.dataset_id}-{get_uuid(8)}" if data_item.id is None else f"{self.dataset_id}-{str(data_item.id)}"
40
- geo_info = data_item.geo_info
41
- if data_item.metadata is not None:
42
- metadata.update(data_item.metadata)
43
- elif image_path is not None:
44
- metadata.update({"filename": os.path.basename(image_path)})
45
- else:
46
- metadata = None
47
-
48
- self.all_input_ids[id] = input_id
49
- if data_item.image_bytes is not None:
50
- input_protos.append(
51
- Inputs.get_input_from_bytes(
52
- input_id=input_id,
53
- image_bytes=data_item.image_bytes,
54
- dataset_id=self.dataset_id,
55
- labels=labels,
56
- label_ids=label_ids,
57
- geo_info=geo_info,
58
- metadata=metadata))
59
- else:
60
- input_protos.append(
61
- Inputs.get_input_from_file(
62
- input_id=input_id,
63
- image_file=image_path,
64
- dataset_id=self.dataset_id,
65
- labels=labels,
66
- label_ids=label_ids,
67
- geo_info=geo_info,
68
- metadata=metadata))
69
-
70
- with ThreadPoolExecutor(max_workers=self.max_workers) as executor:
71
- futures = [executor.submit(process_data_item, id) for id in batch_input_ids]
72
- for job in futures:
73
- job.result()
74
-
75
- return input_protos, annotation_protos
19
+ def _extract_protos(
20
+ self, batch_input_ids: List[str]
21
+ ) -> Tuple[List[resources_pb2.Input], List[resources_pb2.Annotation]]:
22
+ """Create input image and annotation protos for batch of input ids.
23
+ Args:
24
+ batch_input_ids: List of input IDs to retrieve the protos for.
25
+ Returns:
26
+ input_protos: List of input protos.
27
+ annotation_protos: List of annotation protos.
28
+ """
29
+ input_protos, annotation_protos = [], []
30
+
31
+ def process_data_item(id):
32
+ data_item = self.data_generator[id]
33
+ metadata = Struct()
34
+ image_path = data_item.image_path
35
+ labels = (
36
+ data_item.labels if isinstance(data_item.labels, list) else [data_item.labels]
37
+ ) # clarifai concept
38
+ label_ids = data_item.label_ids
39
+ input_id = (
40
+ f"{self.dataset_id}-{get_uuid(8)}"
41
+ if data_item.id is None
42
+ else f"{self.dataset_id}-{str(data_item.id)}"
43
+ )
44
+ geo_info = data_item.geo_info
45
+ if data_item.metadata is not None:
46
+ metadata.update(data_item.metadata)
47
+ elif image_path is not None:
48
+ metadata.update({"filename": os.path.basename(image_path)})
49
+ else:
50
+ metadata = None
51
+
52
+ self.all_input_ids[id] = input_id
53
+ if data_item.image_bytes is not None:
54
+ input_protos.append(
55
+ Inputs.get_input_from_bytes(
56
+ input_id=input_id,
57
+ image_bytes=data_item.image_bytes,
58
+ dataset_id=self.dataset_id,
59
+ labels=labels,
60
+ label_ids=label_ids,
61
+ geo_info=geo_info,
62
+ metadata=metadata,
63
+ )
64
+ )
65
+ else:
66
+ input_protos.append(
67
+ Inputs.get_input_from_file(
68
+ input_id=input_id,
69
+ image_file=image_path,
70
+ dataset_id=self.dataset_id,
71
+ labels=labels,
72
+ label_ids=label_ids,
73
+ geo_info=geo_info,
74
+ metadata=metadata,
75
+ )
76
+ )
77
+
78
+ with ThreadPoolExecutor(max_workers=self.max_workers) as executor:
79
+ futures = [executor.submit(process_data_item, id) for id in batch_input_ids]
80
+ for job in futures:
81
+ job.result()
82
+
83
+ return input_protos, annotation_protos
76
84
 
77
85
 
78
86
  class VisualDetectionDataset(ClarifaiDataset):
79
- """Visual detection dataset proto class."""
80
-
81
- def __init__(self,
82
- data_generator: Type[ClarifaiDataLoader],
83
- dataset_id: str,
84
- max_workers: int = 4) -> None:
85
- super().__init__(data_generator, dataset_id, max_workers)
86
-
87
- def _extract_protos(self, batch_input_ids: List[int]
88
- ) -> Tuple[List[resources_pb2.Input], List[resources_pb2.Annotation]]:
89
- """Create input image protos for each data generator item.
90
- Args:
91
- batch_input_ids: List of input IDs to retrieve the protos for.
92
- Returns:
93
- input_protos: List of input protos.
94
- annotation_protos: List of annotation protos.
95
- """
96
- input_protos, annotation_protos = [], []
97
-
98
- def process_data_item(id):
99
- data_item = self.data_generator[id]
100
- metadata = Struct()
101
- image = data_item.image_path
102
- labels = data_item.labels # list:[l1,...,ln]
103
- if data_item.label_ids is not None:
104
- assert len(labels) == len(
105
- data_item.label_ids), "Length of labels and label_ids must be equal"
106
- label_ids = data_item.label_ids
107
- else:
108
- label_ids = None
109
- bboxes = data_item.bboxes # [[xmin,ymin,xmax,ymax],...,[xmin,ymin,xmax,ymax]]
110
- input_id = f"{self.dataset_id}-{get_uuid(8)}" if data_item.id is None else f"{self.dataset_id}-{str(data_item.id)}"
111
- if data_item.metadata is not None:
112
- metadata.update(data_item.metadata)
113
- else:
114
- metadata.update({"filename": os.path.basename(image)})
115
- geo_info = data_item.geo_info
116
-
117
- self.all_input_ids[id] = input_id
118
- if data_item.image_bytes is not None:
119
- input_protos.append(
120
- Inputs.get_input_from_bytes(
121
- input_id=input_id,
122
- image_bytes=data_item.image_bytes,
123
- dataset_id=self.dataset_id,
124
- geo_info=geo_info,
125
- metadata=metadata))
126
- else:
127
- input_protos.append(
128
- Inputs.get_input_from_file(
129
- input_id=input_id,
130
- image_file=image,
131
- dataset_id=self.dataset_id,
132
- geo_info=geo_info,
133
- metadata=metadata))
134
- # iter over bboxes and labels
135
- # one id could have more than one bbox and label
136
- for i in range(len(bboxes)):
137
- annotation_protos.append(
138
- Inputs.get_bbox_proto(
139
- input_id=input_id,
140
- label=labels[i],
141
- bbox=bboxes[i],
142
- label_id=label_ids[i] if label_ids else None))
143
-
144
- with ThreadPoolExecutor(max_workers=self.max_workers) as executor:
145
- futures = [executor.submit(process_data_item, id) for id in batch_input_ids]
146
- for job in futures:
147
- job.result()
148
-
149
- return input_protos, annotation_protos
87
+ """Visual detection dataset proto class."""
88
+
89
+ def __init__(
90
+ self, data_generator: Type[ClarifaiDataLoader], dataset_id: str, max_workers: int = 4
91
+ ) -> None:
92
+ super().__init__(data_generator, dataset_id, max_workers)
93
+
94
+ def _extract_protos(
95
+ self, batch_input_ids: List[int]
96
+ ) -> Tuple[List[resources_pb2.Input], List[resources_pb2.Annotation]]:
97
+ """Create input image protos for each data generator item.
98
+ Args:
99
+ batch_input_ids: List of input IDs to retrieve the protos for.
100
+ Returns:
101
+ input_protos: List of input protos.
102
+ annotation_protos: List of annotation protos.
103
+ """
104
+ input_protos, annotation_protos = [], []
105
+
106
+ def process_data_item(id):
107
+ data_item = self.data_generator[id]
108
+ metadata = Struct()
109
+ image = data_item.image_path
110
+ labels = data_item.labels # list:[l1,...,ln]
111
+ if data_item.label_ids is not None:
112
+ assert len(labels) == len(data_item.label_ids), (
113
+ "Length of labels and label_ids must be equal"
114
+ )
115
+ label_ids = data_item.label_ids
116
+ else:
117
+ label_ids = None
118
+ bboxes = data_item.bboxes # [[xmin,ymin,xmax,ymax],...,[xmin,ymin,xmax,ymax]]
119
+ input_id = (
120
+ f"{self.dataset_id}-{get_uuid(8)}"
121
+ if data_item.id is None
122
+ else f"{self.dataset_id}-{str(data_item.id)}"
123
+ )
124
+ if data_item.metadata is not None:
125
+ metadata.update(data_item.metadata)
126
+ else:
127
+ metadata.update({"filename": os.path.basename(image)})
128
+ geo_info = data_item.geo_info
129
+
130
+ self.all_input_ids[id] = input_id
131
+ if data_item.image_bytes is not None:
132
+ input_protos.append(
133
+ Inputs.get_input_from_bytes(
134
+ input_id=input_id,
135
+ image_bytes=data_item.image_bytes,
136
+ dataset_id=self.dataset_id,
137
+ geo_info=geo_info,
138
+ metadata=metadata,
139
+ )
140
+ )
141
+ else:
142
+ input_protos.append(
143
+ Inputs.get_input_from_file(
144
+ input_id=input_id,
145
+ image_file=image,
146
+ dataset_id=self.dataset_id,
147
+ geo_info=geo_info,
148
+ metadata=metadata,
149
+ )
150
+ )
151
+ # iter over bboxes and labels
152
+ # one id could have more than one bbox and label
153
+ for i in range(len(bboxes)):
154
+ annotation_protos.append(
155
+ Inputs.get_bbox_proto(
156
+ input_id=input_id,
157
+ label=labels[i],
158
+ bbox=bboxes[i],
159
+ label_id=label_ids[i] if label_ids else None,
160
+ )
161
+ )
162
+
163
+ with ThreadPoolExecutor(max_workers=self.max_workers) as executor:
164
+ futures = [executor.submit(process_data_item, id) for id in batch_input_ids]
165
+ for job in futures:
166
+ job.result()
167
+
168
+ return input_protos, annotation_protos
150
169
 
151
170
 
152
171
  class VisualSegmentationDataset(ClarifaiDataset):
153
- """Visual segmentation dataset proto class."""
154
-
155
- def __init__(self,
156
- data_generator: Type[ClarifaiDataLoader],
157
- dataset_id: str,
158
- max_workers: int = 4) -> None:
159
- super().__init__(data_generator, dataset_id, max_workers)
160
-
161
- def _extract_protos(self, batch_input_ids: List[str]
162
- ) -> Tuple[List[resources_pb2.Input], List[resources_pb2.Annotation]]:
163
- """Create input image and annotation protos for batch of input ids.
164
- Args:
165
- batch_input_ids: List of input IDs to retrieve the protos for.
166
- Returns:
167
- input_protos: List of input protos.
168
- annotation_protos: List of annotation protos.
169
- """
170
- input_protos, annotation_protos = [], []
171
-
172
- def process_data_item(id):
173
- data_item = self.data_generator[id]
174
- metadata = Struct()
175
- image = data_item.image_path
176
- labels = data_item.labels
177
- if data_item.label_ids is not None:
178
- assert len(labels) == len(
179
- data_item.label_ids), "Length of labels and label_ids must be equal"
180
- label_ids = data_item.label_ids
181
- else:
182
- label_ids = None
183
- _polygons = data_item.polygons # list of polygons: [[[x,y],...,[x,y]],...]
184
- input_id = f"{self.dataset_id}-{get_uuid(8)}" if data_item.id is None else f"{self.dataset_id}-{str(data_item.id)}"
185
- if data_item.metadata is not None:
186
- metadata.update(data_item.metadata)
187
- else:
188
- metadata.update({"filename": os.path.basename(image)})
189
- geo_info = data_item.geo_info
190
-
191
- self.all_input_ids[id] = input_id
192
- if data_item.image_bytes is not None:
193
- input_protos.append(
194
- Inputs.get_input_from_bytes(
195
- input_id=input_id,
196
- image_bytes=data_item.image_bytes,
197
- dataset_id=self.dataset_id,
198
- geo_info=geo_info,
199
- metadata=metadata))
200
- else:
201
- input_protos.append(
202
- Inputs.get_input_from_file(
203
- input_id=input_id,
204
- image_file=image,
205
- dataset_id=self.dataset_id,
206
- geo_info=geo_info,
207
- metadata=metadata))
208
-
209
- ## Iterate over each masked image and create a proto for upload to clarifai
210
- ## The length of masks/polygons-list and labels must be equal
211
- for i, _polygon in enumerate(_polygons):
212
- try:
213
- annotation_protos.append(
214
- Inputs.get_mask_proto(
215
- input_id=input_id,
216
- label=labels[i],
217
- polygons=_polygon,
218
- label_id=label_ids[i] if label_ids else None))
219
- except IndexError:
220
- continue
221
-
222
- with ThreadPoolExecutor(max_workers=self.max_workers) as executor:
223
- futures = [executor.submit(process_data_item, id) for id in batch_input_ids]
224
- for job in futures:
225
- job.result()
226
-
227
- return input_protos, annotation_protos
172
+ """Visual segmentation dataset proto class."""
173
+
174
+ def __init__(
175
+ self, data_generator: Type[ClarifaiDataLoader], dataset_id: str, max_workers: int = 4
176
+ ) -> None:
177
+ super().__init__(data_generator, dataset_id, max_workers)
178
+
179
+ def _extract_protos(
180
+ self, batch_input_ids: List[str]
181
+ ) -> Tuple[List[resources_pb2.Input], List[resources_pb2.Annotation]]:
182
+ """Create input image and annotation protos for batch of input ids.
183
+ Args:
184
+ batch_input_ids: List of input IDs to retrieve the protos for.
185
+ Returns:
186
+ input_protos: List of input protos.
187
+ annotation_protos: List of annotation protos.
188
+ """
189
+ input_protos, annotation_protos = [], []
190
+
191
+ def process_data_item(id):
192
+ data_item = self.data_generator[id]
193
+ metadata = Struct()
194
+ image = data_item.image_path
195
+ labels = data_item.labels
196
+ if data_item.label_ids is not None:
197
+ assert len(labels) == len(data_item.label_ids), (
198
+ "Length of labels and label_ids must be equal"
199
+ )
200
+ label_ids = data_item.label_ids
201
+ else:
202
+ label_ids = None
203
+ _polygons = data_item.polygons # list of polygons: [[[x,y],...,[x,y]],...]
204
+ input_id = (
205
+ f"{self.dataset_id}-{get_uuid(8)}"
206
+ if data_item.id is None
207
+ else f"{self.dataset_id}-{str(data_item.id)}"
208
+ )
209
+ if data_item.metadata is not None:
210
+ metadata.update(data_item.metadata)
211
+ else:
212
+ metadata.update({"filename": os.path.basename(image)})
213
+ geo_info = data_item.geo_info
214
+
215
+ self.all_input_ids[id] = input_id
216
+ if data_item.image_bytes is not None:
217
+ input_protos.append(
218
+ Inputs.get_input_from_bytes(
219
+ input_id=input_id,
220
+ image_bytes=data_item.image_bytes,
221
+ dataset_id=self.dataset_id,
222
+ geo_info=geo_info,
223
+ metadata=metadata,
224
+ )
225
+ )
226
+ else:
227
+ input_protos.append(
228
+ Inputs.get_input_from_file(
229
+ input_id=input_id,
230
+ image_file=image,
231
+ dataset_id=self.dataset_id,
232
+ geo_info=geo_info,
233
+ metadata=metadata,
234
+ )
235
+ )
236
+
237
+ ## Iterate over each masked image and create a proto for upload to clarifai
238
+ ## The length of masks/polygons-list and labels must be equal
239
+ for i, _polygon in enumerate(_polygons):
240
+ try:
241
+ annotation_protos.append(
242
+ Inputs.get_mask_proto(
243
+ input_id=input_id,
244
+ label=labels[i],
245
+ polygons=_polygon,
246
+ label_id=label_ids[i] if label_ids else None,
247
+ )
248
+ )
249
+ except IndexError:
250
+ continue
251
+
252
+ with ThreadPoolExecutor(max_workers=self.max_workers) as executor:
253
+ futures = [executor.submit(process_data_item, id) for id in batch_input_ids]
254
+ for job in futures:
255
+ job.result()
256
+
257
+ return input_protos, annotation_protos
@@ -6,49 +6,51 @@ from clarifai.datasets.upload.base import ClarifaiDataLoader
6
6
 
7
7
  from ..features import VisualClassificationFeatures
8
8
 
9
- #pycocotools is a dependency for this loader
9
+ # pycocotools is a dependency for this loader
10
10
  try:
11
- from pycocotools.coco import COCO
11
+ from pycocotools.coco import COCO
12
12
  except ImportError:
13
- raise ImportError("Could not import pycocotools package. "
14
- "Please do `pip install 'clarifai[all]'` to import pycocotools.")
13
+ raise ImportError(
14
+ "Could not import pycocotools package. "
15
+ "Please do `pip install 'clarifai[all]'` to import pycocotools."
16
+ )
15
17
 
16
18
 
17
19
  class COCOCaptionsDataLoader(ClarifaiDataLoader):
18
- """COCO Image Captioning Dataset."""
20
+ """COCO Image Captioning Dataset."""
19
21
 
20
- def __init__(self, images_dir, label_filepath):
21
- """
22
- Args:
23
- images_dir: Directory containing the images.
24
- label_filepath: Path to the COCO annotation file.
25
- """
26
- self.images_dir = images_dir
27
- self.label_filepath = label_filepath
22
+ def __init__(self, images_dir, label_filepath):
23
+ """
24
+ Args:
25
+ images_dir: Directory containing the images.
26
+ label_filepath: Path to the COCO annotation file.
27
+ """
28
+ self.images_dir = images_dir
29
+ self.label_filepath = label_filepath
28
30
 
29
- self.map_ids = {}
30
- self.load_data()
31
+ self.map_ids = {}
32
+ self.load_data()
31
33
 
32
- @property
33
- def task(self):
34
- return "visual_captioning"
34
+ @property
35
+ def task(self):
36
+ return "visual_captioning"
35
37
 
36
- def load_data(self) -> None:
37
- self.coco = COCO(self.label_filepath)
38
- self.map_ids = {i: img_id for i, img_id in enumerate(list(self.coco.imgs.keys()))}
38
+ def load_data(self) -> None:
39
+ self.coco = COCO(self.label_filepath)
40
+ self.map_ids = {i: img_id for i, img_id in enumerate(list(self.coco.imgs.keys()))}
39
41
 
40
- def __len__(self):
41
- return len(self.coco.imgs)
42
+ def __len__(self):
43
+ return len(self.coco.imgs)
42
44
 
43
- def __getitem__(self, index):
44
- value = self.coco.imgs[self.map_ids[index]]
45
- image_path = os.path.join(self.images_dir, value['file_name'])
46
- annots = []
45
+ def __getitem__(self, index):
46
+ value = self.coco.imgs[self.map_ids[index]]
47
+ image_path = os.path.join(self.images_dir, value['file_name'])
48
+ annots = []
47
49
 
48
- input_ann_ids = self.coco.getAnnIds(imgIds=[value['id']])
49
- input_anns = self.coco.loadAnns(input_ann_ids)
50
+ input_ann_ids = self.coco.getAnnIds(imgIds=[value['id']])
51
+ input_anns = self.coco.loadAnns(input_ann_ids)
50
52
 
51
- for ann in input_anns:
52
- annots.append(ann['caption'])
53
+ for ann in input_anns:
54
+ annots.append(ann['caption'])
53
55
 
54
- return VisualClassificationFeatures(image_path, labels=annots[0], id=str(value['id']))
56
+ return VisualClassificationFeatures(image_path, labels=annots[0], id=str(value['id']))