做者:chen_h
微信号 & QQ:862251340
微信公众号:coderpai
简书地址:https://www.jianshu.com/p/e3a...python
计划现将 tensorflow 中的 Python API 作一个学习,这样方便之后的学习。
原文连接
在神经网络中,咱们有不少的非线性函数来做为激活函数,好比连续的平滑非线性函数(sigmoid
,tanh
和softplus
),连续但不平滑的非线性函数(relu
,relu6
和relu_x
)和随机正则化函数(dropout
)。git
全部的激活函数都是单独应用在每一个元素上面的,而且输出张量的维度和输入张量的维度同样。github
tf.nn.relu(features, name = None)
算法
解释:这个函数的做用是计算激活函数relu
,即max(features, 0)
。api
使用例子:数组
#!/usr/bin/env python # -*- coding: utf-8 -*- import tensorflow as tf a = tf.constant([-1.0, 2.0]) with tf.Session() as sess: b = tf.nn.relu(a) print sess.run(b)
输入参数:微信
features
: 一个Tensor
。数据类型必须是:float32
,float64
,int32
,int64
,uint8
,int16
,int8
。name
: (可选)为这个操做取一个名字。输出参数:网络
Tensor
,数据类型和features
相同。tf.nn.relu6(features, name = None)
dom
解释:这个函数的做用是计算激活函数relu6
,即min(max(features, 0), 6)
。ide
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import tensorflow as tf a = tf.constant([-1.0, 12.0]) with tf.Session() as sess: b = tf.nn.relu6(a) print sess.run(b)
输入参数:
features
: 一个Tensor
。数据类型必须是:float
,double
,int32
,int64
,uint8
,int16
或者int8
。name
: (可选)为这个操做取一个名字。输出参数:
Tensor
,数据类型和features
相同。tf.nn.softplus(features, name = None)
解释:这个函数的做用是计算激活函数softplus
,即log( exp( features ) + 1)
。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import tensorflow as tf a = tf.constant([-1.0, 12.0]) with tf.Session() as sess: b = tf.nn.softplus(a) print sess.run(b)
输入参数:
features
: 一个Tensor
。数据类型必须是:float32
,float64
,int32
,int64
,uint8
,int16
或者int8
。name
: (可选)为这个操做取一个名字。输出参数:
Tensor
,数据类型和features
相同。tf.nn.dropout(x, keep_prob, noise_shape = None, seed = None, name = None)
解释:这个函数的做用是计算神经网络层的dropout
。
一个神经元将以几率keep_prob
决定是否放电,若是不放电,那么该神经元的输出将是0
,若是该神经元放电,那么该神经元的输出值将被放大到原来的1/keep_prob
倍。这里的放大操做是为了保持神经元输出总个数不变。好比,神经元的值为[1, 2]
,keep_prob
的值是0.5
,而且是第一个神经元是放电的,第二个神经元不放电,那么神经元输出的结果是[2, 0]
,也就是至关于,第一个神经元被当作了1/keep_prob
个输出,即2
个。这样保证了总和2
个神经元保持不变。
默认状况下,每一个神经元是否放电是相互独立的。可是,若是noise_shape
被修改了,那么他对于变量x
就是一个广播形式,并且当且仅当 noise_shape[i] == shape(x)[i]
,x
中的元素是相互独立的。好比,若是 shape(x) = [k, l, m, n], noise_shape = [k, 1, 1, n]
,那么每一个批和通道都是相互独立的,可是每行和每列的数据都是关联的,即要不都为0,要不都仍是原来的值。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import tensorflow as tf a = tf.constant([[-1.0, 2.0, 3.0, 4.0]]) with tf.Session() as sess: b = tf.nn.dropout(a, 0.5, noise_shape = [1,4]) print sess.run(b) b = tf.nn.dropout(a, 0.5, noise_shape = [1,1]) print sess.run(b)
输入参数:
x
: 一个Tensor
。keep_prob
: 一个 Python 的 float 类型。表示元素是否放电的几率。noise_shape
: 一个一维的Tensor
,数据类型是int32
。表明元素是否独立的标志。seed
: 一个Python的整数类型。设置随机种子。name
: (可选)为这个操做取一个名字。输出参数:
Tensor
,数据维度和x
相同。异常:
输入异常
: 若是 keep_prob
不是在 (0, 1]
区间,那么会提示错误。tf.nn.bias_add(value, bias, name = None)
解释:这个函数的做用是将误差项 bias
加到 value
上面。
这个操做你能够看作是 tf.add
的一个特例,其中 bias
必须是一维的。该API支持广播形式,所以 value
能够有任何维度。可是,该API又不像 tf.add
,可让 bias
的维度和 value
的最后一维不一样。具体看使用例子。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import tensorflow as tf a = tf.constant([[1.0, 2.0],[1.0, 2.0],[1.0, 2.0]]) b = tf.constant([2.0,1.0]) c = tf.constant([1.0]) sess = tf.Session() print sess.run(tf.nn.bias_add(a, b)) # 由于 a 最后一维的维度是 2 ,可是 c 的维度是 1,因此如下语句将发生错误 print sess.run(tf.nn.bias_add(a, c)) # 可是 tf.add() 能够正确运行 print sess.run(tf.add(a, c))
输入参数:
value
: 一个Tensor
。数据类型必须是float
,double
,int64
,int32
,uint8
,int16
,int8
或者complex64
。bias
: 一个一维的Tensor
,数据维度和 value
的最后一维相同。数据类型必须和value
相同。name
: (可选)为这个操做取一个名字。输出参数:
Tensor
,数据类型和value
相同。tf.sigmoid(x, name = None)
解释:这个函数的做用是计算 x
的 sigmoid 函数。具体计算公式为 y = 1 / (1 + exp(-x))
。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import tensorflow as tf a = tf.constant([[1.0, 2.0], [1.0, 2.0], [1.0, 2.0]]) sess = tf.Session() print sess.run(tf.sigmoid(a))
输入参数:
x
: 一个Tensor
。数据类型必须是float
,double
,int32
,complex64
,int64
或者qint32
。name
: (可选)为这个操做取一个名字。输出参数:
Tensor
,若是 x.dtype != qint32
,那么返回的数据类型和x
相同,不然返回的数据类型是 quint8
。tf.tanh(x, name = None)
解释:这个函数的做用是计算 x
的 tanh 函数。具体计算公式为 ( exp(x) - exp(-x) ) / ( exp(x) + exp(-x) )
。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import tensorflow as tf a = tf.constant([[1.0, 2.0],[1.0, 2.0],[1.0, 2.0]]) sess = tf.Session() print sess.run(tf.tanh(a))
输入参数:
x
: 一个Tensor
。数据类型必须是float
,double
,int32
,complex64
,int64
或者qint32
。name
: (可选)为这个操做取一个名字。输出参数:
Tensor
,若是 x.dtype != qint32
,那么返回的数据类型和x
相同,不然返回的数据类型是 quint8
。卷积操做是使用一个二维的卷积核在一个批处理的图片上进行不断扫描。具体操做是将一个卷积核在每张图片上按照一个合适的尺寸在每一个通道上面进行扫描。为了达到好的卷积效率,须要在不一样的通道和不一样的卷积核之间进行权衡。
conv2d
: 任意的卷积核,能同时在不一样的通道上面进行卷积操做。depthwise_conv2d
: 卷积核能相互独立的在本身的通道上面进行卷积操做。separable_conv2d
: 在纵深卷积 depthwise filter
以后进行逐点卷积 separable filter
。注意,虽然这些操做被称之为“卷积”操做,可是严格的说,他们只是互相关,由于卷积核没有作一个逆向的卷积过程。
卷积核的卷积过程是按照 strides
参数来肯定的,好比 strides = [1, 1, 1, 1]
表示卷积核对每一个像素点进行卷积,即在二维屏幕上面,两个轴方向的步长都是1。strides = [1, 2, 2, 1]
表示卷积核对每隔一个像素点进行卷积,即在二维屏幕上面,两个轴方向的步长都是2。
若是咱们先暂且不考虑通道这个因素,那么卷积操做的空间含义定义以下:若是输入数据是一个四维的 input
,数据维度是 [batch, in_height, in_width, ...]
,卷积核也是一个四维的卷积核,数据维度是 [filter_height, filter_width, ...]
,那么:
shape(output) = [batch, (in_height - filter_height + 1) / strides[1], (in_width - filter_width + 1) / strides[2], ...] output[b, i, j, :] = sum_{di, dj} input[b, strides[1] * i + di, strides[2] * j + dj, ...] * filter[di, dj, ...]
由于,input
数据是一个四维的,每个通道上面是一个向量 input[b, i, j, :]
。对于 conv2d
,这些向量将会被卷积核 filter[di, dj, :, :]
相乘而产生一个新的向量。对于 depthwise_conv_2d
,每一个标量份量 input[b, i, j, k]
将在 k
个通道上面独立的被卷积核 filter[di, dj, k]
进行卷积操做,而后把全部获得的向量进行链接组合成一个新的向量。
对于输出数据的维度 shape(output)
,这取决于填充参数 padding
的设置:
padding = 'SAME'
: 向下取舍,仅适用于全尺寸操做,即输入数据维度和输出数据维度相同。padding = 'VALID
: 向上取舍,适用于部分窗口,即输入数据维度和输出数据维度不一样。tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)
解释:这个函数的做用是对一个四维的输入数据 input
和四维的卷积核 filter
进行操做,而后对输入数据进行一个二维的卷积操做,最后获得卷积以后的结果。
给定的输入张量的维度是 [batch, in_height, in_width, in_channels]
,卷积核张量的维度是 [filter_height, filter_width, in_channels, out_channels]
,具体卷积操做以下:
[filter_height * filter_width * in_channels, output_channels]
[batch, out_height, out_width, filter_height * filter_width * in_channels]
。更加具体的表示细节为:
output[b, i, j, k] = sum_{di, dj, q} input[b, strides[1] * i + di, strides[2] * j + dj, q] * filter[di, dj, q, k]
注意,必须有 strides[0] = strides[3] = 1
。在大部分处理过程当中,卷积核的水平移动步数和垂直移动步数是相同的,即 strides = [1, stride, stride, 1]
。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import tensorflow as tf input_data = tf.Variable( np.random.rand(10,6,6,3), dtype = np.float32 ) filter_data = tf.Variable( np.random.rand(2, 2, 3, 1), dtype = np.float32) y = tf.nn.conv2d(input_data, filter_data, strides = [1, 1, 1, 1], padding = 'SAME') with tf.Session() as sess: init = tf.initialize_all_variables() sess.run(init) print sess.run(y) print sess.run(tf.shape(y))
输入参数:
input
: 一个Tensor
。数据类型必须是float32
或者float64
。filter
: 一个Tensor
。数据类型必须是input
相同。strides
: 一个长度是4的一维整数类型数组,每一维度对应的是 input
中每一维的对应移动步数,好比,strides[1]
对应 input[1]
的移动步数。padding
: 一个字符串,取值为 SAME
或者 VALID
。use_cudnn_on_gpu
: 一个可选布尔值,默认状况下是 True
。name
: (可选)为这个操做取一个名字。输出参数:
Tensor
,数据类型是 input
相同。tf.nn.depthwise_conv2d(input, filter, strides, padding, name=None)
解释:这个函数也是一个卷积操做。
给定一个输入张量,数据维度是 [batch, in_height, in_width, in_channels]
,一个卷积核的维度是 [filter_height, filter_width, in_channels, channel_multiplier]
,在通道 in_channels
上面的卷积深度是 1 (个人理解是在每一个通道上单独进行卷积),depthwise_conv2d
函数将不一样的卷积核独立的应用在 in_channels
的每一个通道上(从通道 1
到通道 channel_multiplier
),而后把因此的结果进行汇总。最后输出通道的总数是 in_channels * channel_multiplier
。
更加具体公式以下:
output[b, i, j, k * channel_multiplier + q] = sum_{di, dj} input[b, strides[1] * i + di, strides[2] * j + dj, k] * filter[di, dj, k, q]
注意,必须有 strides[0] = strides[3] = 1
。在大部分处理过程当中,卷积核的水平移动步数和垂直移动步数是相同的,即 strides = [1, stride, stride,1]
。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import tensorflow as tf input_data = tf.Variable( np.random.rand(10, 6, 6, 3), dtype = np.float32 ) filter_data = tf.Variable( np.random.rand(2, 2, 3, 5), dtype = np.float32) y = tf.nn.depthwise_conv2d(input_data, filter_data, strides = [1, 1, 1, 1], padding = 'SAME') with tf.Session() as sess: init = tf.initialize_all_variables() sess.run(init) print sess.run(y) print sess.run(tf.shape(y))
输入参数:
input
: 一个Tensor
。数据维度是四维 [batch, in_height, in_width, in_channels]
。filter
: 一个Tensor
。数据维度是四维 [filter_height, filter_width, in_channels, channel_multiplier]
。strides
: 一个长度是4的一维整数类型数组,每一维度对应的是 input
中每一维的对应移动步数,好比,strides[1]
对应 input[1]
的移动步数。padding
: 一个字符串,取值为 SAME
或者 VALID
。use_cudnn_on_gpu
: 一个可选布尔值,默认状况下是 True
。name
: (可选)为这个操做取一个名字。输出参数:
Tensor
,数据维度为 [batch, out_height, out_width, in_channels * channel_multiplier]
。tf.nn.separable_conv2d(input, depthwise_filter, pointwise_filter, strides, padding, name=None)
解释:这个函数的做用是利用几个分离的卷积核去作卷积,能够参考这个解释。
好比下图中,常规卷积和分离卷积的区别:
这个卷积是为了不卷积核在全通道的状况下进行卷积,这样很是浪费时间。使用这个API,你将应用一个二维的卷积核,在每一个通道上,以深度 channel_multiplier
进行卷积。其实如上图 Separable Convolution
中,就是先利用 depthwise_filter
,将 ID
的通道数映射到 ID * DM
的通道数上面,以后从 ID * DM
的通道数映射到 OD
的通道数上面,这也就是上面说的深度 channel_multiplier
对应于 DM
。
具体公式以下:
output[b, i, j, k] = sum_{di, dj, q, r] input[b, strides[1] * i + di, strides[2] * j + dj, q] * depthwise_filter[di, dj, q, r] * pointwise_filter[0, 0, q * channel_multiplier + r, k]
strides
只是仅仅控制 depthwise convolution
的卷积步长,由于 pointwise convolution
的卷积步长是肯定的 [1, 1, 1, 1]
。注意,必须有 strides[0] = strides[3] = 1
。在大部分处理过程当中,卷积核的水平移动步数和垂直移动步数是相同的,即 strides = [1, stride, stride, 1]
。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import tensorflow as tf input_data = tf.Variable( np.random.rand(10, 6, 6, 3), dtype = np.float32 ) depthwise_filter = tf.Variable( np.random.rand(2, 2, 3, 5), dtype = np.float32) pointwise_filter = tf.Variable( np.random.rand(1, 1, 15, 20), dtype = np.float32) # out_channels >= channel_multiplier * in_channels y = tf.nn.separable_conv2d(input_data, depthwise_filter, pointwise_filter, strides = [1, 1, 1, 1], padding = 'SAME') with tf.Session() as sess: init = tf.initialize_all_variables() sess.run(init) print sess.run(y) print sess.run(tf.shape(y))
输入参数:
input
: 一个Tensor
。数据维度是四维 [batch, in_height, in_width, in_channels]
。depthwise_filter
: 一个Tensor
。数据维度是四维 [filter_height, filter_width, in_channels, channel_multiplier]
。其中,in_channels
的卷积深度是 1。pointwise_filter
: 一个Tensor
。数据维度是四维 [1, 1, channel_multiplier * in_channels, out_channels]
。其中,pointwise_filter
是在 depthwise_filter
卷积以后的混合卷积。strides
: 一个长度是4的一维整数类型数组,每一维度对应的是 input
中每一维的对应移动步数,好比,strides[1]
对应 input[1]
的移动步数。padding
: 一个字符串,取值为 SAME
或者 VALID
。name
: (可选)为这个操做取一个名字。输出参数:
Tensor
,数据维度为 [batch, out_height, out_width, out_channels]
。异常:
数值异常
: 若是 channel_multiplier * in_channels > out_channels
,那么将报错。池化操做是利用一个矩阵窗口在输入张量上进行扫描,而且将每一个矩阵窗口中的值经过取最大值,平均值或者XXXX来减小元素个数。每一个池化操做的矩阵窗口大小是由 ksize
来指定的,而且根据步长参数 strides
来决定移动步长。好比,若是 strides
中的值都是1,那么每一个矩阵窗口都将被使用。若是 strides
中的值都是2,那么每一维度上的矩阵窗口都是每隔一个被使用。以此类推。
更具体的输出结果是:
output[i] = reduce( value[ strides * i: strides * i + ksize ] )
输出数据维度是:
shape(output) = (shape(value) - ksize + 1) / strides
其中,取舍方向取决于参数 padding
:
padding = 'SAME'
: 向下取舍,仅适用于全尺寸操做,即输入数据维度和输出数据维度相同。padding = 'VALID
: 向上取舍,适用于部分窗口,即输入数据维度和输出数据维度不一样。tf.nn.avg_pool(value, ksize, strides, padding, name=None)
解释:这个函数的做用是计算池化区域中元素的平均值。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import tensorflow as tf input_data = tf.Variable( np.random.rand(10,6,6,3), dtype = np.float32 ) filter_data = tf.Variable( np.random.rand(2, 2, 3, 10), dtype = np.float32) y = tf.nn.conv2d(input_data, filter_data, strides = [1, 1, 1, 1], padding = 'SAME') output = tf.nn.avg_pool(value = y, ksize = [1, 2, 2, 1], strides = [1, 1, 1, 1], padding = 'SAME') with tf.Session() as sess: init = tf.initialize_all_variables() sess.run(init) print sess.run(output) print sess.run(tf.shape(output))
输入参数:
value
: 一个四维的Tensor
。数据维度是 [batch, height, width, channels]
。数据类型是float32
,float64
,qint8
,quint8
,qint32
。ksize
: 一个长度不小于4的整型数组。每一位上面的值对应于输入数据张量中每一维的窗口对应值。strides
: 一个长度不小于4的整型数组。该参数指定滑动窗口在输入数据张量每一维上面的步长。padding
: 一个字符串,取值为 SAME
或者 VALID
。name
: (可选)为这个操做取一个名字。输出参数:
Tensor
,数据类型和value
相同。tf.nn.max_pool(value, ksize, strides, padding, name=None)
解释:这个函数的做用是计算池化区域中元素的最大值。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import tensorflow as tf input_data = tf.Variable( np.random.rand(10,6,6,3), dtype = np.float32 ) filter_data = tf.Variable( np.random.rand(2, 2, 3, 10), dtype = np.float32) y = tf.nn.conv2d(input_data, filter_data, strides = [1, 1, 1, 1], padding = 'SAME') output = tf.nn.max_pool(value = y, ksize = [1, 2, 2, 1], strides = [1, 1, 1, 1], padding = 'SAME') with tf.Session() as sess: init = tf.initialize_all_variables() sess.run(init) print sess.run(output) print sess.run(tf.shape(output))
输入参数:
value
: 一个四维的Tensor
。数据维度是 [batch, height, width, channels]
。数据类型是float32
,float64
,qint8
,quint8
,qint32
。ksize
: 一个长度不小于4的整型数组。每一位上面的值对应于输入数据张量中每一维的窗口对应值。strides
: 一个长度不小于4的整型数组。该参数指定滑动窗口在输入数据张量每一维上面的步长。padding
: 一个字符串,取值为 SAME
或者 VALID
。name
: (可选)为这个操做取一个名字。输出参数:
Tensor
,数据类型和value
相同。tf.nn.max_pool_with_argmax(input, ksize, strides, padding, Targmax = None, name=None)
解释:这个函数的做用是计算池化区域中元素的最大值和该最大值所在的位置。
由于在计算位置 argmax
的时候,咱们将 input
铺平了进行计算,因此,若是 input = [b, y, x, c]
,那么索引位置是 ( ( b * height + y ) * width + x ) * channels + c
。
查看源码,该API只能在GPU环境下使用,因此我没有测试下面的使用例子,若是你能够测试,请告诉我程序是否能够运行。
源码展现:
REGISTER_KERNEL_BUILDER(Name("MaxPoolWithArgmax") .Device(DEVICE_GPU) .TypeConstraint<int64>("Targmax") .TypeConstraint<float>("T"), MaxPoolingWithArgmaxOp<Eigen::GpuDevice, float>); REGISTER_KERNEL_BUILDER(Name("MaxPoolWithArgmax") .Device(DEVICE_GPU) .TypeConstraint<int64>("Targmax") .TypeConstraint<Eigen::half>("T"), MaxPoolingWithArgmaxOp<Eigen::GpuDevice, Eigen::half>);
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import tensorflow as tf input_data = tf.Variable( np.random.rand(10,6,6,3), dtype = tf.float32 ) filter_data = tf.Variable( np.random.rand(2, 2, 3, 10), dtype = np.float32) y = tf.nn.conv2d(input_data, filter_data, strides = [1, 1, 1, 1], padding = 'SAME') output, argmax = tf.nn.max_pool_with_argmax(input = y, ksize = [1, 2, 2, 1], strides = [1, 1, 1, 1], padding = 'SAME') with tf.Session() as sess: init = tf.initialize_all_variables() sess.run(init) print sess.run(output) print sess.run(tf.shape(output))
输入参数:
input
: 一个四维的Tensor
。数据维度是 [batch, height, width, channels]
。数据类型是float32
。ksize
: 一个长度不小于4的整型数组。每一位上面的值对应于输入数据张量中每一维的窗口对应值。strides
: 一个长度不小于4的整型数组。该参数指定滑动窗口在输入数据张量每一维上面的步长。padding
: 一个字符串,取值为 SAME
或者 VALID
。Targmax
: 一个可选的数据类型: tf.int32
或者tf.int64
。默认状况下是 tf.int64
。name
: (可选)为这个操做取一个名字。输出参数:
一个元祖张量 (output, argmax)
:
output
: 一个Tensor
,数据类型是float32
。表示池化区域的最大值。argmax
: 一个Tensor
,数据类型是Targmax
。数据维度是四维的。标准化是能防止模型过拟合的好方法。特别是在大数据的状况下。
tf.nn.l2_normalize(x, dim, epsilon=1e-12, name=None)
解释:这个函数的做用是利用 L2 范数对指定维度 dim
进行标准化。
好比,对于一个一维的张量,指定维度 dim = 0
,那么计算结果为:
output = x / sqrt( max( sum( x ** 2 ) , epsilon ) )
假设 x
是多维度的,那么标准化只会独立的对维度 dim
进行,不会影响到别的维度。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import tensorflow as tf input_data = tf.Variable( np.random.rand(2, 3), dtype = tf.float32 ) output = tf.nn.l2_normalize(input_data, dim = 0) with tf.Session() as sess: init = tf.initialize_all_variables() sess.run(init) print sess.run(output) print sess.run(tf.shape(output))
输入参数:
x
: 一个Tensor
。dim
: 须要标准化的维度。epsilon
: 一个很小的值,肯定标准化的下边界。若是 norm < sqrt(epsilon)
,那么咱们将使用 sqrt(epsilon)
进行标准化。name
: (可选)为这个操做取一个名字。输出参数:
一个 Tensor
,数据维度和 x
相同。
tf.nn.local_response_normalization(input, depth_radius=None, bias=None, alpha=None, beta=None, name=None)
解释:这个函数的做用是计算局部数据标准化。
输入的数据 input
是一个四维的张量,但该张量被看作是一个一维的向量( input
的最后一维做为向量),向量中的每个元素都是一个三维的数组(对应 input
的前三维)。向量的每个元素都是独立的被标准化的。具体数学形式以下:
sqr_sum[a, b, c, d] = sum(input[a, b, c, d - depth_radius : d + depth_radius + 1] ** 2) output = input / (bias + alpha * sqr_sum ** beta)
若是你想更加了解这种标准化,能够参考这篇论文。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import tensorflow as tf input_data = tf.Variable( np.random.rand(1, 2, 3, 4), dtype = tf.float32 ) output = tf.nn.local_response_normalization(input_data) with tf.Session() as sess: init = tf.initialize_all_variables() sess.run(init) print sess.run(input_data) print sess.run(output) print sess.run(tf.shape(output))
输入参数:
input
: 一个Tensor
。数据维度是四维的,数据类型是 float32
。depth_radius
: (可选)一个整型,默认状况下是 5 。bias
: (可选)一个浮点型,默认状况下是 1。一个偏移项,为了不除0,通常状况下咱们取正值。alpha
: (可选)一个浮点型,默认状况下是 1。一个比例因子,通常状况下咱们取正值。beta
: (可选)一个浮点型,默认状况下是 0.5。一个指数。name
: (可选)为这个操做取一个名字。输出参数:
一个 Tensor
,数据类型是 float32
。
tf.nn.moments(x, axes, name=None)
解释:这个函数的做用是计算 x
的均值和方差。
沿着 axes
维度,计算 x
的均值和方差。若是 x
是一维的,而且 axes = [0]
,那么就是计算整个向量的均值和方差。
若是,咱们取 axes = [0, 1, 2] (batch, height, width)
,那么咱们就是计算卷积的全局标准化。若是只是计算批处理的标准化,那么咱们取 axes = [0] (batch)
。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import tensorflow as tf input_data = tf.Variable( np.random.rand(2, 3), dtype = tf.float32 ) mean, variance = tf.nn.moments(input_data, [0]) with tf.Session() as sess: init = tf.initialize_all_variables() sess.run(init) print sess.run(input_data) print sess.run(mean) print sess.run(tf.shape(mean))
输入参数:
x
: 一个Tensor
。axes
: 一个整型的数组,肯定计算均值和方差的维度 。name
: 为这个操做取个名字。输出参数:
两个 Tensor
,分别是均值 mean
和方差 variance
。
度量两个张量或者一个张量和零之间的损失偏差,这个可用于在一个回归任务或者用于正则的目的(权重衰减)。
tf.nn.l2_loss(t, name=None)
解释:这个函数的做用是利用 L2 范数来计算张量的偏差值,可是没有开方而且只取 L2 范数的值的一半,具体以下:
output = sum(t ** 2) / 2
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import tensorflow as tf input_data = tf.Variable( np.random.rand(2, 3), dtype = tf.float32 ) output = tf.nn.l2_loss(input_data) with tf.Session() as sess: init = tf.initialize_all_variables() sess.run(init) print sess.run(input_data) print sess.run(output) print sess.run(tf.shape(output))
输入参数:
t
: 一个Tensor
。数据类型必须是一下之一:float32
,float64
,int64
,int32
,uint8
,int16
,int8
,complex64
,qint8
,quint8
,qint32
。虽然通常状况下,数据维度是二维的。可是,数据维度能够取任意维度。name
: 为这个操做取个名字。输出参数:
一个 Tensor
,数据类型和 t
相同,是一个标量。
Tensorflow提供了操做,能帮助你更好的进行分类操做。
tf.nn.sigmoid_cross_entropy_with_logits(logits, targets, name=None)
解释:这个函数的做用是计算 logits
经 sigmoid 函数激活以后的交叉熵。
对于一个不相互独立的离散分类任务,这个函数做用是去度量几率偏差。好比,好比,在一张图片中,同时包含多个分类目标(大象和狗),那么就可使用这个函数。
为了描述简洁,咱们规定 x = logits
,z = targets
,那么 Logistic 损失值为:
x - x * z + log( 1 + exp(-x) )
为了确保计算稳定,避免溢出,真实的计算实现以下:
max(x, 0) - x * z + log(1 + exp(-abs(x)) )
logits
和 targets
必须有相同的数据类型和数据维度。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import tensorflow as tf input_data = tf.Variable( np.random.rand(1,3), dtype = tf.float32 ) output = tf.nn.sigmoid_cross_entropy_with_logits(input_data, [[1.0,0.0,0.0]]) with tf.Session() as sess: init = tf.initialize_all_variables() sess.run(init) print sess.run(input_data) print sess.run(output) print sess.run(tf.shape(output))
输入参数:
logits
: 一个Tensor
。数据类型是如下之一:float32
或者float64
。targets
: 一个Tensor
。数据类型和数据维度都和 logits
相同。name
: 为这个操做取个名字。输出参数:
一个 Tensor
,数据维度和 logits
相同。
tf.nn.softmax(logits, name=None)
解释:这个函数的做用是计算 softmax 激活函数。
对于每一个批 i
和 分类 j
,咱们能够获得:
softmax[i, j] = exp(logits[i, j]) / sum(exp(logits[i]))
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import tensorflow as tf input_data = tf.Variable( [[0.2, 0.1, 0.9]] , dtype = tf.float32 ) output = tf.nn.softmax(input_data) with tf.Session() as sess: init = tf.initialize_all_variables() sess.run(init) print sess.run(input_data) print sess.run(output) print sess.run(tf.shape(output))
输入参数:
logits
: 一个Tensor
。数据类型是如下之一:float32
或者float64
。数据维度是二维 [batch_size, num_classes]
。name
: 为这个操做取个名字。输出参数:
一个 Tensor
,数据维度和数据类型都和 logits
相同。
tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)
解释:这个函数的做用是计算 logits
经 softmax 函数激活以后的交叉熵。
对于每一个独立的分类任务,这个函数是去度量几率偏差。好比,在 CIFAR-10 数据集上面,每张图片只有惟一一个分类标签:一张图多是一只狗或者一辆卡车,但绝对不可能二者都在一张图中。(这也是和 `tf.nn.sigmoid_cross_entropy_with_logits(logits, targets, name=None)
`这个API的区别)
警告:输入API的数据 logits
不能进行缩放,由于在这个API的执行中会进行 softmax 计算,若是 logits
进行了缩放,那么会影响计算正确率。不要调用这个API区计算 softmax 的值,由于这个API最终输出的结果并非通过 softmax 函数的值。
logits
和 labels
必须有相同的数据维度 [batch_size, num_classes]
,和相同的数据类型 float32
或者 float64
。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import tensorflow as tf input_data = tf.Variable( [[0.2, 0.1, 0.9]] , dtype = tf.float32 ) output = tf.nn.softmax_cross_entropy_with_logits(input_data, [[1,0,0]]) with tf.Session() as sess: init = tf.initialize_all_variables() sess.run(init) print sess.run(input_data) print sess.run(output) print sess.run(tf.shape(output))
输入参数:
logits
: 一个没有缩放的对数张量。labels
: 每一行 labels[i]
必须是一个有效的几率分布值。name
: 为这个操做取个名字。输出参数:
一个 Tensor
,数据维度是一维的,长度是 batch_size
,数据类型都和 logits
相同。
Tensorflow 提供了从张量中嵌入查找的库。
tf.nn.embedding_lookup(params, ids, name=None)
解释:这个函数的做用是查询 params
中索引是 ids
的值。
这个操做是 tf.gather()
的一个泛化,但它能够被并行计算处理,其中 params
被认为是一个大型的张量库,ids
中的值对应于各个分区。
若是 len(params) > 1
,ids
中每一个元素 id
对应于 params
中每一个分区 p
,即 p = id % len(params)
。那么,咱们获得的每一个切片是 params[p][id // len(params), ...]
。
最后获得的切片结果被从新链接成一个稠密张量,最后返回的张量维度是 shape(ids) + shape(params)[1: ]
。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import tensorflow as tf import numpy as np params = tf.constant(np.random.rand(3,4)) ids = tf.constant([0,2]) output = tf.nn.embedding_lookup(params, ids) with tf.Session() as sess: print 'params: ', sess.run(params) print '-------------------------------' print '输出第0行和第2行: ', sess.run(output)
输入参数:
params
: 一个拥有相同数据维度和数据类型的张量。ids
: 一个张量,数据类型是 int32
。name
: 为这个操做取个名字。输出参数:
一个 Tensor
,数据类型和 params
相同。
异常:
数值异常
: 若是 params
是空的,那么会抛出这个异常。评估操做对于测量网络的性能是有用的。 因为它们是不可微分的,因此它们一般只是被用在评估阶段。
tf.nn.top_k(input, k, name=None)
解释:这个函数的做用是返回 input
中每行最大的 k
个数,而且返回它们所在位置的索引。
value(i, j)
表示输入数据 input(i)
的第 j
大的元素。
indices(i, j)
给出对应元素的列索引,即 input(i, indices(i, j)) = values(i, j)
。若是遇到两个相等的元素,那么咱们先取索引小的值。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import tensorflow as tf import numpy as np input = tf.constant(np.random.rand(3,4)) k = 2 output = tf.nn.top_k(input, k) with tf.Session() as sess: print sess.run(input) print '--------------------' print sess.run(output)
输入参数:
input
: 一个张量,数据类型必须是如下之一:float32
、float64
、int32
、int64
、uint8
、int16
、int8
。数据维度是 batch_size
乘上 x
个类别。k
: 一个整型,必须 >= 1
。在每行中,查找最大的 k
个值。name
: 为这个操做取个名字。输出参数:
一个元组 Tensor
,数据元素是 (values, indices)
,具体以下:
values
: 一个张量,数据类型和 input
相同。数据维度是 batch_size
乘上 k
个最大值。indices
: 一个张量,数据类型是 int32
。每一个最大值在 input
中的索引位置。tf.nn.in_top_k(predictions, targets, k, name=None)
解释:这个函数的做用是返回一个布尔向量,说明目标值是否存在于预测值之中。
输出数据是一个 batch_size
长度的布尔向量,若是目标值存在于预测值之中,那么 out[i] = true
。
注意:targets
是predictions
中的索引位,并非 predictions
中具体的值。
使用例子:
#!/usr/bin/env python # -*- coding: utf-8 -*- import tensorflow as tf import numpy as np input = tf.constant(np.random.rand(3,4), tf.float32) k = 2 output = tf.nn.in_top_k(input, [3,3,3], k) with tf.Session() as sess: print sess.run(input) print '--------------------' print sess.run(output)
输入参数:
predictions
: 一个张量,数据类型是 float32
。数据维度是 batch_size
乘上 x
个类别。targets
: 一个张量,数据类型是 int32
。一个长度是 batch_size
的向量,里面的元素是目标 class ID
。k
: 一个整型。在每行中,查找最大的 k
个值。name
: 为这个操做取个名字。输出参数:
一个张量,数据类型是 bool
。判断是否预测正确。
这是一些采样的函数,因为目前不是很理解,暂且不学习......
做者:chen_h
微信号 & QQ:862251340
简书地址:https://www.jianshu.com/p/e3a...
CoderPai 是一个专一于算法实战的平台,从基础的算法到人工智能算法都有设计。若是你对算法实战感兴趣,请快快关注咱们吧。加入AI实战微信群,AI实战QQ群,ACM算法微信群,ACM算法QQ群。长按或者扫描以下二维码,关注 “CoderPai” 微信号(coderpai)