神经网络:
正向传播:利用输入值算出预测值
对神经网络逐层进行计算
步骤:
(1)对神经网络第一层计算
1. 对第一层第一个神经元计算
1)应用线性函数计算
2)应用非线性函数计算(激活函数:Sigmod,Tanh,Relu,Leaky Relu)
2. 对第一层第二个神经元计算…
3…
(2) 对神经网络第二层计算…
反向传播:通过损失函数(真实值-预测值),应用梯度下降,来计算出当w[1],b[1],w[2],b[2]为何值时,损失函数值最小
导数的意义:通过导数,我们能知道损失函数的损失值的来源;
反向传播的核心:通过导数,得到损失函数的来源,然后减少/增大来源,来调式w,b
步骤:
(1)对最后一层求导
(2)对倒数第二层求导
(3)直到最后一层…
MNIST手写数字识别代码实现
#!/home/kiosk/anaconda3/bin/python
#encoding:utf-8
"""
date:2019-08-19 14-09
name:liu
Email:729768527@qq.com
"""
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import numpy as np
import matplotlib as plt
from tensorflow.contrib.layers import fully_connected
n_inputs = 28*28 #输入图片的纬度
n_hidden1 = 300 #第一个隐藏层神经元个数
n_hidden2 = 100 #第二个隐藏层神经元个数
n_outputs = 10 #softmax之前输出层的神经元个数,因为手写数字识别是10个数字,所以softmax层是10个神经元,softmax层之前的层也应该是10个神经元
X=tf.placeholder(tf.float32,shape=(None,n_inputs),name='X')
y=tf.placeholder(tf.int64,shape=(None),name='y')
# 构建神经网络层,我们这里两个隐藏层,基本一样,除了输入inputs到每个神经元的连接不同
# X输入数据, n_neurons神经元数量, name name_scope名字, activation是不是线性
def neuron_layer(X,n_neurons,name,activation=None):
with tf.name_scope(name):
# 取输入矩阵的维度作为层的输入连接个数
n_inputs = int(X.get_shape()[1])
stddev = 2 / np.sqrt(n_inputs) #计算标准方差
init = tf.truncated_normal((n_inputs,n_neurons),stddev=stddev)
w=tf.Variable(init,name='weights')
b=tf.Variable(tf.zeros([n_neurons]),name='biases')
z = tf.matmul(X,w)+b
if activation=='relu':
return tf.nn.relu(z)
else:
return z
with tf.name_scope('dnn'):
hidden1 = neuron_layer(X,n_hidden1,'hidden1',activation='relu')
hidden2 = neuron_layer(hidden1,n_hidden2,'hidden2',activation='relu')
#进入到softmax层之前最后一层的结果
logits=neuron_layer(hidden2,n_outputs,'outputs')
with tf.name_scope('loss'):
# # 定义交叉熵损失函数,并且求个样本平均
# 函数等价于先使用softmax损失函数,再接着计算交叉熵,并且更有效率
xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y,logits=logits)
loss = tf.reduce_mean(xentropy,name='loss')
#定义学习率
learning_rate = 0.01
with tf.name_scope('train'):
optimizer= tf.train.GradientDescentOptimizer(learning_rate)
training_op = optimizer.minimize(loss)
with tf.name_scope('eval'):
correct = tf.nn.in_top_k(logits,y,1)
accuracy = tf.reduce_mean(tf.cast(correct,tf.float32))
#初始化并保存模型
init = tf.global_variables_initializer()
saver = tf.train.Saver()
#加载mnist数据集
mnist = input_data.read_data_sets("MNIST_data_bak/")
n_epochs = 400
batch_size = 50
训练代码:
with tf.Session() as sess:
init.run()
for epoch in range(n_epochs):
for iteration in range(mnist.train.num_examples // batch_size):
X_batch, y_batch = mnist.train.next_batch(batch_size)
sess.run(training_op, feed_dict={X: X_batch, y: y_batch})
acc_train = accuracy.eval(feed_dict={X: X_batch, y: y_batch})
acc_test = accuracy.eval(feed_dict={X: mnist.test.images,
y: mnist.test.labels})
print(epoch, "Train accuracy:", acc_train, "Test accuracy:", acc_test)
#模型保存路径
save_path = saver.save(sess, "./my_dnn_model_final.ckpt")
测试代码:
# 使用模型预测
with tf.Session() as sess:
saver.restore(sess, "./my_dnn_model_final.ckpt")
X_new_scaled = mnist.train.images[2000].reshape(1, 784)
y_pred = tf.argmax(logits, axis=1) # 查看最大的类别是哪个
Z = y_pred.eval(feed_dict={X: X_new_scaled})
print(Z)