add dncc to model zoo

This commit is contained in:
chen-yiqiang 2021-05-31 22:25:03 +08:00
parent 303d4857e8
commit 288e51b623
9 changed files with 712 additions and 0 deletions

View File

@ -0,0 +1,139 @@
### 目录
[TOC]
### DnCNN描述
DnCNN是一个使用FCN处理图像降噪任务的模型 本项目是图像去躁模型DnCNN在mindspore上的复现。
论文\: Zhang, K., Zuo, W., Chen, Y., Meng, D., & Zhang, L. (2017). Beyond a gaussian denoiser: Residual learning of deep cnn for image denoising. IEEE transactions on image processing, 26(7), 3142-3155.
### 模型结构
网络由N层convolution block组成。其中第一层是conv加reLU中间n-2层是conv+BN+ReLU最后一层是单独的conv
### 数据集
训练集DnCNN-S、DnCNN-B使用BSD500中的400张图片
DnCNN-3使用BSD500中的200张图片和T91中的91张图片
测试集包括BDS68Set5 Set14 clasic5 live1等
### 环境要求
mindspore=1.1
skimage=0.18.1
numpy
PIL
opencv
argparse
### 快速入门
通过官方网站安装MindSpore后您可以按照如下步骤进行训练和评估
```bash
# 训练示例
python train.py --dataset_path=/path/to/training/data --model_type DnCNN-S --ckpt-prefix=DnCNN-S_25noise --noise_level=25
# 或者
sh ./scripts/run_train_gpu.sh /path/to/training/data DnCNN-S DnCNN-S_25noise 25
# 评估示例
python eval.py --dataset_path=/path/to/test/data --ckpt_path=./ckpt/DnCNN-S-50_1800.ckpt --model_type=DnCNN-S --noise_level=25 --noise_type=denoise
# 或者
sh ./scripts/run_eval_gpu.sh /path/to/test/data ./ckpt/DnCNN-S-50_1800.ckpt DnCNN-S 25 denoise
```
### 脚本说明
├── readme.md
├── scripts
│ ├── run_eval_gpu.sh //训练shell脚本
│ └── run_train_gpu.sh //评估shell脚本
├── src
│ ├── dataset.py //数据读取
│ └──model.py //模型定义
├── eval.py //评估脚本
├── export.py //导出模型
└── train.py //训练脚本
### 训练过程
可通过`train.py`脚本中的参数修改训练行为。`train.py`脚本中的参数如下:
#### 训练参数
--dataset_path 训练数据路径
--model_type 模型类型 = ['DnCNN-S', 'DnCNN-B', 'DnCNN-3']
--ckpt-prefix 检查点前缀
--noise_level 噪音等级
--batch_size 批次大小
--lr 学习率
--epoch_num 轮次数
#### 默认训练参数
optimizer=adam
learning rate=0.001
batch_size=128
weight_decay=0.0001
epoch=50
#### 训练
只有DnCNN-S 需要指定noise_level
```python
python train.py --dataset_path=/path/to/training/data --model_type=DnCNN-S --ckpt-prefix=DnCNN-S_25noise --noise_level=25
python train.py --dataset_path=/path/to/training/data --model_type=DnCNN-B --ckpt-prefix=DnCNN-B
python train.py --dataset_path=/path/to/training/data --model_type=DnCNN-3 --ckpt-prefix=DnCNN-3
```
在ckpt文件夹下保存检查点
### 评估过程
评估需要通过命令行提供以下参数:
--dataset_path 数据路径
--ckpt_path 检查点路径
--model_type 模型类型
--noise_type 噪音类型, 通过noise_type选择图像测试噪音的类型["denoise", "super-resolution","jpeg-deblock"]
--noise_level 噪音等级对应三种noise type的强度噪音sigma/下采样上采样scale/jpeg压缩quality
ex:
```python
python eval.py --dataset_path=/path/to/test/data --ckpt_path=./ckpt/DnCNN-B-50_3000.ckpt --model_type=DnCNN-B --noise_level=50 --noise_type=denoise
```
### 模型描述
#### 训练准确率结果
| 参数 | GPU |
| ------------- | -------------------------------------------------------- |
| 模型版本 | DnCNN-S |
| 资源 | Nvidia V100 |
| mindspore版本 | mindspore 1.1 |
| 数据集 | Berkeley Segmentation Datase |
| 轮次 | 50 |
| 输出 | noise残差 |
| 性能 | 在BSD68测试PSNR=32.92(σ=15) 31.73(σ=25)30.59(σ=50) |
#### 训练性能结果
| 参数 | GPU |
| ------------- | ---------------------------------- |
| 模型版本 | DnCNN-S |
| 资源 | Nvidia V100 |
| mindspore版本 | mindspore 1.1 |
| 训练参数 | lr 0.001, batch_size 128, epoch 50 |
| 优化器 | adam |
| 损失函数 | MSE |
| 输出 | noise残差 |
| 速度 | 320ms/batch |
| 总时长 | 7h9min |
| 检查点 | 6.38M |

