输入input
tf.palceholder()
接收数据并返回一个tensor,这个tensor用来传入tf.session.run()。
Session’s feed_dict
在**tf.Session.run()**中使用feed_dict参数来为placeholder传递tensor。注意Session大写!!!
x = tf.placeholder(tf.string)
y = tf.placeholder(tf.int32)
z = tf.placeholder(tf.float32)
with tf.Session() as sess:
output = sess.run(x, feed_dict={x: 'Test String', y: 123, z: 45.67})
张量的数学运算
加法
tf.add()接收两个数字、两个张量或者一个张量和一个数字,以张量的形式返回他们的和。
x = tf.add(5, 2)
减法和乘法
x = tf.subtract(10 ,4)
y = tf.multiply(2 ,5)
z = tf.mutmal(a, b)#矩阵乘(点乘)
类型转换 tf.cast
tf.subtract(tf.constant(2.0),tf.constant(1)) # Fails with ValueError: Tensor conversion requested dtype float32 for Tensor with dtype int32:
上面的语句中,tonsor分别为float和int,而subtract要求他们类型匹配。
使用tf.cast进行类型转换,其中tensor是目标张量,tf.datatype是转换目标类型。
tf.cast(tensor, tf.datatype)
tf.subtract(tf.cast(tf.constant(2.0), tf.int32), tf.constant(1)) # 1
更新权重与偏差
tf.variable()
tf.Variable创建变量tensor,权重与偏差以变量形式存储其中,具有可修改的属性。由于训练数据不希望被修改,所以用tf.constant存储。
x = tf.Variable(5)
tf.global_variables_initializer()
上述tensor储存在session中,需要手动初始化。tf.global_variables_initializer()初始化graph中素有TensorFlow变量。
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
tf.truncated_normal()
tf.truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)
权重变量需要随机初始化,以防止训练卡在同一位置,同时防止一个权重远远压倒其他权重。使用**tf.truncated_normal()**从正态分布产生随机数,返回一个带有随机值的tensor。
注意参数shape = (n_features, n_labels),故下例中括号千万不能忽略
n_features = 120
n_labels = 5
weights = tf.Variable(tf.truncated_normal((n_features, n_labels)))
tf.zeros()
此例中bias无需进行随机初始化,初始化为0。tf.zeros返回一个全零张量。
n_labels = 5
bias = tf.Variable(tf.zeros(n_labels))
转置
通常的讲解中,计算神经网络的过程如y = Wx + b,在tensorflow中,应为y = xW + b,即W,x和b进行了转置:
TensorFlow Softmax
x = tf.nn.softmax([2.0, 1.0, 0.2])
Cross Entropy 交叉熵
交叉熵用于分类模型classifier的精度计算,应用one-hot码时才会使用:D(S,L) = -∑(Li*ln(Si))
注意D(S,L)跟D(L,S)的差别。因为log(0)无意义,所以不能颠倒。
交叉熵在tensorflow中实现
用到如下两个函数。
tf.resuce_sum()#x = tf.reduce_sum([1, 2, 3, 4, 5])接收array并输出求和。
tf.log()#x = tf.log(100)#求自然对数
注意tf.log(n)计算的是自然对数ln(n)
最小化交叉熵
使用gradient descent最小化平均交叉熵。图示仅表示W内含两个元素的情况,实际上通常W内含非常多元素。
归一化
test:
a=100000000
b=0.00000001
c=a+b
d=c-a
print(d)
输出为1.4901161193847656e-08,误差很大。在程序中,变量差值悬殊会带来精确度的问题。我们尽量希望变量的均值为0,方差相同。
输入为图像时,初始化输入为==(pixels-128)/128==
初始值的方差大时,表示模型初始优化时对onehot中某个码的肯定程度大,所以初始W时尽量选择小方差。
train set, validation set and test set
训练过程中,如果只有训练和验证集,为了获得更好的效果,我们会改变神经网络的参数设置,在这个过程中,验证集慢慢渗透至训练集,无法避免神经网络是“记住”了数据,而不是“学习”了数据,即过拟合。
故按照以下设置三个集合,其中test集合在神经网络的一切确定后再用来测试神经网络的表现。
统计学上,大于30个体的改变才被认为可信。所以对30000行的数据集来说,准确度 的“分辨率”只有最多0.1%。解决方法:
1.获得更多数据(更佳)
2.交叉检验(慢)
Gradient Descent
SGD
为了缩减反向传播的计算量,同时一定程度上改善过拟合,采用SGD,每次求导时,仅随机使用数据集中的一小部分数据,但进行重复更多次的求导和优化。
SGD对数据的要求,正是输入X和初始化W的均值为0,同类拥有相同小方差。
momentum
SGD,每次梯度基于当前的批次,不稳定。对梯度给予修正,使其在一定程度上保持上一个梯度的特性,Momentum算法会观察历史梯度Vt−1,若当前梯度的方向与历史梯度一致(表明当前样本不太可能为异常点),则会增强这个方向的梯度,若当前梯度与历史梯方向不一致,则梯度会衰减。一种形象的解释是:我们把一个球推下山,球在下坡时积聚动量,在途中变得越来越快,γ可视为空气阻力,若球的方向发生变化,则动量会衰减。
learning rate decay
使用动态learning rate学习率,随着越接近最小值(训练时间变长),学习率变得越小。
Adagrad
Adagrad算法能够在训练中自动的对learning rate进行调整,对于出现频率较低参数采用较大的α更新;相反,对于出现频率较高的参数采用较小的α更新。因此,Adagrad非常适合处理稀疏数据。Adagrad的缺点是在训练的中后期,分母上梯度平方的累加将会越来越大,从而梯度趋近于0,使得训练提前结束。
Mini batch
经常存在数据集无法被分配为整数个batch的情况,所以placeholder要能够接受变化维度的输入:
features = tf.placeholder(tf.float32, [None, n_input])
labels = tf.placeholder(tf.float32, [None, n_classes])
None表示None处能接收0以上的任何数。
batches
一个实现batches的例子:
import math
def batches(batch_size, features, labels):
"""
Create batches of features and labels
:param batch_size: The batch size
:param features: List of features
:param labels: List of labels
:return: Batches of (Features, Labels)
"""
assert len(features) == len(labels)
# TODO: Implement batching
output = []
for start_index in range(0, len(features), batch_size):
temp_comb = []
temp_features = features[start_index:start_index+batch_size]
temp_labels = labels[start_index:start_index+batch_size]
temp_comb = [temp_features, temp_labels]
output.append(temp_comb)
return output
设置epochs重复训练
频繁出现错误
错误Process finished with exit code -1073740791,查询得知是因为GPU内存不足导致的,但是跑的是一个数据量非常小的模型,应该不会出现这个问题才对,设置os.environ[“CUDA_VISIBLE_DEVICES”]为1或-1时成功运行,设置为“0”时报错。
方法一
import os
import tensorflow as tf
os.environ["CUDA_VISIBLE_DEVICES"]="-1" CPU模式
CUDA_VISIBLE_DEVICES=1 Only device 1 will be seen
CUDA_VISIBLE_DEVICES=0,1 Devices 0 and 1 will be visible
CUDA_VISIBLE_DEVICES="0,1" Same as above, quotation marks are optional
CUDA_VISIBLE_DEVICES=0,2,3 Devices 0, 2, 3 will be visible; device 1 is masked
方法二
CUDA_VISIBLE_DEVICES=1 python **.py