Multi-task learning of facial landmarks and attributes with Tensorflow(三)

26 篇文章 5 订阅
4 篇文章 0 订阅

singleTask_att.py

对人脸属性进行训练在main_simple.py中指定训练哪个属性:

0:gender, 1:smiling, 2:glasses, 3:head_pose

network = CNNSingleAtt(data, 50, 1) #batch size, attribute
sess = network.train_network(100, 0.9, True) # epochs, keep_prob, use_early_stopping
singleTask_att采用了conv,maxpool,conv,maxpool,fc1,dropout,fc2的组合方式,个人感觉他这个训练单个属性的网络写的特别笨
import numpy as np
import tensorflow as tf
import math
import os
import time
from PIL import Image
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' # 1:Info, 2:Warning, 3:Error

class CNNSingleAtt():

    def __init__(self, data, batchSize, attribute):
        # attribute values:
        # 0:gender, 1:smiling, 2:glasses, 3:head_pose

        self.data = data # The dataset
        self.batchSize = batchSize # The mini-batch size for training/testing
        self.attribute = attribute 
        self.f_size = 5 # receptive field size
        self.conv1filters = 16 # nr of output channels from conv layer 1
        self.conv2filters = self.conv1filters*2 # nr of output channels from conv layer 2
        self.fc1size = 1024 # Output size of the first fully connected layer

        if self.attribute < 3:
            self.output_size = 2 # gender, smiling and glasses have True/False labels
        else:
            self.output_size = 5 # head pose has 5 labels
        self.create_comp_graph()

    def weight_variable(self, shape, name):
        # Helper function to create weight variables with Xavier initialization
        w = tf.get_variable(name, shape=shape,
           initializer=tf.contrib.layers.xavier_initializer())
        return w

    def bias_variable(self, shape):
        # Helper function to create bias variables, initialized slightly positive
        initial = tf.constant(0.1, shape=shape)
        return tf.Variable(initial)

    def conv2d(self, x, W):
        # Helper function to create a conv layer
        return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

    def max_pool_2x2(self, x):
        # Helper function to create a max pooling layer
        return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                          strides=[1, 2, 2, 1], padding='SAME')

    def feed_forward(self, x, y):
        # Constructs the network, returns the loss and output from the last FC layer
        h_conv1 = tf.nn.relu(self.conv2d(x, self.W_conv1)+self.b_conv1)
        h_pool1 = self.max_pool_2x2(h_conv1)
        
        h_conv2 = tf.nn.relu(self.conv2d(h_pool1, self.W_conv2) + self.b_conv2)
        h_pool2 = self.max_pool_2x2(h_conv2)
        h_pool2_flat = tf.reshape(h_pool2, [-1, 38 * 38 * self.conv2filters])
        h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, self.W_fc1)+self.b_fc1)

        h_fc1_drop = tf.nn.dropout(h_fc1, self.keep_prob)
        y_conv = tf.matmul(h_fc1_drop, self.W_fc2) + self.b_fc2
        cross_entr = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=y_conv))
        lambda_reg = 0.01
        reg = lambda_reg*(tf.nn.l2_loss(self.W_conv1) + tf.nn.l2_loss(self.W_conv2) + 
            tf.nn.l2_loss(self.W_fc1) + tf.nn.l2_loss(self.W_fc2))
        loss = cross_entr + reg
        return y_conv, loss

    def calc_accuracy(self, y, y_conv):
        # Returns the accuracy of the network
        correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y,1))
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
        return accuracy

    def initiate_net(self):
        # Initiates the weights, biases and other variables
        # We have 3 input channels, rgb
        #初始化网络
        self.keep_prob = tf.placeholder(tf.float32)
        self.W_conv1 = self.weight_variable([self.f_size, self.f_size, 3, 
            self.conv1filters], "w1_conv")
        self.b_conv1 = self.bias_variable([self.conv1filters])

        self.W_conv2 = self.weight_variable([self.f_size, self.f_size, self.conv1filters, 
            self.conv2filters], "w2_conv")
        self.b_conv2 = self.bias_variable([self.conv2filters])

        # 38x38 = 150/2/2 x 150/2/2
        self.W_fc1 = self.weight_variable([38 * 38 * self.conv2filters, self.fc1size], "w1_fc")
        self.b_fc1 = self.bias_variable([self.fc1size])

        self.W_fc2 = self.weight_variable([self.fc1size, self.output_size], "w2_fc")
        self.b_fc2 = self.bias_variable([self.output_size])

    def create_comp_graph(self):     
        # Constructs the computational graph for training, testing and validation
        self.initiate_net()    

        # Training comp graph
        self.train_x, _ , self.train_attr = self.data.read_batch(self.batchSize, 0)
        self.train_attr = tf.one_hot(self.train_attr[:,self.attribute], self.output_size)
        self.train_attr_conv, self.train_loss =  self.feed_forward(self.train_x, self.train_attr)
        self.train_acc = self.calc_accuracy(self.train_attr, self.train_attr_conv)

        # Validation comp graph
        self.val_x, _ , self.val_attr = self.data.read_batch(self.batchSize, 1)
        self.val_attr = tf.one_hot(self.val_attr[:,self.attribute], self.output_size)
        self.val_attr_conv, self.val_loss =  self.feed_forward(self.val_x, self.val_attr)
        self.val_acc = self.calc_accuracy(self.val_attr, self.val_attr_conv)

        # Testing comp graph
        self.test_x, _, self.test_attr = self.data.read_batch(self.batchSize, 2)
        self.test_attr = tf.one_hot(self.test_attr[:,self.attribute], self.output_size)
        self.test_attr_conv, self.test_loss =  self.feed_forward(self.test_x, self.test_attr)
        self.test_acc = self.calc_accuracy(self.test_attr, self.test_attr_conv)

        self.train_step = tf.train.AdamOptimizer(1e-4).minimize(self.train_loss)

    def train_network(self, nrEpochs, keep_prob, dummyVar):
        # Start a session, start input queues, initialize variables
        sess = tf.Session()
        coord = tf.train.Coordinator()
        threads = tf.train.start_queue_runners(sess= sess, coord=coord)
        sess.run(tf.global_variables_initializer())
        steps = self.data.size[0]//self.batchSize

        print("Number of steps per epoch: " + str(steps))
        for epoch in range(1, nrEpochs + 1):
            avg_acc = 0
            for i in range(steps):
                # Perform a training step, get accuracy
                _, loss, acc, conv = sess.run([self.train_step, self.train_loss, self.train_acc, 
                    self.train_attr_conv], feed_dict={self.keep_prob:keep_prob})
                if (i == 0 and epoch == 1):
                    smooth_loss = loss
                else:
                    smooth_loss = 0.95 * smooth_loss + 0.05 * loss
                # Maintain an avg of training acc over the epoch
                avg_acc += acc
            val_acc = self.compute_accuracy_set(sess, 1)
            avg_acc = avg_acc/steps
            print("Epoch: " + str(epoch))
            print("Avg acc on training set: " + str(np.round(avg_acc,6)))
            print("Avg acc on validation set: " + str(val_acc))
            # print("Smooth loss " + str(smooth_loss))
        print("Training finished.")
        return sess

    def test_network(self, sess):
        # Computes the acc on the test set
        mean_acc = self.compute_accuracy_set(sess, 2)
        print("Accuracy on test set: " + str(mean_acc))
     

    def compute_accuracy_set(self, sess, cur_set): # set i = [training, validation testing]
        # Returns the acc and loss of a specified dataset
        mean_acc = 0
        steps = self.data.size[cur_set]//self.batchSize + 1
        for i in range(steps):
            if(cur_set == 1): # evaluate accuracy on validation set
                acc = sess.run([self.val_acc], feed_dict={self.keep_prob:1.0})[0]
            elif(cur_set == 2):
                acc = sess.run([self.test_acc], feed_dict={self.keep_prob:1.0})[0]
            mean_acc += acc
        mean_acc = mean_acc/steps
        return mean_acc
    

    def debug_network(self):
        sess = tf.Session()
        coord = tf.train.Coordinator()
        threads = tf.train.start_queue_runners(sess= sess, coord=coord)
        sess.run(tf.global_variables_initializer())

        output = sess.run(self.loss, feed_dict={self.keep_prob:1.0, self.training:True})
        print(output)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
