Tensorflow学习日志

Tensorflow学习日志

2020.2.17

1.ImportError: cannot import name '_validate_lengths' 解决方法

numpy升级以后遇到以上错误,版本变化函数名称发生变化:根据错误提示点击到arrycrop.py文件

加入下面语句

修改前:

1
2
import numpy as np
from numpy.lib.arraypad import _validate_lengths

修改后

1
2
3
4
5
6
7
import numpy as np
from distutils.version import LooseVersion as Version
old_numpy = Version(np.__version__) < Version('1.16')
if old_numpy:
from numpy.lib.arraypad import _validate_lengths
else:
from numpy.lib.arraypad import _as_pairs

2020.2.16

1.python里__pycache__文件夹的产生与作用

模块的调用
Python中导入模块时,实际上会把被导入的模块执行一遍,如下:
先看被调用的模块test.py:

1
2
3
def haha():
print("哈哈")
haha()

再看主程序main.py:

1
2
import test
print("一条大树")

执行结果是:

1
2
哈哈
一条大树

那怎么才能只是单纯调用而不执行被调用模块的代码呢?要想被调用模块代码不被执行,前提得知道变量__name__是什么意思,简单来说就是,如果不涉及模块导入的话,__name__的值就是” __main__“,如果当此模块被导入引用的话,那么这个模块内的__name__值就是文件的名字(不带.py),如下test_1.py:

1
2
3
4
5
def haha():
print("哈哈")

haha()
print(__name__)

test_1.py执行结果为:

1
2
哈哈
__main__

如果test_1被导入引用的话,如test_2:

1
2
import test_1
print("一条大树")

test_2x运行结果为:

1
2
3
哈哈
test_1
一条大树

上边所说要是弄懂的话,那我们在被调用的模块中,可执行的代码前加上这么一句判断,if __name __ == '__main __':,被调用的模块的代码就不会被执行了!

接下来才是正题
以下参考自Joy_Shen的一个回答。
先大概了解一下python基本运行机制。Python程序运行时不需要编译成二进制代码,而直接从源码运行程序,简单来说是,Python解释器将源码转换为字节码,然后再由解释器来执行这些字节码。

解释器的具体工作:
1、完成模块的加载和链接;
2、将源代码编译为PyCodeObject对象(即字节码),写入内存中,供CPU读取;
3、从内存中读取并执行,结束后将PyCodeObject写回硬盘当中,也就是复制到.pyc或.pyo文件中,以保存当前目录下所有脚本的字节码文件。

之后若再次执行该脚本,它先检查【本地是否有上述字节码文件】和【该字节码文件的修改时间是否在其源文件之后】,是就直接执行,否则重复上述步骤。

__pycache__文件夹的意义何在呢?
因为第一次执行代码的时候,Python解释器已经把编译的字节码放在__pycache__文件夹中,这样以后再次运行的话,如果被调用的模块未发生改变,那就直接跳过编译这一步,直接去__pycache__文件夹中去运行相关的 *.pyc 文件,大大缩短了项目运行前的准备时间。

2.梯度下降法(minist,softmax)

不使用tf的梯度下降

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import tensorflow as tf

#Import MNIST data
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("./MNIST_data", one_hot=True)

#Parameters
learning_rate = 0.01
training_epochs = 10
batch_size = 100
display_step = 1

#Parameters
learning_rate = 0.01
training_epochs = 10
batch_size = 100
display_step = 1

#tf Graph Input
x = tf.placeholder(tf.float32, [None, 784]) # mnist data image of shape 28*28=784
y = tf.placeholder(tf.float32, [None, 10]) # 0-9 digits recognition => 10 classes

#Set model weights
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))

#Construct model
pred = tf.nn.softmax(tf.matmul(x, W)+b) # Softmax

#Minimize error using cross entropy
cost = tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred), reduction_indices=1))

W_grad = - tf.matmul ( tf.transpose(x) , y - pred)
b_grad = - tf.reduce_mean( tf.matmul(tf.transpose(x), y - pred), reduction_indices=0)

new_W = W.assign(W - learning_rate * W_grad)
new_b = b.assign(b - learning_rate * b_grad)

init = tf.global_variables_initializer()


with tf.Session() as sess:
sess.run(init)

