我是靠谱客的博主 真实鸡,最近开发中收集的这篇文章主要介绍Tensorflow(二),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.tf.nn.bias_add():

参考:https://blog.csdn.net/mieleizhi0522/article/details/80416668

一个叫bias的向量加到一个叫value的矩阵上,是向量与矩阵的每一行进行相加,得到的结果和value矩阵大小相同。

解释:这个函数的作用是将偏差项bias加到value上面。可以看作tf.add的一weide个特列,其中bias必须是一维的。

import tensorflow as tf
a=tf.constant([[1,1],[2,2],[3,3]],dtype=tf.float32)
b=tf.constant([1,-1],dtype=tf.float32)
c=tf.constant([1],dtype=tf.float32)
with tf.Session() as sess:
print('bias_add:')
print(sess.run(tf.nn.bias_add(a, b)))
#执行下面语句错误
#print(sess.run(tf.nn.bias_add(a, c)))

输出结果:

bias_add:
[[ 2. 0.]
[ 3. 1.]

[ 4. 2.]]

2.tf.transpose函数解析

tf.transpose(a,perm=None,name='transpose')

解释:将a进行转置,并且根据perm参数重新排列输出维度。这是对数据的维度的进行操作的形式。

图像处理时数据集中存储数据的形式为[channel,image_height,image_width],在tensorflow中使用CNN时我们需要将其转化为[image_height,image_width,channel]的形式,只需要使用tf.transpose(input_data,[1,2,0])

输出数据tensor的第i维将根据perm[i]指定。比如,如果perm没有给定,那么默认是perm = [n-1, n-2, ..., 0],其中rank(a) = n。

import tensorflow as tf
sess = tf.Session()
input_data = tf.constant([[1, 2, 3], [4, 5, 6]])
print(sess.run(tf.transpose(input_data)))
# [[1 4]
#
[2 5]
#
[3 6]]
print(sess.run(input_data))
# [[1 2 3]
#
[4 5 6]]
print(sess.run(tf.transpose(input_data, perm=[1, 0])))
# [[1 4]
#
[2 5]
#
[3 6]]
input_data = tf.constant([[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]])
print('input_data shape: ', sess.run(tf.shape(input_data)))
# [1, 4, 3]
output_data = tf.transpose(input_data, perm=[1, 2, 0])
print('output_data shape: ', sess.run(tf.shape(output_data)))
# [4, 3, 1]
print(sess.run(output_data))
# [[[ 1]
#
[ 2]
#
[ 3]]
#
[[ 4]
#
[ 5]
#
[ 6]]
#
#
[[ 7]
#
[ 8]
#
[ 9]]
#
#
[[10]
#
[11]
#
[12]]]
"""形式为:[[[],[],[]],[[],[],[]],[[],[],[]],[[],[],[]]]"""
"""输入参数:
● a: 一个Tensor。
● perm: 一个对于a的维度的重排列组合。
● name:(可选)为这个操作取一个名字。
输出参数:
● 一个经过翻转的Tensor。"""
#perm没有指定的情况下transpose函数的结果
input_data = tf.constant([[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]])
print('input_data shape: ', sess.run(tf.shape(input_data)))
# [1, 4, 3]
output_data = tf.transpose(input_data)
print('output_data shape: ', sess.run(tf.shape(output_data)))
# output_data shape:
[3 4 1]
sess.close()

 3.tf.multiply()两个矩阵中对应元素各自相乘

格式: tf.multiply(x, y, name=None) 
参数: 
x: 一个类型为:half, float32, float64, uint8, int8, uint16, int16, int32, int64, complex64, complex128的张量。 
y: 一个类型跟张量x相同的张量。  
返回值: x * y element-wise.  
注意: 
(1)multiply这个函数实现的是元素级别的相乘,也就是两个相乘的数元素各自相乘,而不是矩阵乘法,注意和tf.matmul区别。 
(2)两个相乘的数必须有相同的数据类型,不然就会报错。

4.tf.matmul()将矩阵a乘以矩阵b,生成a * b。

格式: tf.matmul(a, b, transpose_a=False, transpose_b=False, adjoint_a=False, adjoint_b=False, a_is_sparse=False, b_is_sparse=False, name=None) 

参考:https://www.cnblogs.com/AlvinSui/p/8987707.html

注:就是线性代数中的矩阵乘法

