全连接层的作用
将前面经过多次卷积的高度抽象化的特征进行整合,然后进行归一化,对各种分类情况都输出一个概率,之后的分类器可以根据全连接得到的概率进行分类。
什么意思呢
卷积层提取特征值之后经过池化层压缩,进入全连接层,之后全连接层将卷积层提取的特征进行分类归一化,各种情况都输出一个概率,最后进行分类,得到一个结果。
全连接层1
在将数据输入到全连接层之前,我们要对卷积层的输出进行处理
h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])
这可以将卷积层的输出摊平为一维张量。
W_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])
在这一层设置了1024个神经元
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
激活层,给上面的计算结果通过一个激活函数加一个非线性关系,来激活神经元
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
keep_prob = tf.placeholder(tf.float32)
keep_prob_rate = 0.5
在机器学习的模型中,如果模型的参数太多,而训练样本又太少,训练出来的模型很容易产生过拟合的现象。
在训练神经网络的时候经常会遇到过拟合的问题,过拟合具体表现在:模型在训练数据上损失函数较小,预测准确率较高;但是在测试数据上损失函数比较大,预测准确率较低。
神经元按1-keep_prob概率置0,否则以1/keep_prob的比例缩放该元(并非保持不变)
这是为了保证神经元输出激活值的期望值与不使用dropout时一致,结合概率论的知识来具体看一下:假设一个神经元的输出激活值为a,在不使用dropout的情况下,其输出期望值为a,如果使用了dropout,神经元就可能有保留和关闭两种状态,把它看作一个离散型随机变量,符合概率论中的0-1分布,其输出激活值的期望变为 p*a+(1-p)*0=pa,为了保持测试集与训练集神经元输出的分布一致,可以在训练时除以此系数或者测试时乘以此系数,或者在测试时乘以该系数
简单点说就是为了防止过拟合,使训练出来的模型只会对训练集有作用,但是对其他数据没有作用。
全连接层2
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
这一层的输入为上一层的1024个神经元,输出是十个神经元。在这里输出的是一个概率,这十个神经元的序号代表着最后输出数字的值,比如说第五个神经元的概率为0.9,意思为该数字为5的概率为0.9
prediction = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction),
reduction_indices=[1]))
上面两行代码是计算模型的损失,然后用损失才能用优化器进行优化,提高模型的准确率。
这里用到的是一个交叉熵函数:
定义优化器
上面构建了整个模型,权重和偏置都是随机初始化的,然后我们在训练模型的时候要去更新权重和偏置的值,使结果更好的计算到他的标签上去
learning_rate = 1e-4
train_step = tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy)
这里使ADAM优化器做梯度下降:
每个train_step就会做一次优化,目的是最小化这个交叉熵(cross_entropy)。同时根据优化器,他会更新整个模型的权重和偏置。