TensorFlow2.0
北京大学TensorFlow2.0笔记
前言
- TensorFlow
是一个采用数据流图(Data Flow Graphs),用于高性能数值计算的开源软件库。 - Tensor(张量)
即多维数组,是TensorFlow中数据表现的形式。Flow:基于数据流图(Data FlowGraphs)的计算。 - Data Flow
Graph用结点和线的有向图来描述数学计算。节点通常代表数学运算,边表示节点之间的某种联系,它负责传输多维数据(Tensors)。如下图所示:
提示:以下是本篇文章正文内容,下面案例可供参考
一、人工智能三学派
- 行为主义:
基于控制论,构建感知-动作控制系统。如人的平衡、行走、避障等自适应控制系统 - 符号主义:
基于算数逻辑表达式,求解问题时先把问题描述为表达式,再求解表达式。可用公式描述、实现理性思维,如专家系统。 - 连接主义:
仿生学,模仿神经元连接关系。仿脑神经元连接,实现感性席位,如神经网络
二、基于连接主义的神经网络设计过程
- 准备数据:采集大量“特征/标签”数据
- 搭建网络:搭建神经网络结构
- 优化参数:训练网络获取最佳参数
- 应用网络:将网络保存为模型,输入新数据,输出分类或者预测结果
三、Tensor张量
1、tf.constant()
import tensorflow.compat.v1 as tf
c = tf.constant("Hello World")
print(c)
print(c.dtype)
print(c.shape)
3
[1., 2., 3.]
[[1., 2., 3.], [4., 5., 6.]]
[[[1., 2., 3.]], [[7., 8., 9.]]]
- dtype Tensor 存储的数据的类型,可以为tf.float32、tf.int32、tf.string…
- shape Tensor 存储的多维数组中每个维度的数组中元素的个数
应用实例:
import tensorflow as tf
t0 = tf.constant(3, dtype=tf.int32)
t1 = tf.constant([3., 4.1, 5.2], dtype=tf.float32)
t2 = tf.constant([['Apple', 'Orange'], ['Potato', 'Tomato']], dtype=tf.string)
t3 = tf.constant([[[5], [6], [7]], [[4], [3], [2]]])
很多时候数据是由numpy格式给出的 因此要将numpy的数据类型转换为Tensor数据类型
2、将numpy的数据类型转换为Tensor数据
- 用法:tf.convert_to_tensor(数据名, dtype=数据类型)
应用实例:
import tensorflow as tf
import numpy as np
a = np.arange(0, 5)
b = tf.convert_to_tensor(a, dtype=tf.int64)
3、创建张量
import tensorflow as tf
a = tf.zeros([2, 3])
b = tf.ones(4)
c = tf.fill([2, 2], 9)
print("a:", a)
print("b:", b)
print("c:", c)
4、生成随机数
import tensorflow as tf
d = tf.random.normal([2, 2], mean=0.5, stddev=1)
print("d:", d)
e = tf.random.truncated_normal([2, 2], mean=0.5, stddev=1)
print("e:", e)
f = tf.random.uniform([2, 2], minval=0, maxval=1)
print("f:", f)
注意区间: [minval=最小值, maxval=最大值) 前开后闭
四、TensorFlow常用函数
1、计算张量维度的最大最小值与强制转换tensor数据类型
import tensorflow as tf
x1 = tf.constant([1., 2., 3.], dtype=tf.float64)
print("x1:", x1)
x2 = tf.cast(x1, tf.int32)
print("x2", x2)
print("minimum of x2:", tf.reduce_min(x2))
print("maxmum of x2:", tf.reduce_max(x2))
2、计算指定维度
import tensorflow as tf
x = tf.constant([[1, 2, 3], [2, 2, 3]])
print("x:", x)
print("mean of x:", tf.reduce_mean(x))
print("sum of x:", tf.reduce_sum(x, axis=1))
- axis=1代表跨列,沿纬度方向(横)
- axis=0代表跨行,沿经度方向(竖)
3、张量的四则运算
import tensorflow as tf
a = tf.ones([1, 3])
b = tf.fill([1, 3], 3.)
print("a:", a)
print("b:", b)
print("a+b:", tf.add(a, b))
print("a-b:", tf.subtract(a, b))
print("a*b:", tf.multiply(a, b))
print("b/a:", tf.divide(b, a))
4、张量的方运算
a = tf.fill([1, 2], 3.)
print("a:", a)
print("a的平方:", tf.pow(a, 3))
print("a的平方:", tf.square(a))
print("a的开方:", tf.sqrt(a))
5、张量的矩阵运算
import tensorflow as tf
a = tf.ones([3, 2])
b = tf.fill([2, 3], 3.)
print("a:", a)
print("b:", b)
print("a*b:", tf.matmul(a, b))
6、切分传入张量的第一维度,生成输入特征/标签对,构建数据集
import tensorflow as tf
features = tf.constant([12, 23, 10, 17])
labels = tf.constant([0, 1, 1, 0])
dataset = tf.data.Dataset.from_tensor_slices((features, labels))
for element in dataset:
print(element)
7、python中遍历每个元素
seq = ['one', 'two', 'three']
for i, element in enumerate(seq):
print(i, element)
8、tf.one_hot独热编码(常用独热编码做标签)
import tensorflow as tf
classes = 3
labels = tf.constant([1, 0, 2])
output = tf.one_hot(labels, depth=classes)
print("result of labels1:", output)
print("\n")
9、使输出符合概率的分布
import tensorflow as tf
y = tf.constant([1.01, 2.01, -0.66])
y_pro = tf.nn.softmax(y)
print("After softmax, y_pro is:", y_pro)
print("The sum of y_pro:", tf.reduce_sum(y_pro))
10、赋值操作,更新参数的值并返回
import tensorflow as tf
x = tf.Variable(4)
x.assign_sub(1)
print("x:", x)
11、返回张量沿指定维度最大值的索引
import numpy as np
import tensorflow as tf
test = np.array([[1, 2, 3], [2, 3, 4], [5, 4, 3], [8, 7, 2]])
print("test:\n", test)
print("每一列的最大值的索引:", tf.argmax(test, axis=0))
print("每一行的最大值的索引", tf.argmax(test, axis=1))
四、鸢尾花的分类
神经网络实现鸢尾花的分类流程:
- 准备数据
数据集读入 数据集乱序 生成训练集和测试集 配成(输入特征,标签)对,每次读入batch
- 搭建网络
定义神经网络中所有可训练参数
- 参数优化
嵌套循环迭代,with结构更新参数,显示当前loss
- 测试效果计算当前参数前后
计算当前参数前向传播后的准确率,显示当前acc
- acc/loss可视化
1.从sklearn包datasets读入数据集
from sklearn import datasets
from pandas import DataFrame
import pandas as pd
x_data = datasets.load_iris().data
y_data = datasets.load_iris().target
print("x_data from datasets: \n", x_data)
print("y_data from datasets: \n", y_data)
x_data = DataFrame(x_data, columns=['花萼长度', '花萼宽度', '花瓣长度', '花瓣宽度'])
pd.set_option('display.unicode.east_asian_width', True)
print("x_data add index: \n", x_data)
x_data['类别'] = y_data
print("x_data add a column: \n", x_data)
显示效果:
2.神经网络实现鸢尾花的分类
import tensorflow as tf
from sklearn import datasets
from matplotlib import pyplot as plt
import numpy as np
x_data = datasets.load_iris().data
y_data = datasets.load_iris().target
np.random.seed(116)
np.random.shuffle(x_data)
np.random.seed(116)
np.random.shuffle(y_data)
tf.random.set_seed(116)
x_train = x_data[:-30]
y_train = y_data[:-30]
x_test = x_data[-30:]
y_test = y_data[-30:]
x_train = tf.cast(x_train, tf.float32)
x_test = tf.cast(x_test, tf.float32)
train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32)
test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32)
w1 = tf.Variable(tf.random.truncated_normal([4, 3], stddev=0.1, seed=1))
b1 = tf.Variable(tf.random.truncated_normal([3], stddev=0.1, seed=1))
lr = 0.1
train_loss_results = []
test_acc = []
epoch = 500
loss_all = 0
for epoch in range(epoch):
for step, (x_train, y_train) in enumerate(train_db):
with tf.GradientTape() as tape:
y = tf.matmul(x_train, w1) + b1
y = tf.nn.softmax(y)
y_ = tf.one_hot(y_train, depth=3)
loss = tf.reduce_mean(tf.square(y_ - y))
loss_all += loss.numpy()
grads = tape.gradient(loss, [w1, b1])
w1.assign_sub(lr * grads[0])
b1.assign_sub(lr * grads[1])
print("Epoch {}, loss: {}".format(epoch, loss_all/4))
train_loss_results.append(loss_all / 4)
loss_all = 0
total_correct, total_number = 0, 0
for x_test, y_test in test_db:
y = tf.matmul(x_test, w1) + b1
y = tf.nn.softmax(y)
pred = tf.argmax(y, axis=1)
pred = tf.cast(pred, dtype=y_test.dtype)
correct = tf.cast(tf.equal(pred, y_test), dtype=tf.int32)
correct = tf.reduce_sum(correct)
total_correct += int(correct)
total_number += x_test.shape[0]
acc = total_correct / total_number
test_acc.append(acc)
print("Test_acc:", acc)
print("--------------------------")
plt.title('Loss Function Curve')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.plot(train_loss_results, label="$Loss$")
plt.legend()
plt.show()
plt.title('Acc Curve')
plt.xlabel('Epoch')
plt.ylabel('Acc')
plt.plot(test_acc, label="$Accuracy$")
plt.legend()
plt.show()
五、预备知识
1、tf.where(条件语句, 真返回A, 假返回B)
import tensorflow as tf
a = tf.constant([1, 2, 3, 1, 1])
b = tf.constant([0, 1, 3, 4, 5])
c = tf.where(tf.greater(a, b), a, b)
print("c:", c)
- 运行结果
2、np.random.RandomState.rand(维度)
import numpy as np
rdm = np.random.RandomState(seed=1)
a = rdm.rand()
b = rdm.rand(2, 3)
print("a:", a)
print("b:", b)
- 运行结果
3、np.vstack((数组1, 数组2))将两个数据按垂直方向叠加
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
c = np.vstack((a, b))
print("c:\n", c)
- 运行结果
4、np.mgrid[ ]、 x.ravel()、np.c_[ ]
- np.mgrid[起始值:结束值:步长,起始值:结束值:步长,…]
- x.ravel()将x变为一维数组,“把.前变量拉直”
- np.c_[数值1,数值2]使返回的间隔数值点配对
import numpy as np
import tensorflow as tf
x, y = np.mgrid[1:3:1, 2:4:0.5]
grid = np.c_[x.ravel(), y.ravel()]
print("x:\n", x)
print("y:\n", y)
print("x.ravel():\n", x.ravel())
print("y.ravel():\n", y.ravel())
print('grid:\n', grid)
- 运行结果
六、复杂度学习率
1、学习率公式:
2、 如何寻找最优学习率?
- 指数衰减学习率:
- 可以先用较大的学习率,快速得到较优解,然后逐步减少学习率,使模型在训练后期稳定
import tensorflow as tf
w = tf.Variable(tf.constant(5, dtype=tf.float32))
epoch = 40
LR_BASE = 0.2
LR_DECAY = 0.99
LR_STEP = 1
for epoch in range(epoch):
lr = LR_BASE * LR_DECAY ** (epoch / LR_STEP)
with tf.GradientTape() as tape:
loss = tf.square(w + 1)
grads = tape.gradient(loss, w)
w.assign_sub(lr * grads)
print("After %s epoch,w is %f,loss is %f,lr is %f" % (epoch, w.numpy(), loss, lr))
七、激活函数
1、Sigmoid函数
- 特点:
2、Tanh函数
- 特点:
3、Relu函数
4、Leaky Relu函数
5、softmax函数
- 特点:对神经网络全连接层输出进行变换,使其服从概率分布,即每个值都位于[0,1]区间且和为1。
6、选择函数建议
八、损失函数
1、均方误差损失函数
实例:
- 预测酸奶日销量y,x1、x2是影响日销量的因素。
- 建模前,应预先采集的数据有:每日x1、x2和销量y_(即已知答案,最佳情况:产量=销量)
- 拟造数据集X,Y_: y_ = x1 + x2 噪声:-0.05 ~ +0.05 拟合可以预测销量的函数
import tensorflow as tf
import numpy as np
SEED = 23455
rdm = np.random.RandomState(seed=SEED)
x = rdm.rand(32, 2)
y_ = [[x1 + x2 + (rdm.rand() / 10.0 - 0.05)] for (x1, x2) in x]
x = tf.cast(x, dtype=tf.float32)
w1 = tf.Variable(tf.random.normal([2, 1], stddev=1, seed=1))
epoch = 15000
lr = 0.002
for epoch in range(epoch):
with tf.GradientTape() as tape:
y = tf.matmul(x, w1)
loss_mse = tf.reduce_mean(tf.square(y_ - y))
grads = tape.gradient(loss_mse, w1)
w1.assign_sub(lr * grads)
if epoch % 500 == 0:
print("After %d training steps,w1 is " % (epoch))
print(w1.numpy(), "\n")
print("Final w1 is: ", w1.numpy())
运行结果:
都趋近于1,拟合出的销量Y=1.00x1+1.00x2 与制造数据集Y=1.0x1+1.0x2一致
2、自定义损失函数
如:预测酸奶销量,酸奶成本(COST)1元,酸奶利润(PROFIT)99元。 预测少了损失利润99元,大于预测多了损失成本1元。 预测少了损失大,希望生成的预测函数往多了预测。
import tensorflow as tf
import numpy as np
SEED = 23455
COST = 1
PROFIT = 99
rdm = np.random.RandomState(SEED)
x = rdm.rand(32, 2)
y_ = [[x1 + x2 + (rdm.rand() / 10.0 - 0.05)] for (x1, x2) in x]
x = tf.cast(x, dtype=tf.float32)
w1 = tf.Variable(tf.random.normal([2, 1], stddev=1, seed=1))
epoch = 10000
lr = 0.002
for epoch in range(epoch):
with tf.GradientTape() as tape:
y = tf.matmul(x, w1)
loss = tf.reduce_sum(tf.where(tf.greater(y, y_), (y - y_) * COST, (y_ - y) * PROFIT))
grads = tape.gradient(loss, w1)
w1.assign_sub(lr * grads)
if epoch % 500 == 0:
print("After %d training steps,w1 is " % (epoch))
print(w1.numpy(), "\n")
print("Final w1 is: ", w1.numpy())
3、交叉熵损失函数
import tensorflow as tf
loss_ce1 = tf.losses.categorical_crossentropy([1, 0], [0.6, 0.4])
loss_ce2 = tf.losses.categorical_crossentropy([1, 0], [0.8, 0.2])
print("loss_ce1:", loss_ce1)
print("loss_ce2:", loss_ce2)
import tensorflow as tf
import numpy as np
y_ = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 0, 0], [0, 1, 0]])
y = np.array([[12, 3, 2], [3, 10, 1], [1, 2, 5], [4, 6.5, 1.2], [3, 6, 1]])
y_pro = tf.nn.softmax(y)
loss_ce1 = tf.losses.categorical_crossentropy(y_,y_pro)
loss_ce2 = tf.nn.softmax_cross_entropy_with_logits(y_, y)
print('分步计算的结果:\n', loss_ce1)
print('结合计算的结果:\n', loss_ce2)
总结
本文章不断更新中,欢迎与大家一起学习
|