View File

@ -0,0 +1,146 @@
#!/usr/bin/env python3
# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
import os
import io
import argparse
import glob
import PIL
import numpy as np
import cv2
import skimage.metrics
import mindspore
import mindspore.dataset as ds
from mindspore import context
from mindspore.train.serialization import load_checkpoint, load_param_into_net
import mindspore.dataset.transforms.c_transforms as C
from src.model import DnCNN
class DnCNN_eval_Dataset():
def __init__(self, dataset_path, task_type, noise_level):
self.im_list = []
self.im_list.extend(glob.glob(os.path.join(dataset_path, "*.png")))
self.im_list.extend(glob.glob(os.path.join(dataset_path, "*.bmp")))
self.im_list.extend(glob.glob(os.path.join(dataset_path, "*.jpg")))
self.task_type = task_type
self.noise_level = noise_level
def __getitem__(self, i):
img = cv2.imread(self.im_list[i], 0)
if self.task_type == "denoise":
noisy = self.add_noise(img, self.noise_level)
elif self.task_type == "super-resolution":
h, w = img.shape
noisy = cv2.resize(img, (int(w/self.noise_level), int(h/self.noise_level)))
noisy = cv2.resize(noisy, (w, h))
elif self.task_type == "jpeg-deblock":
noisy = self.jpeg_compression(img, self.noise_level)
#add channel dimension
noisy = noisy[np.newaxis, :, :]
noisy = noisy / 255.0
return noisy, img
def __len__(self):
return len(self.im_list)
def add_noise(self, im, sigma):
gauss = np.random.normal(0, sigma, im.shape)
noisy = im + gauss
noisy = np.clip(noisy, 0, 255)
noisy = noisy.astype('float32')
return noisy
def jpeg_compression(self, img, severity):
im_pil = PIL.Image.fromarray(img)
output = io.BytesIO()
im_pil.save(output, 'JPEG', quality=severity)
im_pil = PIL.Image.open(output)
img_np = np.asarray(im_pil)
return img_np
def create_eval_dataset(data_path, task_type, noise_level, batch_size=1):
# define dataset
dataset = DnCNN_eval_Dataset(data_path, task_type, noise_level)
dataloader = ds.GeneratorDataset(dataset, ["noisy", "clear"])
# apply map operations on images
dataloader = dataloader.map(input_columns="noisy", operations=C.TypeCast(mindspore.float32))
dataloader = dataloader.map(input_columns="clear", operations=C.TypeCast(mindspore.uint8))
dataloader = dataloader.batch(batch_size, drop_remainder=False)
return dataloader
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="DnCNN")
parser.add_argument("--dataset_path", type=str, default="/code/12imgs-TestingSet/", help='eval image path')
parser.add_argument('--ckpt_path', type=str, default=False, help='trained ckpt')
parser.add_argument('--model_type', type=str, default='DnCNN-S', \
choices=['DnCNN-S', 'DnCNN-B', 'DnCNN-3'], help='type of DnCNN')
parser.add_argument('--noise_type', type=str, default=False, \
choices=["denoise", "super-resolution", "jpeg-deblock"], help='trained ckpt')
parser.add_argument('--noise_level', type=int, default=False, help='trained ckpt')
args = parser.parse_args()
context.set_context(mode=context.GRAPH_MODE, device_target="GPU")
ds_eval = create_eval_dataset(args.dataset_path, args.noise_type, args.noise_level, batch_size=1)
print("evaluation image number:", ds_eval.get_dataset_size())
if args.model_type == 'DnCNN-S':
network = DnCNN(1, num_of_layers=17)
elif args.model_type == 'DnCNN-3' or args.model_type == 'DnCNN-B':
network = DnCNN(1, num_of_layers=20)
else:
print("wrong model type")
exit()
# load parameter to the network
param_dict = load_checkpoint(args.ckpt_path)
load_param_into_net(network, param_dict)
mean_psnr = 0
mean_ssim = 0
count = 0
for data in ds_eval.create_dict_iterator():
clear = data["clear"].asnumpy()
#get denoised image
residual = network(data["noisy"]).asnumpy() * 255
noisy_img = data["noisy"].asnumpy() * 255
denoised = np.clip(noisy - residual, 0, 255).astype("uint8")
denoised = np.squeeze(denoised)
clear = np.squeeze(clear)
noisy_img = np.squeeze(noisy_img)
if count == 0: #save example result
cv2.imwrite("noisy.jpg", noisy_img.astype("uint8"))
cv2.imwrite("denoised.jpg", denoised)
cv2.imwrite("original.jpg", clear)
#calculate psnr
mse = np.mean((clear - denoised)**2)
psnr = 10*np.log10(255*255/mse)
#calculate ssim
ssim = skimage.metrics.structural_similarity(clear, denoised, data_range=255) #skimage 0.18
mean_psnr += psnr
mean_ssim += ssim
count += 1
mean_psnr = mean_psnr / count
mean_ssim = mean_ssim / count
print("mean psnr", mean_psnr)
print("mean_ssim", mean_ssim)

