pybaseutils 2.0.6__tar.gz → 2.0.8__tar.gz

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 (252) hide show
  1. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/PKG-INFO +1 -1
  2. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/__init__.py +1 -1
  3. pybaseutils-2.0.8/pybaseutils/dataloader/balanced_classes.py +222 -0
  4. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/dataloader/base_coco.py +1 -1
  5. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/dataloader/base_dataset.py +2 -2
  6. pybaseutils-2.0.8/pybaseutils/dataloader/data_resample.py +220 -0
  7. pybaseutils-2.0.8/pybaseutils/dataloader/parser_image_folder.py +103 -0
  8. pybaseutils-2.0.8/pybaseutils/dataloader/parser_image_text.py +268 -0
  9. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/dataloader/parser_labelme.py +1 -1
  10. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/dataloader/parser_voc.py +1 -1
  11. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/dataloader/parser_yolo.py +2 -2
  12. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/file_utils.py +55 -15
  13. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/image_utils.py +19 -14
  14. pybaseutils-2.0.8/pybaseutils/text_utils.py +197 -0
  15. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils.egg-info/PKG-INFO +1 -1
  16. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils.egg-info/SOURCES.txt +5 -1
  17. pybaseutils-2.0.8/test_py/converter/get_pair_data.py +17 -0
  18. pybaseutils-2.0.8/test_py/demo2.py +24 -0
  19. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_lableme_vis.py +2 -2
  20. pybaseutils-2.0.6/test_py/converter/get_pair_data.py +0 -57
  21. pybaseutils-2.0.6/test_py/demo2.py +0 -29
  22. pybaseutils-2.0.6/test_py/edit_distance/text_utils.py +0 -241
  23. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/LICENCE +0 -0
  24. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/README.md +0 -0
  25. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/audio/__init__.py +0 -0
  26. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/audio/audio_utils.py +0 -0
  27. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/audio/pyaudio_utils.py +0 -0
  28. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/audio/vad_utils.py +0 -0
  29. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/base64_utils.py +0 -0
  30. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/batch_utils.py +0 -0
  31. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/build_utils/__init__.py +0 -0
  32. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/build_utils/cython_utils.py +0 -0
  33. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/build_utils/pyarmor_utils.py +0 -0
  34. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/cluster/__init__.py +0 -0
  35. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/cluster/kmean.py +0 -0
  36. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/cluster/maxmin_distance.py +0 -0
  37. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/cluster/similarity.py +0 -0
  38. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/color_utils.py +0 -0
  39. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/config_utils.py +0 -0
  40. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/__init__.py +0 -0
  41. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/build_coco.py +0 -0
  42. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/build_cvat.py +0 -0
  43. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/build_labelme.py +0 -0
  44. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/build_voc.py +0 -0
  45. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/concat_coco.py +0 -0
  46. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/convert_coco2labelme.py +0 -0
  47. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/convert_coco2voc.py +0 -0
  48. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/convert_cvat2labelme.py +0 -0
  49. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/convert_labelme2coco.py +0 -0
  50. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/convert_labelme2cvat.py +0 -0
  51. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/convert_labelme2voc.py +0 -0
  52. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/convert_labelme2yolo.py +0 -0
  53. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/convert_voc2coco.py +0 -0
  54. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/convert_voc2labelme.py +0 -0
  55. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/convert_voc2voc.py +0 -0
  56. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/convert_voc2yolo.py +0 -0
  57. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/converter/convert_yolo2voc.py +0 -0
  58. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/coords_utils.py +0 -0
  59. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/cvutils/__init__.py +0 -0
  60. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/cvutils/corner_utils.py +0 -0
  61. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/cvutils/monitor.py +0 -0
  62. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/cvutils/mouse_utils.py +0 -0
  63. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/cvutils/video_utils.py +0 -0
  64. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/dataloader/__init__.py +0 -0
  65. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/dataloader/parser_coco_det.py +0 -0
  66. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/dataloader/parser_coco_ins.py +0 -0
  67. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/dataloader/parser_coco_kps.py +0 -0
  68. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/dataloader/voc_seg_utils.py +0 -0
  69. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/filter/QueueTable.py +0 -0
  70. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/filter/__init__.py +0 -0
  71. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/filter/demo.py +0 -0
  72. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/filter/kalman_filter.py +0 -0
  73. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/filter/mean_filter.py +0 -0
  74. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/filter/motion_filter.py +0 -0
  75. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/filter/pose_filter.py +0 -0
  76. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/font_style/__init__.py +0 -0
  77. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/font_utils.py +0 -0
  78. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/geometry_tools.py +0 -0
  79. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/heatmap_utils.py +0 -0
  80. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/json_utils.py +0 -0
  81. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/log.py +0 -0
  82. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/logger.py +0 -0
  83. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/metrics/__init__.py +0 -0
  84. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/metrics/accuracy.py +0 -0
  85. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/metrics/average_meter.py +0 -0
  86. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/metrics/class_report.py +0 -0
  87. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/metrics/plot_pr.py +0 -0
  88. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/metrics/plot_roc.py +0 -0
  89. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/numpy_utils.py +0 -0
  90. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/pandas_utils.py +0 -0
  91. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/plot_utils.py +0 -0
  92. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/pose/__init__.py +0 -0
  93. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/pose/bones_utils.py +0 -0
  94. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/pose/human_pose.py +0 -0
  95. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/pose/pose_utils.py +0 -0
  96. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/pycpp/__init__.py +0 -0
  97. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/pycpp/demo.py +0 -0
  98. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/pycpp/main.py +0 -0
  99. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/server/__init__.py +0 -0
  100. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/server/apm_server.py +0 -0
  101. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/setup_config.py +0 -0
  102. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/singleton_utils.py +0 -0
  103. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/thread_utils.py +0 -0
  104. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/time_utils.py +0 -0
  105. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/tracemalloc_utils.py +0 -0
  106. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/tracemalloc_utils2.py +0 -0
  107. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/tracking/QueueTable.py +0 -0
  108. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/tracking/__init__.py +0 -0
  109. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/tracking/demo.py +0 -0
  110. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/tracking/kalman_filter.py +0 -0
  111. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/tracking/mean_filter.py +0 -0
  112. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/tracking/motion_filter.py +0 -0
  113. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/tracking/pose_filter.py +0 -0
  114. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/transforms/__init__.py +0 -0
  115. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/transforms/affine_transform.py +0 -0
  116. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/transforms/augment_utils.py +0 -0
  117. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/transforms/face_alignment.py +0 -0
  118. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/transforms/transform_utils.py +0 -0
  119. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/word_utils.py +0 -0
  120. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/worker.py +0 -0
  121. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils/yaml_utils.py +0 -0
  122. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils.egg-info/dependency_links.txt +0 -0
  123. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils.egg-info/not-zip-safe +0 -0
  124. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/pybaseutils.egg-info/top_level.txt +0 -0
  125. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/setup.cfg +0 -0
  126. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/setup.py +0 -0
  127. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/WebCrawler/__init__.py +0 -0
  128. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/WebCrawler/search_image.py +0 -0
  129. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/WebCrawler/search_image_for_baidu.py +0 -0
  130. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/__init__.py +0 -0
  131. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/aije/__init__.py +0 -0
  132. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/aije/action_dataset.py +0 -0
  133. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/aije/build_cython.py +0 -0
  134. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/aije/build_pyarmor.py +0 -0
  135. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/aije/build_service.py +0 -0
  136. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/aije/convert_cvat2labelme.py +0 -0
  137. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/aije/convert_labelme2coco.py +0 -0
  138. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/aije/convert_labelme2voc.py +0 -0
  139. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/aije/copy_move.py +0 -0
  140. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/aije/demo_labelme_crop.py +0 -0
  141. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/aije/demo_video_aije.py +0 -0
  142. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/aije/demo_voc_crop.py +0 -0
  143. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/aije/demo_voc_vis.py +0 -0
  144. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/aije/video_convertor.py +0 -0
  145. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/audio/__init__.py +0 -0
  146. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/audio/demo.py +0 -0
  147. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/audio/main.py +0 -0
  148. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/audio/main_read.py +0 -0
  149. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/audio/segment.py +0 -0
  150. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/audio/speechbrain_asr_indoor_prod.py +0 -0
  151. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/audio/speechbrain_demo.py +0 -0
  152. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/captcha/__init__.py +0 -0
  153. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/captcha/demo.py +0 -0
  154. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/class_attribute.py +0 -0
  155. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/class_names.py +0 -0
  156. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/AffectNet.py +0 -0
  157. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/AsianMovie.py +0 -0
  158. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/BITVehicle2voc.py +0 -0
  159. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/BSTLD2voc.py +0 -0
  160. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/CCPD.py +0 -0
  161. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/CCPD2voc.py +0 -0
  162. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/FL3D_dataset.py +0 -0
  163. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/FreiHAND2coco.py +0 -0
  164. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/MTFL2voc.py +0 -0
  165. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/TT100K.py +0 -0
  166. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/WaterMeters1.py +0 -0
  167. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/WaterMeters2.py +0 -0
  168. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/__init__.py +0 -0
  169. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/concat_coco.py +0 -0
  170. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/convert_coco2voc.py +0 -0
  171. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/convert_cvat2labelme.py +0 -0
  172. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/convert_gesture2hand.py +0 -0
  173. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/convert_labelme2coco.py +0 -0
  174. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/convert_labelme2cvat.py +0 -0
  175. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/convert_labelme2voc.py +0 -0
  176. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/convert_voc2labelme.py +0 -0
  177. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/fatigue_driving.py +0 -0
  178. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/fdd_dataset.py +0 -0
  179. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/handpose2coco.py +0 -0
  180. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/insects_for_aichallenger.py +0 -0
  181. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/tt100k_utils.py +0 -0
  182. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/ua_detrac2voc.py +0 -0
  183. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/ucf101_dataset.py +0 -0
  184. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/converter/voc_sbd2labelme.py +0 -0
  185. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/cython_build/__init__.py +0 -0
  186. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/cython_build/build_cython.py +0 -0
  187. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/cython_build/build_pyarmor.py +0 -0
  188. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/cython_build/cryptography_demo.py +0 -0
  189. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/cython_build/fun_sum.py +0 -0
  190. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/cython_build/main.py +0 -0
  191. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/cython_build/model_des_enctypt.py +0 -0
  192. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/cython_build/model_enctypt.py +0 -0
  193. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo1.py +0 -0
  194. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo3.py +0 -0
  195. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_async_await1.py +0 -0
  196. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_async_await2.py +0 -0
  197. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_coco_vis.py +0 -0
  198. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_copy_files.py +0 -0
  199. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_copy_files_for_voc.py +0 -0
  200. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_ffmpy.py +0 -0
  201. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_for_pair_file.py +0 -0
  202. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_for_polygon.py +0 -0
  203. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_for_trt.py +0 -0
  204. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_get_file_list.py +0 -0
  205. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_gif.py +0 -0
  206. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_gif_video.py +0 -0
  207. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_image_crop.py +0 -0
  208. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_kpts.py +0 -0
  209. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_labelme.py +0 -0
  210. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_labelme_crop.py +0 -0
  211. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_metrics.py +0 -0
  212. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_mouse.py +0 -0
  213. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_nii.py +0 -0
  214. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_pandas.py +0 -0
  215. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_plot.py +0 -0
  216. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_rename.py +0 -0
  217. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_standard_image .py +0 -0
  218. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_standard_video .py +0 -0
  219. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_taichi.py +0 -0
  220. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_video.py +0 -0
  221. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_voc_crop.py +0 -0
  222. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_voc_vis.py +0 -0
  223. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_word_similar.py +0 -0
  224. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_worker1.py +0 -0
  225. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/demo_worker2.py +0 -0
  226. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/detector/__init__.py +0 -0
  227. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/detector/demo.py +0 -0
  228. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/detector/detect_face_person.py +0 -0
  229. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/detector/predet_labelme.py +0 -0
  230. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/edit_distance/__init__.py +0 -0
  231. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/edit_distance/demo.py +0 -0
  232. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/edit_distance/text_matching.py +0 -0
  233. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/flask_demo/__init__.py +0 -0
  234. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/flask_demo/func.py +0 -0
  235. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/flask_demo/server.py +0 -0
  236. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/image_correction/__init__.py +0 -0
  237. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/image_correction/demo_correction_v1.py +0 -0
  238. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/image_correction/demo_correction_v2.py +0 -0
  239. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/image_correction/demo_correction_v3.py +0 -0
  240. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/kafka_worker.py +0 -0
  241. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/men_tracemalloc.py +0 -0
  242. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/performance.py +0 -0
  243. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/pose/__init__.py +0 -0
  244. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/pose/human_pose.py +0 -0
  245. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/registry/__init__.py +0 -0
  246. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/registry/base.py +0 -0
  247. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/registry/component.py +0 -0
  248. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/registry/main.py +0 -0
  249. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/registry/register.py +0 -0
  250. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/test_fr/__init__.py +0 -0
  251. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/test_fr/demo11.py +0 -0
  252. {pybaseutils-2.0.6 → pybaseutils-2.0.8}/test_py/test_fr/idcardocr.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pybaseutils
