TensorFlow通過人臉識別年齡(1)

目的

使用tensorflow訓練集通過人臉識別年齡

源代碼

參考了博主的源碼 http://blog.csdn.net/u014365862/article/details/53869712
訓練集地址

import os  
import glob  
import tensorflow as tf
from tensorflow.contrib.layers import *  
from tensorflow.contrib.slim.python.slim.nets.inception_v3 import inception_v3_base  
import numpy as np  
from random import shuffle  

age_table=['(0, 2)','(4, 6)','(8, 12)','(15, 20)','(25, 32)','(38, 43)','(48, 53)','(60, 100)']  
sex_table=['f','m']  # f:女; m:男  

# AGE==True 訓練年齡模型,False,訓練性別模型  
AGE = True  

if AGE == True:  
    lables_size = len(age_table) # 年齡  
else:  
    lables_size = len(sex_table) # 性別  

face_set_fold = 'AdienceBenchmarkOfUnfilteredFacesForGenderAndAgeClassification'  

fold_0_data = os.path.join(face_set_fold, 'fold_0_data.txt')  
fold_1_data = os.path.join(face_set_fold, 'fold_1_data.txt')  
fold_2_data = os.path.join(face_set_fold, 'fold_2_data.txt')  
fold_3_data = os.path.join(face_set_fold, 'fold_3_data.txt')  
fold_4_data = os.path.join(face_set_fold, 'fold_4_data.txt')  

face_image_set = os.path.join(face_set_fold, 'aligned')  

def parse_data(fold_x_data):  
    data_set = []  

    with open(fold_x_data, 'r') as f:  
        line_one = True  
        for line in f:  
            tmp = []  
            if line_one == True:  
                line_one = False  
                continue  

            tmp.append(line.split('\t')[0])  
            tmp.append(line.split('\t')[1])  
            tmp.append(line.split('\t')[3])  
            tmp.append(line.split('\t')[4])  

            file_path = os.path.join(face_image_set, tmp[0])  
            if os.path.exists(file_path):  
                filenames = glob.glob(file_path + "/*.jpg")  
                for filename in filenames:  
                    if tmp[1] in filename:  
                        break  
                if AGE == True:  
                    if tmp[2] in age_table:  
                        data_set.append([filename, age_table.index(tmp[2])])  
                else:  
                    if tmp[3] in sex_table:  
                        data_set.append([filename, sex_table.index(tmp[3])])  

    return data_set  

data_set_0 = parse_data(fold_0_data)  
data_set_1 = parse_data(fold_1_data)  
data_set_2 = parse_data(fold_2_data)  
data_set_3 = parse_data(fold_3_data)  
data_set_4 = parse_data(fold_4_data)  

data_set = data_set_0 + data_set_1 + data_set_2 + data_set_3 + data_set_4  
shuffle(data_set)  

# 縮放圖像的大小  
IMAGE_HEIGHT = 227  
IMAGE_WIDTH = 227  
# 讀取縮放圖像  
jpg_data = tf.placeholder(dtype=tf.string)  
decode_jpg = tf.image.decode_jpeg(jpg_data, channels=3)  
resize = tf.image.resize_images(decode_jpg, [IMAGE_HEIGHT, IMAGE_WIDTH])  
resize = tf.cast(resize, tf.uint8) / 255  
def resize_image(file_name):  
    with tf.gfile.FastGFile(file_name, 'r') as f:  
        image_data = f.read()  
    with tf.Session() as sess:  
        image = sess.run(resize, feed_dict={jpg_data: image_data})  
    return image  

pointer = 0  
# 有點慢(先睡了),應該先處理好圖片或使用string_input_producer  
def get_next_batch(data_set, batch_size=128):  
    global pointer  
    batch_x = []  
    batch_y = []  
    for i in range(batch_size):  
        batch_x.append(resize_image(data_set[pointer][0]))  
        batch_y.append(data_set[pointer][1])  
        pointer += 1  
    return batch_x, batch_y  

batch_size = 128  
num_batch = len(data_set) // batch_size  

X = tf.placeholder(dtype=tf.float32, shape=[batch_size, IMAGE_HEIGHT, IMAGE_WIDTH, 3])  
Y = tf.placeholder(dtype=tf.int32, shape=[batch_size])  