View File

@ -0,0 +1,52 @@
#!/usr/bin/env python3
# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
import argparse
import numpy as np
import mindspore as ms
from mindspore import Tensor, load_checkpoint, load_param_into_net, export, context
from src.model import DnCNN
parser = argparse.ArgumentParser(description='DnCNN')
parser.add_argument("--batch_size", type=int, default=1, help="batch size")
parser.add_argument("--image_height", type=int, default=256, help="image_height")
parser.add_argument("--image_width", type=int, default=256, help="image_width")
parser.add_argument("--ckpt_file", type=str, required=True, help="Checkpoint file path.")
parser.add_argument("--file_name", type=str, default="DnCNN", help="output file name.")
parser.add_argument('--file_format', type=str, choices=["AIR", "ONNX", "MINDIR"], default='MINDIR', help='file format')
parser.add_argument('--model_type', type=str, default='DnCNN-S', \
choices=['DnCNN-S', 'DnCNN-B', 'DnCNN-3'], help='type of DnCNN')
args = parser.parse_args()
if __name__ == '__main__':
context.set_context(mode=context.GRAPH_MODE, device_target="GPU")
if args.model_type == 'DnCNN-S':
network = DnCNN(1, num_of_layers=17)
elif args.model_type == 'DnCNN-3' or args.model_type == 'DnCNN-B':
network = DnCNN(1, num_of_layers=20)
else:
print("wrong model type")
exit()
param_dict = load_checkpoint(args.ckpt_file)
load_param_into_net(network, param_dict)
input_arr = Tensor(np.ones([args.batch_size, 1, args.image_height, args.image_width]), ms.float32)
export(network, input_arr, file_name=args.file_name, file_format=args.file_format)

View File

@ -0,0 +1,5 @@
mindspore-gpu==1.1.1
numpy==1.17.0
Pillow=6.2.2
opencv-python==4.2.0.34
scikit-image==0.18.1

View File

@ -0,0 +1,16 @@
#!/bin/bash
# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
python eval.py --dataset_path=$1 --ckpt_path=$2 --model_type=$3 --noise_level=$4 --noise_type=$5

View File

@ -0,0 +1,21 @@
#!/bin/bash
# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
if [ "$2" == "DnCNN-S" ]
then
python train.py --dataset_path=$1 --model_type=$2 --ckpt_prefix=$3 --noise_level=$4
else
python train.py --dataset_path=$1 --model_type=$2 --ckpt_prefix=$3
fi

View File

@ -0,0 +1,182 @@
#!/usr/bin/env python3
# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
import os
import random
import glob
import io
import numpy as np
import cv2
import PIL
import mindspore
import mindspore.dataset as ds
import mindspore.dataset.transforms.c_transforms as C
def create_train_dataset(data_path, model_type, noise_level=25, batch_size=128):
# define dataset
if model_type == "DnCNN-S":
dataset = DnCNN_train_Dataset(data_path, model_type, batch_size, noise_level, patch_shape=(40, 40))
if model_type in ["DnCNN-B", "DnCNN-3"]:
dataset = DnCNN_train_Dataset(data_path, model_type, batch_size, patch_shape=(50, 50))
print("total training patch numbers per epoch", len(dataset))
dataloader = ds.GeneratorDataset(dataset, ["noisy", "gt"])
# apply map operations on images
dataloader = dataloader.map(input_columns="noisy", operations=C.TypeCast(mindspore.float32))
dataloader = dataloader.map(input_columns="gt", operations=C.TypeCast(mindspore.float32))
# apply DatasetOps
dataloader = dataloader.shuffle(buffer_size=10000)
dataloader = dataloader.batch(batch_size, drop_remainder=True)
dataloader = dataloader.repeat(1) #here 400 images as an epoch , on the paper 128x1600 patches as a epoch
return dataloader
class DnCNN_train_Dataset():
def __init__(self, dataset_path, model_type, batch_size=128, noise_level=25, \
image_shape=(180, 180), patch_shape=(50, 50)):
#DnCNN-S/B uses 200 training and 200 test images in BDS500 as training set
#DnCNN-3 uses 200 training images in BDS500 and T91 images as training set
self.im_list = []
self.im_list.extend(glob.glob(os.path.join(dataset_path, "*/*.jpg")))
self.im_list.extend(glob.glob(os.path.join(dataset_path, "*/*.bmp")))
self.im_list.extend(glob.glob(os.path.join(dataset_path, "*/*.png")))
self.patch_shape = patch_shape
self.image_shape = image_shape
self.batch_size = batch_size
self.model_type = model_type
self.noise_level = noise_level
self.scales = [0.8, 1, 1.25]
self.sr_scales = [2, 3, 4]
self.compression_range = (5, 100)
self.sigma_range = (0, 55)
def __getitem__(self, i):
i = i % len(self.im_list)
img = cv2.imread(self.im_list[i], 0)
#random scale
scale = random.choice(self.scales)
img_h = int(self.image_shape[1]*scale)
img_w = int(self.image_shape[0]*scale)
img = cv2.resize(img, (img_w, img_h))
#crop random patch
start_w = random.randint(0, img_w - self.patch_shape[0])
start_h = random.randint(0, img_h - self.patch_shape[1])
patch = img[start_h:start_h+self.patch_shape[1], start_w:start_w+self.patch_shape[0]]
#random flip & rotation
patch = self.data_augment(patch)
#add noise
if self.model_type == "DnCNN-S":
#add specific level of noise
noisy = self.add_noise(patch, self.noise_level)
elif self.model_type == "DnCNN-B":
#add random level of noise
sigma = random.uniform(*self.sigma_range)
noisy = self.add_noise(patch, sigma)
elif self.model_type == "DnCNN-3":
#randomly add noise, down-up sampling blur and jpeg bloc
noisy = self.add_random_type_noise(patch)
else:
print("wrong type")
exit()
noise = np.float32(noisy) - np.float32(patch)
#add channel dimension
noisy = noisy[np.newaxis, :, :]
noise = noise[np.newaxis, :, :]
#normalize
noisy = noisy / 255.0
noise = noise / 255.0
return noisy, noise
def __len__(self):
#To build the same epoch size as original paper
#on the paper, DnCNN-S has 1600 iteratisons per epoch
#DnCNN-B has 3000 and DnCNN-3 has 8000
if self.model_type == "DnCNN-S":
epoch_size = self.batch_size * 1600
elif self.model_type == "DnCNN-B":
epoch_size = self.batch_size * 3000
elif self.model_type == "DnCNN-3":
epoch_size = self.batch_size * 8000
else:
print("wrong model type")
exit()
return epoch_size
def data_augment(self, patch):
#random flip & rotation
if random.random() < 0.5:
patch = np.fliplr(patch)
if random.random() < 0.5:
patch = np.flipud(patch)
alea = random.random()
if alea > 0.25:
patch = np.rot90(patch)
elif alea > 0.5:
patch = np.rot90(patch, k=2)
elif alea > 0.75:
patch = np.rot90(patch, k=3)
return patch
def add_random_type_noise(self, patch):
#random noise/down-up resampling/JPEG compression
alea = random.random()
if alea < 0.33: #generate noisy image
sigma = random.uniform(*self.sigma_range)
noisy = self.add_noise(patch, sigma)
elif alea < 0.66: #generate blur image
sr_scale = random.choice(self.sr_scales)
noisy = cv2.resize(patch, (int(self.patch_shape[0]/sr_scale), int(self.patch_shape[1]/sr_scale)))
noisy = cv2.resize(noisy, (int(self.patch_shape[0]), int(self.patch_shape[1])))
else: #generate JPEG blocking image
compression_level = random.randint(*self.compression_range)
noisy = self.jpeg_compression(patch, compression_level)
return noisy
def add_noise(self, im, sigma):
gauss = np.random.normal(0, sigma, self.patch_shape)
noisy = im + gauss
noisy = np.clip(noisy, 0, 255)
noisy = noisy.astype('uint8')
return noisy
def jpeg_compression(self, img, quality):
im_pil = PIL.Image.fromarray(img)
output = io.BytesIO()
im_pil.save(output, 'JPEG', quality=quality)
im_pil = PIL.Image.open(output)
img_np = np.asarray(im_pil)
return img_np
if __name__ == "__main__":
#only for test
test_dataset_path = "/code/BSR_bsds500/BSR/BSDS500/data/images/"
ds_train = create_train_dataset(test_dataset_path, "DnCNN-S", batch_size=128)
print("batch number:", ds_train.get_dataset_size())
for data in ds_train.create_dict_iterator():
print(type(data))
print(data["noisy"].shape)
print(data["gt"].shape)
print(type(data["noisy"]))
break

View File

@ -0,0 +1,59 @@
#!/usr/bin/env python3
# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
import numpy as np
import mindspore
import mindspore.nn as nn
from mindspore import context
from mindspore import Tensor
from mindspore.common.initializer import HeUniform
class DnCNN(nn.Cell):
def __init__(self, channels, num_of_layers=20):
super(DnCNN, self).__init__()
kernel_size = 3
padding = 1
features = 64
layers = []
layers.append(nn.Conv2d(channels, out_channels=features, kernel_size=kernel_size, \
pad_mode='pad', padding=padding, has_bias=False, weight_init=HeUniform()))
layers.append(nn.ReLU())
for _ in range(num_of_layers-2):
layers.append(nn.Conv2d(features, out_channels=features, kernel_size=kernel_size, \
pad_mode='pad', padding=padding, has_bias=False, weight_init=HeUniform()))
layers.append(nn.BatchNorm2d(features))
layers.append(nn.ReLU())
layers.append(nn.Conv2d(features, out_channels=channels, kernel_size=kernel_size, \
pad_mode='pad', padding=padding, has_bias=False, weight_init=HeUniform()))
self.dncnn = nn.SequentialCell(layers)
def construct(self, x):
out = self.dncnn(x)
return out
if __name__ == "__main__":
#for test
context.set_context(mode=context.GRAPH_MODE, device_target='GPU')
net = DnCNN(1, num_of_layers=17)
a = Tensor(np.ones((2, 1, 40, 40)), mindspore.float32)
output = net(a)
print(output)
print(type(output))
np_out = output.asnumpy()
print(type(np_out))