# Training cycle
for epoch in range(training_epochs):
avg_cost = 0.
total_batch = int(mnist.train.num_examples / batch_size)
# Loop over all batches
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
# Fit training using batch data
_, _, c = sess.run([new_W, new_b, cost], feed_dict={x: batch_xs, y: batch_ys})

# Compute average loss
avg_cost += c / total_batch
# Display logs per epoch step
if (epoch + 1) % display_step == 0:
print("Epoch:", '%04d' % (epoch + 1), "cost=", "{:.9f}".format(avg_cost))

# test
acc=tf.reduce_mean(tf.cast(tf.equal(tf.argmax(pred,1),tf.argmax(y,1)),tf.float32))
print('test acc',acc.eval({x: mnist.test.images, y: mnist.test.labels}))

print("Optimization Finished!")

使用tf的随机梯度下降

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import tensorflow as tf

#Import MNIST data
import input_data
mnist = input_data.read_data_sets("./MNIST_data", one_hot=True)

#Parameters
learning_rate = 0.01
training_epochs = 10
batch_size = 100
display_step = 1

#Parameters
learning_rate = 0.01
training_epochs = 10
batch_size = 100
display_step = 1

#tf Graph Input
x = tf.placeholder(tf.float32, [None, 784]) # mnist data image of shape 28*28=784
y = tf.placeholder(tf.float32, [None, 10]) # 0-9 digits recognition => 10 classes

#Set model weights
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))

#Construct model
pred = tf.nn.softmax(tf.matmul(x, W)+b) # Softmax

#Minimize error using cross entropy
cost = tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred), reduction_indices=1))

#W_grad = - tf.matmul ( tf.transpose(x) , y - pred)
#b_grad = - tf.reduce_mean( tf.matmul(tf.transpose(x), y - pred), reduction_indices=0)
W_grad, b_grad=tf.gradients(cost,[W,b])

new_W = W.assign(W - learning_rate * W_grad)
new_b = b.assign(b - learning_rate * b_grad)

init = tf.global_variables_initializer()


with tf.Session() as sess:
sess.run(init)

# Training cycle
for epoch in range(training_epochs):
avg_cost = 0.
total_batch = int(mnist.train.num_examples / batch_size)
# Loop over all batches
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
# Fit training using batch data
_, _, c = sess.run([new_W, new_b, cost], feed_dict={x: batch_xs, y: batch_ys})

# Compute average loss
avg_cost += c / total_batch
# Display logs per epoch step
if (epoch + 1) % display_step == 0:
print("Epoch:", '%04d' % (epoch + 1), "cost=", "{:.9f}".format(avg_cost))

# test
acc=tf.reduce_mean(tf.cast(tf.equal(tf.argmax(pred,1),tf.argmax(y,1)),tf.float32))
print('test acc',acc.eval({x: mnist.test.images, y: mnist.test.labels}))

print("Optimization Finished!")

还有一些梯度下降例子在这里
https://blog.csdn.net/wc781708249/article/details/79290523

3.卷积

读取图片,生成图片

1
2
3
4
5
6
7
8
9
10
11
12
import matplotlib.pyplot as plt
import cv2
from PIL import Image
from io import BytesIO
import numpy as np

#图片转numpy数组
img_path = "images/1.jpg"
img_data = cv2.imread(img_path)
#numpy数组转图片
#img_data = np.linspace(0,255,100*100*3).reshape(100,100,-1).astype(np.uint8)
cv2.imwrite("images/2.jpg",img_data) # 在当前目录下会生成一张img.jpg的图片

卷积函数

1
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

卷积实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import cv2
import numpy as np
import tensorflow as tf


img_path = "images/2.jpg"
img_data = cv2.imread(img_path)

input_img_data=img_data.reshape(1,512, 512, 3)
input_img_data=tf.constant(input_img_data,dtype=tf.float32)

kernel1 = tf.constant(
[
[
[
[0.5],
[0.5],
[0.5]
],
[
[0.5],
[0.5],
[0.5]
]
],
[
[
[0.5],
[0.5],
[0.5]
],
[
[0.5],
[0.5],
[0.5]
]
],
]
)
kernel = tf.random_normal([2,2,3,3])
sess=tf.compat.v1.Session()
out_img_data = tf.nn.conv2d(input_img_data, kernel,strides=[1, 1, 1, 1],padding='SAME')
out_img_data = sess.run(out_img_data)
out_img_data.resize(512, 512, 3)

cv2.imwrite("images/2.1.jpg",out_img_data)

2020.2.12

1.import错误

换tensorflow版本或者cudnn版本。2.0.0可以运行

2.清除session缓存

1
2
3
from keras import backend as K
K.clear_session()
tf.compat.v1.reset_default_graph()

3.保存图

1
2
3
sess=tf.compat.v1.Session()
sess.run(c)
writer=tf.compat.v1.summary.FileWriter('./my_graph',sess.graph)

4.用浏览器启动图时,cmd指令(端口6006)

1
tensorboard --logdir="保存图的文件夹"

5.graph

每个程序有默认的graph,可以自己新建graph
新建的graph里添加op用with模块,在with模块外的op操作都视作默认graph里的操作

1
2
3
4
import tensorflow as tf
g=tf.Graph()
with g.as_default():
a=tf.multiply(2,3)

6.session的参数

session有target graph config参数
直接用session读取的是默认的graph

1
2
3
以下操作等价
sess=tf.compat.v1.Session()
sess=tf.compat.v1.Session(graph=tf.compat.v1.get_default_graph())

7.session.run()的参数

fetches:可以是op或者tensor对象,如果是op则输出为noe,如果是tensor则run()的输出为一个numpy数组
feed_dict:从字典中取值

8.占位符的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import tensorflow as tf
import numpy as np
from keras import backend as K
K.clear_session()
tf.compat.v1.reset_default_graph()

a=tf.compat.v1.placeholder(tf.int32,shape=[2],name="input1")
b=tf.reduce_prod(a,name="b")
c=tf.reduce_sum(a,name="c")
d=tf.add(b,c,name="d")

sess=tf.compat.v1.Session()
input_dict={a:np.array([5,3])}
sess.run(d,feed_dict=input_dict)

9.变量的使用

变量在sess.run前必须先初始化,否则会报错
正确做法如下

1
2
3
4
e=tf.Variable(3,name="var1")
sess=tf.compat.v1.Session()
init=tf.compat.v1.global_variables_initializer()
sess.run(init)

多个sess里有多份变量的当前值
想要重置变量为初始值时,执行初始化就行

2020.2.9

1.sess的graph为空

试试清空session命令

常用

1.数学运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 算术操作符:+ - * / % 
tf.add(x, y, name=None) # 加法(支持 broadcasting)
tf.subtract(x, y, name=None) # 减法
tf.multiply(x, y, name=None) # 乘法
tf.divide(x, y, name=None) # 浮点除法, 返回浮点数(python3 除法)
tf.mod(x, y, name=None) # 取余


# 幂指对数操作符:^ ^2 ^0.5 e^ ln
tf.pow(x, y, name=None) # 幂次方
tf.square(x, name=None) # 平方
tf.sqrt(x, name=None) # 开根号,必须传入浮点数或复数
tf.exp(x, name=None) # 计算 e 的次方
tf.log(x, name=None) # 以 e 为底,必须传入浮点数或复数


# 取符号、负、倒数、绝对值、近似、两数中较大/小的
tf.negative(x, name=None) # 取负(y = -x).
tf.sign(x, name=None) # 返回 x 的符号
tf.reciprocal(x, name=None) # 取倒数
tf.abs(x, name=None) # 求绝对值
tf.round(x, name=None) # 四舍五入
tf.ceil(x, name=None) # 向上取整
tf.floor(x, name=None) # 向下取整
tf.rint(x, name=None) # 取最接近的整数
tf.maximum(x, y, name=None) # 返回两tensor中的最大值 (x > y ? x : y)
tf.minimum(x, y, name=None) # 返回两tensor中的最小值 (x < y ? x : y)


# 三角函数和反三角函数
tf.cos(x, name=None)
tf.sin(x, name=None)
tf.tan(x, name=None)
tf.acos(x, name=None)
tf.asin(x, name=None)
tf.atan(x, name=None)


