天天看点

根据姓名判断性别-人工智能

本帖训练一个可以根据姓名判断性别的CNN模型;我使用自己爬取的35万中文姓名进行训练。

使用同样的数据集还可以训练起名字模型,参看:

准备姓名数据集

我上网找了一下,并没有找到现成的中文姓名数据集,额,看来只能自己动手了。

我写了一个简单的Python脚本,爬取了上万中文姓名,格式整理如下:

[python] 

view plain copy
  1. 姓名,性别  
  2. 安镶怡,女  
  3. 饶黎明,男  
  4. 段焙曦,男  
  5. 苗芯萌,男  
  6. 覃慧藐,女  
  7. 芦玥微,女  
  8. 苏佳琬,女  
  9. 王旎溪,女  
  10. 彭琛朗,男  
  11. 李昊,男  
  12. 利欣怡,女  
  13. # 貌似有很多名字男女通用  

数据集:https://pan.baidu.com/s/1hsHTEU4。

训练模型

  1. import tensorflow as tf  
  2. import numpy as np  
  3. name_dataset = 'name.csv'  
  4. train_x = []  
  5. train_y = []  
  6. with open(name_dataset, 'r') as f:  
  7.     first_line = True  
  8.     for line in f:  
  9.         if first_line is True:  
  10.             first_line = False  
  11.             continue  
  12.         sample = line.strip().split(',')  
  13.         if len(sample) == 2:  
  14.             train_x.append(sample[0])  
  15.             if sample[1] == '男':  
  16.                 train_y.append([0, 1])  # 男  
  17.             else:  
  18.                 train_y.append([1, 0])  # 女  
  19. max_name_length = max([len(name) for name in train_x])  
  20. print("最长名字的字符数: ", max_name_length)  
  21. max_name_length = 8  
  22. # 数据已shuffle  
  23. #shuffle_indices = np.random.permutation(np.arange(len(train_y)))  
  24. #train_x = train_x[shuffle_indices]  
  25. #train_y = train_y[shuffle_indices]  
  26. # 词汇表(参看聊天机器人练习)  
  27. counter = 0  
  28. vocabulary = {}  
  29. for name in train_x:  
  30.     counter += 1  
  31.     tokens = [word for word in name]  
  32.     for word in tokens:  
  33.         if word in vocabulary:  
  34.             vocabulary[word] += 1  
  35.         else:  
  36.             vocabulary[word] = 1  
  37. vocabulary_list = [' '] + sorted(vocabulary, key=vocabulary.get, reverse=True)  
  38. print(len(vocabulary_list))  
  39. # 字符串转为向量形式  
  40. vocab = dict([(x, y) for (y, x) in enumerate(vocabulary_list)])  
  41. train_x_vec = []  
  42.     name_vec = []  
  43.     for word in name:  
  44.         name_vec.append(vocab.get(word))  
  45.     while len(name_vec) < max_name_length:  
  46.         name_vec.append(0)  
  47.     train_x_vec.append(name_vec)  
  48. #######################################################  
  49. input_size = max_name_length  
  50. num_classes = 2  
  51. batch_size = 64  
  52. num_batch = len(train_x_vec) // batch_size  
  53. X = tf.placeholder(tf.int32, [None, input_size])  
  54. Y = tf.placeholder(tf.float32, [None, num_classes])  
  55. dropout_keep_prob = tf.placeholder(tf.float32)  
  56. def neural_network(vocabulary_size, embedding_size=128, num_filters=128):  
  57.     # embedding layer  
  58.     with tf.device('/cpu:0'), tf.name_scope("embedding"):  
  59.         W = tf.Variable(tf.random_uniform([vocabulary_size, embedding_size], -1.0, 1.0))  
  60.         embedded_chars = tf.nn.embedding_lookup(W, X)  
  61.         embedded_chars_expanded = tf.expand_dims(embedded_chars, -1)  
  62.     # convolution + maxpool layer  
  63.     filter_sizes = [3,4,5]  
  64.     pooled_outputs = []  
  65.     for i, filter_size in enumerate(filter_sizes):  
  66.         with tf.name_scope("conv-maxpool-%s" % filter_size):  
  67.             filter_shape = [filter_size, embedding_size, 1, num_filters]  
  68.             W = tf.Variable(tf.truncated_normal(filter_shape, stddev=0.1))  
  69.             b = tf.Variable(tf.constant(0.1, shape=[num_filters]))  
  70.             conv = tf.nn.conv2d(embedded_chars_expanded, W, strides=[1, 1, 1, 1], padding="VALID")  
  71.             h = tf.nn.relu(tf.nn.bias_add(conv, b))  
  72.             pooled = tf.nn.max_pool(h, ksize=[1, input_size - filter_size + 1, 1, 1], strides=[1, 1, 1, 1], padding='VALID')  
  73.             pooled_outputs.append(pooled)  
  74.     num_filters_total = num_filters * len(filter_sizes)  
  75.     h_pool = tf.concat(3, pooled_outputs)  
  76.     h_pool_flat = tf.reshape(h_pool, [-1, num_filters_total])  
  77.     # dropout  
  78.     with tf.name_scope("dropout"):  
  79.         h_drop = tf.nn.dropout(h_pool_flat, dropout_keep_prob)  
  80.     # output  
  81.     with tf.name_scope("output"):  
  82.         W = tf.get_variable("W", shape=[num_filters_total, num_classes], initializer=tf.contrib.layers.xavier_initializer())  
  83.         b = tf.Variable(tf.constant(0.1, shape=[num_classes]))  
  84.         output = tf.nn.xw_plus_b(h_drop, W, b)  
  85.     return output  
  86. # 训练  
  87. def train_neural_network():  
  88.     output = neural_network(len(vocabulary_list))  
  89.     optimizer = tf.train.AdamOptimizer(1e-3)  
  90.     loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(output, Y))  
  91.     grads_and_vars = optimizer.compute_gradients(loss)  
  92.     train_op = optimizer.apply_gradients(grads_and_vars)  
  93.     saver = tf.train.Saver(tf.global_variables())  
  94.     with tf.Session() as sess:  
  95.         sess.run(tf.global_variables_initializer())  
  96.         for e in range(201):  
  97.             for i in range(num_batch):  
  98.                 batch_x = train_x_vec[i*batch_size : (i+1)*batch_size]  
  99.                 batch_y = train_y[i*batch_size : (i+1)*batch_size]  
  100.                 _, loss_ = sess.run([train_op, loss], feed_dict={X:batch_x, Y:batch_y, dropout_keep_prob:0.5})  
  101.                 print(e, i, loss_)  
  102.             # 保存模型  
  103.             if e % 50 == 0:  
  104.                 saver.save(sess, "name2sex.model", global_step=e)  
  105. train_neural_network()  
  106. # 使用训练的模型  
  107. def detect_sex(name_list):  
  108.     x = []  
  109.     for name in name_list:  
  110.         name_vec = []  
  111.         for word in name:  
  112.             name_vec.append(vocab.get(word))  
  113.         while len(name_vec) < max_name_length:  
  114.             name_vec.append(0)  
  115.         x.append(name_vec)  
  116.         # 恢复前一次训练  
  117.         ckpt = tf.train.get_checkpoint_state('.')  
  118.         if ckpt != None:  
  119.             print(ckpt.model_checkpoint_path)  
  120.             saver.restore(sess, ckpt.model_checkpoint_path)  
  121.             print("没找到模型")  
  122.         predictions = tf.argmax(output, 1)  
  123.         res = sess.run(predictions, {X:x, dropout_keep_prob:1.0})  
  124.         i = 0  
  125.         for name in name_list:  
  126.             print(name, '女' if res[i] == 0 else '男')  
  127.             i += 1  
  128. detect_sex(["白富美", "高帅富", "王婷婷", "田野"])  

执行结果:

本文已获原作者授权转载,附上链接: http://blog.csdn.net/u014365862/article/details/53869732