Tensorflow
主要依赖包
Protocol buffer, bazel 此处偷乐3秒钟,哈哈哈哈
Bazel 支持的编译方式有 py_binary, py_library, py_test
挖坑:docker使用
tensor 张量
阶数和括号的数量一样,
一阶: []
二阶:[[],[]]
类型需要注意
1 | import tensorflow as tf |
全联接层
2层之间任意2个节点都有边
$W$ 表示的是边,
snippet
1 | config = tf.ConfigProto() |
激活函数,非线性
ReLU
$f(x) = max(x, 0)$
sigmod
$f(x) = \frac{1}{1 + e^{-x}}$
tanh
$f(x) = \frac{1 - e^{-2x}}{1 + e^{-2x}}$
softmax
在分类问题中用来归一化最后输出的概率,使得它们的和为1
$softmax(y) = \frac{e^{yi}}{\sum_{j=1}^{n}e^{yi}}$
开始的输出的是每个类的概率,经过这个转换后变成了一个概率分布,强。
交叉熵
用来衡量2个概率分布的差异
$H(p,q) = -\sum_{x}p(x)log q(x)$
按照字面意思,如果交叉熵越大,那么2个概率分布应该会越大,那就错了!🍎🍎 吓得我吃了2个苹果
其实交叉熵的含义是指求熵的时候的交叉
反而,交叉熵越小,2个概率分布差距越小
tf.clip_by_value
tf.clip_by_value(v, low, upp)
1 | v = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) |
* 和 matmul的区别
1 | v1 = tf.constant([[1.0, 2.0], [3.0, 4.0]]) |
reduce_mean
0是列,1是行
1 | x = tf.constant([[1., 1.], [2., 2.]]) |
random
1 | from numpy.random import RandomState |
stochastic gradient descent
每次选一条数据进行计算损失函数
因为举个🌰, y=wx, 那么其实w的梯度是和x相关的。
batch 的方法
取个折中,使用部分的数据进行计算梯度
学习率的衰减
目的是使得前期的时候快速接近较优解,后期的时候不要有太大的波动。
1 | decayed_learning_rate = \ |
其中decay_steps是所有数据数量总和/batch_size。所以用完一遍数据就*decay_rate一次
Global_step是当前的迭代次数。
tf参数staircase的含义
1 | global_step = tf.Variable(0) |
正则化
L1
$R(w) = \sum_{i}|w_i|$
L2
$R(w) = \sum_{i}|w_i^2|$
理解
L1更佳容易使得参数等于0,因为在L2中如果一个数字为0.001平方后就很小了被忽略了。
计算技巧
交叉熵
y_ 是真实值
1 | cross_entropy = -tf.reduce_mean( |
真正的算法应该是对于矩阵 [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]],先每行求和然后再取平均。现在是直接对所有的数字取了平均,这样不会改变结果因为差的是一个D系数。
总之在多分类问题中,
Ground truth是一堆概率值表示了这个东西属于某个类的概率
但是算法输出的也是一堆值,表示这个东西属于某个类的概率,但是不保证输出的概率和是1,所以通过exp{x}然后归一化后,使得概率的和为1,然后再通过交叉熵比较2个概率分布的差异。交叉熵越小的越好
1 | import tensorflow as tf |
MNIST数字识别
6w张训练数据,1w张测试数据
图片大小是28*28,数字出现在正中间
白色背景 background
黑色前景 foreground
tf.cast(x, tf.float32) 类型强制转换
结论
调整网络结构对最后的影响很大
滑动平均模型和指数衰减都是限制神经网络中参数更新的速度,
正则化的作用更加大
变量管理
1 | v = tf.get_variable("v", shape=[1], initializer=tf.constant_initializer(1.0)) |
升级api变化
tf.select->tf.where
疑问
1 | w = tf.Variable(tf.random_normal([2,1], stddev=1, seed=1)) |