import tensorflow as tf
#两个矩阵的对应元素各自相乘!!
x=tf.constant([[1.0,2.0,3.0],[1.0,2.0,3.0],[1.0,2.0,3.0]])
y=tf.constant([[0,0,1.0],[0,0,1.0],[0,0,1.0]])
#注意这里这里x,y要有相同的数据类型,不然就会因为数据类型不匹配而出错
z=tf.multiply(x,y)
#两个数相乘
x1=tf.constant(1)
y1=tf.constant(2)
#注意这里这里x1,y1要有相同的数据类型,不然就会因为数据类型不匹配而出错
z1=tf.multiply(x1,y1)
#数和矩阵相乘
x2=tf.constant([[1.0,2.0,3.0],[1.0,2.0,3.0],[1.0,2.0,3.0]])
y2=tf.constant(2.0)
#注意这里这里x1,y1要有相同的数据类型,不然就会因为数据类型不匹配而出错
z2=tf.multiply(x2,y2)
#两个矩阵相乘
x3=tf.constant([[1.0,2.0,3.0],[1.0,2.0,3.0],[1.0,2.0,3.0]])
y3=tf.constant([[0,0,1.0],[0,0,1.0],[0,0,1.0]])
#注意这里这里x,y要满足矩阵相乘的格式要求。
z3=tf.matmul(x,y)
with tf.Session() as sess:
print(sess.run(z))
print(sess.run(z1))
print(sess.run(z2))
print(sess.run(z3))

这里写图片描述

5.tf.argmax()解析

tf.argmax(input,axis)根据axis取值的不同返回每行或者每列最大值的索引。

tf.argmax就是求最大数值所在下标 

test = np.array([[1, 2, 3], [2, 3, 4], [5, 4, 3], [8, 7, 2]])
np.argmax(test, 0)   #输出:array([3, 3, 1]
np.argmax(test, 1)   #输出:array([2, 2, 0, 0]123

axis=0时比较每一列的元素,将每一列最大元素所在的索引记录下来,最后输出每一列最大元素所在的索引数组。

axis=1的时候,将每一行最大元素所在的索引记录下来,最后返回每一行最大元素所在的索引数组。

这是里面都是数组长度一致的情况,如果不一致,axis最大值为最小的数组长度-1,超过则报错。
  当不一致的时候,axis=0的比较也就变成了每个数组的和的比较。

两种axis的理解:axis=0表示的是“按行”,其实就是对每一列的操作,同理,axis=1按列操作,也即对每一行。我觉得可以类比图像的像素矩阵h*w,第一个坐标轴h的方向是向下的,第二个坐标轴w的方向是向右的。

axis=0的行它不是个名词,他更像一个动词,表示“按行前进”,也即第一行,第二行。。。。那么,它实际就是对每一列的操作。

test = np.array([[[1, 2, 3], [2, 3, 5],[2, 2, 2]], [[5, 4, 3], [8, 7, 2],[1, 2, 3]], [[5, 4, 6], [10, 7, 30], [1, 2, 3]]])
array([[[ 1,
2,
3],
[ 2,
3,
5],
[ 2,
2,
2]],
[[ 5,
4,
3],
[ 8,
7,
2],
[ 1,
2,
3]],
[[ 5,
4,
6],
[10,
7, 30],
[ 1,
2,
3]]])
np.argmax(test, 0):
array([[1, 1, 2],
[2, 1, 2],
[0, 0, 1]], dtype=int64)
np.argmax(test, 1):
array([[1, 1, 1],
[1, 1, 0],
[1, 1, 1]], dtype=int64)
np.argmax(test, 2):
array([[2, 2, 0],
[0, 0, 2],
[2, 2, 2]], dtype=int64)

6. tf.nn.sparse_softmax_cross_entropy_with_logits

tf.nn.sparse_softmax_cross_entropy_with_logits(
_sentinel=None,
labels=None,
logits=None,
name=None
)

labels:为样本的真实标签, shape为[batch_size],每一个值∈[0,num_classes),其实就是代表了batch中对应样本的类别,如二分类的label[0,0,1,0...]

logits:为神经网络输出层的输出,shape为[batch_size,num_classes]

首先来说,这个函数的具体实现分为了两个步骤。
(1)softmax

(2)计算交叉熵

