push icnet code

This commit is contained in:
xinping li 2021-07-21 09:46:03 +08:00
parent 5faf074413
commit f4eebf243c
12 changed files with 79 additions and 46 deletions

View File

@ -8,6 +8,7 @@
- [Script and Sample Code](#script-and-sample-code) - [Script and Sample Code](#script-and-sample-code)
- [Script Parameters](#script-parameters) - [Script Parameters](#script-parameters)
- [Training Process](#training-process) - [Training Process](#training-process)
- [Prepare Dataset](#prepare-dataset)
- [Distributed Training](#distributed-training) - [Distributed Training](#distributed-training)
- [Training Results](#training-results) - [Training Results](#training-results)
- [Evaluation Process](#evaluation-process) - [Evaluation Process](#evaluation-process)
@ -41,8 +42,8 @@ It contains 5,000 finely annotated images split into training, validation and te
- frame: - frame:
- [Mindspore](https://www.mindspore.cn/install) - [Mindspore](https://www.mindspore.cn/install)
- For details, please refer to the following resources: - For details, please refer to the following resources:
- [MindSpore course](https://www.mindspore.cn/tutorials/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/docs/api/zh-CN/master/index.html) - [MindSpore Python API](https://www.mindspore.cn/doc/api_python/zh-CN/master/index.html)
# [Scription Description](#Content) # [Scription Description](#Content)
@ -88,7 +89,7 @@ It contains 5,000 finely annotated images split into training, validation and te
## Script Parameters ## Script Parameters
Set script parameters in configs/icnet.yaml . Set script parameters in src/model_utils/icnet.yaml .
### Model ### Model
@ -112,22 +113,29 @@ weight_decay: 0.0001
```bash ```bash
train_batch_size_percard: 4 train_batch_size_percard: 4
valid_batch_size: 1 valid_batch_size: 1
cityscapes_root: "/data/cityscapes/" cityscapes_root: "/data/cityscapes/" # set dataset path
epochs: 160 epochs: 160
val_epoch: 1 # run validation every val-epoch val_epoch: 1
ckpt_dir: "./ckpt/" # ckpt and training log will be saved here ckpt_dir: "./ckpt/" # ckpt and training log will be saved here
mindrecord_dir: '/root/bigpingping/mindrecord' mindrecord_dir: '' # set mindrecord path
pretrained_model_path: '/root/ResNet50V1B-150_625.ckpt' # set the pretrained model path correctly
save_checkpoint_epochs: 5 save_checkpoint_epochs: 5
keep_checkpoint_max: 10 keep_checkpoint_max: 10
``` ```
### Valid ## Training Process
```bash ### Prepare Datast
ckpt_path: "" # set the pretrained model path correctly
- 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 ### Distributed Training

View File

@ -47,7 +47,7 @@ class Evaluator:
self.image_paths, self.mask_paths = _get_city_pairs(config["train"]["cityscapes_root"], "val") self.image_paths, self.mask_paths = _get_city_pairs(config["train"]["cityscapes_root"], "val")
# create network # 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 # load ckpt
ckpt_file_name = args_opt.checkpoint_path ckpt_file_name = args_opt.checkpoint_path
@ -74,6 +74,7 @@ class Evaluator:
mask = self._mask_transform(mask) # mask shape: (H,w) mask = self._mask_transform(mask) # mask shape: (H,w)
image = Tensor(image) image = Tensor(image)
print(image)
expand_dims = ops.ExpandDims() expand_dims = ops.ExpandDims()
image = expand_dims(image, 0) image = expand_dims(image, 0)
@ -163,7 +164,8 @@ if __name__ == '__main__':
from src.metric import SegmentationMetric from src.metric import SegmentationMetric
from src.logger import SetupLogger from src.logger import SetupLogger
# Set config file # 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: with open(config_path, "r") as yaml_file:
cfg = yaml.load(yaml_file.read()) cfg = yaml.load(yaml_file.read())
logger = SetupLogger(name="semantic_segmentation", logger = SetupLogger(name="semantic_segmentation",

View File

@ -106,7 +106,7 @@ if __name__ == '__main__':
from src.metric import SegmentationMetric from src.metric import SegmentationMetric
from src.logger import SetupLogger from src.logger import SetupLogger
# Set config file # 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) config_path = os.path.join(args_opt.project_path, config_file)
with open(config_path, "r") as yaml_file: with open(config_path, "r") as yaml_file:
cfg = yaml.load(yaml_file.read()) cfg = yaml.load(yaml_file.read())

View File

@ -17,20 +17,28 @@
if [ $# != 2 ] if [ $# != 2 ]
then then
echo "==============================================================================================================" 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 "Please run the script as: "
echo "bash scripts/run_distribute_train.sh [RANK_TABLE_FILE] [PROJECT_PATH]" echo "bash scripts/run_distribute_train8p.sh [RANK_TABLE_FILE] [PROJECT_PATH]"
echo "for example: bash run_distribute_train.sh /absolute/path/to/RANK_TABLE_FILE /root/ICNet/" echo "for example: bash script/run_distribute_train8p.sh /absolute/path/to/RANK_TABLE_FILE /root/ICNet/"
echo "==============================================================================================================" echo "=============================================================================================================="
exit 1 exit 1
fi 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 then
echo "error: DATASET_PATH=$PATH1 is not a directory" echo "error: PROJECT_PATH=$PATH2 is not a directory"
exit 1 exit 1
fi fi
@ -51,7 +59,7 @@ do
echo "start training for rank $i, device $DEVICE_ID" echo "start training for rank $i, device $DEVICE_ID"
env > env.log env > env.log
python3 train.py --project_path=$PATH1 > log.txt 2>&1 & python3 train.py --project_path=$PATH2 > log.txt 2>&1 &
cd ../ cd ../
done done

View File

@ -30,6 +30,7 @@ get_real_path(){
PATH1=$(get_real_path $1) PATH1=$(get_real_path $1)
PATH2=$(get_real_path $2) PATH2=$(get_real_path $2)
PATH3=$(get_real_path $3)
if [ ! -d $PATH1 ] if [ ! -d $PATH1 ]
@ -44,9 +45,15 @@ then
exit 1 exit 1
fi fi
if [ ! -d $PATH3 ]
then
echo "error: PROJECT_PATH=$PATH3 is not a directory"
exit 1
fi
ulimit -u unlimited ulimit -u unlimited
export DEVICE_NUM=1 export DEVICE_NUM=1
export DEVICE_ID=$5 export DEVICE_ID=0
export RANK_SIZE=1 export RANK_SIZE=1
export RANK_ID=0 export RANK_ID=0
@ -61,6 +68,6 @@ cp -r ../src ./eval
cd ./eval || exit cd ./eval || exit
env > env.log env > env.log
echo "start evaluation for device $DEVICE_ID" 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 ..

View File

@ -15,6 +15,7 @@
"""Prepare Cityscapes dataset""" """Prepare Cityscapes dataset"""
import os import os
import random import random
import argparse
import numpy as np import numpy as np
from PIL import Image from PIL import Image
from PIL import ImageOps from PIL import ImageOps
@ -27,6 +28,7 @@ import mindspore.dataset.transforms.py_transforms as tc
def _get_city_pairs(folder, split='train'): def _get_city_pairs(folder, split='train'):
"""Return two path arrays of data set img and mask""" """Return two path arrays of data set img and mask"""
def get_path_pairs(image_folder, masks_folder): def get_path_pairs(image_folder, masks_folder):
image_paths = [] image_paths = []
masks_paths = [] masks_paths = []
@ -145,11 +147,10 @@ def _img_mask_transform(img, mask):
return (img, mask) return (img, mask)
def data_to_mindrecord_img(prefix='cityscapes.mindrecord', file_num=1, def data_to_mindrecord_img(prefix='cityscapes-2975.mindrecord', file_num=1,
root='/data/cityscapes/', split='train'): root='./', split='train', mindrecord_dir="./"):
"""to mindrecord""" """to mindrecord"""
mindrecord_dir = '/data/Mindrecord_cityscapes/' mindrecord_path = os.path.join(mindrecord_dir, prefix)
mindrecord_path = os.path.join(mindrecord_dir, prefix + "2975-2")
writter = FileWriter(mindrecord_path, file_num) 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__': 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)

View File

@ -19,10 +19,11 @@ train:
epochs: 160 epochs: 160
val_epoch: 1 # run validation every val-epoch val_epoch: 1 # run validation every val-epoch
ckpt_dir: "./ckpt/" # ckpt and training log will be saved here 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 save_checkpoint_epochs: 5
keep_checkpoint_max: 10 keep_checkpoint_max: 10
### 4.Valid ### 4.Valid
test: test:
ckpt_path: "" # set the pretrained model path correctly ckpt_path: "" # set the pretrained model path correctly

View File

@ -1,4 +1,3 @@
"""__init__""" """__init__"""
from .icnet import ICNet from .icnet import ICNet
from .icnet_dc import ICNetdc from .icnet_dc import ICNetdc
from .icnet_1p import ICNet1p

View File

@ -28,7 +28,7 @@ context.set_context(mode=context.GRAPH_MODE, device_target='Ascend')
class ICNet(nn.Cell): class ICNet(nn.Cell):
"""Image Cascade Network""" """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__() super(ICNet, self).__init__()
self.conv_sub1 = nn.SequentialCell( self.conv_sub1 = nn.SequentialCell(
_ConvBNReLU(3, 32, 3, 2), _ConvBNReLU(3, 32, 3, 2),
@ -38,7 +38,7 @@ class ICNet(nn.Cell):
self.istraining = istraining self.istraining = istraining
self.ppm = PyramidPoolingModule() self.ppm = PyramidPoolingModule()
self.backbone = SegBaseModel() self.backbone = SegBaseModel(root=pretrained_path)
self.head = _ICHead(nclass) self.head = _ICHead(nclass)
@ -232,11 +232,11 @@ class CascadeFeatureFusion24(nn.Cell):
class SegBaseModel(nn.Cell): class SegBaseModel(nn.Cell):
"""Base Model for Semantic Segmentation""" """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__() super(SegBaseModel, self).__init__()
self.nclass = nclass self.nclass = nclass
if backbone == 'resnet50': if backbone == 'resnet50':
self.pretrained = get_resnet50v1b() self.pretrained = get_resnet50v1b(ckpt_root=root)
def construct(self, x): def construct(self, x):
"""forwarding pre-trained network""" """forwarding pre-trained network"""

View File

@ -28,7 +28,7 @@ context.set_context(mode=context.GRAPH_MODE, device_target='Ascend')
class ICNetdc(nn.Cell): class ICNetdc(nn.Cell):
"""Image Cascade Network""" """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__() super(ICNetdc, self).__init__()
self.conv_sub1 = nn.SequentialCell( self.conv_sub1 = nn.SequentialCell(
_ConvBNReLU(3, 32, 3, 2), _ConvBNReLU(3, 32, 3, 2),
@ -38,7 +38,7 @@ class ICNetdc(nn.Cell):
self.istraining = istraining self.istraining = istraining
self.ppm = PyramidPoolingModule() self.ppm = PyramidPoolingModule()
self.backbone = SegBaseModel() self.backbone = SegBaseModel(root=pretrained_path)
self.head = _ICHead(nclass) self.head = _ICHead(nclass)
@ -235,11 +235,11 @@ class CascadeFeatureFusion24(nn.Cell):
class SegBaseModel(nn.Cell): class SegBaseModel(nn.Cell):
"""Base Model for Semantic Segmentation""" """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__() super(SegBaseModel, self).__init__()
self.nclass = nclass self.nclass = nclass
if backbone == 'resnet50': if backbone == 'resnet50':
self.pretrained = get_resnet50v1b() self.pretrained = get_resnet50v1b(ckpt_root=root)
def construct(self, x): def construct(self, x):
"""forwarding pre-trained network""" """forwarding pre-trained network"""

View File

@ -258,7 +258,7 @@ class Resnet50v1b(nn.Cell):
return out 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. Get SE-ResNet50 neural network.
Default : GE Theta+ version (best) Default : GE Theta+ version (best)

View File

@ -48,16 +48,16 @@ def train_net():
parameter_broadcast=True, parameter_broadcast=True,
gradients_mean=True) gradients_mean=True)
init() init()
prefix = 'cityscapes.mindrecord' prefix = 'cityscapes-2975.mindrecord'
mindrecord_dir = cfg['train']["mindrecord_dir"] 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"], dataset = create_icnet_dataset(mindrecord_file, batch_size=cfg['train']["train_batch_size_percard"],
device_num=device_num, rank_id=device_id) device_num=device_num, rank_id=device_id)
train_data_size = dataset.get_dataset_size() train_data_size = dataset.get_dataset_size()
print("data_size", train_data_size) print("data_size", train_data_size)
epoch = cfg["train"]["epochs"] epoch = cfg["train"]["epochs"]
network = ICNetdc() # __init__ network = ICNetdc(pretrained_path=cfg["train"]["pretrained_model_path"]) # __init__
iters_per_epoch = train_data_size iters_per_epoch = train_data_size
total_train_steps = iters_per_epoch * epoch total_train_steps = iters_per_epoch * epoch
@ -85,7 +85,8 @@ if __name__ == '__main__':
from src.cityscapes_mindrecord import create_icnet_dataset from src.cityscapes_mindrecord import create_icnet_dataset
from src.models.icnet_dc import ICNetdc from src.models.icnet_dc import ICNetdc
from src.lr_scheduler import poly_lr 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: with open(config_path, "r") as yaml_file:
cfg = yaml.load(yaml_file.read()) cfg = yaml.load(yaml_file.read())
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)