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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LSTM模型的输入单输出指的是模型接收两个输入(例如两个不同的序列数据),并输出一个结果。 在TensorFlow中实现LSTM模型的输入单输出可以使用以下步骤: 1. 导入必要的库和模块 ```python import tensorflow as tf from tensorflow.keras.layers import Input, LSTM, Dense from tensorflow.keras.models import Model ``` 2. 定义模型的输入 ```python input1 = Input(shape=(timesteps1, features1)) input2 = Input(shape=(timesteps2, features2)) ``` 其中,timesteps1和timesteps2分别表示输入1和输入2的时间步数,features1和features2分别表示输入1和输入2的特征数。 3. 定义LSTM层 ```python lstm1 = LSTM(units=hidden_size1)(input1) lstm2 = LSTM(units=hidden_size2)(input2) ``` 其中,hidden_size1和hidden_size2分别表示LSTM层的隐藏单元数。 4. 将LSTM层的输出连接起来 ```python merged = tf.keras.layers.concatenate([lstm1, lstm2]) ``` 5. 定义输出层 ```python output = Dense(units=output_size, activation='softmax')(merged) ``` 其中,output_size表示输出层的大小,activation可以根据具体问题选择不同的激活函数。 6. 定义模型 ```python model = Model(inputs=[input1, input2], outputs=output) ``` 7. 编译模型并训练 ```python model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) model.fit([input_data1, input_data2], output_data, epochs=num_epochs, batch_size=batch_size) ``` 其中,input_data1和input_data2表示输入1和输入2的数据,output_data表示输出数据,num_epochs表示训练轮数,batch_size表示批次大小。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值