Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
dcuai
dlexamples
Commits
0fc002df
Commit
0fc002df
authored
Apr 14, 2022
by
huchen
Browse files
init the dlexamples new
parent
0e04b692
Changes
375
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1266 additions
and
0 deletions
+1266
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/build_task.yml
...askRCNN/vision/packaging/windows/templates/build_task.yml
+161
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/build_wheels.yml
...kRCNN/vision/packaging/windows/templates/build_wheels.yml
+9
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/linux_build_task.yml
...N/vision/packaging/windows/templates/linux_build_task.yml
+38
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/override_pytorch_version.yml
.../packaging/windows/templates/override_pytorch_version.yml
+6
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/publish_packages.yml
...N/vision/packaging/windows/templates/publish_packages.yml
+8
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/publish_test_results.yml
...sion/packaging/windows/templates/publish_test_results.yml
+6
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/setup_env_for_msagent.yml
...ion/packaging/windows/templates/setup_env_for_msagent.yml
+25
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/setup_nightly_variables.yml
...n/packaging/windows/templates/setup_nightly_variables.yml
+11
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/upload_to_conda.yml
...NN/vision/packaging/windows/templates/upload_to_conda.yml
+10
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/upload_to_s3.yml
...kRCNN/vision/packaging/windows/templates/upload_to_s3.yml
+15
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/vsts_auth.yml
...MaskRCNN/vision/packaging/windows/templates/vsts_auth.yml
+8
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/.config/miopen/gfx906_64.HIP.2_8_0_0.ufdb.txt
...s/detection/.config/miopen/gfx906_64.HIP.2_8_0_0.ufdb.txt
+2
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/.config/miopen/miopen.udb
...CNN/vision/references/detection/.config/miopen/miopen.udb
+0
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/.config/miopen/miopen.udb.lock
...ision/references/detection/.config/miopen/miopen.udb.lock
+0
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/.config/miopen/miopen_1.0.0.udb
...sion/references/detection/.config/miopen/miopen_1.0.0.udb
+0
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/README.md
.../Objection/MaskRCNN/vision/references/detection/README.md
+52
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/coco_eval.py
...jection/MaskRCNN/vision/references/detection/coco_eval.py
+352
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/coco_utils.py
...ection/MaskRCNN/vision/references/detection/coco_utils.py
+253
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/engine.py
.../Objection/MaskRCNN/vision/references/detection/engine.py
+115
-0
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/group_by_aspect_ratio.py
...RCNN/vision/references/detection/group_by_aspect_ratio.py
+195
-0
No files found.
Too many changes to show.
To preserve performance only
375 of 375+
files are displayed.
Plain diff
Email patch
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/build_task.yml
0 → 100644
View file @
0fc002df
parameters
:
package
:
'
'
spec
:
'
'
jobDesc
:
'
'
packageDesc
:
'
'
msagent
:
true
cpuEnabled
:
true
cudaEnabled
:
true
condaEnabled
:
true
wheelsEnabled
:
true
override
:
false
jobs
:
-
job
:
'
Windows_${{
parameters.spec
}}_${{
parameters.package
}}_Build'
timeoutInMinutes
:
60
cancelTimeoutInMinutes
:
5
condition
:
>
or(and(eq('${{ parameters.package }}', 'Conda'), eq('${{ parameters.spec }}', 'CPU'),
eq('${{ parameters.condaEnabled }}', 'true'), eq('${{ parameters.cpuEnabled }}', 'true')),
and(eq('${{ parameters.package }}', 'Wheels'), eq('${{ parameters.spec }}', 'CPU'),
eq('${{ parameters.wheelsEnabled }}', 'true'), eq('${{ parameters.cpuEnabled }}', 'true')),
and(eq('${{ parameters.package }}', 'Conda'), eq('${{ parameters.spec }}', 'CUDA'),
eq('${{ parameters.condaEnabled }}', 'true'), eq('${{ parameters.cudaEnabled }}', 'true')),
and(eq('${{ parameters.package }}', 'Wheels'), eq('${{ parameters.spec }}', 'CUDA'),
eq('${{ parameters.wheelsEnabled }}', 'true'), eq('${{ parameters.cudaEnabled }}', 'true')))
variables
:
-
${{ if eq(parameters.override, 'true') }}
:
-
name
:
TORCHVISION_BUILD_NUMBER
value
:
1
-
name
:
PYTORCH_REPO
value
:
'
pytorch'
-
name
:
PYTORCH_BRANCH
value
:
'
v0.4.0'
-
${{ if eq(parameters.msagent, 'true') }}
:
-
name
:
USE_SCCACHE
value
:
0
-
${{ if eq(parameters.msagent, 'false') }}
:
-
name
:
USE_SCCACHE
value
:
1
-
${{ if eq(parameters.package, 'Conda') }}
:
-
group
:
peterjc_anaconda_token
-
name
:
PYTORCH_FINAL_PACKAGE_DIR
value
:
'
$(Build.Repository.LocalPath)\packaging\windows\output'
strategy
:
maxParallel
:
10
matrix
:
${{ if eq(parameters.spec, 'CPU') }}
:
PY3.5
:
DESIRED_PYTHON
:
3.5
CUDA_VERSION
:
cpu
PY3.6
:
DESIRED_PYTHON
:
3.6
CUDA_VERSION
:
cpu
PY3.7
:
DESIRED_PYTHON
:
3.7
CUDA_VERSION
:
cpu
PY3.8
:
DESIRED_PYTHON
:
3.8
CUDA_VERSION
:
cpu
${{ if ne(parameters.spec, 'CPU') }}
:
PY3.5_92
:
DESIRED_PYTHON
:
3.5
CUDA_VERSION
:
92
PY3.6_92
:
DESIRED_PYTHON
:
3.6
CUDA_VERSION
:
92
PY3.7_92
:
DESIRED_PYTHON
:
3.7
CUDA_VERSION
:
92
PY3.8_92
:
DESIRED_PYTHON
:
3.8
CUDA_VERSION
:
92
PY3.5_101
:
DESIRED_PYTHON
:
3.5
CUDA_VERSION
:
101
PY3.6_101
:
DESIRED_PYTHON
:
3.6
CUDA_VERSION
:
101
PY3.7_101
:
DESIRED_PYTHON
:
3.7
CUDA_VERSION
:
101
PY3.8_101
:
DESIRED_PYTHON
:
3.8
CUDA_VERSION
:
101
PY3.5_102
:
DESIRED_PYTHON
:
3.5
CUDA_VERSION
:
102
PY3.6_102
:
DESIRED_PYTHON
:
3.6
CUDA_VERSION
:
102
PY3.7_102
:
DESIRED_PYTHON
:
3.7
CUDA_VERSION
:
102
PY3.8_102
:
DESIRED_PYTHON
:
3.8
CUDA_VERSION
:
102
pool
:
${{ if eq(parameters.msagent, 'true') }}
:
vmImage
:
'
vs2017-win2016'
${{ if eq(parameters.msagent, 'false') }}
:
name
:
'
release'
steps
:
-
checkout
:
self
clean
:
true
-
template
:
setup_env_for_msagent.yml
parameters
:
msagent
:
${{ parameters.msagent }}
# - ${{ if and(eq(parameters.override, 'true'), eq(parameters.package, 'Wheels')) }}:
# - template: override_pytorch_version.yml
-
template
:
setup_nightly_variables.yml
parameters
:
package
:
${{ parameters.package }}
-
${{ if eq(parameters.package, 'Wheels') }}
:
-
template
:
build_wheels.yml
parameters
:
msagent
:
${{ parameters.msagent }}
-
${{ if eq(parameters.package, 'Conda') }}
:
-
template
:
build_conda.yml
parameters
:
msagent
:
${{ parameters.msagent }}
-
${{ if or(eq(parameters.package, 'Wheels'), eq(parameters.package, 'Conda')) }}
:
-
template
:
publish_test_results.yml
parameters
:
msagent
:
${{ parameters.msagent }}
# If you want to upload binaries to S3 & Anaconda Cloud, please uncomment this section.
-
${{ if and(eq(parameters.package, 'Wheels'), eq(parameters.spec, 'CPU')) }}
:
-
template
:
upload_to_s3.yml
parameters
:
cuVer
:
'
$(CUDA_VERSION)'
cudaVer
:
'
$(CUDA_VERSION)'
-
${{ if and(eq(parameters.package, 'Wheels'), ne(parameters.spec, 'CPU')) }}
:
-
template
:
upload_to_s3.yml
parameters
:
cuVer
:
'
cu$(CUDA_VERSION)'
cudaVer
:
'
cuda$(CUDA_VERSION)'
-
${{ if eq(parameters.package, 'Conda') }}
:
-
template
:
upload_to_conda.yml
parameters
:
user
:
$(peterjc_conda_username)
pass
:
$(peterjc_conda_password)
# If you want to upload binaries to Azure Git, please uncomment this section.
# - ${{ if or(eq(parameters.package, 'Wheels'), eq(parameters.package, 'Conda')) }}:
# - template: publish_test_results.yml
# parameters:
# msagent: ${{ parameters.msagent }}
# - template: publish_packages.yml
# parameters:
# package: ${{ parameters.package }}
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/build_wheels.yml
0 → 100644
View file @
0fc002df
parameters
:
msagent
:
false
steps
:
-
script
:
'
call
packaging/windows/build_vision.bat
%CUDA_VERSION%
%TORCHVISION_BUILD_VERSION%
%TORCHVISION_BUILD_NUMBER%'
displayName
:
Build
env
:
${{ if eq(parameters.msagent, 'true') }}
:
MAX_JOBS
:
2
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/linux_build_task.yml
0 → 100644
View file @
0fc002df
parameters
:
msagent
:
true
enabled
:
false
jobs
:
-
job
:
'
Linux_CPU_Conda_Build'
timeoutInMinutes
:
0
cancelTimeoutInMinutes
:
5
condition
:
${{ eq(parameters.enabled, 'true') }}
variables
:
CUDA_VERSION
:
cpu
TORCH_CONDA_BUILD_FOLDER
:
pytorch-nightly
PYTORCH_FINAL_PACKAGE_DIR
:
'
$(Build.Repository.LocalPath)/output'
strategy
:
maxParallel
:
10
matrix
:
PY3.5
:
DESIRED_PYTHON
:
3.5
pool
:
vmImage
:
'
ubuntu-16.04'
steps
:
-
checkout
:
self
clean
:
true
-
script
:
'
sudo
apt-get
install
p7zip-full'
displayName
:
'
Install
7Zip'
-
task
:
CondaEnvironment@1
displayName
:
'
Install
conda-build'
inputs
:
packageSpecs
:
'
conda-build'
-
template
:
build_conda.yml
parameters
:
msagent
:
${{ parameters.msagent }}
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/override_pytorch_version.yml
0 → 100644
View file @
0fc002df
steps
:
-
script
:
'
windows/internal/override_pytorch_version.bat'
displayName
:
'
Override
PyTorch
Build
Version
for
Wheels'
-
script
:
'
echo
$(PYTORCH_BUILD_VERSION)'
displayName
:
'
Show
PyTorch
Build
Version'
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/publish_packages.yml
0 → 100644
View file @
0fc002df
parameters
:
package
:
'
'
steps
:
-
script
:
'
packaging/windows/internal/publish.bat'
displayName
:
'
Upload
packages
to
Azure
DevOps
Repo'
env
:
PACKAGEFULLNAME
:
${{ parameters.package }}
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/publish_test_results.yml
0 → 100644
View file @
0fc002df
steps
:
-
task
:
PublishTestResults@2
# No test results to publish
inputs
:
testResultsFiles
:
'
windows/pytorch/test/**/*.xml'
testRunTitle
:
'
Publish
test
results'
enabled
:
false
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/setup_env_for_msagent.yml
0 → 100644
View file @
0fc002df
parameters
:
msagent
:
false
steps
:
-
${{ if eq(parameters.msagent, 'true') }}
:
-
task
:
BatchScript@1
displayName
:
'
Install
7Zip
&
cURL'
inputs
:
filename
:
'
packaging/windows/internal/dep_install.bat'
modifyEnvironment
:
true
-
task
:
BatchScript@1
displayName
:
'
Install
Visual
Studio
2017'
inputs
:
filename
:
'
packaging/windows/internal/vs_install.bat'
modifyEnvironment
:
true
-
task
:
BatchScript@1
displayName
:
'
Install
CUDA'
inputs
:
filename
:
'
packaging/windows/internal/cuda_install.bat'
modifyEnvironment
:
true
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/setup_nightly_variables.yml
0 → 100644
View file @
0fc002df
parameters
:
package
:
'
'
steps
:
-
task
:
BatchScript@1
displayName
:
'
Setup
nightly
variables'
inputs
:
filename
:
'
packaging/windows/internal/nightly_defaults.bat'
arguments
:
${{ parameters.package }}
modifyEnvironment
:
true
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/upload_to_conda.yml
0 → 100644
View file @
0fc002df
parameters
:
user
:
'
'
pass
:
'
'
steps
:
-
script
:
'
call
packaging/windows/internal/upload.bat'
displayName
:
'
Upload
packages
to
Anaconda
Cloud'
env
:
PYTORCH_ANACONDA_USERNAME
:
${{ parameters.user }}
PYTORCH_ANACONDA_PASSWORD
:
${{ parameters.pass }}
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/upload_to_s3.yml
0 → 100644
View file @
0fc002df
parameters
:
cuVer
:
'
'
cudaVer
:
'
'
steps
:
-
task
:
AmazonWebServices.aws-vsts-tools.S3Upload.S3Upload@1
displayName
:
'
Upload
${{
parameters.cuVer
}}
wheel
to
S3'
inputs
:
awsCredentials
:
'
Pytorch
S3
bucket'
bucketName
:
'
pytorch'
sourceFolder
:
'
packaging/windows/output'
globExpressions
:
'
*.whl'
targetFolder
:
'
whl/nightly/${{
parameters.cuVer
}}/'
filesAcl
:
'
public-read'
flattenFolders
:
'
true'
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/packaging/windows/templates/vsts_auth.yml
0 → 100644
View file @
0fc002df
parameters
:
auth
:
'
'
steps
:
-
script
:
'
call
packaging/windows/internal/auth.bat'
displayName
:
'
Sign
in
to
Azure
Pipelines'
env
:
VSTS_AUTH
:
${{ parameters.auth }}
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/.config/miopen/gfx906_64.HIP.2_8_0_0.ufdb.txt
0 → 100644
View file @
0fc002df
3-800-1184-7x7-64-400-592-2-3x3-2x2-1x1-0-NCHW-FP32-F=miopenConvolutionFwdAlgoGEMM:gemm,1.62115,139238400,rocBlas,<unused>
3-800-1216-7x7-64-400-608-2-3x3-2x2-1x1-0-NCHW-FP32-F=miopenConvolutionFwdAlgoGEMM:gemm,1.69475,143001600,rocBlas,<unused>
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/.config/miopen/miopen.udb
0 → 100644
View file @
0fc002df
File added
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/.config/miopen/miopen.udb.lock
0 → 100644
View file @
0fc002df
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/.config/miopen/miopen_1.0.0.udb
0 → 100644
View file @
0fc002df
File added
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/README.md
0 → 100644
View file @
0fc002df
# Object detection reference training scripts
This folder contains reference training scripts for object detection.
They serve as a log of how to train specific models, to provide baseline
training and evaluation scripts to quickly bootstrap research.
To execute the example commands below you must install the following:
```
cython
pycocotools
matplotlib
```
You must modify the following flags:
`--data-path=/path/to/coco/dataset`
`--nproc_per_node=<number_of_gpus_available>`
Except otherwise noted, all models have been trained on 8x V100 GPUs.
### Faster R-CNN
```
python -m torch.distributed.launch --nproc_per_node=8 --use_env train.py\
--dataset coco --model fasterrcnn_resnet50_fpn --epochs 26\
--lr-steps 16 22 --aspect-ratio-group-factor 3
```
### RetinaNet
```
python -m torch.distributed.launch --nproc_per_node=8 --use_env train.py\
--dataset coco --model retinanet_resnet50_fpn --epochs 26\
--lr-steps 16 22 --aspect-ratio-group-factor 3 --lr 0.01
```
### Mask R-CNN
```
python -m torch.distributed.launch --nproc_per_node=8 --use_env train.py\
--dataset coco --model maskrcnn_resnet50_fpn --epochs 26\
--lr-steps 16 22 --aspect-ratio-group-factor 3
```
### Keypoint R-CNN
```
python -m torch.distributed.launch --nproc_per_node=8 --use_env train.py\
--dataset coco_kp --model keypointrcnn_resnet50_fpn --epochs 46\
--lr-steps 36 43 --aspect-ratio-group-factor 3
```
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/coco_eval.py
0 → 100644
View file @
0fc002df
import
json
import
tempfile
import
numpy
as
np
import
copy
import
time
import
torch
import
torch._six
from
pycocotools.cocoeval
import
COCOeval
from
pycocotools.coco
import
COCO
import
pycocotools.mask
as
mask_util
from
collections
import
defaultdict
import
utils
class
CocoEvaluator
(
object
):
def
__init__
(
self
,
coco_gt
,
iou_types
):
assert
isinstance
(
iou_types
,
(
list
,
tuple
))
coco_gt
=
copy
.
deepcopy
(
coco_gt
)
self
.
coco_gt
=
coco_gt
self
.
iou_types
=
iou_types
self
.
coco_eval
=
{}
for
iou_type
in
iou_types
:
self
.
coco_eval
[
iou_type
]
=
COCOeval
(
coco_gt
,
iouType
=
iou_type
)
self
.
img_ids
=
[]
self
.
eval_imgs
=
{
k
:
[]
for
k
in
iou_types
}
def
update
(
self
,
predictions
):
img_ids
=
list
(
np
.
unique
(
list
(
predictions
.
keys
())))
self
.
img_ids
.
extend
(
img_ids
)
for
iou_type
in
self
.
iou_types
:
results
=
self
.
prepare
(
predictions
,
iou_type
)
coco_dt
=
loadRes
(
self
.
coco_gt
,
results
)
if
results
else
COCO
()
coco_eval
=
self
.
coco_eval
[
iou_type
]
coco_eval
.
cocoDt
=
coco_dt
coco_eval
.
params
.
imgIds
=
list
(
img_ids
)
img_ids
,
eval_imgs
=
evaluate
(
coco_eval
)
self
.
eval_imgs
[
iou_type
].
append
(
eval_imgs
)
def
synchronize_between_processes
(
self
):
for
iou_type
in
self
.
iou_types
:
self
.
eval_imgs
[
iou_type
]
=
np
.
concatenate
(
self
.
eval_imgs
[
iou_type
],
2
)
create_common_coco_eval
(
self
.
coco_eval
[
iou_type
],
self
.
img_ids
,
self
.
eval_imgs
[
iou_type
])
def
accumulate
(
self
):
for
coco_eval
in
self
.
coco_eval
.
values
():
coco_eval
.
accumulate
()
def
summarize
(
self
):
for
iou_type
,
coco_eval
in
self
.
coco_eval
.
items
():
print
(
"IoU metric: {}"
.
format
(
iou_type
))
coco_eval
.
summarize
()
def
prepare
(
self
,
predictions
,
iou_type
):
if
iou_type
==
"bbox"
:
return
self
.
prepare_for_coco_detection
(
predictions
)
elif
iou_type
==
"segm"
:
return
self
.
prepare_for_coco_segmentation
(
predictions
)
elif
iou_type
==
"keypoints"
:
return
self
.
prepare_for_coco_keypoint
(
predictions
)
else
:
raise
ValueError
(
"Unknown iou type {}"
.
format
(
iou_type
))
def
prepare_for_coco_detection
(
self
,
predictions
):
coco_results
=
[]
for
original_id
,
prediction
in
predictions
.
items
():
if
len
(
prediction
)
==
0
:
continue
boxes
=
prediction
[
"boxes"
]
boxes
=
convert_to_xywh
(
boxes
).
tolist
()
scores
=
prediction
[
"scores"
].
tolist
()
labels
=
prediction
[
"labels"
].
tolist
()
coco_results
.
extend
(
[
{
"image_id"
:
original_id
,
"category_id"
:
labels
[
k
],
"bbox"
:
box
,
"score"
:
scores
[
k
],
}
for
k
,
box
in
enumerate
(
boxes
)
]
)
return
coco_results
def
prepare_for_coco_segmentation
(
self
,
predictions
):
coco_results
=
[]
for
original_id
,
prediction
in
predictions
.
items
():
if
len
(
prediction
)
==
0
:
continue
scores
=
prediction
[
"scores"
]
labels
=
prediction
[
"labels"
]
masks
=
prediction
[
"masks"
]
masks
=
masks
>
0.5
scores
=
prediction
[
"scores"
].
tolist
()
labels
=
prediction
[
"labels"
].
tolist
()
rles
=
[
mask_util
.
encode
(
np
.
array
(
mask
[
0
,
:,
:,
np
.
newaxis
],
dtype
=
np
.
uint8
,
order
=
"F"
))[
0
]
for
mask
in
masks
]
for
rle
in
rles
:
rle
[
"counts"
]
=
rle
[
"counts"
].
decode
(
"utf-8"
)
coco_results
.
extend
(
[
{
"image_id"
:
original_id
,
"category_id"
:
labels
[
k
],
"segmentation"
:
rle
,
"score"
:
scores
[
k
],
}
for
k
,
rle
in
enumerate
(
rles
)
]
)
return
coco_results
def
prepare_for_coco_keypoint
(
self
,
predictions
):
coco_results
=
[]
for
original_id
,
prediction
in
predictions
.
items
():
if
len
(
prediction
)
==
0
:
continue
boxes
=
prediction
[
"boxes"
]
boxes
=
convert_to_xywh
(
boxes
).
tolist
()
scores
=
prediction
[
"scores"
].
tolist
()
labels
=
prediction
[
"labels"
].
tolist
()
keypoints
=
prediction
[
"keypoints"
]
keypoints
=
keypoints
.
flatten
(
start_dim
=
1
).
tolist
()
coco_results
.
extend
(
[
{
"image_id"
:
original_id
,
"category_id"
:
labels
[
k
],
'keypoints'
:
keypoint
,
"score"
:
scores
[
k
],
}
for
k
,
keypoint
in
enumerate
(
keypoints
)
]
)
return
coco_results
def
convert_to_xywh
(
boxes
):
xmin
,
ymin
,
xmax
,
ymax
=
boxes
.
unbind
(
1
)
return
torch
.
stack
((
xmin
,
ymin
,
xmax
-
xmin
,
ymax
-
ymin
),
dim
=
1
)
def
merge
(
img_ids
,
eval_imgs
):
all_img_ids
=
utils
.
all_gather
(
img_ids
)
all_eval_imgs
=
utils
.
all_gather
(
eval_imgs
)
merged_img_ids
=
[]
for
p
in
all_img_ids
:
merged_img_ids
.
extend
(
p
)
merged_eval_imgs
=
[]
for
p
in
all_eval_imgs
:
merged_eval_imgs
.
append
(
p
)
merged_img_ids
=
np
.
array
(
merged_img_ids
)
merged_eval_imgs
=
np
.
concatenate
(
merged_eval_imgs
,
2
)
# keep only unique (and in sorted order) images
merged_img_ids
,
idx
=
np
.
unique
(
merged_img_ids
,
return_index
=
True
)
merged_eval_imgs
=
merged_eval_imgs
[...,
idx
]
return
merged_img_ids
,
merged_eval_imgs
def
create_common_coco_eval
(
coco_eval
,
img_ids
,
eval_imgs
):
img_ids
,
eval_imgs
=
merge
(
img_ids
,
eval_imgs
)
img_ids
=
list
(
img_ids
)
eval_imgs
=
list
(
eval_imgs
.
flatten
())
coco_eval
.
evalImgs
=
eval_imgs
coco_eval
.
params
.
imgIds
=
img_ids
coco_eval
.
_paramsEval
=
copy
.
deepcopy
(
coco_eval
.
params
)
#################################################################
# From pycocotools, just removed the prints and fixed
# a Python3 bug about unicode not defined
#################################################################
# Ideally, pycocotools wouldn't have hard-coded prints
# so that we could avoid copy-pasting those two functions
def
createIndex
(
self
):
# create index
# print('creating index...')
anns
,
cats
,
imgs
=
{},
{},
{}
imgToAnns
,
catToImgs
=
defaultdict
(
list
),
defaultdict
(
list
)
if
'annotations'
in
self
.
dataset
:
for
ann
in
self
.
dataset
[
'annotations'
]:
imgToAnns
[
ann
[
'image_id'
]].
append
(
ann
)
anns
[
ann
[
'id'
]]
=
ann
if
'images'
in
self
.
dataset
:
for
img
in
self
.
dataset
[
'images'
]:
imgs
[
img
[
'id'
]]
=
img
if
'categories'
in
self
.
dataset
:
for
cat
in
self
.
dataset
[
'categories'
]:
cats
[
cat
[
'id'
]]
=
cat
if
'annotations'
in
self
.
dataset
and
'categories'
in
self
.
dataset
:
for
ann
in
self
.
dataset
[
'annotations'
]:
catToImgs
[
ann
[
'category_id'
]].
append
(
ann
[
'image_id'
])
# print('index created!')
# create class members
self
.
anns
=
anns
self
.
imgToAnns
=
imgToAnns
self
.
catToImgs
=
catToImgs
self
.
imgs
=
imgs
self
.
cats
=
cats
maskUtils
=
mask_util
def
loadRes
(
self
,
resFile
):
"""
Load result file and return a result api object.
Args:
self (obj): coco object with ground truth annotations
resFile (str): file name of result file
Returns:
res (obj): result api object
"""
res
=
COCO
()
res
.
dataset
[
'images'
]
=
[
img
for
img
in
self
.
dataset
[
'images'
]]
# print('Loading and preparing results...')
# tic = time.time()
if
isinstance
(
resFile
,
torch
.
_six
.
string_classes
):
anns
=
json
.
load
(
open
(
resFile
))
elif
type
(
resFile
)
==
np
.
ndarray
:
anns
=
self
.
loadNumpyAnnotations
(
resFile
)
else
:
anns
=
resFile
assert
type
(
anns
)
==
list
,
'results in not an array of objects'
annsImgIds
=
[
ann
[
'image_id'
]
for
ann
in
anns
]
assert
set
(
annsImgIds
)
==
(
set
(
annsImgIds
)
&
set
(
self
.
getImgIds
())),
\
'Results do not correspond to current coco set'
if
'caption'
in
anns
[
0
]:
imgIds
=
set
([
img
[
'id'
]
for
img
in
res
.
dataset
[
'images'
]])
&
set
([
ann
[
'image_id'
]
for
ann
in
anns
])
res
.
dataset
[
'images'
]
=
[
img
for
img
in
res
.
dataset
[
'images'
]
if
img
[
'id'
]
in
imgIds
]
for
id
,
ann
in
enumerate
(
anns
):
ann
[
'id'
]
=
id
+
1
elif
'bbox'
in
anns
[
0
]
and
not
anns
[
0
][
'bbox'
]
==
[]:
res
.
dataset
[
'categories'
]
=
copy
.
deepcopy
(
self
.
dataset
[
'categories'
])
for
id
,
ann
in
enumerate
(
anns
):
bb
=
ann
[
'bbox'
]
x1
,
x2
,
y1
,
y2
=
[
bb
[
0
],
bb
[
0
]
+
bb
[
2
],
bb
[
1
],
bb
[
1
]
+
bb
[
3
]]
if
'segmentation'
not
in
ann
:
ann
[
'segmentation'
]
=
[[
x1
,
y1
,
x1
,
y2
,
x2
,
y2
,
x2
,
y1
]]
ann
[
'area'
]
=
bb
[
2
]
*
bb
[
3
]
ann
[
'id'
]
=
id
+
1
ann
[
'iscrowd'
]
=
0
elif
'segmentation'
in
anns
[
0
]:
res
.
dataset
[
'categories'
]
=
copy
.
deepcopy
(
self
.
dataset
[
'categories'
])
for
id
,
ann
in
enumerate
(
anns
):
# now only support compressed RLE format as segmentation results
ann
[
'area'
]
=
maskUtils
.
area
(
ann
[
'segmentation'
])
if
'bbox'
not
in
ann
:
ann
[
'bbox'
]
=
maskUtils
.
toBbox
(
ann
[
'segmentation'
])
ann
[
'id'
]
=
id
+
1
ann
[
'iscrowd'
]
=
0
elif
'keypoints'
in
anns
[
0
]:
res
.
dataset
[
'categories'
]
=
copy
.
deepcopy
(
self
.
dataset
[
'categories'
])
for
id
,
ann
in
enumerate
(
anns
):
s
=
ann
[
'keypoints'
]
x
=
s
[
0
::
3
]
y
=
s
[
1
::
3
]
x1
,
x2
,
y1
,
y2
=
np
.
min
(
x
),
np
.
max
(
x
),
np
.
min
(
y
),
np
.
max
(
y
)
ann
[
'area'
]
=
(
x2
-
x1
)
*
(
y2
-
y1
)
ann
[
'id'
]
=
id
+
1
ann
[
'bbox'
]
=
[
x1
,
y1
,
x2
-
x1
,
y2
-
y1
]
# print('DONE (t={:0.2f}s)'.format(time.time()- tic))
res
.
dataset
[
'annotations'
]
=
anns
createIndex
(
res
)
return
res
def
evaluate
(
self
):
'''
Run per image evaluation on given images and store results (a list of dict) in self.evalImgs
:return: None
'''
# tic = time.time()
# print('Running per image evaluation...')
p
=
self
.
params
# add backward compatibility if useSegm is specified in params
if
p
.
useSegm
is
not
None
:
p
.
iouType
=
'segm'
if
p
.
useSegm
==
1
else
'bbox'
print
(
'useSegm (deprecated) is not None. Running {} evaluation'
.
format
(
p
.
iouType
))
# print('Evaluate annotation type *{}*'.format(p.iouType))
p
.
imgIds
=
list
(
np
.
unique
(
p
.
imgIds
))
if
p
.
useCats
:
p
.
catIds
=
list
(
np
.
unique
(
p
.
catIds
))
p
.
maxDets
=
sorted
(
p
.
maxDets
)
self
.
params
=
p
self
.
_prepare
()
# loop through images, area range, max detection number
catIds
=
p
.
catIds
if
p
.
useCats
else
[
-
1
]
if
p
.
iouType
==
'segm'
or
p
.
iouType
==
'bbox'
:
computeIoU
=
self
.
computeIoU
elif
p
.
iouType
==
'keypoints'
:
computeIoU
=
self
.
computeOks
self
.
ious
=
{
(
imgId
,
catId
):
computeIoU
(
imgId
,
catId
)
for
imgId
in
p
.
imgIds
for
catId
in
catIds
}
evaluateImg
=
self
.
evaluateImg
maxDet
=
p
.
maxDets
[
-
1
]
evalImgs
=
[
evaluateImg
(
imgId
,
catId
,
areaRng
,
maxDet
)
for
catId
in
catIds
for
areaRng
in
p
.
areaRng
for
imgId
in
p
.
imgIds
]
# this is NOT in the pycocotools code, but could be done outside
evalImgs
=
np
.
asarray
(
evalImgs
).
reshape
(
len
(
catIds
),
len
(
p
.
areaRng
),
len
(
p
.
imgIds
))
self
.
_paramsEval
=
copy
.
deepcopy
(
self
.
params
)
# toc = time.time()
# print('DONE (t={:0.2f}s).'.format(toc-tic))
return
p
.
imgIds
,
evalImgs
#################################################################
# end of straight copy from pycocotools, just removing the prints
#################################################################
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/coco_utils.py
0 → 100644
View file @
0fc002df
import
copy
import
os
from
PIL
import
Image
import
torch
import
torch.utils.data
import
torchvision
from
pycocotools
import
mask
as
coco_mask
from
pycocotools.coco
import
COCO
import
transforms
as
T
class
FilterAndRemapCocoCategories
(
object
):
def
__init__
(
self
,
categories
,
remap
=
True
):
self
.
categories
=
categories
self
.
remap
=
remap
def
__call__
(
self
,
image
,
target
):
anno
=
target
[
"annotations"
]
anno
=
[
obj
for
obj
in
anno
if
obj
[
"category_id"
]
in
self
.
categories
]
if
not
self
.
remap
:
target
[
"annotations"
]
=
anno
return
image
,
target
anno
=
copy
.
deepcopy
(
anno
)
for
obj
in
anno
:
obj
[
"category_id"
]
=
self
.
categories
.
index
(
obj
[
"category_id"
])
target
[
"annotations"
]
=
anno
return
image
,
target
def
convert_coco_poly_to_mask
(
segmentations
,
height
,
width
):
masks
=
[]
for
polygons
in
segmentations
:
rles
=
coco_mask
.
frPyObjects
(
polygons
,
height
,
width
)
mask
=
coco_mask
.
decode
(
rles
)
if
len
(
mask
.
shape
)
<
3
:
mask
=
mask
[...,
None
]
mask
=
torch
.
as_tensor
(
mask
,
dtype
=
torch
.
uint8
)
mask
=
mask
.
any
(
dim
=
2
)
masks
.
append
(
mask
)
if
masks
:
masks
=
torch
.
stack
(
masks
,
dim
=
0
)
else
:
masks
=
torch
.
zeros
((
0
,
height
,
width
),
dtype
=
torch
.
uint8
)
return
masks
class
ConvertCocoPolysToMask
(
object
):
def
__call__
(
self
,
image
,
target
):
w
,
h
=
image
.
size
image_id
=
target
[
"image_id"
]
image_id
=
torch
.
tensor
([
image_id
])
anno
=
target
[
"annotations"
]
anno
=
[
obj
for
obj
in
anno
if
obj
[
'iscrowd'
]
==
0
]
boxes
=
[
obj
[
"bbox"
]
for
obj
in
anno
]
# guard against no boxes via resizing
boxes
=
torch
.
as_tensor
(
boxes
,
dtype
=
torch
.
float32
).
reshape
(
-
1
,
4
)
boxes
[:,
2
:]
+=
boxes
[:,
:
2
]
boxes
[:,
0
::
2
].
clamp_
(
min
=
0
,
max
=
w
)
boxes
[:,
1
::
2
].
clamp_
(
min
=
0
,
max
=
h
)
classes
=
[
obj
[
"category_id"
]
for
obj
in
anno
]
classes
=
torch
.
tensor
(
classes
,
dtype
=
torch
.
int64
)
segmentations
=
[
obj
[
"segmentation"
]
for
obj
in
anno
]
masks
=
convert_coco_poly_to_mask
(
segmentations
,
h
,
w
)
keypoints
=
None
if
anno
and
"keypoints"
in
anno
[
0
]:
keypoints
=
[
obj
[
"keypoints"
]
for
obj
in
anno
]
keypoints
=
torch
.
as_tensor
(
keypoints
,
dtype
=
torch
.
float32
)
num_keypoints
=
keypoints
.
shape
[
0
]
if
num_keypoints
:
keypoints
=
keypoints
.
view
(
num_keypoints
,
-
1
,
3
)
keep
=
(
boxes
[:,
3
]
>
boxes
[:,
1
])
&
(
boxes
[:,
2
]
>
boxes
[:,
0
])
boxes
=
boxes
[
keep
]
classes
=
classes
[
keep
]
masks
=
masks
[
keep
]
if
keypoints
is
not
None
:
keypoints
=
keypoints
[
keep
]
target
=
{}
target
[
"boxes"
]
=
boxes
target
[
"labels"
]
=
classes
target
[
"masks"
]
=
masks
target
[
"image_id"
]
=
image_id
if
keypoints
is
not
None
:
target
[
"keypoints"
]
=
keypoints
# for conversion to coco api
area
=
torch
.
tensor
([
obj
[
"area"
]
for
obj
in
anno
])
iscrowd
=
torch
.
tensor
([
obj
[
"iscrowd"
]
for
obj
in
anno
])
target
[
"area"
]
=
area
target
[
"iscrowd"
]
=
iscrowd
return
image
,
target
def
_coco_remove_images_without_annotations
(
dataset
,
cat_list
=
None
):
def
_has_only_empty_bbox
(
anno
):
return
all
(
any
(
o
<=
1
for
o
in
obj
[
"bbox"
][
2
:])
for
obj
in
anno
)
def
_count_visible_keypoints
(
anno
):
return
sum
(
sum
(
1
for
v
in
ann
[
"keypoints"
][
2
::
3
]
if
v
>
0
)
for
ann
in
anno
)
min_keypoints_per_image
=
10
def
_has_valid_annotation
(
anno
):
# if it's empty, there is no annotation
if
len
(
anno
)
==
0
:
return
False
# if all boxes have close to zero area, there is no annotation
if
_has_only_empty_bbox
(
anno
):
return
False
# keypoints task have a slight different critera for considering
# if an annotation is valid
if
"keypoints"
not
in
anno
[
0
]:
return
True
# for keypoint detection tasks, only consider valid images those
# containing at least min_keypoints_per_image
if
_count_visible_keypoints
(
anno
)
>=
min_keypoints_per_image
:
return
True
return
False
assert
isinstance
(
dataset
,
torchvision
.
datasets
.
CocoDetection
)
ids
=
[]
for
ds_idx
,
img_id
in
enumerate
(
dataset
.
ids
):
ann_ids
=
dataset
.
coco
.
getAnnIds
(
imgIds
=
img_id
,
iscrowd
=
None
)
anno
=
dataset
.
coco
.
loadAnns
(
ann_ids
)
if
cat_list
:
anno
=
[
obj
for
obj
in
anno
if
obj
[
"category_id"
]
in
cat_list
]
if
_has_valid_annotation
(
anno
):
ids
.
append
(
ds_idx
)
dataset
=
torch
.
utils
.
data
.
Subset
(
dataset
,
ids
)
return
dataset
def
convert_to_coco_api
(
ds
):
coco_ds
=
COCO
()
# annotation IDs need to start at 1, not 0, see torchvision issue #1530
ann_id
=
1
dataset
=
{
'images'
:
[],
'categories'
:
[],
'annotations'
:
[]}
categories
=
set
()
for
img_idx
in
range
(
len
(
ds
)):
# find better way to get target
# targets = ds.get_annotations(img_idx)
img
,
targets
=
ds
[
img_idx
]
image_id
=
targets
[
"image_id"
].
item
()
img_dict
=
{}
img_dict
[
'id'
]
=
image_id
img_dict
[
'height'
]
=
img
.
shape
[
-
2
]
img_dict
[
'width'
]
=
img
.
shape
[
-
1
]
dataset
[
'images'
].
append
(
img_dict
)
bboxes
=
targets
[
"boxes"
]
bboxes
[:,
2
:]
-=
bboxes
[:,
:
2
]
bboxes
=
bboxes
.
tolist
()
labels
=
targets
[
'labels'
].
tolist
()
areas
=
targets
[
'area'
].
tolist
()
iscrowd
=
targets
[
'iscrowd'
].
tolist
()
if
'masks'
in
targets
:
masks
=
targets
[
'masks'
]
# make masks Fortran contiguous for coco_mask
masks
=
masks
.
permute
(
0
,
2
,
1
).
contiguous
().
permute
(
0
,
2
,
1
)
if
'keypoints'
in
targets
:
keypoints
=
targets
[
'keypoints'
]
keypoints
=
keypoints
.
reshape
(
keypoints
.
shape
[
0
],
-
1
).
tolist
()
num_objs
=
len
(
bboxes
)
for
i
in
range
(
num_objs
):
ann
=
{}
ann
[
'image_id'
]
=
image_id
ann
[
'bbox'
]
=
bboxes
[
i
]
ann
[
'category_id'
]
=
labels
[
i
]
categories
.
add
(
labels
[
i
])
ann
[
'area'
]
=
areas
[
i
]
ann
[
'iscrowd'
]
=
iscrowd
[
i
]
ann
[
'id'
]
=
ann_id
if
'masks'
in
targets
:
ann
[
"segmentation"
]
=
coco_mask
.
encode
(
masks
[
i
].
numpy
())
if
'keypoints'
in
targets
:
ann
[
'keypoints'
]
=
keypoints
[
i
]
ann
[
'num_keypoints'
]
=
sum
(
k
!=
0
for
k
in
keypoints
[
i
][
2
::
3
])
dataset
[
'annotations'
].
append
(
ann
)
ann_id
+=
1
dataset
[
'categories'
]
=
[{
'id'
:
i
}
for
i
in
sorted
(
categories
)]
coco_ds
.
dataset
=
dataset
coco_ds
.
createIndex
()
return
coco_ds
def
get_coco_api_from_dataset
(
dataset
):
for
_
in
range
(
10
):
if
isinstance
(
dataset
,
torchvision
.
datasets
.
CocoDetection
):
break
if
isinstance
(
dataset
,
torch
.
utils
.
data
.
Subset
):
dataset
=
dataset
.
dataset
if
isinstance
(
dataset
,
torchvision
.
datasets
.
CocoDetection
):
return
dataset
.
coco
return
convert_to_coco_api
(
dataset
)
class
CocoDetection
(
torchvision
.
datasets
.
CocoDetection
):
def
__init__
(
self
,
img_folder
,
ann_file
,
transforms
):
super
(
CocoDetection
,
self
).
__init__
(
img_folder
,
ann_file
)
self
.
_transforms
=
transforms
def
__getitem__
(
self
,
idx
):
img
,
target
=
super
(
CocoDetection
,
self
).
__getitem__
(
idx
)
image_id
=
self
.
ids
[
idx
]
target
=
dict
(
image_id
=
image_id
,
annotations
=
target
)
if
self
.
_transforms
is
not
None
:
img
,
target
=
self
.
_transforms
(
img
,
target
)
return
img
,
target
def
get_coco
(
root
,
image_set
,
transforms
,
mode
=
'instances'
):
anno_file_template
=
"{}_{}2017.json"
#PAN
PATHS
=
{
"train"
:
(
"images/train2017"
,
os
.
path
.
join
(
"annotations"
,
anno_file_template
.
format
(
mode
,
"train"
))),
"val"
:
(
"images/val2017"
,
os
.
path
.
join
(
"annotations"
,
anno_file_template
.
format
(
mode
,
"val"
))),
# "train": ("val2017", os.path.join("annotations", anno_file_template.format(mode, "val")))
}
t
=
[
ConvertCocoPolysToMask
()]
if
transforms
is
not
None
:
t
.
append
(
transforms
)
transforms
=
T
.
Compose
(
t
)
img_folder
,
ann_file
=
PATHS
[
image_set
]
img_folder
=
os
.
path
.
join
(
root
,
img_folder
)
ann_file
=
os
.
path
.
join
(
root
,
ann_file
)
dataset
=
CocoDetection
(
img_folder
,
ann_file
,
transforms
=
transforms
)
if
image_set
==
"train"
:
dataset
=
_coco_remove_images_without_annotations
(
dataset
)
# dataset = torch.utils.data.Subset(dataset, [i for i in range(500)])
return
dataset
def
get_coco_kp
(
root
,
image_set
,
transforms
):
return
get_coco
(
root
,
image_set
,
transforms
,
mode
=
"person_keypoints"
)
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/engine.py
0 → 100644
View file @
0fc002df
import
math
import
sys
import
time
import
torch
import
torchvision.models.detection.mask_rcnn
import
utils
from
coco_eval
import
CocoEvaluator
from
coco_utils
import
get_coco_api_from_dataset
def
train_one_epoch
(
model
,
optimizer
,
data_loader
,
device
,
epoch
,
print_freq
,
scaler
=
None
):
model
.
train
()
metric_logger
=
utils
.
MetricLogger
(
delimiter
=
" "
)
metric_logger
.
add_meter
(
"lr"
,
utils
.
SmoothedValue
(
window_size
=
1
,
fmt
=
"{value:.6f}"
))
header
=
f
"Epoch: [
{
epoch
}
]"
lr_scheduler
=
None
if
epoch
==
0
:
warmup_factor
=
1.0
/
1000
warmup_iters
=
min
(
1000
,
len
(
data_loader
)
-
1
)
lr_scheduler
=
torch
.
optim
.
lr_scheduler
.
LinearLR
(
optimizer
,
start_factor
=
warmup_factor
,
total_iters
=
warmup_iters
)
for
images
,
targets
in
metric_logger
.
log_every
(
data_loader
,
print_freq
,
header
):
images
=
list
(
image
.
to
(
device
)
for
image
in
images
)
targets
=
[{
k
:
v
.
to
(
device
)
for
k
,
v
in
t
.
items
()}
for
t
in
targets
]
with
torch
.
cuda
.
amp
.
autocast
(
enabled
=
scaler
is
not
None
):
loss_dict
=
model
(
images
,
targets
)
losses
=
sum
(
loss
for
loss
in
loss_dict
.
values
())
# reduce losses over all GPUs for logging purposes
loss_dict_reduced
=
utils
.
reduce_dict
(
loss_dict
)
losses_reduced
=
sum
(
loss
for
loss
in
loss_dict_reduced
.
values
())
loss_value
=
losses_reduced
.
item
()
if
not
math
.
isfinite
(
loss_value
):
print
(
f
"Loss is
{
loss_value
}
, stopping training"
)
print
(
loss_dict_reduced
)
sys
.
exit
(
1
)
optimizer
.
zero_grad
()
if
scaler
is
not
None
:
scaler
.
scale
(
losses
).
backward
()
scaler
.
step
(
optimizer
)
scaler
.
update
()
else
:
losses
.
backward
()
optimizer
.
step
()
if
lr_scheduler
is
not
None
:
lr_scheduler
.
step
()
metric_logger
.
update
(
loss
=
losses_reduced
,
**
loss_dict_reduced
)
metric_logger
.
update
(
lr
=
optimizer
.
param_groups
[
0
][
"lr"
])
return
metric_logger
def
_get_iou_types
(
model
):
model_without_ddp
=
model
if
isinstance
(
model
,
torch
.
nn
.
parallel
.
DistributedDataParallel
):
model_without_ddp
=
model
.
module
iou_types
=
[
"bbox"
]
if
isinstance
(
model_without_ddp
,
torchvision
.
models
.
detection
.
MaskRCNN
):
iou_types
.
append
(
"segm"
)
if
isinstance
(
model_without_ddp
,
torchvision
.
models
.
detection
.
KeypointRCNN
):
iou_types
.
append
(
"keypoints"
)
return
iou_types
@
torch
.
inference_mode
()
def
evaluate
(
model
,
data_loader
,
device
):
n_threads
=
torch
.
get_num_threads
()
# FIXME remove this and make paste_masks_in_image run on the GPU
torch
.
set_num_threads
(
1
)
cpu_device
=
torch
.
device
(
"cpu"
)
model
.
eval
()
metric_logger
=
utils
.
MetricLogger
(
delimiter
=
" "
)
header
=
"Test:"
coco
=
get_coco_api_from_dataset
(
data_loader
.
dataset
)
iou_types
=
_get_iou_types
(
model
)
coco_evaluator
=
CocoEvaluator
(
coco
,
iou_types
)
for
images
,
targets
in
metric_logger
.
log_every
(
data_loader
,
100
,
header
):
images
=
list
(
img
.
to
(
device
)
for
img
in
images
)
if
torch
.
cuda
.
is_available
():
torch
.
cuda
.
synchronize
()
model_time
=
time
.
time
()
outputs
=
model
(
images
)
outputs
=
[{
k
:
v
.
to
(
cpu_device
)
for
k
,
v
in
t
.
items
()}
for
t
in
outputs
]
model_time
=
time
.
time
()
-
model_time
res
=
{
target
[
"image_id"
].
item
():
output
for
target
,
output
in
zip
(
targets
,
outputs
)}
evaluator_time
=
time
.
time
()
coco_evaluator
.
update
(
res
)
evaluator_time
=
time
.
time
()
-
evaluator_time
metric_logger
.
update
(
model_time
=
model_time
,
evaluator_time
=
evaluator_time
)
# gather the stats from all processes
metric_logger
.
synchronize_between_processes
()
print
(
"Averaged stats:"
,
metric_logger
)
coco_evaluator
.
synchronize_between_processes
()
# accumulate predictions from all images
coco_evaluator
.
accumulate
()
coco_evaluator
.
summarize
()
torch
.
set_num_threads
(
n_threads
)
return
coco_evaluator
PyTorch/Compute-Vision/Objection/MaskRCNN/vision/references/detection/group_by_aspect_ratio.py
0 → 100644
View file @
0fc002df
import
bisect
from
collections
import
defaultdict
import
copy
from
itertools
import
repeat
,
chain
import
math
import
numpy
as
np
import
torch
import
torch.utils.data
from
torch.utils.data.sampler
import
BatchSampler
,
Sampler
from
torch.utils.model_zoo
import
tqdm
import
torchvision
from
PIL
import
Image
def
_repeat_to_at_least
(
iterable
,
n
):
repeat_times
=
math
.
ceil
(
n
/
len
(
iterable
))
repeated
=
chain
.
from_iterable
(
repeat
(
iterable
,
repeat_times
))
return
list
(
repeated
)
class
GroupedBatchSampler
(
BatchSampler
):
"""
Wraps another sampler to yield a mini-batch of indices.
It enforces that the batch only contain elements from the same group.
It also tries to provide mini-batches which follows an ordering which is
as close as possible to the ordering from the original sampler.
Args:
sampler (Sampler): Base sampler.
group_ids (list[int]): If the sampler produces indices in range [0, N),
`group_ids` must be a list of `N` ints which contains the group id of each sample.
The group ids must be a continuous set of integers starting from
0, i.e. they must be in the range [0, num_groups).
batch_size (int): Size of mini-batch.
"""
def
__init__
(
self
,
sampler
,
group_ids
,
batch_size
):
if
not
isinstance
(
sampler
,
Sampler
):
raise
ValueError
(
"sampler should be an instance of "
"torch.utils.data.Sampler, but got sampler={}"
.
format
(
sampler
)
)
self
.
sampler
=
sampler
self
.
group_ids
=
group_ids
self
.
batch_size
=
batch_size
def
__iter__
(
self
):
buffer_per_group
=
defaultdict
(
list
)
samples_per_group
=
defaultdict
(
list
)
num_batches
=
0
for
idx
in
self
.
sampler
:
group_id
=
self
.
group_ids
[
idx
]
buffer_per_group
[
group_id
].
append
(
idx
)
samples_per_group
[
group_id
].
append
(
idx
)
if
len
(
buffer_per_group
[
group_id
])
==
self
.
batch_size
:
yield
buffer_per_group
[
group_id
]
num_batches
+=
1
del
buffer_per_group
[
group_id
]
assert
len
(
buffer_per_group
[
group_id
])
<
self
.
batch_size
# now we have run out of elements that satisfy
# the group criteria, let's return the remaining
# elements so that the size of the sampler is
# deterministic
expected_num_batches
=
len
(
self
)
num_remaining
=
expected_num_batches
-
num_batches
if
num_remaining
>
0
:
# for the remaining batches, take first the buffers with largest number
# of elements
for
group_id
,
_
in
sorted
(
buffer_per_group
.
items
(),
key
=
lambda
x
:
len
(
x
[
1
]),
reverse
=
True
):
remaining
=
self
.
batch_size
-
len
(
buffer_per_group
[
group_id
])
samples_from_group_id
=
_repeat_to_at_least
(
samples_per_group
[
group_id
],
remaining
)
buffer_per_group
[
group_id
].
extend
(
samples_from_group_id
[:
remaining
])
assert
len
(
buffer_per_group
[
group_id
])
==
self
.
batch_size
yield
buffer_per_group
[
group_id
]
num_remaining
-=
1
if
num_remaining
==
0
:
break
assert
num_remaining
==
0
def
__len__
(
self
):
return
len
(
self
.
sampler
)
//
self
.
batch_size
def
_compute_aspect_ratios_slow
(
dataset
,
indices
=
None
):
print
(
"Your dataset doesn't support the fast path for "
"computing the aspect ratios, so will iterate over "
"the full dataset and load every image instead. "
"This might take some time..."
)
if
indices
is
None
:
indices
=
range
(
len
(
dataset
))
class
SubsetSampler
(
Sampler
):
def
__init__
(
self
,
indices
):
self
.
indices
=
indices
def
__iter__
(
self
):
return
iter
(
self
.
indices
)
def
__len__
(
self
):
return
len
(
self
.
indices
)
sampler
=
SubsetSampler
(
indices
)
data_loader
=
torch
.
utils
.
data
.
DataLoader
(
dataset
,
batch_size
=
1
,
sampler
=
sampler
,
num_workers
=
14
,
# you might want to increase it for faster processing
collate_fn
=
lambda
x
:
x
[
0
])
aspect_ratios
=
[]
with
tqdm
(
total
=
len
(
dataset
))
as
pbar
:
for
_i
,
(
img
,
_
)
in
enumerate
(
data_loader
):
pbar
.
update
(
1
)
height
,
width
=
img
.
shape
[
-
2
:]
aspect_ratio
=
float
(
width
)
/
float
(
height
)
aspect_ratios
.
append
(
aspect_ratio
)
return
aspect_ratios
def
_compute_aspect_ratios_custom_dataset
(
dataset
,
indices
=
None
):
if
indices
is
None
:
indices
=
range
(
len
(
dataset
))
aspect_ratios
=
[]
for
i
in
indices
:
height
,
width
=
dataset
.
get_height_and_width
(
i
)
aspect_ratio
=
float
(
width
)
/
float
(
height
)
aspect_ratios
.
append
(
aspect_ratio
)
return
aspect_ratios
def
_compute_aspect_ratios_coco_dataset
(
dataset
,
indices
=
None
):
if
indices
is
None
:
indices
=
range
(
len
(
dataset
))
aspect_ratios
=
[]
for
i
in
indices
:
img_info
=
dataset
.
coco
.
imgs
[
dataset
.
ids
[
i
]]
aspect_ratio
=
float
(
img_info
[
"width"
])
/
float
(
img_info
[
"height"
])
aspect_ratios
.
append
(
aspect_ratio
)
return
aspect_ratios
def
_compute_aspect_ratios_voc_dataset
(
dataset
,
indices
=
None
):
if
indices
is
None
:
indices
=
range
(
len
(
dataset
))
aspect_ratios
=
[]
for
i
in
indices
:
# this doesn't load the data into memory, because PIL loads it lazily
width
,
height
=
Image
.
open
(
dataset
.
images
[
i
]).
size
aspect_ratio
=
float
(
width
)
/
float
(
height
)
aspect_ratios
.
append
(
aspect_ratio
)
return
aspect_ratios
def
_compute_aspect_ratios_subset_dataset
(
dataset
,
indices
=
None
):
if
indices
is
None
:
indices
=
range
(
len
(
dataset
))
ds_indices
=
[
dataset
.
indices
[
i
]
for
i
in
indices
]
return
compute_aspect_ratios
(
dataset
.
dataset
,
ds_indices
)
def
compute_aspect_ratios
(
dataset
,
indices
=
None
):
if
hasattr
(
dataset
,
"get_height_and_width"
):
return
_compute_aspect_ratios_custom_dataset
(
dataset
,
indices
)
if
isinstance
(
dataset
,
torchvision
.
datasets
.
CocoDetection
):
return
_compute_aspect_ratios_coco_dataset
(
dataset
,
indices
)
if
isinstance
(
dataset
,
torchvision
.
datasets
.
VOCDetection
):
return
_compute_aspect_ratios_voc_dataset
(
dataset
,
indices
)
if
isinstance
(
dataset
,
torch
.
utils
.
data
.
Subset
):
return
_compute_aspect_ratios_subset_dataset
(
dataset
,
indices
)
# slow path
return
_compute_aspect_ratios_slow
(
dataset
,
indices
)
def
_quantize
(
x
,
bins
):
bins
=
copy
.
deepcopy
(
bins
)
bins
=
sorted
(
bins
)
quantized
=
list
(
map
(
lambda
y
:
bisect
.
bisect_right
(
bins
,
y
),
x
))
return
quantized
def
create_aspect_ratio_groups
(
dataset
,
k
=
0
):
aspect_ratios
=
compute_aspect_ratios
(
dataset
)
bins
=
(
2
**
np
.
linspace
(
-
1
,
1
,
2
*
k
+
1
)).
tolist
()
if
k
>
0
else
[
1.0
]
groups
=
_quantize
(
aspect_ratios
,
bins
)
# count number of elements per group
counts
=
np
.
unique
(
groups
,
return_counts
=
True
)[
1
]
fbins
=
[
0
]
+
bins
+
[
np
.
inf
]
print
(
"Using {} as bins for aspect ratio quantization"
.
format
(
fbins
))
print
(
"Count of instances per bin: {}"
.
format
(
counts
))
return
groups
Prev
1
…
6
7
8
9
10
11
12
13
14
…
19
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment