【飞桨模型复现计划】SRCNN网络-超分辨率重建

项目简介

本项目是paperweekly paddlepaddle复现活动的第23篇论文《Single Image Super-Resolution Using Deep Learning》的复现代码。 论文主要介绍了图像超分辨率重建的DNN方法,SRCNN网络。本代码复现了基础模型、修改网络大小的结果和3通道RGB模型的结果,并展示经过超分辨率重建后的图片。

In[1]

# 查看当前挂载的数据集目录 
!ls /home/aistudio/data/
data863  data904

In[2]

# 查看个人持久化工作区文件
!rm -rf /home/aistudio/work/*
!ls /home/aistudio/work/

解压数据集

In[3]

# 这个cell的代码只有第一次运行时需要执行
import os
os.mkdir('/home/aistudio/work/model')    # 用于存储训练好的模型文件
os.mkdir('/home/aistudio/work/model_3d')    # 用于存储训练好的3d模型文件
os.mkdir('/home/aistudio/work/model_fz')    # 用于存储训练好的fz模型文件
os.mkdir('/home/aistudio/work/dataset')    # 用于存放所有的数据集
os.mkdir('/home/aistudio/work/dataset/timofte')    # 91图训练集
# 解压训练集图片
os.chdir('/home/aistudio/work/dataset/timofte')
os.system('tar -xvf /home/aistudio/data/data863/input_images.tar')
# 解压测试集图片
os.chdir('/home/aistudio/work/dataset')
os.system('tar -xvf /home/aistudio/data/data904/val_dataset.tar')
# 回到工作路径
os.chdir('/home/aistudio')

In[4]

# import 要用的库
import paddle.fluid as fluid
import paddle.v2 as paddle
import numpy as np
import cv2        
import os
from matplotlib import pyplot as plt
%matplotlib inline

baseline model

In[6]

class SRCNN(object):   
    # 只对Y通道做超分辨率重构
    def __init__(self, lr, lr_f, batch_size, iter_num):
        self.lr = lr   # 学习率
        self.lr_f = lr_f  # 最后一层学习率
        self.batch_size = batch_size 
        self.iter_num = iter_num   # 总共训练多少次

    def net(self, X, Y):        
        # 搭建模型           
        conv1 = fluid.layers.conv2d(X, 64, 9,act='relu', name='conv1' , 
                                    param_attr= fluid.ParamAttr(initializer=fluid.initializer.NormalInitializer(scale=0.001),
                                                               name='conv1_w'),
                                    bias_attr=fluid.ParamAttr(initializer=fluid.initializer.ConstantInitializer(value=0.),
                                                               name='conv1_b'))
        conv2 = fluid.layers.conv2d(conv1, 32, 1, act='relu', name='conv2' , 
                                    param_attr= fluid.ParamAttr(initializer=fluid.initializer.NormalInitializer(scale=0.001),
                                                               name='conv2_w'),
                                    bias_attr=fluid.ParamAttr(initializer=fluid.initializer.ConstantInitializer(value=0.),
                                                               name='conv2_b'))
        pred = fluid.layers.conv2d(conv2, 1, 5, name='pred', 
                                    param_attr= fluid.ParamAttr(initializer=fluid.initializer.NormalInitializer(scale=0.001),
                                                               name='pred_w'),
                                    bias_attr=fluid.ParamAttr(initializer=fluid.initializer.ConstantInitializer(value=0.),
                                                               name='pred_b'))       
        loss = fluid.layers.reduce_mean(fluid.layers.square(pred - Y))        
        return pred, loss
    
    def train(self):
        # 模型训练
        X_train = fluid.layers.data(shape=[1, 33, 33], dtype='float32', name='image')
        Y_train = fluid.layers.data(shape=[1, 21, 21], dtype='float32', name='gdt')
        y_predict, y_loss = self.net(X_train, Y_train)
        Optimizer = fluid.optimizer.AdamOptimizer(learning_rate=self.lr)
        Optimizer_f = fluid.optimizer.AdamOptimizer(learning_rate=self.lr_f)
        Optimizer.minimize(y_loss, parameter_list=['conv1_w','conv1_b', 'conv2_w', 'conv2_b'])
        Optimizer_f.minimize(y_loss, parameter_list=['pred_w', 'pred_b'])
        
        # 读取训练集数据
        train_reader = paddle.batch(self.read_data('work/dataset/timofte'), batch_size=self.batch_size)        
        
        # 定义执行器
        place = fluid.CPUPlace()
        exe = fluid.Executor(place)
        exe.run(fluid.default_startup_program())
        
        def train_loop(main_program):
            feeder = fluid.DataFeeder(place=place, feed_list=[X_train, Y_train])
            exe.run(fluid.default_startup_program())                
            backprops_cnt = 0  # 论文中作图的横坐标
            self.backprops_cnts = []    # 绑定为类的一个属性,用于画图   
            self.psnr = []          # psnr的值
            for epoch in range(self.iter_num):
                for batch_id, data in enumerate(train_reader()):         
                    loss = exe.run(
                        fluid.framework.default_main_program(),
                        feed=feeder.feed(data),
                        fetch_list=[y_loss])               
                    if batch_id == 0:   #  每个epoch算一下psnr,画图用的
#                         # 算psnr要在测试集上面
                        fluid.io.save_inference_model('work/model/', ['image'], [y_predict], exe)     
                        val_loss, val_psnr = self.validation()
                        self.backprops_cnts.append(backprops_cnt * self.batch_size)          
                        self.psnr.append(val_psnr)
                        print("%i\tEpoch: %d \tCur Cost : %f\t Val Cost: %f\t PSNR :%f" % (backprops_cnt, epoch, np.array(loss[0])[0], val_loss, val_psnr))
                    backprops_cnt += 1            
            fluid.io.save_inference_model('work/model/', ['image'], [y_predict], exe)      
            
        train_loop(fluid.default_main_program())
    
    def validation(self):
        place = fluid.CPUPlace()
        exe = fluid.Executor(place)
        inference_scope = fluid.core.Scope() 
        
        test_set = 'work/dataset/set5/'
        scale_factor = 3      
        for img_name in os.listdir(test_set):  
            img_val = cv2.imread(os.path.join(test_set, img_name))
            yuv = cv2.cvtColor(img_val, cv2.COLOR_BGR2YCrCb)
            img_y, img_u, img_v = cv2.split(yuv)      
            img_h, img_w = img_y.shape
            img_blur = cv2.GaussianBlur(img_y, (5, 5), 0)
            img_subsample = cv2.resize(img_blur, (img_w/scale_factor, img_h/scale_factor))
            img_input = cv2.resize(img_blur, (img_w, img_h), interpolation=cv2.INTER_CUBIC)
            img_input = np.reshape(img_input, [1,1,img_h, img_w]).astype("float32")    # h,w    
            losses = []
            with fluid.scope_guard(inference_scope):
                [inference_program, feed_target_names, fetch_targets] = (
                    fluid.io.load_inference_model('work/model/', exe))  
                results = exe.run(inference_program,
                      feed={feed_target_names[0]: img_input},
                      fetch_list=fetch_targets)[0]
                loss = np.mean(np.square(results[0,0]-img_y[6:-6, 6:-6]))               
                losses.append(loss) 
        avg_loss = np.sum(np.array(losses))/len(losses)
        psnr = 10 * np.log10(255*255/avg_loss)
        return avg_loss,psnr

    def generate_reconstruct_img(self, img_name):        
        place = fluid.CPUPlace()
        exe = fluid.Executor(place)
        inference_scope = fluid.core.Scope()        
        img_test = cv2.imread('work/dataset/set5/%s' % img_name)
        yuv_test = cv2.cvtColor(img_test, cv2.COLOR_BGR2YCrCb)       
        img_h, img_w, img_c = img_test.shape
        print "=====原始图片========="
        b,g,r = cv2.split(img_test)    # AI studio 不支持cv2.imshow,所以用plt.imshow输出,两者rgb顺序不一样
        img_test = cv2.merge([r,g,b])
        plt.imshow(img_test)
        plt.show()        
        #   图像模糊+cubic插值
        img_blur = cv2.GaussianBlur(yuv_test.copy(), (5, 5), 0)
        img_subsample = cv2.resize(img_blur, (img_w/3, img_h/3))   #这里注意cv2.resize里面的shape是w,h的顺序 
        img_cubic = cv2.resize(img_blur, (img_w, img_h), interpolation=cv2.INTER_CUBIC)
        img_y, img_u, img_v = cv2.split(img_cubic)  
        img_input = np.reshape(img_y, [1,1,img_h, img_w]).astype("float32")    # 把y通道作为输入
        with fluid.scope_guard(inference_scope):
            [inference_program, feed_target_names, fetch_targets] = (
                fluid.io.load_inference_model('work/model/', exe))  
            results = exe.run(inference_program,
                  feed={feed_target_names[0]: img_input},
                  fetch_list=fetch_targets)[0]

            result_img = np.array(results)    
            result_img[result_img < 0] = 0
            result_img[result_img >255] = 255
            gap_y = (img_y.shape[0]-result_img.shape[2])/2
            gap_x = (img_y.shape[1]-result_img.shape[3])/2

            print "=====Y通道输入========="
            plt.imshow(img_y, cmap='gray')
            plt.show()

            img_y[gap_y: gap_y + result_img.shape[2],
                 gap_x: gap_x + result_img.shape[3]]=result_img
            img_test_r = cv2.merge([img_y, img_u, img_v])
            img_test_r = cv2.cvtColor(img_test_r, cv2.COLOR_YCrCb2BGR)

            print "=====Y通道输出========="
            plt.imshow(img_y, cmap='gray')            
            plt.show()
            
            print "=====彩图结果========="
            b,g,r = cv2.split(img_test_r)  
            img_test_show = cv2.merge([r,g,b])
            plt.imshow(img_test_show)
            plt.show()

    def read_data(self, data_path):
        def data_reader():
            for image in os.listdir(data_path):
                if image.endswith('.bmp'):
                    img = cv2.imread(os.path.join(data_path, image))
                    yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)
                    img_y, img_u, img_v = cv2.split(yuv)
                    # 下面是切图的步骤
                    j = 0
                    count = 0
                    while j+33 < len(img_y):
                        i = 0
                        while i+33 < len(img_y[0]):
                            img_patch = img_y[j:j+33, i:i+33]
                            img_gth = img_patch[6:27, 6:27].copy()
                            img_blur = cv2.GaussianBlur(img_patch, (5, 5), 0)
                            img_sumsample = cv2.resize(img_blur, (11, 11))
                            img_input = cv2.resize(img_blur, (33, 33), interpolation=cv2.INTER_CUBIC)
                            yield img_input, img_gth
                            i+=14
                        j+= 14
        return data_reader

In[7]

model = SRCNN(0.0001, 0.00001, 100, 150)
model.train()
0	Epoch: 0 	Cur Cost : 18164.226562	 Val Cost: 21233.191406	 PSNR :4.860651
219	Epoch: 1 	Cur Cost : 284.385284	 Val Cost: 417.904175	 PSNR :21.920037
438	Epoch: 2 	Cur Cost : 281.428558	 Val Cost: 413.779419	 PSNR :21.963115
657	Epoch: 3 	Cur Cost : 277.070312	 Val Cost: 406.204071	 PSNR :22.043361
876	Epoch: 4 	Cur Cost : 253.116455	 Val Cost: 372.079315	 PSNR :22.424448
1095	Epoch: 5 	Cur Cost : 207.459930	 Val Cost: 303.296204	 PSNR :23.312134
1314	Epoch: 6 	Cur Cost : 154.225296	 Val Cost: 221.624435	 PSNR :24.674627
1533	Epoch: 7 	Cur Cost : 117.966713	 Val Cost: 165.380890	 PSNR :25.945950
1752	Epoch: 8 	Cur Cost : 114.436462	 Val Cost: 158.598419	 PSNR :26.127815
1971	Epoch: 9 	Cur Cost : 112.926453	 Val Cost: 155.753204	 PSNR :26.206434
2190	Epoch: 10 	Cur Cost : 111.557121	 Val Cost: 153.391846	 PSNR :26.272781
2409	Epoch: 11 	Cur Cost : 110.163071	 Val Cost: 151.123138	 PSNR :26.337494
2628	Epoch: 12 	Cur Cost : 108.720184	 Val Cost: 148.844711	 PSNR :26.403470
2847	Epoch: 13 	Cur Cost : 107.220848	 Val Cost: 146.517197	 PSNR :26.471918
3066	Epoch: 14 	Cur Cost : 105.661781	 Val Cost: 144.118179	 PSNR :26.543616
3285	Epoch: 15 	Cur Cost : 104.040611	 Val Cost: 141.630585	 PSNR :26.619233
3504	Epoch: 16 	Cur Cost : 102.351303	 Val Cost: 139.039047	 PSNR :26.699436
3723	Epoch: 17 	Cur Cost : 100.585503	 Val Cost: 136.326965	 PSNR :26.784986
3942	Epoch: 18 	Cur Cost : 98.731277	 Val Cost: 133.479095	 PSNR :26.876671
4161	Epoch: 19 	Cur Cost : 96.780418	 Val Cost: 130.485748	 PSNR :26.975173
4380	Epoch: 20 	Cur Cost : 94.736946	 Val Cost: 127.345490	 PSNR :27.080968
4599	Epoch: 21 	Cur Cost : 92.607079	 Val Cost: 124.054619	 PSNR :27.194674
4818	Epoch: 22 	Cur Cost : 90.392410	 Val Cost: 120.612396	 PSNR :27.316884
5037	Epoch: 23 	Cur Cost : 88.097008	 Val Cost: 117.033394	 PSNR :27.447706
5256	Epoch: 24 	Cur Cost : 85.727638	 Val Cost: 113.339539	 PSNR :27.586989
5475	Epoch: 25 	Cur Cost : 83.291718	 Val Cost: 109.558945	 PSNR :27.734325
5694	Epoch: 26 	Cur Cost : 80.803673	 Val Cost: 105.716370	 PSNR :27.889381
5913	Epoch: 27 	Cur Cost : 78.289711	 Val Cost: 101.814842	 PSNR :28.052693
6132	Epoch: 28 	Cur Cost : 75.769890	 Val Cost: 97.854851	 PSNR :28.224980
6351	Epoch: 29 	Cur Cost : 73.263191	 Val Cost: 93.865204	 PSNR :28.405757
6570	Epoch: 30 	Cur Cost : 70.802010	 Val Cost: 89.902550	 PSNR :28.593084
6789	Epoch: 31 	Cur Cost : 68.425529	 Val Cost: 86.056076	 PSNR :28.782988
7008	Epoch: 32 	Cur Cost : 66.165245	 Val Cost: 82.378616	 PSNR :28.972659
7227	Epoch: 33 	Cur Cost : 64.029266	 Val Cost: 78.877708	 PSNR :29.161261
7446	Epoch: 34 	Cur Cost : 61.938168	 Val Cost: 75.441162	 PSNR :29.354720
7665	Epoch: 35 	Cur Cost : 59.845867	 Val Cost: 71.962860	 PSNR :29.559719
7884	Epoch: 36 	Cur Cost : 57.924450	 Val Cost: 68.783943	 PSNR :29.755933
8103	Epoch: 37 	Cur Cost : 56.233124	 Val Cost: 65.943611	 PSNR :29.939076
8322	Epoch: 38 	Cur Cost : 54.610748	 Val Cost: 63.266205	 PSNR :30.119086
8541	Epoch: 39 	Cur Cost : 53.087059	 Val Cost: 60.819660	 PSNR :30.290364
8760	Epoch: 40 	Cur Cost : 51.752823	 Val Cost: 58.767235	 PSNR :30.439451
8979	Epoch: 41 	Cur Cost : 50.548962	 Val Cost: 56.994938	 PSNR :30.572441
9198	Epoch: 42 	Cur Cost : 49.409630	 Val Cost: 55.392437	 PSNR :30.696299
9417	Epoch: 43 	Cur Cost : 48.292534	 Val Cost: 53.872486	 PSNR :30.817133
9636	Epoch: 44 	Cur Cost : 47.169697	 Val Cost: 52.356304	 PSNR :30.941114
9855	Epoch: 45 	Cur Cost : 46.026646	 Val Cost: 50.804356	 PSNR :31.071794
10074	Epoch: 46 	Cur Cost : 44.855438	 Val Cost: 49.224430	 PSNR :31.208997
10293	Epoch: 47 	Cur Cost : 43.651192	 Val Cost: 47.612514	 PSNR :31.353592
10512	Epoch: 48 	Cur Cost : 42.413403	 Val Cost: 45.968498	 PSNR :31.506200
10731	Epoch: 49 	Cur Cost : 41.161961	 Val Cost: 44.319637	 PSNR :31.664842
10950	Epoch: 50 	Cur Cost : 39.941639	 Val Cost: 42.723743	 PSNR :31.824111
11169	Epoch: 51 	Cur Cost : 38.763580	 Val Cost: 41.210186	 PSNR :31.980758
11388	Epoch: 52 	Cur Cost : 37.628029	 Val Cost: 39.770855	 PSNR :32.135154
11607	Epoch: 53 	Cur Cost : 36.646980	 Val Cost: 38.539745	 PSNR :32.271715
11826	Epoch: 54 	Cur Cost : 35.795269	 Val Cost: 37.488255	 PSNR :32.391851
12045	Epoch: 55 	Cur Cost : 35.093742	 Val Cost: 36.636829	 PSNR :32.491625
12264	Epoch: 56 	Cur Cost : 34.488441	 Val Cost: 35.905704	 PSNR :32.579169
12483	Epoch: 57 	Cur Cost : 33.963333	 Val Cost: 35.274933	 PSNR :32.656142
12702	Epoch: 58 	Cur Cost : 33.505180	 Val Cost: 34.726208	 PSNR :32.724230
12921	Epoch: 59 	Cur Cost : 33.103012	 Val Cost: 34.243057	 PSNR :32.785078
13140	Epoch: 60 	Cur Cost : 32.750072	 Val Cost: 33.818142	 PSNR :32.839306
13359	Epoch: 61 	Cur Cost : 32.436031	 Val Cost: 33.438747	 PSNR :32.888304
13578	Epoch: 62 	Cur Cost : 32.150639	 Val Cost: 33.090755	 PSNR :32.933737
13797	Epoch: 63 	Cur Cost : 31.886650	 Val Cost: 32.765667	 PSNR :32.976613
14016	Epoch: 64 	Cur Cost : 31.639585	 Val Cost: 32.457993	 PSNR :33.017587
14235	Epoch: 65 	Cur Cost : 31.405382	 Val Cost: 32.163200	 PSNR :33.057211
14454	Epoch: 66 	Cur Cost : 31.181067	 Val Cost: 31.877956	 PSNR :33.095899
14673	Epoch: 67 	Cur Cost : 30.963821	 Val Cost: 31.595957	 PSNR :33.134488
14892	Epoch: 68 	Cur Cost : 30.745806	 Val Cost: 31.313644	 PSNR :33.173467
15111	Epoch: 69 	Cur Cost : 30.530462	 Val Cost: 31.029354	 PSNR :33.213076
15330	Epoch: 70 	Cur Cost : 30.316664	 Val Cost: 30.746445	 PSNR :33.252855
15549	Epoch: 71 	Cur Cost : 30.103735	 Val Cost: 30.461548	 PSNR :33.293284
15768	Epoch: 72 	Cur Cost : 29.889498	 Val Cost: 30.172472	 PSNR :33.334695
15987	Epoch: 73 	Cur Cost : 29.668657	 Val Cost: 29.870338	 PSNR :33.378402
16206	Epoch: 74 	Cur Cost : 29.430288	 Val Cost: 29.451651	 PSNR :33.439707
16425	Epoch: 75 	Cur Cost : 29.207491	 Val Cost: 29.195040	 PSNR :33.477713
16644	Epoch: 76 	Cur Cost : 29.008448	 Val Cost: 28.942610	 PSNR :33.515427
16863	Epoch: 77 	Cur Cost : 28.805315	 Val Cost: 28.677612	 PSNR :33.555374
17082	Epoch: 78 	Cur Cost : 28.597673	 Val Cost: 28.398453	 PSNR :33.597857
17301	Epoch: 79 	Cur Cost : 28.384197	 Val Cost: 28.109222	 PSNR :33.642315
17520	Epoch: 80 	Cur Cost : 28.165312	 Val Cost: 27.810051	 PSNR :33.688786
17739	Epoch: 81 	Cur Cost : 27.941040	 Val Cost: 27.501369	 PSNR :33.737260
17958	Epoch: 82 	Cur Cost : 27.711397	 Val Cost: 27.183748	 PSNR :33.787710
18177	Epoch: 83 	Cur Cost : 27.476480	 Val Cost: 26.856071	 PSNR :33.840379
18396	Epoch: 84 	Cur Cost : 27.235754	 Val Cost: 26.519581	 PSNR :33.895137
18615	Epoch: 85 	Cur Cost : 26.991680	 Val Cost: 26.172489	 PSNR :33.952353
18834	Epoch: 86 	Cur Cost : 26.743433	 Val Cost: 25.811661	 PSNR :34.012644
19053	Epoch: 87 	Cur Cost : 26.480677	 Val Cost: 25.444807	 PSNR :34.074812
19272	Epoch: 88 	Cur Cost : 26.224283	 Val Cost: 25.074034	 PSNR :34.138562
19491	Epoch: 89 	Cur Cost : 25.963892	 Val Cost: 24.700274	 PSNR :34.203786
19710	Epoch: 90 	Cur Cost : 25.710884	 Val Cost: 24.330662	 PSNR :34.269264
19929	Epoch: 91 	Cur Cost : 25.457993	 Val Cost: 23.969437	 PSNR :34.334225
20148	Epoch: 92 	Cur Cost : 25.210745	 Val Cost: 23.615768	 PSNR :34.398783
20367	Epoch: 93 	Cur Cost : 24.963886	 Val Cost: 23.267546	 PSNR :34.463298
20586	Epoch: 94 	Cur Cost : 24.722895	 Val Cost: 22.925728	 PSNR :34.527572
20805	Epoch: 95 	Cur Cost : 24.486914	 Val Cost: 22.588749	 PSNR :34.591882
21024	Epoch: 96 	Cur Cost : 24.253819	 Val Cost: 22.257490	 PSNR :34.656042
21243	Epoch: 97 	Cur Cost : 24.023243	 Val Cost: 21.936876	 PSNR :34.719056
21462	Epoch: 98 	Cur Cost : 23.806646	 Val Cost: 21.630701	 PSNR :34.780098
21681	Epoch: 99 	Cur Cost : 23.600349	 Val Cost: 21.338070	 PSNR :34.839252
21900	Epoch: 100 	Cur Cost : 23.404703	 Val Cost: 21.059601	 PSNR :34.896302
22119	Epoch: 101 	Cur Cost : 23.220484	 Val Cost: 20.796125	 PSNR :34.950979
22338	Epoch: 102 	Cur Cost : 23.047068	 Val Cost: 20.546223	 PSNR :35.003484
22557	Epoch: 103 	Cur Cost : 22.884609	 Val Cost: 20.312155	 PSNR :35.053244
22776	Epoch: 104 	Cur Cost : 22.732927	 Val Cost: 20.091757	 PSNR :35.100624
22995	Epoch: 105 	Cur Cost : 22.590960	 Val Cost: 19.883532	 PSNR :35.145868
23214	Epoch: 106 	Cur Cost : 22.457445	 Val Cost: 19.684614	 PSNR :35.189535
23433	Epoch: 107 	Cur Cost : 22.331661	 Val Cost: 19.496771	 PSNR :35.231177
23652	Epoch: 108 	Cur Cost : 22.212849	 Val Cost: 19.317987	 PSNR :35.271185
23871	Epoch: 109 	Cur Cost : 22.100451	 Val Cost: 19.148111	 PSNR :35.309544
24090	Epoch: 110 	Cur Cost : 21.994497	 Val Cost: 18.987167	 PSNR :35.346202
24309	Epoch: 111 	Cur Cost : 21.894119	 Val Cost: 18.834215	 PSNR :35.381328
24528	Epoch: 112 	Cur Cost : 21.798851	 Val Cost: 18.687769	 PSNR :35.415229
24747	Epoch: 113 	Cur Cost : 21.708071	 Val Cost: 18.547321	 PSNR :35.447992
24966	Epoch: 114 	Cur Cost : 21.621136	 Val Cost: 18.413755	 PSNR :35.479380
25185	Epoch: 115 	Cur Cost : 21.537928	 Val Cost: 18.285975	 PSNR :35.509623
25404	Epoch: 116 	Cur Cost : 21.458000	 Val Cost: 18.164145	 PSNR :35.538654
25623	Epoch: 117 	Cur Cost : 21.381271	 Val Cost: 18.046951	 PSNR :35.566765
25842	Epoch: 118 	Cur Cost : 21.307785	 Val Cost: 17.934608	 PSNR :35.593885
26061	Epoch: 119 	Cur Cost : 21.236940	 Val Cost: 17.827406	 PSNR :35.619922
26280	Epoch: 120 	Cur Cost : 21.168789	 Val Cost: 17.724836	 PSNR :35.644981
26499	Epoch: 121 	Cur Cost : 21.103100	 Val Cost: 17.627266	 PSNR :35.668954
26718	Epoch: 122 	Cur Cost : 21.039707	 Val Cost: 17.533913	 PSNR :35.692015
26937	Epoch: 123 	Cur Cost : 20.978670	 Val Cost: 17.444506	 PSNR :35.714217
27156	Epoch: 124 	Cur Cost : 20.919706	 Val Cost: 17.358051	 PSNR :35.735794
27375	Epoch: 125 	Cur Cost : 20.862633	 Val Cost: 17.275480	 PSNR :35.756502
27594	Epoch: 126 	Cur Cost : 20.807596	 Val Cost: 17.195841	 PSNR :35.776569
27813	Epoch: 127 	Cur Cost : 20.754372	 Val Cost: 17.119400	 PSNR :35.795918
28032	Epoch: 128 	Cur Cost : 20.702871	 Val Cost: 17.045691	 PSNR :35.814658
28251	Epoch: 129 	Cur Cost : 20.652927	 Val Cost: 16.974653	 PSNR :35.832794
28470	Epoch: 130 	Cur Cost : 20.604521	 Val Cost: 16.906082	 PSNR :35.850374
28689	Epoch: 131 	Cur Cost : 20.557560	 Val Cost: 16.840302	 PSNR :35.867305
28908	Epoch: 132 	Cur Cost : 20.511902	 Val Cost: 16.776218	 PSNR :35.883863
29127	Epoch: 133 	Cur Cost : 20.467619	 Val Cost: 16.714396	 PSNR :35.899897
29346	Epoch: 134 	Cur Cost : 20.424440	 Val Cost: 16.654495	 PSNR :35.915489
29565	Epoch: 135 	Cur Cost : 20.382488	 Val Cost: 16.596294	 PSNR :35.930692
29784	Epoch: 136 	Cur Cost : 20.341431	 Val Cost: 16.539652	 PSNR :35.945540
30003	Epoch: 137 	Cur Cost : 20.301138	 Val Cost: 16.484528	 PSNR :35.960039
30222	Epoch: 138 	Cur Cost : 20.261866	 Val Cost: 16.430748	 PSNR :35.974230
30441	Epoch: 139 	Cur Cost : 20.223341	 Val Cost: 16.378759	 PSNR :35.987994
30660	Epoch: 140 	Cur Cost : 20.185614	 Val Cost: 16.328671	 PSNR :36.001295
30879	Epoch: 141 	Cur Cost : 20.148609	 Val Cost: 16.278326	 PSNR :36.014706
31098	Epoch: 142 	Cur Cost : 20.112509	 Val Cost: 16.229719	 PSNR :36.027694
31317	Epoch: 143 	Cur Cost : 20.076233	 Val Cost: 16.180443	 PSNR :36.040900
31536	Epoch: 144 	Cur Cost : 20.039700	 Val Cost: 16.131332	 PSNR :36.054101
31755	Epoch: 145 	Cur Cost : 20.001612	 Val Cost: 16.085133	 PSNR :36.066557
31974	Epoch: 146 	Cur Cost : 19.969093	 Val Cost: 16.049982	 PSNR :36.076058
32193	Epoch: 147 	Cur Cost : 19.926191	 Val Cost: 15.993620	 PSNR :36.091336
32412	Epoch: 148 	Cur Cost : 19.890646	 Val Cost: 15.950057	 PSNR :36.103181
32631	Epoch: 149 	Cur Cost : 19.856085	 Val Cost: 15.906347	 PSNR :36.115099

In[8]

# 绘制训练曲线
plt.plot(model.backprops_cnts,model.psnr)
[]

【飞桨模型复现计划】SRCNN网络-超分辨率重建_第1张图片

In[9]

model.generate_reconstruct_img('butterfly_GT.bmp')
=====原始图片=========

【飞桨模型复现计划】SRCNN网络-超分辨率重建_第2张图片

=====Y通道输入=========

【飞桨模型复现计划】SRCNN网络-超分辨率重建_第3张图片

=====Y通道输出=========

【飞桨模型复现计划】SRCNN网络-超分辨率重建_第4张图片

=====彩图结果=========

【飞桨模型复现计划】SRCNN网络-超分辨率重建_第5张图片

In[10]

model.generate_reconstruct_img('baby_GT.bmp')
=====原始图片=========

【飞桨模型复现计划】SRCNN网络-超分辨率重建_第6张图片

=====Y通道输入=========

【飞桨模型复现计划】SRCNN网络-超分辨率重建_第7张图片

=====Y通道输出=========

【飞桨模型复现计划】SRCNN网络-超分辨率重建_第8张图片

=====彩图结果=========

【飞桨模型复现计划】SRCNN网络-超分辨率重建_第9张图片

In[11]

class SRCNN_fz(object):   
    # 只对Y通道做超分辨率重构
    def __init__(self, lr, lr_f, batch_size, iter_num):
        self.lr = lr   # 学习率
        self.lr_f = lr_f
        self.batch_size = batch_size 
        self.iter_num = iter_num   # 总共训练多少次

    def net(self, X, Y):        
        # 搭建模型           
        conv1 = fluid.layers.conv2d(X, 64, 9,act='relu', name='conv1' , 
                                    param_attr= fluid.ParamAttr(initializer=fluid.initializer.NormalInitializer(scale=0.001),
                                                               name='conv1_w'),
                                    bias_attr=fluid.ParamAttr(initializer=fluid.initializer.ConstantInitializer(value=0.),
                                                               name='conv1_b'))
        conv2 = fluid.layers.conv2d(conv1, 32, 3, act='relu', name='conv2' , 
                                    param_attr= fluid.ParamAttr(initializer=fluid.initializer.NormalInitializer(scale=0.001),
                                                               name='conv2_w'),
                                    bias_attr=fluid.ParamAttr(initializer=fluid.initializer.ConstantInitializer(value=0.),
                                                               name='conv2_b'))
        pred = fluid.layers.conv2d(conv2, 1, 5, name='pred', 
                                    param_attr= fluid.ParamAttr(initializer=fluid.initializer.NormalInitializer(scale=0.001),
                                                               name='pred_w'),
                                    bias_attr=fluid.ParamAttr(initializer=fluid.initializer.ConstantInitializer(value=0.),
                                                               name='pred_b'))       
        loss = fluid.layers.reduce_mean(fluid.layers.square(pred - Y))        
        return pred, loss
    
    def train(self):
        # 模型训练
        X_train = fluid.layers.data(shape=[1, 33, 33], dtype='float32', name='image')
        Y_train = fluid.layers.data(shape=[1, 19, 19], dtype='float32', name='gdt')
        y_predict, y_loss = self.net(X_train, Y_train)
        Optimizer = fluid.optimizer.AdamOptimizer(learning_rate=self.lr)
        Optimizer_f = fluid.optimizer.AdamOptimizer(learning_rate=self.lr_f)
        Optimizer.minimize(y_loss, parameter_list=['conv1_w','conv1_b', 'conv2_w', 'conv2_b'])
        Optimizer_f.minimize(y_loss, parameter_list=['pred_w', 'pred_b'])
        
        # 读取训练集数据
        train_reader = paddle.batch(self.read_data('work/dataset/timofte'), batch_size=self.batch_size)        
        
        # 定义执行器
        place = fluid.CPUPlace()
        exe = fluid.Executor(place)
        exe.run(fluid.default_startup_program())
        
        def train_loop(main_program):
            feeder = fluid.DataFeeder(place=place, feed_list=[X_train, Y_train])
            exe.run(fluid.default_startup_program())                
            backprops_cnt = 0  # 论文中作图的横坐标
            self.backprops_cnts = []    # 绑定为类的一个属性,用于画图   
            self.psnr = []          # psnr的值
            for epoch in range(self.iter_num):
                for batch_id, data in enumerate(train_reader()):         
                    loss = exe.run(
                        fluid.framework.default_main_program(),
                        feed=feeder.feed(data),
                        fetch_list=[y_loss])                 
                    if batch_id == 0:   #  每个epoch算一下psnr,画图用的
#                         # 算psnr要在测试集上面
                        fluid.io.save_inference_model('work/model_fz/', ['image'], [y_predict], exe)     
                        val_loss, val_psnr = self.validation()
                        self.backprops_cnts.append(backprops_cnt * self.batch_size)          
                        self.psnr.append(val_psnr)
                        print("%i\tEpoch: %d \tCur Cost : %f\t Val Cost: %f\t PSNR :%f" % (backprops_cnt, epoch, np.array(loss[0])[0], val_loss, val_psnr))
                    backprops_cnt += 1            
            fluid.io.save_inference_model('work/model_fz/', ['image'], [y_predict], exe)      
            
        train_loop(fluid.default_main_program())
    
    def validation(self):
        place = fluid.CPUPlace()
        exe = fluid.Executor(place)
        inference_scope = fluid.core.Scope() 
        
        test_set = 'work/dataset/set5/'
        scale_factor = 3      
        for img_name in os.listdir(test_set):  
            img_val = cv2.imread(os.path.join(test_set, img_name))
            yuv = cv2.cvtColor(img_val, cv2.COLOR_BGR2YCrCb)
            img_y, img_u, img_v = cv2.split(yuv)      
            img_h, img_w = img_y.shape
            img_blur = cv2.GaussianBlur(img_y, (5, 5), 0)
            img_subsample = cv2.resize(img_blur, (img_w/scale_factor, img_h/scale_factor))
            img_input = cv2.resize(img_blur, (img_w, img_h), interpolation=cv2.INTER_CUBIC)
            img_input = np.reshape(img_input, [1,1,img_h, img_w]).astype("float32")    # h,w    
            losses = []
            with fluid.scope_guard(inference_scope):
                [inference_program, feed_target_names, fetch_targets] = (
                    fluid.io.load_inference_model('work/model_fz/', exe))  
                results = exe.run(inference_program,
                      feed={feed_target_names[0]: img_input},
                      fetch_list=fetch_targets)[0]
                loss = np.mean(np.square(results[0,0]-img_y[7:-7, 7:-7]))               
                losses.append(loss) 
        avg_loss = np.sum(np.array(losses))/len(losses)
        psnr = 10 * np.log10(255*255/avg_loss)
        return avg_loss,psnr

    def generate_reconstruct_img(self, img_name):        
        place = fluid.CPUPlace()
        exe = fluid.Executor(place)
        inference_scope = fluid.core.Scope()        
        img_test = cv2.imread('work/dataset/set5/%s' % img_name)
        yuv_test = cv2.cvtColor(img_test, cv2.COLOR_BGR2YCrCb)       
        img_h, img_w, img_c = img_test.shape
        print "=====原始图片========="
        b,g,r = cv2.split(img_test)    # AI studio 不支持cv2.imshow,所以用plt.imshow输出,两者rgb顺序不一样
        img_test = cv2.merge([r,g,b])
        plt.imshow(img_test)
        plt.show()        
        #   图像模糊+cubic插值
        img_blur = cv2.GaussianBlur(yuv_test.copy(), (5, 5), 0)
        img_subsample = cv2.resize(img_blur, (img_w/3, img_h/3))   #这里注意cv2.resize里面的shape是w,h的顺序 
        img_cubic = cv2.resize(img_blur, (img_w, img_h), interpolation=cv2.INTER_CUBIC)
        img_y, img_u, img_v = cv2.split(img_cubic)  
        img_input = np.reshape(img_y, [1,1,img_h, img_w]).astype("float32")    # 把y通道作为输入
        with fluid.scope_guard(inference_scope):
            [inference_program, feed_target_names, fetch_targets] = (
                fluid.io.load_inference_model('work/model_fz/', exe))  
            results = exe.run(inference_program,
                  feed={feed_target_names[0]: img_input},
                  fetch_list=fetch_targets)[0]

            result_img = np.array(results)    
            result_img[result_img < 0] = 0
            result_img[result_img >255] = 255
            gap_y = (img_y.shape[0]-result_img.shape[2])/2
            gap_x = (img_y.shape[1]-result_img.shape[3])/2

            print "=====Y通道输入========="
            plt.imshow(img_y, cmap='gray')
            plt.show()

            img_y[gap_y: gap_y + result_img.shape[2],
                 gap_x: gap_x + result_img.shape[3]]=result_img
            img_test_r = cv2.merge([img_y, img_u, img_v])
            img_test_r = cv2.cvtColor(img_test_r, cv2.COLOR_YCrCb2BGR)

            print "=====Y通道输出========="
            plt.imshow(img_y, cmap='gray')            
            plt.show()
            
            print "=====彩图结果========="
            b,g,r = cv2.split(img_test_r)  
            img_test_show = cv2.merge([r,g,b])
            plt.imshow(img_test_show)
            plt.show()

    def read_data(self, data_path):
        def data_reader():
            for image in os.listdir(data_path):
                if image.endswith('.bmp'):
                    img = cv2.imread(os.path.join(data_path, image))
                    yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)
                    img_y, img_u, img_v = cv2.split(yuv)
                    # 下面是切图的步骤
                    j = 0
                    count = 0
                    while j+33 < len(img_y):
                        i = 0
                        while i+33 < len(img_y[0]):
                            img_patch = img_y[j:j+33, i:i+33]
                            img_gth = img_patch[7:-7, 7:-7].copy()
                            img_blur = cv2.GaussianBlur(img_patch, (5, 5), 0)
                            img_sumsample = cv2.resize(img_blur, (11, 11))
                            img_input = cv2.resize(img_blur, (33, 33), interpolation=cv2.INTER_CUBIC)
                            yield img_input, img_gth
                            i+=14
                        j+= 14
        return data_reader

改变filter_size的训练结果

需要重启一下kernel清空定义的模型

In[12]

model = SRCNN_fz(0.0001, 0.00001, 100, 150)
model.train()
0	Epoch: 0 	Cur Cost : 18187.878906	 Val Cost: 21415.037109	 PSNR :4.823615
219	Epoch: 1 	Cur Cost : 293.490234	 Val Cost: 423.864105	 PSNR :21.858537
438	Epoch: 2 	Cur Cost : 286.713898	 Val Cost: 413.923096	 PSNR :21.961607
657	Epoch: 3 	Cur Cost : 277.595795	 Val Cost: 400.915894	 PSNR :22.100271
876	Epoch: 4 	Cur Cost : 266.524780	 Val Cost: 385.093658	 PSNR :22.275140
1095	Epoch: 5 	Cur Cost : 253.052292	 Val Cost: 365.947205	 PSNR :22.496619
1314	Epoch: 6 	Cur Cost : 236.651108	 Val Cost: 342.572601	 PSNR :22.783277
1533	Epoch: 7 	Cur Cost : 216.273224	 Val Cost: 312.513641	 PSNR :23.182114
1752	Epoch: 8 	Cur Cost : 189.500977	 Val Cost: 272.160767	 PSNR :23.782548
1971	Epoch: 9 	Cur Cost : 157.191208	 Val Cost: 224.049789	 PSNR :24.627358
2190	Epoch: 10 	Cur Cost : 129.589066	 Val Cost: 182.939468	 PSNR :25.507729
2409	Epoch: 11 	Cur Cost : 113.882393	 Val Cost: 155.549286	 PSNR :26.212123
2628	Epoch: 12 	Cur Cost : 109.084671	 Val Cost: 146.027054	 PSNR :26.486470
2847	Epoch: 13 	Cur Cost : 104.128502	 Val Cost: 137.899292	 PSNR :26.735183
3066	Epoch: 14 	Cur Cost : 97.342422	 Val Cost: 127.754402	 PSNR :27.067045
3285	Epoch: 15 	Cur Cost : 91.355812	 Val Cost: 118.736206	 PSNR :27.384972
3504	Epoch: 16 	Cur Cost : 85.422371	 Val Cost: 109.795456	 PSNR :27.724960
3723	Epoch: 17 	Cur Cost : 79.140945	 Val Cost: 100.095528	 PSNR :28.126657
3942	Epoch: 18 	Cur Cost : 73.169403	 Val Cost: 90.881409	 PSNR :28.546053
4161	Epoch: 19 	Cur Cost : 67.917305	 Val Cost: 82.804932	 PSNR :28.950242
4380	Epoch: 20 	Cur Cost : 63.625111	 Val Cost: 76.324135	 PSNR :29.304185
4599	Epoch: 21 	Cur Cost : 59.751232	 Val Cost: 70.921104	 PSNR :29.623049
4818	Epoch: 22 	Cur Cost : 55.927074	 Val Cost: 65.637527	 PSNR :29.959281
5037	Epoch: 23 	Cur Cost : 52.361134	 Val Cost: 60.628269	 PSNR :30.304052
5256	Epoch: 24 	Cur Cost : 49.219032	 Val Cost: 56.010677	 PSNR :30.648095
5475	Epoch: 25 	Cur Cost : 46.496906	 Val Cost: 51.900589	 PSNR :30.979081
5694	Epoch: 26 	Cur Cost : 44.209206	 Val Cost: 48.567101	 PSNR :31.267382
5913	Epoch: 27 	Cur Cost : 42.444748	 Val Cost: 46.098759	 PSNR :31.493911
6132	Epoch: 28 	Cur Cost : 40.951580	 Val Cost: 44.224030	 PSNR :31.674220
6351	Epoch: 29 	Cur Cost : 39.668636	 Val Cost: 42.721249	 PSNR :31.824364
6570	Epoch: 30 	Cur Cost : 38.468319	 Val Cost: 41.372662	 PSNR :31.963669
6789	Epoch: 31 	Cur Cost : 37.305447	 Val Cost: 40.067513	 PSNR :32.102880
7008	Epoch: 32 	Cur Cost : 36.248657	 Val Cost: 38.869499	 PSNR :32.234714
7227	Epoch: 33 	Cur Cost : 35.280151	 Val Cost: 37.761169	 PSNR :32.360349
7446	Epoch: 34 	Cur Cost : 34.358017	 Val Cost: 36.653786	 PSNR :32.489615
7665	Epoch: 35 	Cur Cost : 33.456329	 Val Cost: 35.482918	 PSNR :32.630610
7884	Epoch: 36 	Cur Cost : 32.594936	 Val Cost: 34.364208	 PSNR :32.769740
8103	Epoch: 37 	Cur Cost : 31.807510	 Val Cost: 33.297546	 PSNR :32.906681
8322	Epoch: 38 	Cur Cost : 31.098452	 Val Cost: 32.322258	 PSNR :33.035787
8541	Epoch: 39 	Cur Cost : 30.458292	 Val Cost: 31.449808	 PSNR :33.154624
8760	Epoch: 40 	Cur Cost : 29.896788	 Val Cost: 30.646156	 PSNR :33.267043
8979	Epoch: 41 	Cur Cost : 29.400312	 Val Cost: 29.952234	 PSNR :33.366511
9198	Epoch: 42 	Cur Cost : 28.963032	 Val Cost: 29.316887	 PSNR :33.459625
9417	Epoch: 43 	Cur Cost : 28.554939	 Val Cost: 28.730633	 PSNR :33.547352
9636	Epoch: 44 	Cur Cost : 28.187880	 Val Cost: 28.178003	 PSNR :33.631701
9855	Epoch: 45 	Cur Cost : 27.815355	 Val Cost: 27.621120	 PSNR :33.718391
10074	Epoch: 46 	Cur Cost : 27.450251	 Val Cost: 27.054892	 PSNR :33.808346
10293	Epoch: 47 	Cur Cost : 27.095476	 Val Cost: 26.506290	 PSNR :33.897314
10512	Epoch: 48 	Cur Cost : 26.726200	 Val Cost: 25.993595	 PSNR :33.982140
10731	Epoch: 49 	Cur Cost : 26.418917	 Val Cost: 25.480820	 PSNR :34.068670
10950	Epoch: 50 	Cur Cost : 26.102079	 Val Cost: 25.046286	 PSNR :34.143370
11169	Epoch: 51 	Cur Cost : 25.814594	 Val Cost: 24.607016	 PSNR :34.220214
11388	Epoch: 52 	Cur Cost : 25.541672	 Val Cost: 24.180517	 PSNR :34.296148
11607	Epoch: 53 	Cur Cost : 25.276190	 Val Cost: 23.795362	 PSNR :34.365880
11826	Epoch: 54 	Cur Cost : 25.032814	 Val Cost: 23.423958	 PSNR :34.434201
12045	Epoch: 55 	Cur Cost : 24.795341	 Val Cost: 23.076561	 PSNR :34.499093
12264	Epoch: 56 	Cur Cost : 24.567106	 Val Cost: 22.729460	 PSNR :34.564912
12483	Epoch: 57 	Cur Cost : 24.350388	 Val Cost: 22.400122	 PSNR :34.628300
12702	Epoch: 58 	Cur Cost : 24.139818	 Val Cost: 22.082649	 PSNR :34.690292
12921	Epoch: 59 	Cur Cost : 23.937288	 Val Cost: 21.775942	 PSNR :34.751034
13140	Epoch: 60 	Cur Cost : 23.740856	 Val Cost: 21.478758	 PSNR :34.810712
13359	Epoch: 61 	Cur Cost : 23.550505	 Val Cost: 21.190653	 PSNR :34.869360
13578	Epoch: 62 	Cur Cost : 23.365761	 Val Cost: 20.912657	 PSNR :34.926712
13797	Epoch: 63 	Cur Cost : 23.186628	 Val Cost: 20.643282	 PSNR :34.983016
14016	Epoch: 64 	Cur Cost : 23.012552	 Val Cost: 20.381088	 PSNR :35.038530
14235	Epoch: 65 	Cur Cost : 22.843679	 Val Cost: 20.126986	 PSNR :35.093016
14454	Epoch: 66 	Cur Cost : 22.680412	 Val Cost: 19.880857	 PSNR :35.146452
14673	Epoch: 67 	Cur Cost : 22.522045	 Val Cost: 19.643797	 PSNR :35.198549
14892	Epoch: 68 	Cur Cost : 22.368488	 Val Cost: 19.414352	 PSNR :35.249575
15111	Epoch: 69 	Cur Cost : 22.227560	 Val Cost: 19.191557	 PSNR :35.299702
15330	Epoch: 70 	Cur Cost : 22.084782	 Val Cost: 18.978037	 PSNR :35.348291
15549	Epoch: 71 	Cur Cost : 21.936750	 Val Cost: 18.766928	 PSNR :35.396872
15768	Epoch: 72 	Cur Cost : 21.809185	 Val Cost: 18.569225	 PSNR :35.442866
15987	Epoch: 73 	Cur Cost : 21.701038	 Val Cost: 18.389750	 PSNR :35.485045
16206	Epoch: 74 	Cur Cost : 21.573944	 Val Cost: 18.225378	 PSNR :35.524038
16425	Epoch: 75 	Cur Cost : 21.466406	 Val Cost: 18.062704	 PSNR :35.562976
16644	Epoch: 76 	Cur Cost : 21.362574	 Val Cost: 17.919756	 PSNR :35.597483
16863	Epoch: 77 	Cur Cost : 21.265091	 Val Cost: 17.759726	 PSNR :35.636441
17082	Epoch: 78 	Cur Cost : 21.167427	 Val Cost: 17.617479	 PSNR :35.671366
17301	Epoch: 79 	Cur Cost : 21.079617	 Val Cost: 17.467531	 PSNR :35.708488
17520	Epoch: 80 	Cur Cost : 20.975424	 Val Cost: 17.328568	 PSNR :35.743177
17739	Epoch: 81 	Cur Cost : 20.885769	 Val Cost: 17.211353	 PSNR :35.772653
17958	Epoch: 82 	Cur Cost : 20.804918	 Val Cost: 17.072248	 PSNR :35.807896
18177	Epoch: 83 	Cur Cost : 20.729193	 Val Cost: 16.936848	 PSNR :35.842478
18396	Epoch: 84 	Cur Cost : 20.651018	 Val Cost: 16.827904	 PSNR :35.870503
18615	Epoch: 85 	Cur Cost : 20.577908	 Val Cost: 16.708214	 PSNR :35.901503
18834	Epoch: 86 	Cur Cost : 20.506536	 Val Cost: 16.616051	 PSNR :35.925526
19053	Epoch: 87 	Cur Cost : 20.444763	 Val Cost: 16.530025	 PSNR :35.948068
19272	Epoch: 88 	Cur Cost : 20.384291	 Val Cost: 16.441322	 PSNR :35.971436
19491	Epoch: 89 	Cur Cost : 20.331388	 Val Cost: 16.359850	 PSNR :35.993010
19710	Epoch: 90 	Cur Cost : 20.274405	 Val Cost: 16.283634	 PSNR :36.013290
19929	Epoch: 91 	Cur Cost : 20.223141	 Val Cost: 16.202314	 PSNR :36.035033
20148	Epoch: 92 	Cur Cost : 20.172297	 Val Cost: 16.124725	 PSNR :36.055880
20367	Epoch: 93 	Cur Cost : 20.120977	 Val Cost: 16.051615	 PSNR :36.075616
20586	Epoch: 94 	Cur Cost : 20.073071	 Val Cost: 15.968109	 PSNR :36.098269
20805	Epoch: 95 	Cur Cost : 20.027214	 Val Cost: 15.915732	 PSNR :36.112537
21024	Epoch: 96 	Cur Cost : 19.984432	 Val Cost: 15.839420	 PSNR :36.133411
21243	Epoch: 97 	Cur Cost : 19.940655	 Val Cost: 15.775101	 PSNR :36.151082
21462	Epoch: 98 	Cur Cost : 19.899282	 Val Cost: 15.708839	 PSNR :36.169363
21681	Epoch: 99 	Cur Cost : 19.859011	 Val Cost: 15.640730	 PSNR :36.188233
21900	Epoch: 100 	Cur Cost : 19.821726	 Val Cost: 15.585388	 PSNR :36.203627
22119	Epoch: 101 	Cur Cost : 19.786446	 Val Cost: 15.522793	 PSNR :36.221105
22338	Epoch: 102 	Cur Cost : 19.748981	 Val Cost: 15.472646	 PSNR :36.235158
22557	Epoch: 103 	Cur Cost : 19.715595	 Val Cost: 15.406190	 PSNR :36.253851
22776	Epoch: 104 	Cur Cost : 19.679775	 Val Cost: 15.351366	 PSNR :36.269333
22995	Epoch: 105 	Cur Cost : 19.644049	 Val Cost: 15.300534	 PSNR :36.283738
23214	Epoch: 106 	Cur Cost : 19.611214	 Val Cost: 15.245579	 PSNR :36.299364
23433	Epoch: 107 	Cur Cost : 19.583275	 Val Cost: 15.178621	 PSNR :36.318480
23652	Epoch: 108 	Cur Cost : 19.554924	 Val Cost: 15.142241	 PSNR :36.328902
23871	Epoch: 109 	Cur Cost : 19.527620	 Val Cost: 15.100776	 PSNR :36.340811
24090	Epoch: 110 	Cur Cost : 19.499495	 Val Cost: 15.060397	 PSNR :36.352439
24309	Epoch: 111 	Cur Cost : 19.472237	 Val Cost: 15.014300	 PSNR :36.365753
24528	Epoch: 112 	Cur Cost : 19.443647	 Val Cost: 14.971251	 PSNR :36.378223
24747	Epoch: 113 	Cur Cost : 19.417927	 Val Cost: 14.922546	 PSNR :36.392374
24966	Epoch: 114 	Cur Cost : 19.388918	 Val Cost: 14.871901	 PSNR :36.407139
25185	Epoch: 115 	Cur Cost : 19.362228	 Val Cost: 14.819825	 PSNR :36.422373
25404	Epoch: 116 	Cur Cost : 19.338102	 Val Cost: 14.777211	 PSNR :36.434879
25623	Epoch: 117 	Cur Cost : 19.306536	 Val Cost: 14.740740	 PSNR :36.445611
25842	Epoch: 118 	Cur Cost : 19.279057	 Val Cost: 14.691047	 PSNR :36.460276
26061	Epoch: 119 	Cur Cost : 19.254765	 Val Cost: 14.637246	 PSNR :36.476210
26280	Epoch: 120 	Cur Cost : 19.223206	 Val Cost: 14.604916	 PSNR :36.485813
26499	Epoch: 121 	Cur Cost : 19.197382	 Val Cost: 14.570190	 PSNR :36.496151
26718	Epoch: 122 	Cur Cost : 19.166422	 Val Cost: 14.527482	 PSNR :36.508900
26937	Epoch: 123 	Cur Cost : 19.141092	 Val Cost: 14.476220	 PSNR :36.524252
27156	Epoch: 124 	Cur Cost : 19.113115	 Val Cost: 14.421227	 PSNR :36.540782
27375	Epoch: 125 	Cur Cost : 19.084183	 Val Cost: 14.397281	 PSNR :36.547999
27594	Epoch: 126 	Cur Cost : 19.063801	 Val Cost: 14.360329	 PSNR :36.559160
27813	Epoch: 127 	Cur Cost : 19.037209	 Val Cost: 14.328735	 PSNR :36.568725
28032	Epoch: 128 	Cur Cost : 19.020245	 Val Cost: 14.305547	 PSNR :36.575759
28251	Epoch: 129 	Cur Cost : 18.989275	 Val Cost: 14.252780	 PSNR :36.591808
28470	Epoch: 130 	Cur Cost : 18.959911	 Val Cost: 14.243009	 PSNR :36.594786
28689	Epoch: 131 	Cur Cost : 18.954180	 Val Cost: 14.218270	 PSNR :36.602336
28908	Epoch: 132 	Cur Cost : 18.909533	 Val Cost: 14.155800	 PSNR :36.621459
29127	Epoch: 133 	Cur Cost : 18.883560	 Val Cost: 14.137563	 PSNR :36.627058
29346	Epoch: 134 	Cur Cost : 18.869696	 Val Cost: 14.116048	 PSNR :36.633672
29565	Epoch: 135 	Cur Cost : 18.832462	 Val Cost: 14.054341	 PSNR :36.652699
29784	Epoch: 136 	Cur Cost : 18.814505	 Val Cost: 14.029723	 PSNR :36.660313
30003	Epoch: 137 	Cur Cost : 18.805397	 Val Cost: 14.000203	 PSNR :36.669460
30222	Epoch: 138 	Cur Cost : 18.781073	 Val Cost: 13.994488	 PSNR :36.671234
30441	Epoch: 139 	Cur Cost : 18.746599	 Val Cost: 13.965572	 PSNR :36.680216
30660	Epoch: 140 	Cur Cost : 18.732073	 Val Cost: 13.914907	 PSNR :36.696000
30879	Epoch: 141 	Cur Cost : 18.704937	 Val Cost: 13.902081	 PSNR :36.700005
31098	Epoch: 142 	Cur Cost : 18.685591	 Val Cost: 13.889931	 PSNR :36.703803
31317	Epoch: 143 	Cur Cost : 18.670761	 Val Cost: 13.844592	 PSNR :36.718002
31536	Epoch: 144 	Cur Cost : 18.646767	 Val Cost: 13.832062	 PSNR :36.721934
31755	Epoch: 145 	Cur Cost : 18.633806	 Val Cost: 13.826068	 PSNR :36.723817
31974	Epoch: 146 	Cur Cost : 18.607412	 Val Cost: 13.794584	 PSNR :36.733717
32193	Epoch: 147 	Cur Cost : 18.596941	 Val Cost: 13.769987	 PSNR :36.741468
32412	Epoch: 148 	Cur Cost : 18.576069	 Val Cost: 13.756820	 PSNR :36.745623
32631	Epoch: 149 	Cur Cost : 18.549088	 Val Cost: 13.727606	 PSNR :36.754856

In[ 13 ]

plt.plot(model.backprops_cnts,model.psnr)

In[ 14 ]

model.generate_reconstruct_img('butterfly_GT.bmp')

In[ 15 ]

model.generate_reconstruct_img('baby_GT.bmp')

3通道彩色模型的训练结果

需要重启kernel

In[ 16 ]

# 先读取单通道训练结果,作为pre_train结果
def get_w(img_name):        
    place = fluid.CPUPlace()
    exe = fluid.Executor(place)
    inference_scope = fluid.core.Scope()        
    img_test = cv2.imread('work/dataset/set5/%s' % img_name)
    yuv_test = cv2.cvtColor(img_test, cv2.COLOR_BGR2YCrCb)       
    img_h, img_w, img_c = img_test.shape     
    #   图像模糊+cubic插值
    img_blur = cv2.GaussianBlur(yuv_test.copy(), (5, 5), 0)
    img_subsample = cv2.resize(img_blur, (img_w/3, img_h/3))   #这里注意cv2.resize里面的shape是w,h的顺序 
    img_cubic = cv2.resize(img_blur, (img_w, img_h), interpolation=cv2.INTER_CUBIC)
    img_y, img_u, img_v = cv2.split(img_cubic)  
    img_input = np.reshape(img_y, [1,1,img_h, img_w]).astype("float32")    # 把y通道作为输入
   
    with fluid.scope_guard(inference_scope):
        [inference_program, feed_target_names, fetch_targets] = (
            fluid.io.load_inference_model('work/model/', exe))          
        results = exe.run(inference_program,
              feed={feed_target_names[0]: img_input},
              fetch_list=fetch_targets)[0]
        with fluid.program_guard(inference_program):
            conv1_w_v = fluid.fetch_var('conv1_w')
            conv1_b_v = fluid.fetch_var('conv1_b')
            conv2_w_v = fluid.fetch_var('conv2_w')
            conv2_b_v = fluid.fetch_var('conv2_b')
            pred_w_v = fluid.fetch_var('pred_w')
            pred_b_v = fluid.fetch_var('pred_b')
            return conv1_w_v, conv1_b_v, conv2_w_v, conv2_b_v, pred_w_v,  pred_b_v
conv1_w_v, conv1_b_v, conv2_w_v, conv2_b_v, pred_w_v,  pred_b_v = get_w('butterfly_GT.bmp')
conv1_w_v.dump('work/model/conv1_w_v')
conv1_b_v.dump('work/model/conv1_b_v')
conv2_w_v.dump('work/model/conv2_w_v')
conv2_b_v.dump('work/model/conv2_b_v')
pred_w_v.dump('work/model/pred_w_v')
pred_b_v.dump('work/model/pred_b_v')

In[ 17 ]

class SRCNN_3dim(object):   

    def __init__(self, lr, lr_f, batch_size, iter_num):
        self.lr = lr   # 学习率
        self.lr_f = lr_f  # 最后一层学习率
        self.batch_size = batch_size 
        self.iter_num = iter_num   # 总共训练多少次

    def net(self, X, Y):        
        # 搭建模型           
        conv1 = fluid.layers.conv2d(X, 64, 9,act='relu', name='conv1' , 
                                    param_attr= fluid.ParamAttr(initializer=fluid.initializer.NormalInitializer(scale=0.001),
                                                               name='conv1_w'),
                                    bias_attr=fluid.ParamAttr(initializer=fluid.initializer.ConstantInitializer(value=0.),
                                                               name='conv1_b'))
        conv2 = fluid.layers.conv2d(conv1, 32, 1, act='relu', name='conv2' , 
                                    param_attr= fluid.ParamAttr(initializer=fluid.initializer.NormalInitializer(scale=0.001),
                                                               name='conv2_w'),
                                    bias_attr=fluid.ParamAttr(initializer=fluid.initializer.ConstantInitializer(value=0.),
                                                               name='conv2_b'))
        pred = fluid.layers.conv2d(conv2, 3, 5, name='pred', 
                                    param_attr= fluid.ParamAttr(initializer=fluid.initializer.NormalInitializer(scale=0.001),
                                                               name='pred_w'),
                                    bias_attr=fluid.ParamAttr(initializer=fluid.initializer.ConstantInitializer(value=0.),
                                                               name='pred_b'))    
        loss = fluid.layers.reduce_mean(fluid.layers.square(pred - Y))        
        return pred, loss
    
    def train(self):
        # 模型训练

        X_train = fluid.layers.data(shape=[3, 33, 33], dtype='float32', name='image')
        Y_train = fluid.layers.data(shape=[3, 21, 21], dtype='float32', name='gdt')
        y_predict, y_loss = self.net(X_train, Y_train)

        Optimizer = fluid.optimizer.AdamOptimizer(learning_rate=self.lr)
        Optimizer_f = fluid.optimizer.AdamOptimizer(learning_rate=self.lr_f)
        Optimizer.minimize(y_loss, parameter_list=['conv1_w','conv1_b', 'conv2_w', 'conv2_b'])
        Optimizer_f.minimize(y_loss, parameter_list=['pred_w', 'pred_b'])

        # 读取训练集数据
        train_reader = paddle.batch(self.read_data('work/dataset/timofte'), batch_size=self.batch_size)        

        # 定义执行器
        place = fluid.CPUPlace()
        exe = fluid.Executor(place)
        exe.run(fluid.default_startup_program())


        def train_loop(main_program):
            feeder = fluid.DataFeeder(place=place, feed_list=[X_train, Y_train])
            exe.run(fluid.default_startup_program())                
                    
            # 用预训练的结果赋值
            conv1_w = fluid.global_scope().find_var('conv1_w').get_tensor()
            conv1_b = fluid.global_scope().find_var('conv1_b').get_tensor()
            conv2_w = fluid.global_scope().find_var('conv2_w').get_tensor()
            conv2_b = fluid.global_scope().find_var('conv2_b').get_tensor()
            pred_w = fluid.global_scope().find_var('pred_w').get_tensor()
            pred_b = fluid.global_scope().find_var('pred_b').get_tensor()
            conv1_w.set(np.tile(conv1_w_v, (1,3,1,1)),place)             
            conv1_b.set(conv1_b_v,place) 
            conv2_w.set(conv2_w_v,place) 
            conv2_b.set(conv2_b_v,place) 
            pred_w.set(np.tile(pred_w_v,(3,1,1,1)),place)
            pred_b.set(np.tile(pred_b_v,(3)),place)

            backprops_cnt = 0  # 论文中作图的横坐标
            self.backprops_cnts = []    # 绑定为类的一个属性,用于画图   
            self.psnr = []          # psnr的值
            for epoch in range(self.iter_num):
                for batch_id, data in enumerate(train_reader()):       
                    loss = exe.run(
                        fluid.framework.default_main_program(),
                        feed=feeder.feed(data),
                        fetch_list=[y_loss])               
                    if batch_id == 0:   #  每个epoch算一下psnr,画图用的
#                         # 算psnr要在测试集上面
                        fluid.io.save_inference_model('work/model_3d/', ['image'], [y_predict], exe)     
                        val_loss, val_psnr = self.validation()
                        self.backprops_cnts.append(backprops_cnt * self.batch_size)          
                        self.psnr.append(val_psnr)
                        print("%i\tEpoch: %d \tCur Cost : %f\t Val Cost: %f\t PSNR :%f" % (backprops_cnt, epoch, np.array(loss[0])[0], val_loss, val_psnr))
                    backprops_cnt += 1            
            fluid.io.save_inference_model('work/model_3d/', ['image'], [y_predict], exe)      

        train_loop(fluid.default_main_program())

    def validation(self):
        place = fluid.CPUPlace()
        exe = fluid.Executor(place)
        inference_scope = fluid.core.Scope() 
        
        test_set = 'work/dataset/set5/'
        scale_factor = 3      
        for img_name in os.listdir(test_set):  
            img_val = cv2.imread(os.path.join(test_set, img_name))
            img_h, img_w, _ = img_val.shape
            img_blur = cv2.GaussianBlur(img_val, (5, 5), 0)
            img_subsample = cv2.resize(img_blur, (img_w/scale_factor, img_h/scale_factor))
            img_input = cv2.resize(img_blur, (img_w, img_h), interpolation=cv2.INTER_CUBIC)
            img_input = np.swapaxes(img_input, 1, 2)   # HWC->CHW
            img_input = np.swapaxes(img_input, 0, 1)
            img_input = np.reshape(img_input, [1,3, img_h, img_w]).astype("float32")    # h,w    
            losses = []
            with fluid.scope_guard(inference_scope):
                [inference_program, feed_target_names, fetch_targets] = (
                    fluid.io.load_inference_model('work/model_3d/', exe))  
                results = exe.run(inference_program,
                      feed={feed_target_names[0]: img_input},
                      fetch_list=fetch_targets)[0]
                img_val = np.swapaxes(img_val, 1, 2)   # HWC->CHW
                img_val = np.swapaxes(img_val, 0, 1)
                loss = np.mean(np.square(results[0]-img_val[:,6:-6, 6:-6]))               
                losses.append(loss) 
        avg_loss = np.sum(np.array(losses))/len(losses)
        psnr = 10 * np.log10(255*255/avg_loss)
        return avg_loss,psnr

    def generate_reconstruct_img(self, img_name):        
        place = fluid.CPUPlace()
        exe = fluid.Executor(place)
        inference_scope = fluid.core.Scope()        
        img_test = cv2.imread('work/dataset/set5/%s' % img_name)
        print "=====原始图片========="
        b,g,r = cv2.split(img_test)    # AI studio 不支持cv2.imshow,所以用plt.imshow输出,两者rgb顺序不一样
        img_show = cv2.merge([r,g,b])
        plt.imshow(img_show)
        plt.show()        
        #   图像模糊+cubic插值
        img_h, img_w, _ = img_test.shape
        img_blur = cv2.GaussianBlur(img_test, (5, 5), 0)
        img_subsample = cv2.resize(img_blur, (img_w/3, img_h/3))   #这里注意cv2.resize里面的shape是w,h的顺序 
        img_cubic = cv2.resize(img_blur, (img_w, img_h), interpolation=cv2.INTER_CUBIC)       
        print "=====输入图片========="
        b,g,r = cv2.split(img_cubic)    # AI studio 不支持cv2.imshow,所以用plt.imshow输出,两者rgb顺序不一样
        img_show = cv2.merge([r,g,b])
        plt.imshow(img_show)
        plt.show()  
        img_cubic = np.swapaxes(img_cubic, 1, 2)   # HWC->CHW
        img_cubic = np.swapaxes(img_cubic, 0, 1)
        img_input = np.reshape(img_cubic, [1,3,img_h, img_w]).astype("float32")    # 把RGB3通道作为输入
        with fluid.scope_guard(inference_scope):
            [inference_program, feed_target_names, fetch_targets] = (
                fluid.io.load_inference_model('work/model_3d/', exe))  
            results = exe.run(inference_program,
                  feed={feed_target_names[0]: img_input},
                  fetch_list=fetch_targets)[0]            
            result_img = np.array(results)    
            result_img[result_img < 0] = 0
            result_img[result_img >255] = 255
            gap_y = (img_test.shape[0]-result_img.shape[2])/2
            gap_x = (img_test.shape[1]-result_img.shape[3])/2            
            result = np.swapaxes(result_img[0].copy(), 0,1)   # CHW_>HWC
            result = np.swapaxes(result, 1,2)

            img_test[gap_y: gap_y + result_img.shape[2],
                 gap_x: gap_x + result_img.shape[3]]=result

            print "=====彩图结果========="
            b,g,r = cv2.split(img_test)  
            img_test_show = cv2.merge([r,g,b])
            plt.imshow(img_test_show)
            plt.show()

    def read_data(self, data_path):
        def data_reader():
            for image in os.listdir(data_path):
                if image.endswith('.bmp'):
                    img = cv2.imread(os.path.join(data_path, image))
                    # 下面是切图的步骤
                    j = 0
                    count = 0
                    while j+33 < len(img):
                        i = 0
                        while i+33 < len(img[0]):
                            img_patch = img[j:j+33, i:i+33, :]
                            img_gth = img_patch[6:27, 6:27].copy()
                            img_blur = cv2.GaussianBlur(img_patch, (5, 5), 0)
                            img_sumsample = cv2.resize(img_blur, (11, 11))
                            img_input = cv2.resize(img_blur, (33, 33), interpolation=cv2.INTER_CUBIC)
                            img_input = np.swapaxes(img_input, 1, 2)   # HWC->CHW
                            img_input = np.swapaxes(img_input, 0, 1)  
                            img_gth = np.swapaxes(img_gth, 1, 2)   # HWC->CHW
                            img_gth = np.swapaxes(img_gth, 0, 1)  
                            yield img_input, img_gth
                            i+=14
                        j+= 14
        return data_reader

In[ 18 ]

conv1_w_v=np.load('work/model/conv1_w_v')
conv1_b_v=np.load('work/model/conv1_b_v')
conv2_w_v=np.load('work/model/conv2_w_v')
conv2_b_v=np.load('work/model/conv2_b_v')
pred_w_v=np.load('work/model/pred_w_v')
pred_b_v=np.load('work/model/pred_b_v')

In[ 19 ]

model = SRCNN_3dim(0.0001, 0.00001, 100, 200)
model.train()

In[ 20 ]

plt.plot(model.backprops_cnts,model.psnr)

In[ 21 ]

model.generate_reconstruct_img('butterfly_GT.bmp')

In[ 22 ]

model.generate_reconstruct_img('baby_GT.bmp')

你可能感兴趣的:(【飞桨模型复现计划】SRCNN网络-超分辨率重建)