参考:https://blog.csdn.net/qq_31829611/article/details/89195148?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

https://blog.csdn.net/ZJRN1027/article/details/80199248

7.tf.nn.softmax_cross_entropy_with_logits

tf.nn.softmax_cross_entropy_with_logits(
_sentinel=None,
labels=None,
logits=None,
dim=-1,
name=None
)

labels:为one-hot处理后的真实标签, shape为[batch_size, num_classes],如多分类的label[0,2,1,0...]处理后的标签为[[1,0,0],[0,0,1],[0,1,0],[1,0,0]...];除了one-hot表示,labels的每一行也可以是一个概率分布,每个数值表示属于每个类别的概率。

注:这个函数将会被弃用,取而代之的是tf.nn.softmax_cross_entropy_with_logits_v2()

logits:为神经网络输出层的输出,shape为[batch_size,num_classes]
注意:两个函数作用是一样的,一个处理的是真是标签,一个处理的是one-hot的标签;

8.tf.squeeze()

squeeze(
input,
axis=None,
name=None,
squeeze_dims=None
)

该函数返回一个张量,这个张量是将原始input中所有维度为1的那些维都删掉的结果
axis可以用来指定要删掉的为1的维度,此处要注意指定的维度必须确保其是1,否则会报错

>>>y = tf.squeeze(inputs, [0, 1], name='squeeze')
>>>ValueError: Can not squeeze dim[0], expected a dimension of 1, got 32 for 'squeeze' (op: 'Squeeze') with input shapes: [32,1,1,3].

例子:

#
't' 是一个维度是[1, 2, 1, 3, 1, 1]的张量
tf.shape(tf.squeeze(t))
# [2, 3], 默认删除所有为1的维度
# 't' 是一个维度[1, 2, 1, 3, 1, 1]的张量
tf.shape(tf.squeeze(t, [2, 4]))
# [1, 2, 3, 1],标号从零开始,只删掉了2和4维的1

9.tf.expand_dims()

TensorFlow中,想要维度增加一维,可以使用tf.expand_dims(input, dim, name=None)函数。当然,我们常用tf.reshape(input, shape=[])也可以达到相同效果,但是有些时候在构建图的过程中,placeholder没有被feed具体的值,这时就会包下面的错误:TypeError: Expected binary or unicode string, got 1 
在这种情况下,我们就可以考虑使用expand_dims来将维度加1。比如我自己代码中遇到的情况,在对图像维度降到二维做特定操作后,要还原成四维[batch, height, width, channels],前后各增加一维。如果用reshape,则因为上述原因报错

one_img2 = tf.reshape(one_img, shape=[1, one_img.get_shape()[0].value, one_img.get_shape()[1].value, 1])

用下面的方法可以实现:

one_img = tf.expand_dims(one_img, 0)
one_img = tf.expand_dims(one_img, -1) #-1表示最后一维
# 't' is a tensor of shape [2]
shape(expand_dims(t, 0)) ==> [1, 2]
shape(expand_dims(t, 1)) ==> [2, 1]
shape(expand_dims(t, -1)) ==> [2, 1]
# 't2' is a tensor of shape [2, 3, 5]
shape(expand_dims(t2, 0)) ==> [1, 2, 3, 5]
shape(expand_dims(t2, 2)) ==> [2, 3, 1, 5]
shape(expand_dims(t2, 3)) ==> [2, 3, 5, 1]

10.tensorflow中的reshape(tensor,[1,-1])和reshape(tensor,[-1,1])

tf.reshape(tensor,[-1,1])将张量变为一维列向量

tf.reshape(tensor,[1,-1])将张量变为一维行向量

11.tf.reshape()

     tf.reshape(tensor,shape,name=None)

函数的作用是将tensor变换为参数shape形式,其中的shape为一个列表形式,特殊的是列表可以实现逆序的遍历,即list(-1).-1所代表的含义是我们不用亲自去指定这一维的大小,函数会自动进行计算,但是列表中只能存在一个-1。

下面就说一下reshape是如何进行矩阵的变换的,其简单的流程就是:
将矩阵t变换为一维矩阵,然后再对矩阵的形式进行更改就好了,具体的流程如下:

