This post uses TensorFlow as an exercise to infer the age and gender of photos based on the face, and there are many similar apps online. Training Data –adience data set
The adience data set is from Flickr, which is used by users on the iphone or other smartphone devices, and is primarily intended for unfiltered face estimation of age and gender. At the same time, the corresponding landmark is also labeled, which contains 2,284 categories and 26580 images.
Adience Data Set Download address: Http://www.openu.ac.il/home/hassner/Adience/data.html#agegender
Because the data source FTP site is wall, I can only use the ladder, the download process is very long and painful. In order to protect you from torture, I sent a copy to the net disk.Code 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, +) ', ' (+ +) ', ' (+ +) ', ' (+ +) ', ' (+) ', ' (+) ', ' (+ +) ', ' (+) ', ' ([+] ') ', ' (+ + M: Male # Age==true Training age model, false, training gender model: Age = False if ages = = True:lables_size = Len (age_table) # aged else:lables_size = Len ( sex_table) # Sex 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] "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 + dat A_set_3 + Data_set_4 Shuffle (data_set) # scaled image size Image_height = 227 image_width = 227 # read scaled image jpg_data = Tf.placeholder (d type=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.S Ession () as Sess:image = Sess.run (resize, feed_dict={jpg_data:image_data}) return image pointer = 0 # a bit slow (sleep first), you should first handle the picture or Using String_input_producer def get_next_batch (Data_set, batch_size=128): global pointer batch_x = [] batch_y = [] for i in RA Nge (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 = 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,, [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_respo Nse_normalization (Pool1, 5, alpha=0.0001, beta=0.75, name= ' Norm1 ') conv2 = convolution2d (Norm1,, [5, 5], [1, 1], Paddi Ng= ' same ', scope= ' conv2 ') pool2 = max_pool2d (Conv2, 3, 2, padding= ' VALID ', scope= ' pool2 ') Norm2 = Tf.nn.local_response_no Rmalization (Pool2, 5, alpha=0.0001, beta=0.75, name= ' norm2 ') conv3 = convolution2d (Norm2, 384, [3, 3], [1, 1], Biases_init Ializer=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, scope= ' full1 ') Drop1 = Tf.nn.dropout (Full1, Pkeep, name= ' drop1 ') full2 = fully_connected (dro P1, scope= ' full2 ') Drop2 = Tf.nn.dropout (Full2, Pkeep, name= ' Drop2 ') with Tf.variable_scope (' output ') as Scope:weigh TS = tf. Variable (Tf.random_normal ([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): G Lobal_step = tf. Variable (0, trainable=false) Optz = Lambda Lr:tf.train.MomentumOptimizer (LR, 0.9) Lr_decay_fn = Lambda lr,global_step:t F.train.exponential_decay (LR, global_step, 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 ()) W ITH 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_lo SS], 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 () "" "# Detect gender and Age # change batch_size to 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 (l ogits) res = Sess.run (softmax_output, Feed_dict={x:[resize_image (Image_path)]}) res = Np.argmax (res) if age = = True:retur N Age_table[res] Else:return sex_table[res] "" "
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 1 18 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 1 181 182 183 184 185 186 |
Import OS import glob import tensorflow as TF # 0.12 from TensorFlow. Contrib. Layers Import * from TensorFlow. Co Ntrib. 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, +) ', ' ((+) ', ' (+ +) ', ' (+, +) ', ' ((+) ', ' (+ +) ', ' (+ +) ', ' ([+] ') ', ' [' f ', '] sex_table # f: female; M: Men's # Age==true training age model, false, training gender model ages = false if age = = True:lables_size = Len (age_table) # aged else: Lables_size = Len (sex_table) # sex Face_set_fold = ' Adiencebenchmarkofunfilteredfacesforgenderandageclassificati On ' 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 |