3
- Version: 2.0.6
3
+ Version: 2.0.8
4
4
  Summary: pybaseutils
5
5
  Home-page: https://github.com/PanJinquan/base-utils
6
6
  Author: PanJinquan
@@ -5,4 +5,4 @@
5
5
  @Date : 2019-05-07 17:40:27
6
6
  """
7
7
 
8
- __version__ = '2.0.6'
8
+ __version__ = '2.0.8'
@@ -0,0 +1,222 @@
1
+ # -*-coding: utf-8 -*-
2
+ """
3
+ @Author : panjq
4
+ @E-mail : pan_jinquan@163.com
5
+ @Date : 2019-11-18 14:08:46
6
+ """
7
+ import numpy as np
8
+ import math
9
+
10
+
11
+ def get_torch_sample(weights,
12
+ num_samples: int,
13
+ replacement: bool = True,
14
+ generator=None):
15
+ '''
16
+ https://blog.csdn.net/caihuanqia/article/details/113258690
17
+ :param weights:weights参数对应的是“样本”的权重而不是“类别的权重”,权重越大,采样次数更多
18
+ :param num_samples:
19
+ :param replacement:
20
+ :param generator:
21
+ :return:
22
+ '''
23
+ import torch.utils.data as torch_utils
24
+ sampler = torch_utils.sampler.WeightedRandomSampler(weights, len(weights))
25
+ return sampler
26
+
27
+
28
+ def class_weight_to_sample_weight(labels_list: list, class_weight: dict):
29
+ '''
30
+ :param labels_list:lable必须从0开始的,连续的int类型
31
+ :param class_weight:
32
+ :return:
33
+ '''
34
+ sample_weight = [0] * len(labels_list)
35
+ for idx, name in enumerate(labels_list):
36
+ sample_weight[idx] = class_weight[name]
37
+ return sample_weight
38
+
39
+
40
+ def count_class_samples_nums(labels_list):
41
+ '''
42
+ classes_dict = {cls_id0: nums_of_id0,cls_id1: nums_of_id1,...,}
43
+ classes_dict = {0: 5,1: 5, 2: 2, 3: 2, 4: 4}
44
+ =========
45
+ # nclasses = len(set(labels_list)) # fix a BUG
46
+ nclasses = max(labels_list) + 1
47
+ count = [0] * nclasses
48
+ for name in labels_list:
49
+ count[name] += 1 # item is (img-data, label-id)
50
+ classes_dict = dict(enumerate(count))
51
+ =========
52
+ :param labels_list:lable必须从0开始的,连续的int类型
53
+ :return:
54
+ '''
55
+ count_class = {}
56
+ for name in labels_list:
57
+ try:
58
+ count_class[name] += 1
59
+ except Exception as e:
60
+ count_class[name] = 1
61
+ return count_class
62
+
63
+
64
+ def create_class_sample_weight_sklearn(labels_list: list, balanced='balanced', weight_type="class_weight"):
65
+ '''
66
+ balanced : dict, 'balanced' or None
67
+ If 'balanced', class weights will be given by
68
+ ``n_samples / (n_classes * np.bincount(lt_steps))``.
69
+ If a dictionary is given, keys are classes and values are corresponding class weights.
70
+ If None
71
+ :param labels_list: lable必须从0开始的,连续的int类型
72
+ :param balanced:dict, 'balanced' or None
73
+ If 'balanced', class weights will be given by
74
+ ``n_samples / (n_classes * np.bincount(lt_steps))``.
75
+ If a dictionary is given, keys are classes and values
76
+ are corresponding class weights.
77
+ If None is given, the class weights will be uniform.
78
+ :param weight_type: class_weight or sample_weight
79
+ :return:
80
+ '''
81
+ import sklearn
82
+ classes = np.unique(labels_list)
83
+ weight_list = sklearn.utils.class_weight.compute_class_weight(balanced,
84
+ classes,
85
+ labels_list)
86
+ if weight_type == "class_weight":
87
+ class_weight = dict(zip([x for x in classes], weight_list))
88
+ return class_weight
89
+ elif weight_type == "sample_weight":
90
+ class_weight = dict(zip([x for x in classes], weight_list))
91
+ sample_weight = class_weight_to_sample_weight(labels_list, class_weight)
92
+ return sample_weight
93
+ else:
94
+ return weight_list
95
+
96
+
97
+ def create_class_sample_weight_custom(labels_list, balanced="balanced", weight_type="class_weight"):
98
+ '''
99
+
100
+ :param labels_list:lable必须从0开始的,连续的int类型
101
+ :param balanced:
102
+ :param weight_type: class_weight:返回每个classs的权重
103
+ sample_weight:返回每个labels_list对应的权重
104
+ :param mu:
105
+ :return:
106
+ '''
107
+ count_class = count_class_samples_nums(labels_list)
108
+ n_samples = np.sum(list(count_class.values()))
109
+ classes = count_class.keys()
110
+ n_classes = len(classes)
111
+ class_weight = dict()
112
+ weight = sum(class_weight.values())
113
+ # 计算每个类别的权重:样本越少,权重越大
114
+ for cls in classes:
115
+ cls_num = float(count_class[cls])
116
+ if balanced == "log_balanced":
117
+ mu = 0.15
118
+ score = math.log(mu * n_samples / cls_num)
119
+ class_weight[cls] = score if score > 1.0 else 1.0
120
+ elif balanced == "balanced":
121
+ # score = n_samples / (n_classes * np.bincount(lt_steps))
122
+ score = n_samples / (n_classes * cls_num)
123
+ class_weight[cls] = score
124
+ elif balanced == "auto":
125
+ # N / float(count[i])
126
+ score = n_samples / cls_num
127
+ class_weight[cls] = score
128
+ else:
129
+ raise Exception("Error:{}".format(balanced))
130
+ # loss_weight = {k: v / weight for k, v in class_weight.items()}
131
+ if weight_type == "class_weight":
132
+ return class_weight
133
+ elif weight_type == "sample_weight":
134
+ sample_weight = class_weight_to_sample_weight(labels_list, class_weight)
135
+ return sample_weight
136
+ else:
137
+ raise Exception("Error:{}".format(weight_type))
138
+
139
+
140
+ def create_sample_weight_torch(labels_list, nclasses=None):
141
+ '''
142
+ Make a vector of weights for each image in the dataset, based
143
+ on class frequency. The returned vector of weights can be used
144
+ to create a WeightedRandomSampler for a DataLoader to have
145
+ class balancing when sampling for a training batch.
146
+ images - torchvisionDataset.imgs
147
+ nclasses - len(torchvisionDataset.classes)
148
+ https://discuss.pytorch.org/t/balanced-sampling-between-classes-with-torchvision-dataloader/2703/3
149
+ labels_list = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4]
150
+ weight =[3.6, 3.6, 3.6, 3.6, 3.6, 3.6, 3.6, 3.6, 3.6, 3.6, 9.0, 9.0, 9.0, 9.0, 4.5, 4.5, 4.5, 4.5]
151
+ '''
152
+ if not nclasses:
153
+ nclasses = len(set(labels_list))
154
+ classes_dict = count_class_samples_nums(labels_list)
155
+ count = list(classes_dict.values())
156
+ weight_per_class = [0.] * nclasses
157
+ N = float(sum(count)) # total number of images
158
+ for i in range(nclasses):
159
+ weight_per_class[i] = N / float(count[i])
160
+ weight = [0] * len(labels_list)
161
+ for idx, name in enumerate(labels_list):
162
+ weight[idx] = weight_per_class[name]
163
+
164
+ return weight
165
+
166
+
167
+ def keras_example(class_weight, sample_weight):
168
+ '''
169
+ 在keras,fit函数中调用class_weight,可以通过字典设置每个类别输入权重,比如:cw = {0: 1, 1: 25},
170
+ 类别序列可以使用.class_indices获取。
171
+ :param model:
172
+ :param class_weight: Optional dictionary mapping class indices (integers)
173
+ to a weight (float) value, used for weighting the loss function
174
+ (during training only).
175
+ This can be useful to tell the model to
176
+ "pay more attention" to samples from
177
+ an under-represented class.
178
+ :param sample_weight: type->numpy array,用于在训练时调整损失函数(仅用于训练)。
179
+ 可以传递一个1D的与样本等长的向量用于对样本进行1对1的加权,或者在面对时序数据时,
180
+ 传递一个的形式为(samples,sequence_length)的矩阵来为每个时间步上的样本赋不同的权。
181
+ 这种情况下请确定在compile时添加了sample_weight_mode=‘temporal’。
182
+ 1.sample_weight会覆盖class_weight,所以二者用其一;
183
+ 2.如果仅仅是类不平衡,则使用class_weight,sample_weights则是类内样本之间还不平衡的时候使用。
184
+ 3.keras已经在新版本中加入了 class_weight = ‘auto’。
185
+ 设置了这个参数后,keras会自动设置class weight让每类的sample对损失的贡献相等。
186
+ 4.在设置类别权重的时候,类别序列可以使用train_generator.class_indices获取。
187
+ :return:
188
+ '''
189
+ import tensorflow as tf
190
+ train_dataset = ...
191
+ steps_per_epoch = ...
192
+ model = tf.keras.models.Sequential([
193
+ tf.keras.layers.Dense(512, activation=None, name="fc1")
194
+ ])
195
+ model.compile(optimizer='adam',
196
+ loss='sparse_categorical_crossentropy',
197
+ metrics=['accuracy'])
198
+ model.fit(train_dataset,
199
+ steps_per_epoch=steps_per_epoch,
200
+ sample_weight=sample_weight,
201
+ class_weight='auto')
202
+
203
+
204
+ if __name__ == "__main__":
205
+ # random labels_dict
206
+ # labels_dict = {0: 2813, 1: 78, 2: 2814, 3: 78, 4: 7914, 5: 248, 6: 7914, 7: 248}
207
+ labels_list = [4, 1, 2, 3, 2, 3, 3, 4, 4, 4, 0]
208
+ print("create_class_sample_weight_custom-------------------------")
209
+ w1 = create_class_sample_weight_custom(labels_list, balanced="balanced", weight_type="class_weight")
210
+ w2 = create_class_sample_weight_custom(labels_list, balanced="balanced", weight_type="sample_weight")
211
+ print("class_weight :{}".format(w1))
212
+ print("labels_list :{}".format(labels_list))
213
+ print("sample_weight:{}".format(w2))
214
+ print("create_class_sample_weight_sklearn-------------------------")
215
+ w2 = create_class_sample_weight_sklearn(labels_list, balanced="balanced", weight_type="class_weight")
216
+ w3 = create_class_sample_weight_sklearn(labels_list, balanced="balanced", weight_type="sample_weight")
217
+ print("class_weight :{}".format(w2))
218
+ print("labels_list :{}".format(labels_list))
219
+ print("sample_weight:{}".format(w3))
220
+ # print(class_weight_to_sample_weight(labels_list, w2))
221
+ # w3 = create_sample_weight_torch(labels_list, nclasses=5)
222
+ # print(w3)
@@ -200,7 +200,7 @@ class CocoDataset(object):
200
200
  :return:
201
201
  """