reshape(t,shape) =>reshape(t,[-1]) =>reshape(t,shape)
>>>a = np.array([[1,2,3],[4,5,6]])
>>>np.reshape(a,(3,-1))
array([[1, 2],
[3, 4],
[5, 6]])
>>> np.reshape(a,(1,-1))
array([[1, 2, 3, 4, 5, 6]])
>>> np.reshape(a,(6,-1))
array([[1],
[2],
[3],
[4],
[5],
[6]])
>>> np.reshape(a,(-1,1))
array([[1],
[2],
[3],
[4],
[5],
[6]])

 12.【TensorFlow】理解tf.nn.conv2d方法 ( 附代码详解注释 )

方法定义
      tf.nn.conv2d (input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)

参数:

  • input : 输入的要做卷积的图片,要求为一个张量,shape为 [ batch, in_height, in_weight, in_channel ],其中batch为图片的数量,in_height 为图片高度,in_weight 为图片宽度,in_channel 为图片的通道数,灰度图该值为1,彩色图为3。(也可以用其它值,但是具体含义不是很理解)
  • filter: 卷积核,要求也是一个张量,shape为 [ filter_height, filter_weight, in_channel, out_channels ],其中 filter_height 为卷积核高度,filter_weight 为卷积核宽度,in_channel 是图像通道数 ,和 input 的 in_channel 要保持一致,out_channel 是卷积核数量。
  • strides: 卷积时在图像每一维的步长,这是一个一维的向量,[ 1, strides, strides, 1],第一位和最后一位固定必须是1
  • padding: string类型,值为“SAME” 和 “VALID”,表示的是卷积的形式,是否考虑边界。"SAME"是考虑边界,不足的时候用0去填充周围,"VALID"则不考虑
  • use_cudnn_on_gpu: bool类型,是否使用cudnn加速,默认为true

具体实现
参考:https://blog.csdn.net/zuolixiangfisher/article/details/80528989

import tensorflow as tf
# case 1
# 输入是1张 3*3 大小的图片,图像通道数是5,卷积核是 1*1 大小,数量是1
# 步长是[1,1,1,1]最后得到一个 3*3 的feature map
# 1张图最后输出就是一个 shape为[1,3,3,1] 的张量
input = tf.Variable(tf.random_normal([1,3,3,5]))
filter = tf.Variable(tf.random_normal([1,1,5,1]))
op1 = tf.nn.conv2d(input, filter, strides=[1,1,1,1], padding='SAME')
# case 2
# 输入是1张 3*3 大小的图片,图像通道数是5,卷积核是 2*2 大小,数量是1
# 步长是[1,1,1,1]最后得到一个 3*3 的feature map
# 1张图最后输出就是一个 shape为[1,3,3,1] 的张量
input = tf.Variable(tf.random_normal([1,3,3,5]))
filter = tf.Variable(tf.random_normal([2,2,5,1]))
op2 = tf.nn.conv2d(input, filter, strides=[1,1,1,1], padding='SAME')
# case 3
# 输入是1张 3*3 大小的图片,图像通道数是5,卷积核是 3*3 大小,数量是1
# 步长是[1,1,1,1]最后得到一个 1*1 的feature map (不考虑边界)
# 1张图最后输出就是一个 shape为[1,1,1,1] 的张量
input = tf.Variable(tf.random_normal([1,3,3,5]))
filter = tf.Variable(tf.random_normal([3,3,5,1]))
op3 = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='VALID')
# case 4
# 输入是1张 5*5 大小的图片,图像通道数是5,卷积核是 3*3 大小,数量是1
# 步长是[1,1,1,1]最后得到一个 3*3 的feature map (不考虑边界)
# 1张图最后输出就是一个 shape为[1,3,3,1] 的张量
input = tf.Variable(tf.random_normal([1,5,5,5]))
filter = tf.Variable(tf.random_normal([3,3,5,1]))
op4 = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='VALID')
# case 5
# 输入是1张 5*5 大小的图片,图像通道数是5,卷积核是 3*3 大小,数量是1
# 步长是[1,1,1,1]最后得到一个 5*5 的feature map (考虑边界)
# 1张图最后输出就是一个 shape为[1,5,5,1] 的张量
input = tf.Variable(tf.random_normal([1,5,5,5]))
filter = tf.Variable(tf.random_normal([3,3,5,1]))
op5 = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='SAME')
# case 6
# 输入是1张 5*5 大小的图片,图像通道数是5,卷积核是 3*3 大小,数量是7
# 步长是[1,1,1,1]最后得到一个 5*5 的feature map (考虑边界)
# 1张图最后输出就是一个 shape为[1,5,5,7] 的张量
input = tf.Variable(tf.random_normal([1,5,5,5]))
filter = tf.Variable(tf.random_normal([3,3,5,7]))
op6 = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='SAME')
# case 7
# 输入是1张 5*5 大小的图片,图像通道数是5,卷积核是 3*3 大小,数量是7
# 步长是[1,2,2,1]最后得到7个 3*3 的feature map (考虑边界)
# 1张图最后输出就是一个 shape为[1,3,3,7] 的张量
input = tf.Variable(tf.random_normal([1,5,5,5]))
filter = tf.Variable(tf.random_normal([3,3,5,7]))
op7 = tf.nn.conv2d(input, filter, strides=[1, 2, 2, 1], padding='SAME')
# case 8
# 输入是10 张 5*5 大小的图片,图像通道数是5,卷积核是 3*3 大小,数量是7
# 步长是[1,2,2,1]最后每张图得到7个 3*3 的feature map (考虑边界)
# 10张图最后输出就是一个 shape为[10,3,3,7] 的张量
input = tf.Variable(tf.random_normal([10,5,5,5]))
filter = tf.Variable(tf.random_normal([3,3,5,7]))
op8 = tf.nn.conv2d(input, filter, strides=[1, 2, 2, 1], padding='SAME')
init = tf.initialize_all_variables()
with tf.Session() as sess:
sess.run(init)
print('*' * 20 + ' op1 ' + '*' * 20)
print(sess.run(op1))
print('*' * 20 + ' op2 ' + '*' * 20)
print(sess.run(op2))
print('*' * 20 + ' op3 ' + '*' * 20)
print(sess.run(op3))
print('*' * 20 + ' op4 ' + '*' * 20)
print(sess.run(op4))
print('*' * 20 + ' op5 ' + '*' * 20)
print(sess.run(op5))
print('*' * 20 + ' op6 ' + '*' * 20)
print(sess.run(op6))
print('*' * 20 + ' op7 ' + '*' * 20)
print(sess.run(op7))
print('*' * 20 + ' op8 ' + '*' * 20)
print(sess.run(op8))

