神经元模型
用数学公式表示为:f为激活函数。引入非线性激活因素,提高模型的表达力。
常见的激活函数有relu,sigmoid,tanh等。
损失函数
用来预测表示预测值(y)与已知答案(y_)的差距。在训练神经网络时,通过不断改变神经网络中的所有参数,使损失函数不断减小,从而训练出更高准确率的神经网络模型。
常用的损失函数有均方误差,自定义和交叉熵等。
代码示例1
预测酸奶日销售量y, x1和x2为影响日销售量的两个因素。
利用TensorFlow中的函数随机生成x1,x2,制造标准答案y_=x1+x2,为了更真实,求和后还加了正负0.05的随机噪音。
#coding:utf-8
#预测多或预测少的影响一样
import tensorflow as tf
import numpy as np
BATCH_SIZE=8
seed=23455
#基于seed产生随机数
rng=np.random.RandomState(seed)
#随机数返回32行2列的矩阵 表示32组 体积和重量 作为输入数据集
X=rng.rand(32,2)
#作为输入数据集的标签(正确答案)
Y=[[int(x0+x1+(rng.rand()/10.0-0.05))] for (x0,x1) in X]
print "X:\n",X
print "Y:\n",Y
#定义神经网络的输入 参数和输出,定义前向传播过程。
x=tf.placeholder(tf.float32,shape=(None,2))
y_=tf.placeholder(tf.float32,shape=(None,1))
w1=tf.Variable(tf.random_normal([2,1],stddev=1,seed=1))
#定义向前传播过程
y=tf.matmul(x,w1)
#定义损失函数及反向传播方法
loss=tf.reduce_mean(tf.square(y_-y))
train_step=tf.train.GradientDescentOptimizer(0.001).minimize(loss)
#生成会话,训练STEPS
with tf.Session() as sess:
init_op=tf.initialize_all_variables()
sess.run(init_op)
#输出目前(未经训练)的参数取值
print "w1:\n",sess.run(w1)
print "\n"
#训练模型
STEPS=20000
for i in range(STEPS):
start=(i*BATCH_SIZE)%32
end=start+BATCH_SIZE
sess.run(train_step,feed_dict={x: X[start:end],y_: Y[start:end]})
if(i%5000)==0:
print "w1:\n",sess.run(w1)
#输出训练后的参数取值
print "\n"
print "w1:\n",sess.run(w1)
但是我这边测试跑出来的结果跟教程里的不一样,x1离标准答案1差的比较远。(这个问题后续再研究)
自定义损失函数
损失函数表示,若预测结果y小于标准答案y_,损失函数为利润乘以预测结果y与标准答案y_之差;
若预测结果y大于标准答案y_,损失函数为成本乘以预测结果y与标准答案y_之差。
将损失函数修改如下:
loss=tf.reduce_sum(tf.select(tf.greater(y,y_),(y-y_)1,(y_-y)9))
教程中为where,应该是版本问题,这边改成select
交叉熵(Cross Entropy)
表示两个概率分布之间的距离。交叉熵越大,两个概率分布距离越远,两个概率分布越相异;交叉熵越小,两个概率分布距离越近,两个概率分布越相似。
损失函数如下:
ce=tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,labels=tf.argmax(y_,1))
loss=tf.reduce_mean(ce)
学习率(learning_rate)
表示了每次参数更新的幅度大小。学习率过大,会导致待优化的参数在最小值附近波动,不收敛;学习率过小,会导致待优化的参数收敛缓慢。
示例代码2
#coding:utf-8
#设损失函数 loss=(w+1)^2,令w初值为常数5。反向传播就是求最优w,即求最小loss对应的w值
import tensorflow as tf
#定义待优化参数w初始值5
w=tf.Variable(tf.constant(5,dtype=tf.float32))
#定义损失函数
loss=tf.square(w+1)
#定义反向传播方法
train_step=tf.train.GradientDescentOptimizer(0.2).minimize(loss)
#生成会话,训练40轮
with tf.Session() as sess:
init_op=tf.initialize_all_variables()
sess.run(init_op)
for i in range(40):
sess.run(train_step)
w_val=sess.run(w)
loss_val=sess.run(loss)
print "After %s steps: w is %f,loss is %f."%(i,w_val,loss_val)
指数衰减学习率
学习率随着训练轮数变化而动态更新
tf里的代码为:
LEARNING_RATE_BASE=0.1 #最初学习率
LEARNING_RATE_DECAY=0.99 #学习率衰减率
LEARNING_RATE_STEP =1 #喂入多少轮BATCH_SIZE后,更新一次学习率,一般设为:总样本数/BATCH_SIZE
#运行了几轮BATCH_SIZE的计数器,初值为0,设为不被训练
global_step=tf.Variable(0,trainable=False)
#定义指数下降学习率
learning_rate=tf.train.exponential_decay(LEARNING_RATE_BASE,global_step,LEARNING_RATE_STEP,LEARNING_RATE_DECAY,staircase=True)
滑动平均
记录了一段时间内模型中所有参数w和b各自的平均值。利用滑动平均值可以增强模型的泛化能力。
过拟合
神经网络模型在训练数据集上的准确率较高,在新的数据进行预测或分类时准确率较低,说明模型的泛化能力差
正则化
在损失函数中给每个参数w加上权重,引入模型复杂度指标,从而抑制模型噪声,减少过拟合。