本文主要是介绍TensorFlow练习: 根据大脸判断性别和年龄,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
本帖使用TensorFlow做一个根据脸部推断照片人物年龄和性别的练习,网上有很多类似app。
训练数据 – Adience数据集
Adience数据集来源为Flickr相册,由用户使用iPhone或者其它智能手机设备拍摄,该数据集主要用于进行年龄和性别的未经过滤的面孔估计。同时,里面还进行了相应的landmark的标注,其中包含2284个类别和26580张图片。
Adience数据集下载地址:http://www.openu.ac.il/home/hassner/Adience/data.html#agegender
由于数据源ftp站点被墙,我只能使用梯子,下载过程非常漫长和痛苦。为了让你免受折磨,我传了一份到网盘。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | import os import glob import tensorflow as tf # 0.12 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 = False 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] """ |
后续:使用OpenCV检测提取人脸,然后使用训练好的模型判断性别和年龄。
相关资源:
- http://www.openu.ac.il/home/hassner/projects/cnn_agegender/
- https://github.com/GilLevi/AgeGenderDeepLearning
- https://cmusatyalab.github.io/openface/
- https://github.com/RiweiChen/DeepFace
- https://data.vision.ee.ethz.ch/cvl/rrothe/imdb-wiki/
- http://blog.csdn.net/qq_14845119/article/details/51913171
这篇关于TensorFlow练习: 根据大脸判断性别和年龄的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!