近年来,半监督深度面部表情识别成为了人们关注的热点问题之一。在这个领域,研究人员一直致力于利用少量有标签的数据和大量无标签的数据来提高面部表情识别的准确性和鲁棒性。Adaptive是一种有效的半监督学习方法,它能够自适应地利用标签和无标签数据,使得深度学习模型在应用于面部表情识别时更加有效。 半监督学习是一种机器学习方法,利用少量有标签的数据和大量无标签的数据来训练模型。在面部表情识别中,往往很难获取大量有标签的数据,而无标签数据却很容易获取,因此半监督学习成为了一种有吸引力的解决方案。通过利用Adaptive方法,研究人员可以更好地利用无标签数据,提高模型的泛化能力和鲁棒性,从而提升面部表情识别的准确性。 Adaptive方法还可以帮助模型在数据分布变化时自适应地调整,使得模型更具灵活性和稳健性。在面部表情识别任务中,由于不同环境和条件下的面部表情具有差异性,Adaptive方法能够使模型更好地适应这种差异,提高识别的鲁棒性。 总之,半监督深度面部表情识别与Adaptive方法的结合,有望提高面部表情识别的准确性和鲁棒性,为人们提供更加高效和可靠的面部表情识别技术。相信随着更多研究和实践的开展,半监督深度面部表情识别将迎来更加广阔的发展前景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值