13.【Tensorflow】tf.nn.atrous_conv2d如何实现空洞卷积?

方法定义
    tf.nn.atrous_conv2d(value,filters,rate,padding,name=None)

参数:

  • value:指需要做卷积的输入图像,要求是一个4维Tensor,具有[batch, height, width, channels]这样的shape,具体含义是[训练时一个batch的图片数量, 图片高度, 图片宽度, 图像通道数]
  • filters:相当于CNN中的卷积核,要求是一个4维Tensor,具有[filter_height, filter_width, channels, out_channels]这样的shape,具体含义是[卷积核的高度,卷积核的宽度,图像通道数,卷积核个数],同理这里第三维channels,就是参数value的第四维
  • rate:要求是一个int型的正数,正常的卷积操作应该会有stride(即卷积核的滑动步长),但是空洞卷积是没有stride参数的,这一点尤其要注意。取而代之,它使用了新的rate参数,那么rate参数有什么用呢?它定义为我们在输入图像上卷积时的采样间隔,你可以理解为卷积核当中穿插了(rate-1)数量的“0”,把原来的卷积核插出了很多“洞洞”,这样做卷积时就相当于对原图像的采样间隔变大了。具体怎么插得,可以看后面更加详细的描述。此时我们很容易得出rate=1时,就没有0插入,此时这个函数就变成了普通卷积。
  • padding:string类型的量,只能是”SAME”,”VALID”其中之一,这个值决定了不同边缘填充方式。

那“stride”参数呢。其实这个函数已经默认了stride=1,也就是滑动步长无法改变,固定为1。

结果返回一个Tensor,填充方式为“VALID”时,返回[batch,height-2*(filter_width-1),width-2*(filter_height-1),out_channels]的Tensor,填充方式为“SAME”时,返回[batch, height, width, out_channels]的Tensor。

参考:https://blog.csdn.net/mao_xiao_feng/article/details/78003730

 

最后

以上就是真实鸡为你收集整理的Tensorflow(二)的全部内容,希望文章能够帮你解决Tensorflow(二)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部