View File

@ -0,0 +1,92 @@
#!/usr/bin/env python3
# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
import argparse
import datetime
import mindspore.nn as nn
from mindspore import context
from mindspore.train.callback import ModelCheckpoint, CheckpointConfig, LossMonitor, LearningRateScheduler
from mindspore.train import Model
from mindspore.train.callback import Callback
from src.dataset import create_train_dataset
from src.model import DnCNN
class BatchAverageMSELoss(nn.Cell):
def __init__(self, batch_size):
super(BatchAverageMSELoss, self).__init__()
self.batch_size = batch_size
self.sumMSELoss = nn.MSELoss(reduction='sum')
def construct(self, logits, labels):
#equation 1 on the paper
loss = self.sumMSELoss(logits, labels) / self.batch_size / 2
return loss
class Print_info(Callback):
def epoch_end(self, run_context):
cb_params = run_context.original_args()
print(datetime.datetime.now(), "end epoch", cb_params.cur_epoch_num)
def learning_rate_function(lr, cur_step_num):
if cur_step_num % 40000 == 0:
lr = lr*0.8
print("current lr: ", str(lr))
return lr
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="DnCNN")
parser.add_argument("--dataset_path", type=str, default="/code/BSR_bsds500/BSR/BSDS500/data/images/", \
help='training image path')
parser.add_argument("--batch_size", type=int, default=128, help='training batch size')
parser.add_argument('--lr', type=float, default=0.001, help='learning rate')
parser.add_argument('--weight_decay', type=float, default=0.0001, help='weight_decay')
parser.add_argument('--model_type', type=str, default='DnCNN-S', \
choices=['DnCNN-S', 'DnCNN-B', 'DnCNN-3'], help='type of DnCNN')
parser.add_argument('--noise_level', type=int, default=25, help="noise level only for DnCNN-S")
parser.add_argument('--ckpt_prefix', type=str, default="dncnn_mindspore", help='ckpt name prefix')
parser.add_argument('--epoch_num', type=int, default=50, help='epoch number')
args = parser.parse_args()
context.set_context(mode=context.GRAPH_MODE, device_target="GPU")
if args.model_type == 'DnCNN-S':
network = DnCNN(1, num_of_layers=17)
elif args.model_type == 'DnCNN-3' or args.model_type == 'DnCNN-B':
network = DnCNN(1, num_of_layers=20)
else:
print("wrong model type")
exit()
ds_train = create_train_dataset(args.dataset_path, args.model_type, noise_level=args.noise_level, \
batch_size=args.batch_size)
opt = nn.AdamWeightDecay(network.trainable_params(), args.lr, weight_decay=args.weight_decay)
loss_fun = BatchAverageMSELoss(args.batch_size)
model = Model(network, loss_fun, opt)
#training callbacks
checkpoint_config = CheckpointConfig(save_checkpoint_steps=1000, keep_checkpoint_max=3)
ckpoint_cb = ModelCheckpoint(prefix=args.ckpt_prefix, directory='./ckpt/', config=checkpoint_config)
print_cb = Print_info()
lr_cb = LearningRateScheduler(learning_rate_function)
loss_monitor_cb = LossMonitor(per_print_times=100)
print(datetime.datetime.now(), " training starts")
model.train(args.epoch_num, ds_train, callbacks=[lr_cb, ckpoint_cb, print_cb, loss_monitor_cb], \
dataset_sink_mode=False)