3. 回归问题
3.1 非线性回归
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
# 从-0.5到0.5之间生成200个随机点,
# 同时将其保存在方括号表示的:位置,并且给数组增加了一个维度,增加的维度用np.newaxis来占位
# 即,x_data就是一个两百行一列的二维数据
x_data = np.linspace(-0.5,0.5,200)[:,np.newaxis]
noise = np.random.normal(0,0.02,x_data.shape) # 生成一些随机的噪声值,形状和x_data的形状一致
y_data = np.square(x_data) + noise # 即,y_data定义为x_data的平方加上一些随机数
# 定义两个placeholder
x = tf.placeholder(tf.float32,[None,1]) # None表示行不确定,1表示1列,由于前面生成了200个随机点,所以实际上这里在运行过程中是有200行
y = tf.placeholder(tf.float32,[None,1])
# 定义神经网络的中间层
# 这里是先给一个权重,开始的时候,这里是设置了给一个随机数,
# 形状设置为1行10列,由于第一层是连接输入层和中间层的,因此1表示输入层的1个神经元,10表示中间层的10个神经元
Weights_L1 = tf.Variable(tf.random_normal([1,10]))
biases_L1 = tf.Variable(tf.zeros([1,10])) # 设置偏置的初始化,初始化偏置的值为0
# 这里是在计算信号的总和,x表示输入,输入是一个矩阵,Weights_L1也是一个矩阵,
# matmul()表示矩阵乘法
Wx_plus_b_L1 = tf.matmul(x,Weights_L1) + biases_L1
# L1是中间层的输出,用的是双曲正切函数作为激活函数
# 将双曲正切函数作用于信号的总和
L1 = tf.nn.tanh()
# 定义神经网络的输出层
# 神经网络的输出层和前面的差不多,但是在权重和偏置上有一些差别
# 对于权重而言,其为10行1列,因为中间有10个神经元而最后只有一个输出
# 对于偏置值而言,由于只有一个输出
Weights_L2 = tf.Variable(tf.random_normal([10,1]))
biases_L2 = tf.Variable(tf.zeros([1,1])) # 这里有一点问题还没理解,为什么不是[10,1]?
Wx_plus_b_L2 = tf.matmul(L1,Weights_L2) + biases_L2 # 计算信号总和时,输入为L1,即,中间层的输出L1为输出层的输入
prediction = tf.nn.tanh(Wx_plus_b_L2) # 最后的输出结果,也就是预测值,还需要经过激活函数的计算
loss = tf.reduce_mean(tf.square(y-prediction)) # 定义二次代价函数
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss) # 采用梯度下降法进行优化训练
with tf.Session() as sess:
sess.run(tf.global_variables_initializer()) # 变量初始化
for _ in range(2000): # 对这个模型训练2000次
sess.run(train_step,feed_dict={x:x_data,y:y_data}) # 在训练过程中,对变量采用字典的方式传入值,在这里x的值为x_data,y的值为y_data
prediction_value = sess.run(prediction,feed_dic={x:x_data})# 获得预测值
plt.figure() # 画图
plt.scatter(x_data,y_data) # 这里表示,将x_data和y_data这些样本点画出来,形成一个散点图
plt.plot(x_data,prediction_value,'r-',lw=5) # 这里表示将预测数据画出来,r表示红色,-表示实线,lw=5是设置线宽
plt.show() # 显示画的所有图
对神经网络的训练目的是,输入一个x,输出一个y,而输出的y要尽量接近y_data这个真实值。
输入只有1个x,因此输入层只有1个神经元,
中间层是可以调整的,在此设计为10个神经元,
输出只有1个y,因此输出层只有1个神经元。
实际上在训练过程中就是在执行train_step,并且在训练时会把数据传进去,让用梯度下降法去进行训练,去最小化loss的值。同时,在优化过程中会去改变Weights_L2和biases_L2的值,也就是在改变Weights_L1和biases_L1的值。总之,整个优化过程就是通过改变L1和L2的权重和偏置值,从而朝着loss不断减小的方向进行。
这里有一个问题没有解决,查了但是没有找到相关的,看后面能不能遇到并理解:
biases_L2 = tf.Variable(tf.zeros([1,1])) # 这里有一点问题还没理解,为什么不是[10,1]?
3.2 分类问题
3.2.1 相关背景:
mnist.train.images:[60000, 784],表示是哪张图片,并索引图片中的像素点
每一张图片包含28*28个像素,把这一个数组展开成一个向量,长度是28*28=784。因此在MNIST训练数据集中mnist.train.images是一个形状为[60000, 784]的张量,第一个维度数字用来索引图片,第二个维度数字用来索引每张图片中的像素点。图片里的某个像素的强度值介于0-1之间。
mnist.train.labels:[60000,10],表示标签
MNIST数据集的标签是介于0-9的数字,我们要把标签转化为“one-hot vectors”一个onehot向量除了某一位数字是1以外,其余维度数字都是0,比如标签0将表示为([1,0,0,0,0,0,0,0,0,01)标签3将表示为([0,0,0,1,0,0,0,0,0,0])。因此,mnist.train.labels 是一个 [60000,10] 的数字矩阵。
Softmax函数:用来给不同的对象分配概率
放在分类的最后一层,是要把分类结果经过softmax函数,然后把结果转换为概率。比如,MNIST的结果是0-9,我们的模型可能推测出一张图片是数字9的概率是80%,是数字8的概率是10%,然后其他数字的概率更小,总体概率加起来等于1。
暂时学习以回归问题为主,因此此处分类问题的代码没有进行学习