LLNet模型实现——LLNet深度卷积网络

1. 简介

主要实现LLNet模型的神经网络结构


2. 模型实现

# Ref: LLNet: Deep Autoencoders for Low-light Image Enhancement
# 
# CVPR 2014
# 
# Author: HSW
# Date: 2018-05-11

import tensorflow as tf
import numpy as np 

class LLNet_Model(object):

    def __init__(self, LLNet_Shape=(289, 847, 578, 289), sparseCoef = 0.05, beta_pretrain, lambda_pretrain, lambda_finetune, transfer_function=tf.nn.softplus):
        ''' LLNet Model Inputs is 17 x 17 image Patch: 289 pixels '''
        # Inputs + Outputs
        self.inputs = tf.placeholder(tf.float32, [None, self.LLnet_Shape[0]])
        self.labels = tf.placeholder(tf.float32, [None, self.LLNet_Shape[0]])
        # other initial Params 
        self.LLnet_Shape     = LLNet_Shape
        self.transfer        = transfer_function 
    self.sparseCoef      = sparseCoef 
    self.beta_pretrain   = beta_pretrain
    self.lambda_pretrain = lambda_pretrain
    self.lambda_finetune = lambda_finetune 
        self.weights         = self.initial_weights()

    def initial_weights(self):
        ''' Create LLNet weights and biads '''
        all_weights = dict()
        # Layer1 
        all_weights['w1'] = tf.Variable(xavier_init(self.LLnet_Shape[0], self.LLnet_Shape[1]))
        all_weights['b1'] = tf.Variable(tf.zeros([self.LLnet_Shape[1]], dtype=tf.float32))
        # Layer2
        all_weigths['w2'] = tf.Variable(xavier_init(self.LLnet_Shape[1], self.LLnet_Shape[2]))
        all_weights['b2'] = tf.Variable(tf.zeros([self.LLnet_Shape[2]], dtype=tf.float32))
        # Layer3
        all_weights['w3'] = tf.Variable(xavier_init(self.LLnet_Shape[2], self.LLnet_Shape[3]))
        all_weights['b3'] = tf.Variable(tf.zeros([self.LLnet_Shape[3]], dtype=tf.float32))
        # Layer4 
        all_weights['w4'] = tf.Variable(xavier_init(self.LLnet_Shape[3], self.LLnet_Shape[2]))
        all_weights['b4'] = tf.Variable(tf.zeros([self.LLnet_Shape[2]], dtype=tf.float32))
        # Layer5 
        all_weights['w5'] = tf.Variable(xavier_init(self.LLnet_Shape[2], self.LLnet_Shape[1]))
        all_weights['b5'] = tf.Variable(tf.zeros([self.LLnet_Shape[1]], dtype=tf.float32))
        # Layer6
        all_weights['w6'] = tf.Variable(xavier_init(self.LLnet_Shape[1], self.LLnet_Shape[0]))
        all_weights['b6'] = tf.Variable(tf.zeros([self.LLnet_Shape[0]], dtype=tf.float32))

        return all_weights 

    def build_graph_pretrain(self):
        '''Create LLNet Graph '''
        self.inputs = tf.placeholder(tf.float32, [None, self.LLnet_Shape[0]])

        self.labels = tf.placeholder(tf.float32, [None, self.LLNet_Shape[0]])
        
        self.hidder1 = self.transfer(tf.add(tf.matmul(self.inputs, self.weights['w1']), self.weights['b1']))

        self.hidder2 = self.transfer(tf.add(tf.matmul(self.hidder1, self.weights['w2']), self.weights['b2']))

        self.hidder3 = self.transfer(tf.add(tf.matmul(self.hidder2, self.weights['w3']), self.weights['b3']))

        self.hidder4 = self.transfer(tf.add(tf.matmul(self.hidder3, self.weight['w4']), self.weights['b4']))

        self.hidder5 = self.transfer(tf.add(tf.matmul(self.hidder4, self.weight['w5']), self.weights['b5']))

        self.ouputs  = self.transfer(self.add(tf.matmul(self.hidder5, self.weight['w6']), self.weights['b6']))

        # First Two Layer 
        self.var1 = tf.trainable_variables()[0:4]
        # Last Layer 
        self.var2 = tf.trainable_variables()[4:]

        loss_pretrain()
        optimizer_pretrain()

        init = tf.global_variables_initializer()

        self.sess = tf.Session()

        self.sess.run(init) 

        
    def build_graph_finetune(self, epoch):
        '''Create LLNet Graph '''
        
        self.hidder1 = self.transfer(tf.add(tf.matmul(self.inputs, self.weights['w1']), self.weights['b1']))

        self.hidder2 = self.transfer(tf.add(tf.matmul(self.hidder1, self.weights['w2']), self.weights['b2']))

        self.hidder3 = self.transfer(tf.add(tf.matmul(self.hidder2, self.weights['w3']), self.weights['b3']))

        self.hidder4 = self.transfer(tf.add(tf.matmul(self.hidder3, self.weights['w4']), self.weights['b4']))

        self.hidder5 = self.transfer(tf.add(tf.matmul(self.hidder4, self.weights['w5']), self.weights['b5']))

        self.ouputs  = self.transfer(tf.add(tf.matmul(self.hidder5, self.weights['w6']), self.weights['b6'])) 

        loss_finetune()
        
        optimizer_finetune_first()
        optimizer_finetune_last()
        
        self.saver = tf.train.Saver()  

        init = tf.global_variables_initializer()

        self.sess = tf.Session()

        self.sess.run(init) 


    def loss_pretrain(self):
        ''' Compute LLNet Graph loss in pre-train''' 
        self.data_loss_pretrain   = tf.reduce_mean(tf.pow(tf.subtract(self.outputs, self.labels), 2))
        
        sparse_hidder1 = tf.reduce_mean(self.hidder1, 0)
        KL_hidder1 = sparse_hidder1 * tf.log(sparse_hidder1 / self.sparseCoef) + (1 - self.sparseCoef) * tf.log((1 - self.sparseCoef) / (1 - sparse_hidder1)) 
        
        sparse_hidder2 = tf.reduce_mean(self.hidder2, 0) 
        KL_hidder2 = sparse_hidder2 * tf.log(sparse_hidder2 / self.sparseCoef) + (1 - self.sparseCoef) * tf.log((1 - self.sparseCoef) / (1 - sparse_hidder2)) 
        
        sparse_hidder3 = tf.reduce_mean(self.hidder3, 0)
        KL_hidder3 = sparse_hidder3 * tf.log(sparse_hidder2 / self.sparseCoef) + (1 - self.sparseCoef) * tf.log((1 - self.sparseCoef) / (1 - sparse_hidder3)) 
        
        sparse_hidder4 = tf.reduce_mean(self.hidder4, 0) 
        KL_hidder4 = sparse_hidder4 * tf.log(sparse_hidder2 / self.sparseCoef) + (1 - self.sparseCoef) * tf.log((1 - self.sparseCoef) / (1 - sparse_hidder4))
        
        sparse_hidder5 = tf.reduce_mean(self.hidder5, 0) 
        KL_hidder5 = sparse_hidder5 * tf.log(sparse_hidder2 / self.sparseCoef) + (1 - self.sparseCoef) * tf.log((1 - self.sparseCoef) / (1 - sparse_hidder5))
        
        self.kl_loss_pretrain     = sparse_hidder1 + sparse_hidder2 + sparse_hidder3 + sparse_hidder4 + sparse_hidder5
        
        norm_w1 = tf.norm(self.weights['w1'], ord='fro', axis=[-2, -1])
        norm_w2 = tf.norm(self.weights['w2'], ord='fro', axis=[-2, -1])
        norm_w3 = tf.norm(self.weights['w3'], ord='fro', axis=[-2, -1])
        norm_w4 = tf.norm(tf.tranpose(self.weights['w3']), ord='fro', axis=[-2,-1]) 
        norm_w5 = tf.norm(tf.tranpose(self.weights['w2']), ord='fro', axis=[-2,-1])
        norm_w6 = tf.norm(tf.tranpose(self.weights['w1']), ord='fro', axis=[-2,-1]) 
        
        self.sparse_loss_pretrain = norm_w1 + norm_w2 + norm_w3 + norm_w4 + norm_w5 + norm_w6 
        # 总损失函数
        self.pretrain_loss        = self.data_loss_pretrain + self.beta_pretrain * self.kl_loss_pretrain + self.lambda_pretrain * self.sparse_loss_pretrain

                
    def loss_finetune(self, lambda_finetune):
        ''' Compute LLNet Graph loss in finetuned '''
        # data loss 
        self.data_loss_finetune   = tf.reduce_mean(tf.pow(tf.subtract(self.outputs, self.labels), 2))
        
        norm_w1 = tf.norm(self.weights['w1'], ord='fro', axis=[-2, -1])
        norm_w2 = tf.norm(self.weights['w2'], ord='fro', axis=[-2, -1])
        norm_w3 = tf.norm(self.weights['w3'], ord='fro', axis=[-2, -1])
        norm_w4 = tf.norm(tf.tranpose(self.weights['w3']), ord='fro', axis=[-2,-1]) 
        norm_w5 = tf.norm(tf.tranpose(self.weights['w2']), ord='fro', axis=[-2,-1])
        norm_w6 = tf.norm(tf.tranpose(self.weights['w1']), ord='fro', axis=[-2,-1]) 

        # sparse loss 
        self.sparse_loss_finetune = norm_w1 + norm_w2 + norm_w3 + norm_w4 + norm_w5 + norm_w6 

        # total loss 
        self.finetune_loss = self.data_loss_finetune + self.lambda_finetune * self.sparse_loss_finetune

    def optimizer_pretrain(self, lr_first = 0.1, lr_last = 0.01):
        ''' Compute LLNet optimizer in pre-train '''
        opt_first = tf.AdamOptimizer(lr_first).minimizer(self.pretrain_loss, var_list=self.var1)
        opt_last  = tf.AdamOptimizer(lr_last).minimizer(self.pretrain_loss, var_list=self.var2)
        self.pretrain_opt = tf.group(opt_first, opt_last)

    def optimizer_finetune_first(self, lr_first = 0.1):
        ''' Compute LLNet optimizer in finetune '''
        self.finetune_opt_first = tf.AdamOptimizer(lr_first).minimizer(self.finetune_loss)
            
    def optimizer_finetune_last(self, lr_last = 0.01):
        ''' Compute LLNet optimizer in finetune '''
        self.finetune_opt_last = tf.AdamOptimizer(lr_first).minimizer(self.finetune_loss)
            
    def xavier_init(self, fan_in, fan_out, constant = 1):
        ''' Data initial ''' 
        low = -constant * np.sqrt(6.0 / (fan_in + fan_out))
        high = constant * np.sqrt(6.0 / (fan_in + fan_out))

        return tf.random_uniform((fan_in, fan_out), minval=low, maxval=high, dtype=tf.float32)

    def run_fitting_pretrain(self, inputs, labels):
        ''' run pre-train ''' 
        return self.sess.run((self.pretrain_loss, self.pretrain_opt), feed_dict={self.Inputs: inputs, self.labels: labels})

    def run_fitting_finetune_first(self, inputs, labels):
        ''' run finetune at first stage ''' 
        return self.sess.run((self.finetune_loss, self.finetune_opt_first), feed_dict={self.Inputs: inputs, self.labels: labels})

    
    def run_fitting_finetune_last(self, inputs, labels):
        ''' run finetune at second stage ''' 
        return self.sess.run((self.finetune_loss, self.finetune_opt_last), feed_dict={self.Inputs: inputs, self.labels: labels}) 
    


    

实际在实现的过程中,存在一个疑问,就是在预训练和调优过程中,使用不同的学习率,本人的实现方式是否合适呢?


猜你喜欢

转载自blog.csdn.net/hit1524468/article/details/80288711