身份证问题的引入
我们都知道身份证由18位数字组成,倒数第2位数字代表男女性别,如果是奇数,表明持有身份证的人事男性;如果是偶数,则表明为女性。假如事先不知道这个规则,但是收集了一大堆身份证,在收集过程中通过身份证上的照片知道持有者的性别,现在我们希望通过神经网络来寻找这个规律。
问题分析
初步分析这个问题可以得到下面几条思路
- 已知的信息包括身份证号和对应的持有者身份,显然身份证号可以作为神经网络的输入,而持有者性别则是神经网络计算结果的目标值,因此,我们已经拥有完备的训练数据。
- 由于性别一般分为男、女两类,本问题显然是一个二分类问题。
- 本问题只有两个结果值,初步判断,本问题显然不是一个线性问题;因为线性问题一般会随权重值的变化有一个线性变化的范围。
- 如果我们预知这个与性别有关的编号规则,会发现这个也不是一个跳变的非线性问题,因为它不像我们之前处理的三好学生评选结果问题那样只有一个门槛且门槛内外分别代表两个分类,而随着的变化“上下跳动”,一会是男性,一会是女性。可以预想到,用原来的单神经元(单层)的结构恐怕难以解决这个问题。
单层网络的模型
根据问题分析,我们可以先采用与图5.4类似的神经网络进行尝试,为了简化起见,我们取身份证号码的后4位作为演示。那么,这个神经网络将有4个数字作为输入,4个数字的范围都是[0,9]之间;输出结果是男性(0)和女性(1)。显而以见,我们需要sigmoid函数把输出结果收敛到[0,1]的范围内。如图1.1所示
图1.1 身份证问题的单层神经网络模型
我们根据图1.1的神经网络模型进行代码的实现,具体如下:
# Author:北京
# time:2021/4/20
import tensorflow as tf
import random
random.seed()
x = tf.placeholder(tf.float32)
yTrain = tf.placeholder(tf.float32)
# random_normal函数是一个产生随机数的函数,本问题中w的形态是[4],是一个4维的向量,使用random_normal赋初值后,其中每一个数字都将被置为随机数。
# random_normal函数产生的随机数服从正态分布,我们设置平均值(mean)为0.5,stddev指定这个波动范围
w = tf.Variable(tf.random_normal([4], mean=0.5, stddev=0.1), dtype=tf.float32)
b = tf.Variable(0, dtype=tf.float32)
n1 = x * w + b
y = tf.nn.sigmoid(tf.reduce_sum(n1))
loss = tf.abs(y - yTrain)
optimizer = tf.train.RMSPropOptimizer(0.01)
train = optimizer.minimize(loss)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
# 记录训练误差总和,在每次训练后,将它的值除以训练次数得到平均误差作为信息来输出以便参考
lossSum = 0.0
for i in range(5000):
# 随机产生[0,9]的4位整数,模拟身份证后4位
xDataRandom = [int(random.random() * 10), int(random.random() * 10), int(random.random() * 10),
int(random.random() * 10)]
# 判断倒数第2位数字奇数或者偶数来模型对应的性别男女
if xDataRandom[2] % 2 == 0:
yTrainDataRandom = 0
else:
yTrainDataRandom = 1
result = sess.run([train, x, yTrain, y, loss], feed_dict={x: xDataRandom, yTrain: yTrainDataRandom})
lossSum = lossSum + float(result[len(result) - 1])
print("i:%d,loss:%10.10f,avgLoss:%10.10f" % (i, float(result[len(result) - 1]), lossSum / (i + 1)))
运行结果:
我们发现在训练5000次后,平均误差会在0.46左右,基本稳定下来,再加多训练次数也并不会使误差越来越小。说明目前的神经网络模型无法解决当前这个问题,需要进一步优化。
i:4990,loss:0.0000288486,avgLoss:0.4647823456
i:4991,loss:0.0002346635,avgLoss:0.4646892872
i:4992,loss:0.0011085739,avgLoss:0.4645964411
i:4993,loss:0.9992531538,avgLoss:0.4647035009
i:4994,loss:0.0000253916,avgLoss:0.4646104722
i:4995,loss:0.3684671521,avgLoss:0.4645912282
i:4996,loss:0.0379816890,avgLoss:0.4645058550
i:4997,loss:0.9515267611,avgLoss:0.4646032982
i:4998,loss:0.9845128655,avgLoss:0.4647073009
i:4999,loss:0.0000001192,avgLoss:0.4646143595
常见的优化神经网络结构的方法
- 增加神经元节点数量
- 增加隐藏层的数量
- 隐藏层采用全连接方法,全连接层应该是前后两层所有的节点之间都是连线。