def conv_net(nlabels, images, pkeep=1.0):  
    weights_regularizer = tf.contrib.layers.l2_regularizer(0.0005)  
    with tf.variable_scope("conv_net", "conv_net", [images]) as scope:  
        with tf.contrib.slim.arg_scope([convolution2d, fully_connected], weights_regularizer=weights_regularizer, biases_initializer=tf.constant_initializer(1.), weights_initializer=tf.random_normal_initializer(stddev=0.005), trainable=True):  
            with tf.contrib.slim.arg_scope([convolution2d], weights_initializer=tf.random_normal_initializer(stddev=0.01)):  
                conv1 = convolution2d(images, 96, [7,7], [4, 4], padding='VALID', biases_initializer=tf.constant_initializer(0.), scope='conv1')  
                pool1 = max_pool2d(conv1, 3, 2, padding='VALID', scope='pool1')  
                norm1 = tf.nn.local_response_normalization(pool1, 5, alpha=0.0001, beta=0.75, name='norm1')  
                conv2 = convolution2d(norm1, 256, [5, 5], [1, 1], padding='SAME', scope='conv2')   
                pool2 = max_pool2d(conv2, 3, 2, padding='VALID', scope='pool2')  
                norm2 = tf.nn.local_response_normalization(pool2, 5, alpha=0.0001, beta=0.75, name='norm2')  
                conv3 = convolution2d(norm2, 384, [3, 3], [1, 1], biases_initializer=tf.constant_initializer(0.), padding='SAME', scope='conv3')  
                pool3 = max_pool2d(conv3, 3, 2, padding='VALID', scope='pool3')  
                flat = tf.reshape(pool3, [-1, 384*6*6], name='reshape')  
                full1 = fully_connected(flat, 512, scope='full1')  
                drop1 = tf.nn.dropout(full1, pkeep, name='drop1')  
                full2 = fully_connected(drop1, 512, scope='full2')  
                drop2 = tf.nn.dropout(full2, pkeep, name='drop2')  
    with tf.variable_scope('output') as scope:  
        weights = tf.Variable(tf.random_normal([512, nlabels], mean=0.0, stddev=0.01), name='weights')  
        biases = tf.Variable(tf.constant(0.0, shape=[nlabels], dtype=tf.float32), name='biases')  
        output = tf.add(tf.matmul(drop2, weights), biases, name=scope.name)  
    return output  

def training():  
    logits = conv_net(lables_size, X)  

    def optimizer(eta, loss_fn):  
        global_step = tf.Variable(0, trainable=False)  
        optz = lambda lr: tf.train.MomentumOptimizer(lr, 0.9)  
        lr_decay_fn = lambda lr,global_step : tf.train.exponential_decay(lr, global_step, 100, 0.97, staircase=True)  
        return tf.contrib.layers.optimize_loss(loss_fn, global_step, eta, optz, clip_gradients=4., learning_rate_decay_fn=lr_decay_fn)  

    def loss(logits, labels):  
        cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits, labels)  
        cross_entropy_mean = tf.reduce_mean(cross_entropy)  
        regularization_losses = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)  
        total_loss = cross_entropy_mean + 0.01 * sum(regularization_losses)  
        loss_averages = tf.train.ExponentialMovingAverage(0.9)  
        loss_averages_op = loss_averages.apply([cross_entropy_mean] + [total_loss])  
        with tf.control_dependencies([loss_averages_op]):  
            total_loss = tf.identity(total_loss)  
        return total_loss  
    # loss  
    total_loss = loss(logits, Y)  
    # optimizer  
    train_op = optimizer(0.001, total_loss)  

    saver = tf.train.Saver(tf.global_variables())  
    with tf.Session() as sess:  
        sess.run(tf.global_variables_initializer())  

        global pointer  
        epoch = 0  
        while True:  
            pointer = 0  
            for batch in range(num_batch):  
                batch_x, batch_y = get_next_batch(data_set, batch_size)  
                _, loss_value = sess.run([train_op, total_loss], feed_dict={X:batch_x, Y:batch_y})  
                print(epoch, batch, loss_value)  
            saver.save(sess, 'age.module' if AGE == True else 'sex.module')  
            epoch += 1  

training()  

""" 
# 檢測性別和年齡 
# 把batch_size改爲1 
def detect_age_or_sex(image_path): 
    logits = conv_net(lables_size, X) 
    saver = tf.train.Saver() 

    with tf.Session() as sess: 
        saver.restore(sess, './age.module' if AGE == True else './sex.module') 

        softmax_output = tf.nn.softmax(logits) 
        res = sess.run(softmax_output, feed_dict={X:[resize_image(image_path)]}) 
        res = np.argmax(res) 

        if AGE == True: 
            return age_table[res] 
        else: 
            return sex_table[res] 
"""

訓練的結果很不理想
最後測試結果也不理想。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章