tensorflow基础语法讲解

文章目录

  • 张量定义
  • tensorflow数据类型
  • 创建张量tensor方法
  • tensorflow常用函数
  • 实例:训练Iris数据集

张量定义

张量(tensor):多维数组或列表,其中阶表示张量的维数,即张量可以表示0阶到n阶的数组或列表

维数 名称 例子
0D 0 标量 scalar s=1,s=2,s=3
1D 1 向量 vector v=[1,2,3]
2D 2 矩阵 matrix m=[[1,2],[3,4]]
nD n 张量 tensor t=[[[[…,连续n个“[”

tensorflow数据类型

  1. tf.int , tf.float …
    e.g. : tf.int 32, tf.float32, tf.float64
  2. tf.bool
    e.g. : tf.constant([True, False])
  3. tf.string
    e.g. : tf.constant(“Hello, world!”)

创建张量tensor方法

  1. 创建一个张量
    tf.constant(张量内容,dtype=数据类型(可选))
import tensorflow as tf
a=tf.constant([1,5],dtype=tf.int64)
print(a)
print(a.dtype)
print(a.shape)

# 运行结果
<tf.Tensor([1,5], shape=(2 , ) , dtype=int64)
<dtype: 'int64'>
(2,)
  1. 将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)
print(a)
print(b)

# 运行结果
[0 1 2 3 4]
tf.Tensor([0 1 2 3 4], shape=( 5 , ), dtype=int64)
  1. 创建特殊张量
  • 全为0的张量:tf. zeros(维度)
  • 全为1的张量:tf. ones(维度)
  • 全为指定值的张量:tf. fill(维度,指定值)
    维度:一维直接写个数;二维用[行,列];多维用[n,m,j,k……]
a = tf.zeros([2, 3])
b = tf.ones(4)
c = tf.fill([2, 2], 9)
print(a)
print(b)
print(c)

# 运行结果
tf.Tensor([[0. 0. 0.] [0. 0. 0.]], shape=(2, 3), dtype=float32)
tf.Tensor([1. 1. 1. 1.], shape=(4, ), dtype=float32)
tf.Tensor([[9 9] [9 9]], shape=(2, 2), dtype=int32)
  • 生成正态分布的随机数,默认均值为0,标准差为1:
    tf. random.normal(维度,mean=均值,stddev=标准差)
  • 生成截断式正态分布的随机数
    tf. random.truncated_normal (维度,mean=均值,stddev=标准差)
    在tf.truncated_normal中如果随机生成数据的取值在(μ-2σ,μ+2σ)之外则重新进行生成,保证了生成值在均值附近
d = tf.random.normal([2, 2], mean=0.5, stddev=1)
print(d)
e = tf.random.truncated_normal([2, 2], mean=0.5, stddev=1)
print(e)

# 运行结果
tf.Tensor(
[[0.7925745 0.643315]
 [1.4752257 0.2533372]], shape=(2, 2), dtype=float32)
tf.Tensor(
[[1.3688478 1.0125661]
 [0.17475659 -0.02224463]], shape=(2, 2), dtype=float32)
  • 生成均匀分布随机数[minval, maxval)
    tf. random. uniform(维度,minval=最小值,maxval=最大值)
f = tf.random.uniform([2, 2], minval=0, maxval=1)
print(f)

# 运行结果:
tf.Tensor(
[[0.28219545 0.15581512]
[0.77972126 0.47817433]], shape=(2, 2), dtype=float32)

tensorflow常用函数

  1. 强制tensor转换为该数据类型
    tf.cast(张量名,dtype=数据类型)
x1 = tf.constant([1., 2., 3.],dtype=tf.float64)
print(x1)
x2 = tf.cast(x1, tf.int32)
print(x2)

# 运行结果
tf.Tensor([1. 2. 3.], shape=(3,), dtype=float64)
tf.Tensor([1 2 3], shape=(3,), dtype=int32)
  1. 计算张量维度上元素的最值
  • 计算张量维度上元素的最小值:tf.reduce_min(张量名)
  • 计算张量维度上元素的最大值:tf.reduce_max(张量名)
print (tf.reduce_min(x2), tf.reduce_max(x2))

# 运行结果
tf.Tensor(1, shape=(), dtype=int32)
tf.Tensor(3, shape=(), dtype=int32)
  1. 维度操作函数
  • 计算张量沿着指定维度的平均值:tf.reduce_mean(张量名,axis=操作轴)
  • 计算张量沿着指定维度的和:tf.reduce_sum(张量名,axis=操作轴)
  • 返回张量沿指定维度最大值的索引:tf.argmax(张量名,axis=操作轴)
    在一个二维张量或数组中,可以通过调整axis等于0或1控制执行维度。axis=0代表跨行(经度,down),而axis=1代表跨列(纬度,across)。如果不指定axis,则所有元素参与计算
x=tf.constant([[1, 2, 3],[2, 2, 3]])
print(x)
print(tf.reduce_mean(x))
print(tf.reduce_sum(x, axis=1))

import numpy as np
test = np.array([[1, 2, 3], [2, 3, 4], [5, 4, 3], [8, 7, 2]])
print(test)
print( tf.argmax(test, axis=0)) # 返回每一列(经度)最大值的索引
print( tf.argmax(test, axis=1)) # 返回每一行(纬度)最大值的索引

# 运行结果:
tf.Tensor([[1 2 3][2 2 3]], shape=(2, 3), dtype=int32)
tf.Tensor(2, shape=(), dtype=int32)
tf.Tensor([6 7], shape=(2,), dtype=int32)

[[1 2 3]
[2 3 4]
[5 4 3]
[8 7 2]]
tf.Tensor([3 3 1], shape=(3,), dtype=int64)
tf.Tensor([2 2 0 0], shape=(4,), dtype=int64)
  1. 参数更新函数
  • 将变量标记为“可训练”
    tf.Variable(初始值)
    被标记的变量会在反向传播中记录梯度信息。神经网络训练中,常用该函数标记待训练参数
w = tf.Variable(tf.random.normal([2, 2], mean=0, stddev=1))
  • 求出张量的梯度
    grad=tape.gradient(函数,对谁求导)
    with结构记录计算过程,gradient求出张量的梯度
    e.g. : 令loss=w2,则loss’=2w
with tf.GradientTape( ) as tape:
	w = tf.Variable(tf.constant(3.0))
	loss = tf.pow(w,2) 
grad = tape.gradient(loss,w)
print(grad)

# 运行结果:
tf.Tensor(6.0, shape=(), dtype=float32)
  • 自减函数
    w.assign_sub(w要自减的内容)
    赋值操作,更新参数的值并返回。调用assign_sub前,先用tf.Variable定义变量w为可训练(可自更新)。
w = tf.Variable(4)
w.assign_sub(1)
print(w)

# 运行结果:
<tf.Variable 'Variable:0' shape=() dtype=int32, numpy=3>
  1. 四则运算
  • 实现两个张量的对应元素相加
    tf.add(张量1,张量2)
  • 实现两个张量的对应元素相减
    tf.subtract(张量1,张量2)
  • 实现两个张量的对应元素相乘
    tf.multiply(张量1,张量2)
  • 实现两个张量的对应元素相除
    tf.divide(张量1,张量2)
    只有维度相同的张量才可以做四则运算
a = tf.ones([1, 3])
b = tf.fill([1, 3], 3.)
print(a)
print(b)
print(tf.add(a,b))
print(tf.subtract(a,b))
print(tf.multiply(a,b))
print(tf.divide(b,a))

# 运行结果:
tf.Tensor([[1. 1. 1.]], shape=(1, 3), dtype=float32)
tf.Tensor([[3. 3. 3.]], shape=(1, 3), dtype=float32
tf.Tensor([[4. 4. 4.]], shape=(1, 3), dtype=float32)
tf.Tensor([[-2. -2. -2.]], shape=(1, 3), dtype=float32)
tf.Tensor([[3. 3. 3.]], shape=(1, 3), dtype=float32)
tf.Tensor([[3. 3. 3.]], shape=(1, 3), dtype=float32)
  1. 平方、次方与开方
  • 计算某个张量的平方
    tf.square(张量名)
  • 计算某个张量的n次方
    tf.pow(张量名,n次方数)
  • 计算某个张量的开方
    tf.sqrt(张量名)
a = tf.fill([1, 2], 3.)
print(a)
print(tf.pow(a, 3))
print(tf.square(a))
print(tf.sqrt(a))

# 运行结果:
tf.Tensor([[3. 3.]], shape=(1, 2), dtype=float32)
tf.Tensor([[27. 27.]], shape=(1, 2), dtype=float32)
tf.Tensor([[9. 9.]], shape=(1, 2), dtype=float32)
tf.Tensor([[1.7320508 1.7320508]], shape=(1, 2), dtype=float32)
  1. 矩阵乘法
    tf.matmul(矩阵1,矩阵2)
a = tf.ones([3, 2])
b = tf.fill([2, 3], 3.)
print(tf.matmul(a, b))

# 运行结果:
tf.Tensor(
[[6. 6. 6.]
 [6. 6. 6.]
 [6. 6. 6.]], shape=(3, 3), dtype=float32)
  1. 切分传入张量的第一维度,生成输入特征/标签对
    data = tf.data.Dataset.from_tensor_slices((输入特征, 标签))
    Numpy和Tensor格式都可用该语句读入数据
features = tf.constant([12,23,10,17])
labels = tf.constant([0, 1, 1, 0])
dataset = tf.data.Dataset.from_tensor_slices((features, labels))
print(dataset)
for element in dataset:
	print(element)

# 运行结果:
<TensorSliceDataset shapes: ((),()), types: (tf.int32, tf.int32))>
(<tf.Tensor: id=9, shape=(), dtype=int32, numpy=12>, <tf.Tensor: id=10, shape=(), dtype=int32, numpy=0>)
(<tf.Tensor: id=11, shape=(), dtype=int32, numpy=23>, <tf.Tensor: id=12, shape=(), dtype=int32, numpy=1>)
(<tf.Tensor: id=13, shape=(), dtype=int32, numpy=10>, <tf.Tensor: id=14, shape=(), dtype=int32, numpy=1>)
(<tf.Tensor: id=15, shape=(), dtype=int32, numpy=17>, <tf.Tensor: id=16, shape=(), dtype=int32, numpy=0>)
  1. 枚举
    enumerate(列表名)
    enumerate是python的内建函数,它可遍历每个元素(如列表、元组或字符串),组合为:索引元素,常在for循环中使用。
seq= ['one', 'two', 'three']
for i, element in enumerate(seq):
print(i, element)

# 运行结果:
0 one
1 two
2 three
  1. 独热编码
    tf.one_hot(待转换数据, depth=几分类)
    tf.one_hot()函数将待转换数据,转换为one-hot形式的数据输出
    独热编码(one-hot encoding):在分类问题中,常用独热码做标签,标记类别:1表示是,0表示非。
0狗尾草鸢尾 1杂色鸢尾 2弗吉尼亚鸢尾
标签 0
独热码 1. 0. 0.
标签 1
独热码 0. 1. 0.
标签 2
独热码 0. 0. 1.
classes = 3
labels = tf.constant([1,0,2]) #输入的元素值最小为0,最大为2
output = tf.one_hot(labels, depth=classes)
print(output)

# 运行结果:
[[0. 1. 0.]
[1. 0. 0.]
[0. 0. 1.]], shape=(3, 3), dtype=float32)
  1. 激活函数
  • sigmoid函数
    tf.nn.sigmoid(待激活张量)
  • tanh函数
    tf.nn.tanh(待激活张量)
  • relu函数
    tf.nn.relu(待激活张量)
sess=tf.Session()
a=tf.constant([10,2,1,0.5,0,-0.5,-1,-2,-10])
print(sess.run(a))

S=tf.nn.sigmoid(a)
print(sess.run(S))

T=tf.nn.tanh(a)
print(sess.run(T))

R=tf.nn.relu(a)
print(sess.run(R))

# 运行结果
[ 10.    2.    1.    0.5   0.   -0.5  -1.   -2.  -10. ]
[9.9995458e-01 8.8079709e-01 7.3105860e-01 6.2245929e-01 5.0000000e-01 3.7754071e-01 2.6894143e-01 1.1920291e-01 4.5397872e-05]
[ 1.          0.9640276   0.7615942   0.46211717  0.  -0.46211717  -0.7615942  -0.9640276  -1.        ]
[10.   2.   1.   0.5  0.   0.   0.   0.   0. ]
  1. 损失函数
  • 均方误差mse
    tf.reduce_mean(tf.square(标准值 - 预测值))
  • 交叉熵损失函数CE
    tf.losses.categorical_crossentropy(标准值,预测值)
loss1=tf.losses.categorical_crossentropy([1,0],[0.6,0.4])
loss2=tf.losses.categorical_crossentropy([1,0],[0.8,0.2])
print(loss1)
print(loss2)

# 运行结果:
tf.Tensor(0.5108256, shape=(), dtype=float32)
tf.Tensor(0.22314353, shape=(), dtype=float32)
  1. softmax函数
    tf.nn.softmax(x)
y = tf.constant( [1.01, 2.01, -0.66] )
y_pro= tf.nn.softmax(y)
print(y_pro)

# 输出结果:
tf.Tensor([0.255981740.695830460.0481878], shape=(3,), dtype=float32)
  • softmax与交叉熵结合
    tf.nn.softmax_cross_entropy_with_logits(标准值 - 预测值)
    输出先过softmax函数,再计算y与y_的交叉熵损失函数
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)
loss1 = tf.losses.categorical_crossentropy(y_, y_pro)

loss2 = tf.nn.softmax_cross_entropy_with_logits(y_, y)

print('分步计算的结果:\n', loss1)
print('结合计算的结果:\n', loss2)

# 运行结果:
分步计算的结果:
tf.Tensor([1.68795487e-041.03475622e-036.58839038e-022.58349207e+005.49852354e-02],shape=(5,),dtype=float64)
结合计算的结果:
tf.Tensor([1.68795487e-041.03475622e-036.58839038e-022.58349207e+005.49852354e-02],shape=(5,),dtype=float64)

实例:训练Iris数据集

  1. 整体思路
  • 准备数据
    • 数据集读入
    • 数据集乱序
    • 生成训练集和测试集
    • 配成(输入特征,标签)对,每次读入一小撮(batch)
  • 搭建网络
    • 定义神经网路中所有可训练参数
  • 参数优化
    • 嵌套循环迭代,with结构更新参数,显示当前loss
  • 测试效果
    • 计算当前参数前向传播后的准确率,显示当前acc
  • acc / loss可视化
# 导入所需模块
import tensorflow as tf
from sklearn import datasets
from matplotlib import pyplot as plt
import numpy as np

# 数据集读入,从sklearn包datasets 读入数据集:
x_data = datasets.load_iris().data # 返回iris数据集所有输入特征
y_data = datasets.load_iris().target # 返回iris数据集所有标签

# 数据集乱序
np.random.seed(0) # 使用相同的seed,使输入特征/标签一一对应
np.random.shuffle(x_data)
np.random.seed(0)
np.random.shuffle(y_data)
tf.random.set_seed(0)

# 分为训练集和测试集
x_train = x_data[:-30]
y_train = y_data[:-30]
x_test = x_data[-30:]
y_test = y_data[-30:]

# 转换x的数据类型,否则后面矩阵相乘时会因数据类型不一致报错
x_train = tf.cast(x_train, tf.float32)
x_test = tf.cast(x_test, tf.float32)

# 配成[输入特征,标签]对,把数据集分批次,每个批次batch组数据
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)

# 生成神经网络的参数,4个输入特征,故输入层为4个输入节点;因为3分类,故输出层为3个神经元
# 用tf.Variable()标记参数可训练
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  # 学习率为0.1
train_loss_results = []  # 将每轮的loss记录在此列表中,为后续画loss曲线提供数据
test_acc = []  # 将每轮的acc记录在此列表中,为后续画acc曲线提供数据
epoch = 500  # 循环500轮
loss_all = 0  # 每轮分4个step,loss_all记录四个step生成的4个loss的和

# 训练部分
for epoch in range(epoch):  #数据集级别的循环,每个epoch循环一次数据集
    for step, (x_train, y_train) in enumerate(train_db):  #batch级别的循环 ,每个step循环一个batch
        with tf.GradientTape() as tape:  # with结构记录梯度信息
            y = tf.matmul(x_train, w1) + b1  # 神经网络乘加运算
            y = tf.nn.softmax(y)  # 使输出y符合概率分布(此操作后与独热码同量级,可相减求loss)
            y_ = tf.one_hot(y_train, depth=3)  # 将标签值转换为独热码格式,方便计算loss和accuracy
            loss = tf.reduce_mean(tf.square(y_ - y))  # 采用均方误差损失函数mse = mean(sum(y-out)^2)
            loss_all += loss.numpy()  # 将每个step计算出的loss累加,为后续求loss平均值提供数据,这样计算的loss更准确
        # 计算loss对各个参数的梯度
        grads = tape.gradient(loss, [w1, b1])

        # 实现梯度更新 w1 = w1 - lr * w1_grad    b = b - lr * b_grad
        w1.assign_sub(lr * grads[0])  # 参数w1自更新
        b1.assign_sub(lr * grads[1])  # 参数b自更新

    # 每个epoch,打印loss信息
    print("Epoch {}, loss: {}".format(epoch, loss_all/4))
    train_loss_results.append(loss_all / 4)  # 将4个step的loss求平均记录在此变量中
    loss_all = 0  # loss_all归零,为记录下一个epoch的loss做准备

    # 测试部分
    # total_correct为预测对的样本个数, total_number为测试的总样本数,将这两个变量都初始化为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)  # 返回y中最大值的索引,即预测的分类
        # 将pred转换为y_test的数据类型
        pred = tf.cast(pred, dtype=y_test.dtype)
        # 若分类正确,则correct=1,否则为0,将bool型的结果转换为int型
        correct = tf.cast(tf.equal(pred, y_test), dtype=tf.int32)
        # 将每个batch的correct数加起来
        correct = tf.reduce_sum(correct)
        # 将所有batch中的correct数加起来
        total_correct += int(correct)
        # total_number为测试的总样本数,也就是x_test的行数,shape[0]返回变量的行数
        total_number += x_test.shape[0]
    # 总的准确率等于total_correct/total_number
    acc = total_correct / total_number
    test_acc.append(acc)
    print("Test_acc:", acc)
    print("--------------------------")

# 绘制 loss 曲线
plt.title('Loss Function Curve')  # 图片标题
plt.xlabel('Epoch')  # x轴变量名称
plt.ylabel('Loss')  # y轴变量名称
plt.plot(train_loss_results, label="$Loss$")  # 逐点画出trian_loss_results值并连线,连线图标是Loss
plt.legend()  # 画出曲线图标
plt.show()  # 画出图像

# 绘制 Accuracy 曲线
plt.title('Acc Curve')  # 图片标题
plt.xlabel('Epoch')  # x轴变量名称
plt.ylabel('Acc')  # y轴变量名称
plt.plot(test_acc, label="$Accuracy$")  # 逐点画出test_acc值并连线,连线图标是Accuracy
plt.legend()
plt.show()

你可能感兴趣的:(深度学习,深度学习,tensorflow)