创建图,启动图
#创建一个常量op
m1 = tf.constant([[3,3]]) #两行一列
m2 = tf.constant([[2],[3]]) #一行两列
# 创建一个矩阵乘法op
product = tf.matmul(m1,m2)
print(product) #结果返回一个tensor
# Tensor("MatMul:0", shape=(1, 1), dtype=int32)
#定义一个会话,启动默认的图
sess = tf.Session()
# run(product)触发了图中三个op
result = sess.run(product)
print(result)
sess.close()
# [[15]]
# 另外一种写法
with tf.Session() as sess:
result = sess.run(product)
print(result)
# 不需要关闭操作
变量的使用
x = tf.Variable([1,2])
a = tf.constant([3,3])
# 增加一个减法op
sub = tf.subtract(x,a)
# 增加一个加法op
add= tf.add(x,sub)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
print(sess.run(sub))
print(sess.run(add))
#Attempting to use uninitialized value Variable_1
for循环
# 变量和操作其实是可以起名字的
status = tf.Variable(0,name = 'counter')
new_value = tf.add(status,1)
# 赋值op new_value赋值给status
update = tf.assign(status,new_value)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
print(sess.run(status))
for _ in range(5):
sess.run(update)
print(sess.run(status))
fetch、feed的使用
# fetch 同时执行多个op
input1 = tf.constant(3.0)
input2 = tf.constant(2.0)
input3 = tf.constant(5.0)
add = tf.add(input2, input3)
mul = tf.multiply(input1,add)
with tf.Session() as sess:
result = sess.run([mul,add])
print(result)
# feed
input1 = tf.placeholder(tf.float32)#创建占位符
input2 = tf.placeholder(tf.float32)
output = tf.multiply(input1,input2)
with tf.Session() as sess:
# feed的数据以字典的形式传入
print(sess.run(output, feed_dict = {
input1:[7.],input2:[2.0]}))
线性规划
# 线性规划
x_data = np.random.rand(100)
y_data = x_data*0.1 + 0.2
b = tf.Variable(0.)
k = tf.Variable(0.)
y = k*x_data + b
# 二次代价函数
loss = tf.reduce_mean(tf.square(y_data-y)) #误差平方均值
# 定义一个梯度下降法来进行训练的优化器
optimizer = tf.train.GradientDescentOptimizer(0.2) # 随机梯度下降法,学习率0.2
# 最小化代价函数
train = optimizer.minimize(loss)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for step in range(201):
sess.run(train)
if step%20 ==0:
print(step,sess.run([k,b]))
'''
0 [0.053777255, 0.10018825]
20 [0.10350733, 0.19811046]
40 [0.102103, 0.19886708]
60 [0.10126095, 0.1993207]
80 [0.10075606, 0.1995927]
100 [0.10045333, 0.19975579]
120 [0.10027182, 0.19985357]
140 [0.100162975, 0.1999122]
160 [0.10009772, 0.19994736]
180 [0.10005858, 0.19996844]
200 [0.10003512, 0.1999811]
'''
二次代价函数
合理的是:在离目标远的地方更新的比较快,离目标近的地方更新的比较慢。之所以要慢,就是怕太快了,跳过最优解。
二次代价函数问题:w和b的梯度跟激活函数的梯度成正比。如果最终的结果由0更新到4,更新的速度由快到慢。如果最终的结果由4更新到-4,更新的速度由慢到快到慢,不合理。
交叉熵损失
w和b的梯度跟激活函数的梯度无关。梯度公式sigma-y表示预测值与实际值的误差,所以当误差较大时,梯度就越大,参数w和b调整的就快,训练的速度也会越来越快,符合预期。
二次代价函数与交叉熵代价函数的比较:如果输出神经元是线性的,那么二次代价函数就是一种合适的选择,如果输出神经元是S型函数,那就比较适合交叉熵代价函数。
minist数据库,二次代价函数,迭代7次就到达90%,14次91%。
minist数据库,交叉熵函数(softmax_cross_entropy_with_logits),迭代2次就到达90%,5次91%,收敛速度显比二次代价小很多明。
提高准确度:
1、每个批次的大小,50-300
2、更改初始化方法
3、尝试不同的激活函数
4、尝试dropout(参数)、不同正则
5、网络的深度、网络的宽度,五六万张,三层神经网络比较匹配。
6、尝试不同的损失函数
7、改变学习率
8、尝试不同的优化器
9、迭代次数epoch
为什么正则能够防止过拟合?
L1正则,会使一些w等于0。
L2正则,也会使一些w变得非常小,接近0。
实验:增加层数,初始化方法
实验:增加层数,初始化方法,增加dropout 0.7
过拟合有所改正,但收敛速度会变慢。当网络非常复杂的时候,如imagenet比赛那种,dropout会更明显。
注:Adagrad适用于数据不平衡的数据集。优点:不需要人为的调解学习率。缺点:随着迭代的次数增加,学习率会越来越小,最终趋近于0。
针对Adagrad的缺点如何改进? RMSprop,学习率不会趋近于0。
有没有不需要学习率的优化器?Adadelta。
SGC缺点:收敛速度慢,无法解决“鞍点”的问题。
SGD这么多缺点是不是就被抛弃掉:SGD虽然速度慢,但在确准率上不一定。为了提高准确率,最好每种优化器都要试一下。
Momentum特点:模型收敛速度很快,经常会走一些无效的路径。
AdamOptimizer:学习率一般比10^-2还要小,一般设置的很小,0.001或者0.0001,一般比SGD要小。速度比SGD要快。
神经网络训练样本数经验:训练集数量是参数5-30倍。
卷积核就是滤波器
max-pooling
mean-poolong
随机pooling:随机找一个值
卷积:same padding 和 valid padding。
池化:same padding 和 valid padding。