# 其它
tf.div(x, y, name=None) # python 2.7 除法, x/y-->int or x/float(y)-->float
tf.truediv(x, y, name=None) # python 3 除法, x/y-->float
tf.floordiv(x, y, name=None) # python 3 除法, x//y-->int
tf.realdiv(x, y, name=None)
tf.truncatediv(x, y, name=None)
tf.floor_div(x, y, name=None)
tf.truncatemod(x, y, name=None)
tf.floormod(x, y, name=None)
tf.cross(x, y, name=None)
tf.add_n(inputs, name=None) # inputs: A list of Tensor objects, each with same shape and type
tf.squared_difference(x, y, name=None)

矩阵数学函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# 矩阵乘法(tensors of rank >= 2)
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)
#transpose_a:如果 True,a 在乘法之前转置.
#transpose_b:如果 True,b 在乘法之前转置.
#adjoint_a:如果 True,a 在乘法之前共轭和转置.
#adjoint_b:如果 True,b 在乘法之前共轭和转置.

# 转置,可以通过指定 perm=[1, 0] 来进行轴变换
tf.transpose(a, perm=None, name='transpose')


# 在张量 a 的最后两个维度上进行转置
tf.matrix_transpose(a, name='matrix_transpose')
# Matrix with two batch dimensions, x.shape is [1, 2, 3, 4]
# tf.matrix_transpose(x) is shape [1, 2, 4, 3]


# 求矩阵的迹
tf.trace(x, name=None)


# 计算方阵行列式的值
tf.matrix_determinant(input, name=None)


# 求解可逆方阵的逆,input 必须为浮点型或复数
tf.matrix_inverse(input, adjoint=None, name=None)


# 奇异值分解
tf.svd(tensor, full_matrices=False, compute_uv=True, name=None)


# QR 分解
tf.qr(input, full_matrices=None, name=None)


# 求张量的范数(默认2)
tf.norm(tensor, ord='euclidean', axis=None, keep_dims=False, name=None)



# 构建一个单位矩阵, 或者 batch 个矩阵,batch_shape 以 list 的形式传入
tf.eye(num_rows, num_columns=None, batch_shape=None, dtype=tf.float32, name=None)
# Construct one identity matrix.
tf.eye(2)
==> [[1., 0.],
[0., 1.]]

# Construct a batch of 3 identity matricies, each 2 x 2.
# batch_identity[i, :, :] is a 2 x 2 identity matrix, i = 0, 1, 2.
batch_identity = tf.eye(2, batch_shape=[3])

# Construct one 2 x 3 "identity" matrix
tf.eye(2, num_columns=3)
==> [[ 1., 0., 0.],
[ 0., 1., 0.]]


# 构建一个对角矩阵,rank = 2*rank(diagonal)
tf.diag(diagonal, name=None)
# 'diagonal' is [1, 2, 3, 4]
tf.diag(diagonal) ==> [[1, 0, 0, 0]
[0, 2, 0, 0]
[0, 0, 3, 0]
[0, 0, 0, 4]]



# 其它
tf.diag_part
tf.matrix_diag
tf.matrix_diag_part
tf.matrix_band_part
tf.matrix_set_diag
tf.cholesky
tf.cholesky_solve
tf.matrix_solve
tf.matrix_triangular_solve
tf.matrix_solve_ls
tf.self_adjoint_eig
tf.self_adjoint_eigvals

Reduction:reduce various dimensions of a tensor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 计算输入 tensor 所有元素的和,或者计算指定的轴所有元素的和
tf.reduce_sum(input_tensor, axis=None, keep_dims=False, name=None)
# 'x' is [[1, 1, 1]
# [1, 1, 1]]
tf.reduce_sum(x) ==> 6
tf.reduce_sum(x, 0) ==> [2, 2, 2]
tf.reduce_sum(x, 1) ==> [3, 3]
tf.reduce_sum(x, 1, keep_dims=True) ==> [[3], [3]] # 维度不缩减
tf.reduce_sum(x, [0, 1]) ==> 6