202
202
  if isinstance(class_name, str):
203
- class_name = Dataset.read_files(class_name)
203
+ class_name = Dataset.read_file(class_name)
204
204
  elif isinstance(class_name, list) and "unique" in class_name:
205
205
  self.unique = True
206
206
  if isinstance(class_name, list) and len(class_name) > 0:
@@ -66,7 +66,7 @@ class Dataset(object):
66
66
  :return:
67
67
  """
68
68
  if isinstance(class_name, str):
69
- class_name = Dataset.read_files(class_name)
69
+ class_name = Dataset.read_file(class_name)
70
70
  elif isinstance(class_name, list) and "unique" in class_name:
71
71
  self.unique = True
72
72
  if isinstance(class_name, list) and len(class_name) > 0:
@@ -109,7 +109,7 @@ class Dataset(object):
109
109
  return json_data
110
110
 
111
111
  @staticmethod
112
- def read_files(filename, split=None):
112
+ def read_file(filename, split=None):
113
113
  """
114
114
  :param filename:
115
115
  :param split:分割
@@ -0,0 +1,220 @@
1
+ # -*-coding: utf-8 -*-
2
+ """
3
+ @Author : Pan
4
+ @E-mail :
5
+ @Date : 2021-04-21 09:41:34
6
+ """
7
+ import random
8
+ import numpy as np
9
+ import math
10
+
11
+
12
+ class ResampleExample(object):
13
+ """样本均衡,重采样DataResampler的使用方法"""
14
+
15
+ def __init__(self, item_list, label_index=1, shuffle=True, disp=False):
16
+ """
17
+ :param item_list: item_list=[item_0,item_1,...,item_n],
18
+ item_n= [path/to/image,label]
19
+ :param label_index: label在item_n的index
20
+ :param disp: 是否打印log信息
21
+ """
22
+ self.disp = disp
23
+ self.shuffle = shuffle
24
+ self.item_list = item_list
25
+ self.resampler = DataResample(self.item_list,
26
+ label_index=label_index,
27
+ shuffle=self.shuffle,
28
+ disp=self.disp)
29
+
30
+ def __len__(self):
31
+ # 更新resampler,实现每个epoch重新采样,避免样本数比较多的类别,没有加入训练
32
+ self.item_list = self.resampler.update(self.shuffle)
33
+ return len(self.item_list)
34
+
35
+ def __getitem__(self, idx):
36
+ image_path = self.item_list[idx][0]
37
+ label_id = self.item_list[idx][1]
38
+ return image_path, label_id
39
+
40
+
41
+ class DataResample(object):
42
+ """样本均衡,重采样的方法"""
43
+
44
+ def __init__(self, item_list=[], label_index=1, balance="mean", shuffle=True, disp=False):
45
+ """
46
+ Usage:
47
+ 参考:ResampleExample例子的使用方法
48
+ :param item_list:
49
+ :param label_index:
50
+ :param balance:实现样本均衡策略,均衡力度:mean > log > sqrt > y
51
+ "y": 每个label样本数跟原来一样
52
+ "sqrt": 每个label样本取sqrt数,实现样本均衡
53
+ "log": 每个label样本取log数,实现样本均衡
54
+ "mean": 每个label样本取样本平均数,每个label的个数一样
55
+ """
56
+ self.src_item_list = item_list
57
+ self.label_index = label_index
58
+ self.balance = balance
59
+ self.shuffle = shuffle
60
+ self.disp = disp
61
+ self.class_count = self.get_class_count(self.src_item_list, label_index)
62
+ self.class_item_dict = self.get_class_item_dict(self.src_item_list, label_index)
63
+ self.balance_nums = self.get_balance_nums(self.class_count, self.balance)
64
+ self.item_list = self.update(shuffle=self.shuffle)
65
+ self.class_weight = self.get_class_weight(self.class_count)
66
+
67
+ def __len__(self):
68
+ self.update(shuffle=self.shuffle)
69
+ return len(self.item_list)
70
+
71
+ def update(self, shuffle=False):
72
+ self.item_list = self.get_resample_data(shuffle=shuffle)
73
+ return self.item_list
74
+
75
+ def get_resample_data(self, shuffle=True):
76
+ """
77
+ 获得重采样的数据
78
+ :param item_list:
79
+ :param label_index:
80
+ :param shuffle:
81
+ :return:
82
+ """
83
+ if self.disp:
84
+ print("class_item_dict:{}".format({k: len(v) for k, v in self.class_item_dict.items()}))
85
+ out_list = []
86
+ for name, per_class_list in self.class_item_dict.items():
87
+ nums = self.balance_nums[name]
88
+ per_list = self.get_sampler(per_class_list, nums, shuffle=shuffle)
89
+ out_list += per_list
90
+ if shuffle:
91
+ random.shuffle(out_list)
92
+ if self.disp:
93
+ # 统计每个类别的个数
94
+ class_count = self.get_class_count(out_list, self.label_index)
95
+ print("resampler count_class :{},total:{}".format(class_count, sum(class_count.values())))
96
+ return out_list
97
+
98
+ def get_balance_nums(self, class_count: dict, balance):
99
+ """
100
+ 获得平衡后,每个样本的数目
101
+ :param class_count:
102
+ :param balance:
103
+ :return:
104
+ """
105
+ class_name = list(class_count.keys())
106
+ num_samples = sum(class_count.values()) # 总样本数目
107
+ if balance == "mean":
108
+ mean_samples = num_samples * 1.0 / len(class_name) # 平均样本数
109
+ balance_nums = {name: mean_samples for name, c in class_count.items()}
110
+ elif balance == "log":
111
+ # Fix Bug:c=1
112
+ balance_nums = {name: np.log(c + 1) for name, c in class_count.items()}
113
+ elif balance == "sqrt":
114
+ # Fix Bug:c=0
115
+ balance_nums = {name: np.sqrt(c + 1) for name, c in class_count.items()}
116
+ elif balance == "y":
117
+ balance_nums = {name: c for name, c in class_count.items()}
118
+ else:
119
+ raise Exception("Error:{}".format(balance))
120
+ sum_balance = sum(balance_nums.values())
121
+ balance_nums = {name: math.ceil(c / sum_balance * num_samples) for name, c in balance_nums.items()}
122
+ return balance_nums
123
+
124
+ def get_sampler(self, item_list, nums, shuffle=True):
125
+ """
126
+ 提取nums个数,不足nums个时,会进行填充
127
+ :param item_list: 输入样本列表
128
+ :param nums: 需要提取的样本数目
129
+ :param shuffle: 是否随机提取样本
130
+ :return:
131
+ """
132
+ item_nums = len(item_list)
133
+ if nums > item_nums:
134
+ item_list = item_list * math.ceil(nums / item_nums)
135
+ if shuffle:
136
+ random.shuffle(item_list)
137
+ out_list = item_list[:nums]
138
+ return out_list
139
+
140
+ @staticmethod
141
+ def get_label_list(item_list, label_index):
142
+ labels_list = []
143
+ for item in item_list:
144
+ label = item[label_index]
145
+ labels_list.append(label)
146
+ return labels_list
147
+
148
+ @staticmethod
149
+ def get_class_item_dict(item_list, label_index):
150
+ """
151
+ 获得每一类的样本
152
+ :param item_list:
153
+ :return:
154
+ """
155
+ class_item_dict = {}
156
+ for item in item_list:
157
+ label = item[label_index]
158
+ try:
159
+ # if label in class_item_dict: # 比较慢,相当于需要查询label是否存在
160
+ class_item_dict[label] += [item]
161
+ except Exception as e:
162
+ class_item_dict[label] = [item]
163
+ return class_item_dict
164
+
165
+ @staticmethod
166
+ def get_class_count(item_list, label_index):
167
+ """
168
+ 统计每个类别的个数
169
+ :param item_list:
170
+ :param label_index: label在item中的序号
171
+ :return:
172
+ """
173
+ class_count = {}
174
+ for item in item_list:
175
+ label = item[label_index]
176
+ try:
177
+ # if label in class_count: # 比较慢,相当于需要查询label是否存在
178
+ class_count[label] += 1
179
+ except Exception as e:
180
+ class_count[label] = 1
181
+ return class_count
182
+
183
+ @staticmethod
184
+ def get_class_weight(class_count: dict):
185
+ """
186
+ 计算每个label的权重,类别越少,权重越大
187
+ :param class_count:
188
+ :return:
189
+ """
190
+ n_samples = sum(list(class_count.values()))
191
+ class_weight = {}
192
+ for cls, num in class_count.items():
193
+ score = n_samples / num
194
+ class_weight[cls] = score
195
+ return class_weight
196
+
197
+
198
+ if __name__ == "__main__":
199
+ from torch.utils.data import Dataset, DataLoader, Sampler
200
+ from utils import torch_tools
201
+
202
+ torch_tools.set_env_random_seed()
203
+ label0 = [["0.1.jpg", 0], ["0.2.jpg", 0], ["0.3.jpg", 0]]
204
+ label1 = [["1.jpg", 1]] * 5
205
+ label2 = [["2.0.jpg", 2], ["2.1.jpg", 2], ["2.2.jpg", 2], ["2.3.jpg", 2], ["2.4.jpg", 2],
206
+ ["2.5.jpg", 2], ["2.6.jpg", 2], ["2.7.jpg", 2], ["2.8.jpg", 2]]
207
+ label3 = [["3.1.jpg", 3], ["3.2.jpg", 3], ["3.3.jpg", 3]]
208
+ item_list = label0 + label1 + label2 + label3
209
+ item_list = item_list * 1000000
210
+ print("have item_list:{}".format(len(item_list)))
211
+ dataset_train = ResampleExample(item_list=item_list, label_index=1, shuffle=True, disp=True)
212
+ # dataset_train = ResampleExample(item_list=item_list, label_index=1, disp=False)
213
+ # dataset_train = ResampleExample(item_list=item_list, label_index=1, disp=False)
214
+ batch_size = 4
215
+ dataloader = DataLoader(dataset_train, batch_size, num_workers=0)
216
+ epochs = 2
217
+ for epoch in range(epochs):
218
+ print("{}===".format(epoch) * 10)
219
+ for batch_image, batch_label in iter(dataloader):
220
+ print(batch_image, batch_label)
@@ -0,0 +1,103 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ # --------------------------------------------------------
4
+ # @Author : panjq
5
+ # @Date : 2019-9-20 13:18:34
6
+ # --------------------------------------------------------
7
+ """
8
+
9
+ import os
10
+ import cv2
11
+ import PIL.Image as Image
12
+ import numpy as np
13
+ import random
14
+ from pybaseutils import image_utils, file_utils
15
+ from pybaseutils.dataloader import parser_image_text
16
+
17
+
18
+ class FolderDataset(parser_image_text.TextDataset):
19
+ def __init__(self, image_dir, class_name=None, transform=None, use_rgb=False, shuffle=False,
20
+ phase="test", disp=False, check=False, **kwargs):
21
+ """
22
+ :param image_dir: [image_dir]->list or `path/to/image_dir`->str
23
+ :param class_name:
24
+ :param transform: torch transform
25
+ :param shuffle:
26
+ :param disp:
27
+ """
28
+ super(FolderDataset, self).__init__(filename=image_dir,
29
+ data_root=None,
30
+ class_name=class_name,
31
+ transform=transform,
32
+ shuffle=shuffle,
33
+ use_rgb=use_rgb,
34
+ phase=phase,
35
+ disp=disp,
36
+ check=check,
37
+ **kwargs)
38
+
39
+ def __getitem__(self, index):
40
+ """
41
+ :param index:
42
+ :return: image,label
43
+ """
44
+ item = self.item_list[index]
45
+ bbox = item[2:] if len(item) == 6 else []
46
+ image_file, label = item[0], item[1]
47
+ image = self.read_image(image_file, use_rgb=self.use_rgb)
48
+ image = self.crop_image(image, bbox=bbox) if bbox else image
49
+ if self.transform:
50
+ image = Image.fromarray(image)
51
+ image = self.transform(image)
52
+ if image is None:
53
+ index = int(random.uniform(0, self.num_images))
54
+ return self.__getitem__(index)
55
+ return {"image": image, "label": label}
56
+
57
+ def load_dataset(self, filename, data_root="", use_sub=False):
58
+ """
59
+ 保存格式:[path,label] 或者 [path,label,xmin,ymin,xmax,,ymax]
60
+ :param filename:
61
+ :param data_root:
62
+ :return: item_list [path,label] 或者 [path,label,xmin,ymin,xmax,,ymax]
63
+ """
64
+ if isinstance(filename, str): filename = [filename]
65
+ item_list = []
66
+ for i, dir in enumerate(filename):
67
+ print("loading image from:{}".format(dir))
68
+ if not os.path.exists(dir): raise Exception("image_dir:{}".format(dir))
69
+ paths, labels = file_utils.get_files_labels(dir, postfix=file_utils.IMG_POSTFIX)
70
+ # TODO # 避免多个数据集的相同的label
71
+ if use_sub: labels = [os.path.join(str(i), l) for l in labels]
72
+ data = [[p, l] for p, l in zip(paths, labels)]
73
+ item_list += data
74
+ return item_list
75
+
76
+
77
+ if __name__ == '__main__':
78
+ from pybaseutils import image_utils
79
+ from torchvision import transforms
80
+
81
+ image_dir = ['/home/PKing/nasdata/release/infrastructure/DMClassification/data/dataset/train']
82
+ input_size = [224, 224]
83
+ rgb_mean = [0., 0., 0.]
84
+ rgb_std = [1.0, 1.0, 1.0]
85
+ transform = transforms.Compose([
86
+ transforms.Resize(input_size),
87
+ transforms.ToTensor(),
88
+ transforms.Normalize(mean=rgb_mean, std=rgb_std),
89
+ ])
90
+ dataset = FolderDataset(image_dir=image_dir,
91
+ transform=transform,
92
+ shuffle=True,
93
+ class_name=None,
94
+ resample=True,
95
+ disp=True)
96
+ for i in range(len(dataset)):
97
+ data_info = dataset.__getitem__(i)
98
+ image, label = data_info["image"], data_info["label"]
99
+ image = np.asarray(image).transpose(1, 2, 0) # 通道由[c,h,w]->[h,w,c]
100
+ image = np.asarray(image * 255, dtype=np.uint8)
101
+ label = np.asarray(label, dtype=np.int32)
102
+ print("batch_image.shape:{},batch_label:{}".format(image.shape, label))
103
+ image_utils.cv_show_image("image", image)