forked from mindspore-Ecosystem/mindspore
!20622 push icnet code
Merge pull request !20622 from bigpingping/master
This commit is contained in:
commit
aed52ca7c5
|
@ -8,6 +8,7 @@
|
|||
- [Script and Sample Code](#script-and-sample-code)
|
||||
- [Script Parameters](#script-parameters)
|
||||
- [Training Process](#training-process)
|
||||
- [Prepare Dataset](#prepare-dataset)
|
||||
- [Distributed Training](#distributed-training)
|
||||
- [Training Results](#training-results)
|
||||
- [Evaluation Process](#evaluation-process)
|
||||
|
@ -41,8 +42,8 @@ It contains 5,000 finely annotated images split into training, validation and te
|
|||
- frame:
|
||||
- [Mindspore](https://www.mindspore.cn/install)
|
||||
- For details, please refer to the following resources:
|
||||
- [MindSpore course](https://www.mindspore.cn/tutorials/zh-CN/master/index.html)
|
||||
- [MindSpore Python API](https://www.mindspore.cn/docs/api/zh-CN/master/index.html)
|
||||
- [MindSpore course](https://www.mindspore.cn/tutorial/training/zh-CN/master/index.html)
|
||||
- [MindSpore Python API](https://www.mindspore.cn/doc/api_python/zh-CN/master/index.html)
|
||||
|
||||
# [Scription Description](#Content)
|
||||
|
||||
|
@ -88,7 +89,7 @@ It contains 5,000 finely annotated images split into training, validation and te
|
|||
|
||||
## Script Parameters
|
||||
|
||||
Set script parameters in configs/icnet.yaml .
|
||||
Set script parameters in src/model_utils/icnet.yaml .
|
||||
|
||||
### Model
|
||||
|
||||
|
@ -112,22 +113,29 @@ weight_decay: 0.0001
|
|||
```bash
|
||||
train_batch_size_percard: 4
|
||||
valid_batch_size: 1
|
||||
cityscapes_root: "/data/cityscapes/"
|
||||
cityscapes_root: "/data/cityscapes/" # set dataset path
|
||||
epochs: 160
|
||||
val_epoch: 1 # run validation every val-epoch
|
||||
ckpt_dir: "./ckpt/" # ckpt and training log will be saved here
|
||||
mindrecord_dir: '/root/bigpingping/mindrecord'
|
||||
val_epoch: 1
|
||||
ckpt_dir: "./ckpt/" # ckpt and training log will be saved here
|
||||
mindrecord_dir: '' # set mindrecord path
|
||||
pretrained_model_path: '/root/ResNet50V1B-150_625.ckpt' # set the pretrained model path correctly
|
||||
save_checkpoint_epochs: 5
|
||||
keep_checkpoint_max: 10
|
||||
```
|
||||
|
||||
### Valid
|
||||
## Training Process
|
||||
|
||||
```bash
|
||||
ckpt_path: "" # set the pretrained model path correctly
|
||||
### Prepare Datast
|
||||
|
||||
- Convert dataset to Mindrecord
|
||||
|
||||
```python
|
||||
python cityscapes_mindrecord.py [DATASET_PATH] [MINDRECORD_PATH]
|
||||
```
|
||||
|
||||
## Training Process
|
||||
- Note:
|
||||
|
||||
[MINDRCORD_PATH] in script should be consistent with 'mindrecord_dir' in config file.
|
||||
|
||||
### Distributed Training
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ class Evaluator:
|
|||
self.image_paths, self.mask_paths = _get_city_pairs(config["train"]["cityscapes_root"], "val")
|
||||
|
||||
# create network
|
||||
self.model = ICNet(nclass=19, backbone='resnet50', istraining=False)
|
||||
self.model = ICNet(nclass=19, pretrained_path=cfg["train"]["pretrained_model_path"], istraining=False)
|
||||
|
||||
# load ckpt
|
||||
ckpt_file_name = args_opt.checkpoint_path
|
||||
|
@ -74,6 +74,7 @@ class Evaluator:
|
|||
mask = self._mask_transform(mask) # mask shape: (H,w)
|
||||
|
||||
image = Tensor(image)
|
||||
print(image)
|
||||
|
||||
expand_dims = ops.ExpandDims()
|
||||
image = expand_dims(image, 0)
|
||||
|
@ -163,7 +164,8 @@ if __name__ == '__main__':
|
|||
from src.metric import SegmentationMetric
|
||||
from src.logger import SetupLogger
|
||||
# Set config file
|
||||
config_path = args_opt.project_path + "/src/model_utils/icnet.yaml"
|
||||
config_file = "src/model_utils/icnet.yaml"
|
||||
config_path = os.path.join(args_opt.project_path, config_file)
|
||||
with open(config_path, "r") as yaml_file:
|
||||
cfg = yaml.load(yaml_file.read())
|
||||
logger = SetupLogger(name="semantic_segmentation",
|
||||
|
|
|
@ -106,7 +106,7 @@ if __name__ == '__main__':
|
|||
from src.metric import SegmentationMetric
|
||||
from src.logger import SetupLogger
|
||||
# Set config file
|
||||
config_file = "/src/model_utils/icnet.yaml"
|
||||
config_file = "src/model_utils/icnet.yaml"
|
||||
config_path = os.path.join(args_opt.project_path, config_file)
|
||||
with open(config_path, "r") as yaml_file:
|
||||
cfg = yaml.load(yaml_file.read())
|
||||
|
|
|
@ -17,20 +17,28 @@
|
|||
if [ $# != 2 ]
|
||||
then
|
||||
echo "=============================================================================================================="
|
||||
echo "Usage: bash scripts/run_distribute_train.sh [RANK_TABLE_FILE] [PROJECT_PATH]"
|
||||
echo "Usage: bash scripts/run_distribute_train8p.sh [RANK_TABLE_FILE] [PROJECT_PATH]"
|
||||
echo "Please run the script as: "
|
||||
echo "bash scripts/run_distribute_train.sh [RANK_TABLE_FILE] [PROJECT_PATH]"
|
||||
echo "for example: bash run_distribute_train.sh /absolute/path/to/RANK_TABLE_FILE /root/ICNet/"
|
||||
echo "bash scripts/run_distribute_train8p.sh [RANK_TABLE_FILE] [PROJECT_PATH]"
|
||||
echo "for example: bash script/run_distribute_train8p.sh /absolute/path/to/RANK_TABLE_FILE /root/ICNet/"
|
||||
echo "=============================================================================================================="
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PATH1=$(get_real_path $1)
|
||||
get_real_path(){
|
||||
if [ "${1:0:1}" == "/" ]; then
|
||||
echo "$1"
|
||||
else
|
||||
echo "$(realpath -m $PWD/$1)"
|
||||
fi
|
||||
}
|
||||
|
||||
PATH2=$(get_real_path $2)
|
||||
|
||||
|
||||
if [ ! -d $PATH1 ]
|
||||
if [ ! -d $PATH2 ]
|
||||
then
|
||||
echo "error: DATASET_PATH=$PATH1 is not a directory"
|
||||
echo "error: PROJECT_PATH=$PATH2 is not a directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
@ -51,7 +59,7 @@ do
|
|||
echo "start training for rank $i, device $DEVICE_ID"
|
||||
env > env.log
|
||||
|
||||
python3 train.py --project_path=$PATH1 > log.txt 2>&1 &
|
||||
python3 train.py --project_path=$PATH2 > log.txt 2>&1 &
|
||||
|
||||
cd ../
|
||||
done
|
||||
done
|
||||
|
|
|
@ -30,6 +30,7 @@ get_real_path(){
|
|||
|
||||
PATH1=$(get_real_path $1)
|
||||
PATH2=$(get_real_path $2)
|
||||
PATH3=$(get_real_path $3)
|
||||
|
||||
|
||||
if [ ! -d $PATH1 ]
|
||||
|
@ -44,9 +45,15 @@ then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d $PATH3 ]
|
||||
then
|
||||
echo "error: PROJECT_PATH=$PATH3 is not a directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ulimit -u unlimited
|
||||
export DEVICE_NUM=1
|
||||
export DEVICE_ID=$5
|
||||
export DEVICE_ID=0
|
||||
export RANK_SIZE=1
|
||||
export RANK_ID=0
|
||||
|
||||
|
@ -61,6 +68,6 @@ cp -r ../src ./eval
|
|||
cd ./eval || exit
|
||||
env > env.log
|
||||
echo "start evaluation for device $DEVICE_ID"
|
||||
python eval.py --dataset_path=$PATH1 --checkpoint_path=$PATH2 &> log &
|
||||
python eval.py --dataset_path=$PATH1 --checkpoint_path=$PATH2 --project_path=$PATH3 &> log &
|
||||
|
||||
cd ..
|
||||
cd ..
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
"""Prepare Cityscapes dataset"""
|
||||
import os
|
||||
import random
|
||||
import argparse
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
from PIL import ImageOps
|
||||
|
@ -27,6 +28,7 @@ import mindspore.dataset.transforms.py_transforms as tc
|
|||
|
||||
def _get_city_pairs(folder, split='train'):
|
||||
"""Return two path arrays of data set img and mask"""
|
||||
|
||||
def get_path_pairs(image_folder, masks_folder):
|
||||
image_paths = []
|
||||
masks_paths = []
|
||||
|
@ -145,11 +147,10 @@ def _img_mask_transform(img, mask):
|
|||
return (img, mask)
|
||||
|
||||
|
||||
def data_to_mindrecord_img(prefix='cityscapes.mindrecord', file_num=1,
|
||||
root='/data/cityscapes/', split='train'):
|
||||
def data_to_mindrecord_img(prefix='cityscapes-2975.mindrecord', file_num=1,
|
||||
root='./', split='train', mindrecord_dir="./"):
|
||||
"""to mindrecord"""
|
||||
mindrecord_dir = '/data/Mindrecord_cityscapes/'
|
||||
mindrecord_path = os.path.join(mindrecord_dir, prefix + "2975-2")
|
||||
mindrecord_path = os.path.join(mindrecord_dir, prefix)
|
||||
|
||||
writter = FileWriter(mindrecord_path, file_num)
|
||||
|
||||
|
@ -202,4 +203,10 @@ def create_icnet_dataset(mindrecord_file, batch_size=16, device_num=1, rank_id=0
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
data_to_mindrecord_img()
|
||||
parser = argparse.ArgumentParser(description="dataset_to_mindrecord")
|
||||
parser.add_argument("--dataset_path", type=str, default="/data/cityscapes/", help="dataset path")
|
||||
parser.add_argument("--mindrecord_path", type=str, default="/data/cityscapes_mindrecord/",
|
||||
help="mindrecord_path")
|
||||
|
||||
args_opt = parser.parse_args()
|
||||
data_to_mindrecord_img(root=args_opt.dataset_path, mindrecord_dir=args_opt.mindrecord_path)
|
||||
|
|
|
@ -19,10 +19,11 @@ train:
|
|||
epochs: 160
|
||||
val_epoch: 1 # run validation every val-epoch
|
||||
ckpt_dir: "./ckpt/" # ckpt and training log will be saved here
|
||||
mindrecord_dir: '/root/ICNet/mindrecord'
|
||||
mindrecord_dir: '/data/cityscapes_mindrecord'
|
||||
pretrained_model_path: '/root/ResNet50V1B-150_625.ckpt'
|
||||
save_checkpoint_epochs: 5
|
||||
keep_checkpoint_max: 10
|
||||
|
||||
### 4.Valid
|
||||
test:
|
||||
ckpt_path: "" # set the pretrained model path correctly
|
||||
ckpt_path: "" # set the pretrained model path correctly
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
"""__init__"""
|
||||
from .icnet import ICNet
|
||||
from .icnet_dc import ICNetdc
|
||||
from .icnet_1p import ICNet1p
|
||||
|
|
|
@ -28,7 +28,7 @@ context.set_context(mode=context.GRAPH_MODE, device_target='Ascend')
|
|||
class ICNet(nn.Cell):
|
||||
"""Image Cascade Network"""
|
||||
|
||||
def __init__(self, nclass=19, backbone='resnet50', pretrained_base=True, istraining=True):
|
||||
def __init__(self, nclass=19, backbone='resnet50', pretrained_path='', istraining=True):
|
||||
super(ICNet, self).__init__()
|
||||
self.conv_sub1 = nn.SequentialCell(
|
||||
_ConvBNReLU(3, 32, 3, 2),
|
||||
|
@ -38,7 +38,7 @@ class ICNet(nn.Cell):
|
|||
self.istraining = istraining
|
||||
self.ppm = PyramidPoolingModule()
|
||||
|
||||
self.backbone = SegBaseModel()
|
||||
self.backbone = SegBaseModel(root=pretrained_path)
|
||||
|
||||
self.head = _ICHead(nclass)
|
||||
|
||||
|
@ -232,11 +232,11 @@ class CascadeFeatureFusion24(nn.Cell):
|
|||
class SegBaseModel(nn.Cell):
|
||||
"""Base Model for Semantic Segmentation"""
|
||||
|
||||
def __init__(self, nclass=19, backbone='resnet50', pretrained_base=True, **kwargs):
|
||||
def __init__(self, nclass=19, backbone='resnet50', root=''):
|
||||
super(SegBaseModel, self).__init__()
|
||||
self.nclass = nclass
|
||||
if backbone == 'resnet50':
|
||||
self.pretrained = get_resnet50v1b()
|
||||
self.pretrained = get_resnet50v1b(ckpt_root=root)
|
||||
|
||||
def construct(self, x):
|
||||
"""forwarding pre-trained network"""
|
||||
|
|
|
@ -28,7 +28,7 @@ context.set_context(mode=context.GRAPH_MODE, device_target='Ascend')
|
|||
class ICNetdc(nn.Cell):
|
||||
"""Image Cascade Network"""
|
||||
|
||||
def __init__(self, nclass=19, backbone='resnet50', pretrained_base=True, istraining=True):
|
||||
def __init__(self, nclass=19, pretrained_path="", istraining=True):
|
||||
super(ICNetdc, self).__init__()
|
||||
self.conv_sub1 = nn.SequentialCell(
|
||||
_ConvBNReLU(3, 32, 3, 2),
|
||||
|
@ -38,7 +38,7 @@ class ICNetdc(nn.Cell):
|
|||
self.istraining = istraining
|
||||
self.ppm = PyramidPoolingModule()
|
||||
|
||||
self.backbone = SegBaseModel()
|
||||
self.backbone = SegBaseModel(root=pretrained_path)
|
||||
|
||||
self.head = _ICHead(nclass)
|
||||
|
||||
|
@ -235,11 +235,11 @@ class CascadeFeatureFusion24(nn.Cell):
|
|||
class SegBaseModel(nn.Cell):
|
||||
"""Base Model for Semantic Segmentation"""
|
||||
|
||||
def __init__(self, nclass=19, backbone='resnet50', pretrained_base=True, **kwargs):
|
||||
def __init__(self, nclass=19, backbone='resnet50', root=""):
|
||||
super(SegBaseModel, self).__init__()
|
||||
self.nclass = nclass
|
||||
if backbone == 'resnet50':
|
||||
self.pretrained = get_resnet50v1b()
|
||||
self.pretrained = get_resnet50v1b(ckpt_root=root)
|
||||
|
||||
def construct(self, x):
|
||||
"""forwarding pre-trained network"""
|
||||
|
|
|
@ -258,7 +258,7 @@ class Resnet50v1b(nn.Cell):
|
|||
return out
|
||||
|
||||
|
||||
def get_resnet50v1b(class_num=1001, ckpt_root='/root/ICNet/ckpt/ResNet50V1B-150_625.ckpt', pretrained=True):
|
||||
def get_resnet50v1b(class_num=1001, ckpt_root='', pretrained=True):
|
||||
"""
|
||||
Get SE-ResNet50 neural network.
|
||||
Default : GE Theta+ version (best)
|
||||
|
|
|
@ -48,16 +48,16 @@ def train_net():
|
|||
parameter_broadcast=True,
|
||||
gradients_mean=True)
|
||||
init()
|
||||
prefix = 'cityscapes.mindrecord'
|
||||
prefix = 'cityscapes-2975.mindrecord'
|
||||
mindrecord_dir = cfg['train']["mindrecord_dir"]
|
||||
mindrecord_file = os.path.join(mindrecord_dir, prefix + '2975')
|
||||
mindrecord_file = os.path.join(mindrecord_dir, prefix)
|
||||
dataset = create_icnet_dataset(mindrecord_file, batch_size=cfg['train']["train_batch_size_percard"],
|
||||
device_num=device_num, rank_id=device_id)
|
||||
|
||||
train_data_size = dataset.get_dataset_size()
|
||||
print("data_size", train_data_size)
|
||||
epoch = cfg["train"]["epochs"]
|
||||
network = ICNetdc() # __init__
|
||||
network = ICNetdc(pretrained_path=cfg["train"]["pretrained_model_path"]) # __init__
|
||||
|
||||
iters_per_epoch = train_data_size
|
||||
total_train_steps = iters_per_epoch * epoch
|
||||
|
@ -85,7 +85,8 @@ if __name__ == '__main__':
|
|||
from src.cityscapes_mindrecord import create_icnet_dataset
|
||||
from src.models.icnet_dc import ICNetdc
|
||||
from src.lr_scheduler import poly_lr
|
||||
config_path = args_opt.project_path + "src/model_utils/icnet.yaml"
|
||||
config_file = "src/model_utils/icnet.yaml"
|
||||
config_path = os.path.join(args_opt.project_path, config_file)
|
||||
with open(config_path, "r") as yaml_file:
|
||||
cfg = yaml.load(yaml_file.read())
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
|
Loading…
Reference in New Issue