# 计算输入 tensor 所有元素的均值/最大值/最小值/积/逻辑与/或
# 或者计算指定的轴所有元素的均值/最大值/最小值/积/逻辑与/或(just like reduce_sum)
tf.reduce_mean(input_tensor, axis=None, keep_dims=False, name=None)
tf.reduce_max(input_tensor, axis=None, keep_dims=False, name=None)
tf.reduce_min(input_tensor, axis=None, keep_dims=False, name=None)
tf.reduce_prod(input_tensor, axis=None, keep_dims=False, name=None)
tf.reduce_all(input_tensor, axis=None, keep_dims=False, name=None) # 全部满足条件
tf.reduce_any(input_tensor, axis=None, keep_dims=False, name=None) #至少有一个满足条件


-------------------------------------------
# 分界线以上和 Numpy 中相应的用法完全一致
-------------------------------------------



# inputs 为一 list, 计算 list 中所有元素的累计和,
# tf.add(x, y, name=None)只能计算两个元素的和,此函数相当于扩展了其功能
tf.accumulate_n(inputs, shape=None, tensor_dtype=None, name=None)


# Computes log(sum(exp(elements across dimensions of a tensor)))
tf.reduce_logsumexp(input_tensor, axis=None, keep_dims=False, name=None)


# Computes number of nonzero elements across dimensions of a tensor
tf.count_nonzero(input_tensor, axis=None, keep_dims=False, name=None)

Scan:perform scans (running totals) across one axis of a tensor

1
2
3
4
5
6
7
8
9
10
11
# Compute the cumulative sum of the tensor x along axis
tf.cumsum(x, axis=0, exclusive=False, reverse=False, name=None)
# Eg:
tf.cumsum([a, b, c]) # => [a, a + b, a + b + c]
tf.cumsum([a, b, c], exclusive=True) # => [0, a, a + b]
tf.cumsum([a, b, c], reverse=True) # => [a + b + c, b + c, c]
tf.cumsum([a, b, c], exclusive=True, reverse=True) # => [b + c, c, 0]


# Compute the cumulative product of the tensor x along axis
tf.cumprod(x, axis=0, exclusive=False, reverse=False, name=None)

Segmentation
沿着第一维(x 轴)根据 segment_ids(list)分割好相应的数据后再进行操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Computes the sum/mean/max/min/prod along segments of a tensor
tf.segment_sum(data, segment_ids, name=None)
# Eg:
m = tf.constant([5,1,7,2,3,4,1,3])
s_id = [0,0,0,1,2,2,3,3]
s.run(tf.segment_sum(m, segment_ids=s_id))
>array([13, 2, 7, 4], dtype=int32)

tf.segment_mean(data, segment_ids, name=None)
tf.segment_max(data, segment_ids, name=None)
tf.segment_min(data, segment_ids, name=None)
tf.segment_prod(data, segment_ids, name=None)


# 其它
tf.unsorted_segment_sum
tf.sparse_segment_sum
tf.sparse_segment_mean
tf.sparse_segment_sqrt_n

序列比较与索引提取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 比较两个 list 或者 string 的不同,并返回不同的值和索引
tf.setdiff1d(x, y, index_dtype=tf.int32, name=None)


# 返回 x 中的唯一值所组成的tensor 和原 tensor 中元素在现 tensor 中的索引
tf.unique(x, out_idx=None, name=None)


# x if condition else y, condition 为 bool 类型的,可用tf.equal()等来表示
# x 和 y 的形状和数据类型必须一致
tf.where(condition, x=None, y=None, name=None)


# 返回沿着坐标轴方向的最大/最小值的索引
tf.argmax(input, axis=None, name=None, output_type=tf.int64)
tf.argmin(input, axis=None, name=None, output_type=tf.int64)


# x 的值当作 y 的索引,range(len(x)) 索引当作 y 的值
# y[x[i]] = i for i in [0, 1, ..., len(x) - 1]
tf.invert_permutation(x, name=None)


# 其它
tf.edit_distance

2.变量初始化函数

1
2
3
4
5
6
7
8
9
10
zeros=tf.zeros([2,2])
#全部0,2×2
ones=tf.ones([6])
#全部1,1×6
uniform=tf.random.uniform([3,3,3],minval=0,maxval=10)
#3×3×3,元素服从0-10均匀分布
normal=tf.random.normal([3,3,3],mean=0,stddev=2)
#3×3×3,元素服从均值为0标准差为2的正态分布
trunc=tf.random.truncated_normal([3,3,3],mean=5,stddev=1)
#用来限制正态分布偏差不超过2,即不会出现小于3或大于7的元素