《TensorFlow深度学习》笔记(一)

TensorFlow 进阶

最值、均值、和

  • 通过 tf.reduce_max、tf.reduce_min、tf.reduce_mean、tf.reduce_sum 函数可以求解张量 在某个维度上的最大、最小、均值、和

张量比较

  • 为了计算分类任务的准确率等指标,一般需要将预测结果和真实标签比较,统计比较 结果中正确的数量来计算准确率,通过 tf.argmax 获取预测类别

经典数据集加载

  • 在 TensorFlow 中,keras.datasets 模块提供了常用经典数据集的自动下载、管理、加载 与转换功能,并且提供了 tf.data.Dataset 数据集对象

  • 通过 datasets.xxx.load_data()函数即可实现经典数据集的自动加载,其中 xxx 代表具体 的数据集名称,如“CIFAR10”、“MNIST”

  • import tensorflow as tf
    from tensorflow import keras
    from tensorflow.keras import datasets  # 导入经典数据集加载模块
    
    # 加载 MNIST 数据集
    (x, y), (x_test, y_test) = datasets.mnist.load_data()
    print('x:', x.shape, 'y:', y.shape, 'x test:', x_test.shape, 'y test:',y_test)
    
  • 数据加载进入内存后,需要转换成 Dataset 对象,才能利用 TensorFlow 提供的各种便捷功能。通过 Dataset.from_tensor_slices 可以将训练部分的数据图片 x 和标签 y 都转换成 Dataset 对象, 将数据转换成 Dataset 对象后,一般需要再添加一系列的数据集标准处理步骤,如随机打 散、预处理、按批装载等

  • train_db = tf.data.Dataset.from_tensor_slices((x, y)) # 构建 Dataset 对象 
    ----------------------------------------------------------
    
    train_db = train_db.shuffle(10000) # 随机打散样本,不会打乱样本与标签映射关系 
    
    --------------------------------------------------------
    
    # 为了利用显卡的并行计算能力,一般在网络的计算过程中会同时计算多个样本,我们 把这种训# 练方式叫做批训练,其中一个批中样本的数量叫做 Batch Size
    train_db = train_db.batch(128) # 设置批训练,batch size 为 128 
    
    --------------------------------------------------------
    
    # 预处理函数实现在 preprocess 函数中,传入函数名即可 
    train_db = train_db.map(preprocess)
    # 下面是自定义预处理函数
    def preprocess(x, y): # 自定义的预处理函数 
    # 调用此函数时会自动传入 x,y 对象,shape 为[b, 28, 28], [b]  
        # 标准化到 0~1 
        x = tf.cast(x, dtype=tf.float32) / 255. 
        x = tf.reshape(x, [-1, 28*28])     # 打平 
        y = tf.cast(y, dtype=tf.int32)    # 转成整型张量 
        y = tf.one_hot(y, depth=10)    # one-hot 编码 
        # 返回的 x,y 将替换传入的 x,y 参数,从而实现数据的预处理功能 
        return x,y  
    --------------------------------------------------------
    #  循环训练 
    # 当对 train_db 的所有样本完 成一次迭代后,for 循环终止退出。这样完成一个 Batch 的  
    # 数据训练,叫做一个 Step;通过 多个 step 来完成整个训练集的一次迭代,叫做一个 Epoch
    
    # 对于 Dataset 对象,在使用时可以通过 
       for step, (x,y) in enumerate(train_db): # 迭代数据集对象,带 step 参数 
    # 或 
        for x,y in train_db: # 迭代数据集对象 
    # 例如:训练20个Epoch
     for epoch in range(20): # 训练 Epoch 数 
            for step, (x,y) in enumerate(train_db): # 迭代 Step 数 
                # training... 
    
    --------------------------------------------------------    
    
    # 在训练的过程中,通过间隔数个 Step 后打印误差数据,可以有效监督模型的训练 进度,代码# 如下: 
            # 间隔 100 个 step 打印一次训练误差 
            if step % 100 == 0: 
                print(step, 'loss:', float(loss))
    

神经网络

感知机

  • 感知机模型的结构=它接受长度为𝑛的一维向量𝒙 = [𝑥1,𝑥2,…,𝑥𝑛],每个 输入节点通过权值为𝑤𝑖,𝑖𝜖[1,𝑛]的连接汇集为变量𝑧,即:

                       𝑧 = 𝑤1 𝑥1 + 𝑤2 𝑥2 + ⋯+ 𝑤𝑛 𝑥𝑛 + 𝑏 
    

​ 其中𝑏称为感知机的偏置(Bias),一维向量𝒘 = [𝑤1,𝑤2,…,𝑤𝑛]称为感知机的权值(Weight),𝑧 称为 感知机的净活性值(Net Activation)。

​ 上式写成向量形式: ​ 𝑧 = 𝒘T𝒙+ 𝑏

全连接层(即:神经网络 的一层)

  • 张量方式实现

  • # 创建 W,b 张量 
    x = tf.random.normal([2,784]) 
    w1 = tf.Variable(tf.random.truncated_normal([784, 256], stddev=0.1)) 
    b1 = tf.Variable(tf.zeros([256])) 
    o1 = tf.matmul(x,w1) + b1  # 线性变换 
    o1 = tf.nn.relu(o1)  # 激活函数
    
  • 层方式实现

  • x = tf.random.normal([4,28*28]) 
    from    tensorflow.keras import  layers # 导入层模块 
    # 创建全连接层,指定输出节点数和激活函数 
    fc = layers.Dense(512, activation=tf.nn.relu)  
    h1 = fc(x)  # 通过 fc 类实例完成一次全连接层的计算,返回输出张量 
    
    ########################################################################   fc.kernel # 获取 Dense 类的权值矩阵 
    fc.bias # 获取 Dense 类的偏置向量 
    fc.trainable_variables  # 返回待优化参数列表 
    fc.variables # 返回所有参数列表
    

神经网络

  • 张量方式实现

  • x = tf.random.normal([4,28*28]) 
    from    tensorflow.keras import  layers # 导入层模块 
    
    # 隐藏层 1 张量 
    w1 = tf.Variable(tf.random.truncated_normal([784, 256], stddev=0.1)) b1 = tf.Variable(tf.zeros([256])) 
    # 隐藏层 2 张量 
    w2 = tf.Variable(tf.random.truncated_normal([256, 128], stddev=0.1)) 
    b2 = tf.Variable(tf.zeros([128])) 
    # 隐藏层 3 张量 
    w3 = tf.Variable(tf.random.truncated_normal([128, 64], stddev=0.1)) b3 = tf.Variable(tf.zeros([64])) 
    # 输出层张量 
    w4 = tf.Variable(tf.random.truncated_normal([64, 10], stddev=0.1)) 
    b4 = tf.Variable(tf.zeros([10])) 
    
    # 在使用 TensorFlow 自动求导功能计算梯度时,需要将前向计算过程放置在 tf.GradientTape()环境中,从而利用 GradientTape 对象的 gradient()方法自动求解参数的梯 度,并利用 optimizers 对象更新参数。 
    with tf.GradientTape() as tape: # 梯度记录器 
         #  隐藏层 1 前向计算,[b, 28*28] => [b, 256]             
          h1 = x@w1 + tf.broadcast_to(b1, [x.shape[0], 256])             
          h1 = tf.nn.relu(h1) 
         # 隐藏层 2 前向计算,[b, 256] => [b, 128]             
          h2 = h1@w2 + b2             
          h2 = tf.nn.relu(h2) 
          # 隐藏层 3 前向计算,[b, 128] => [b, 64]              
          h3 = h2@w3 + b3             
          h3 = tf.nn.relu(h3) 
          # 输出层前向计算,[b, 64] => [b, 10]              
          h4 = h3@w4 + b4
    
  • 层方式实现

  • ```python

    对于这种数据依次向前传播的网络,也可以通过 Sequential 容器封装成一个网络大类对象

    ,调用大类的前向计算函数一次即可完成所有层的前向计算,使用起来更加方便,

    实现如下:

    import tensorflow as tf

    导入 Sequential 容器

    from tensorflow.keras import layers,Sequential x = tf.random.normal([4,28*28])

    通过 Sequential 容器封装为一个网络类

    model = Sequential([ layers.Dense(256, activation=tf.nn.relu), # 创建隐藏层 1 layers.Dense(128, activation=tf.nn.relu) , # 创建隐藏层 2 layers.Dense(64, activation=tf.nn.relu) , # 创建隐藏层 3 layers.Dense(10, activation=None) , # 创建输出层 ]);

    out = model(x) # 前向计算得到输出


###  优化目标 

- 我们把神经网络从输入到输出的计算过程叫做前向传播(Forward Propagation)
- 上述的最小化优化问题一般采用误差反向传播(Backward Propagation,简称 BP)算法来求解 网络参数𝜃的梯度信息,并利用梯度下降(Gradient Descent,简称 GD)算法

###  输出层设计 

- 我们将根据输出值的区间范围来分类讨论。常见的几种输出类型包括:  

  - 𝑜𝑖 ∈ 𝑅𝑑 输出属于整个实数空间,或者某段普通的实数空间,比如函数值趋势的预 测,年龄的预测问题等。 

  - 𝑜𝑖 ∈ [0,1] 输出值特别地落在[0,1]的区间,如图片生成,图片像素值一般用[0,1]区间 的值表示;或者二分类问题的概率,如硬币正反面的概率预测问题。 

  - 𝑜𝑖 ∈ [0, 1],  𝑜𝑖 𝑖 = 1 输出值落在[0,1]的区间,并且所有输出值之和为 1,常见的如 多分类问题,如 MNIST 手写数字图片识别,图片属于 10 个类别的概率之和应为 1。 

    - ```python
      z = tf.random.normal([2,10]) # 构造输出层的输出 
      y_onehot = tf.constant([1,3]) # 构造真实值 
      y_onehot = tf.one_hot(y_onehot, depth=10) # one-hot 编码 
      # 输出层未使用 Softmax 函数,故 from_logits 设置为 True 
      # 这样 categorical_crossentropy 函数在计算损失函数前,会先内部调用 Softmax 函数 
      loss = keras.losses.categorical_crossentropy(y_onehot,z,from_logits=True) 
      loss = tf.reduce_mean(loss) # 计算平均交叉熵损失 
      criteon = keras.losses.CategoricalCrossentropy(from_logits=True) 
      loss = criteon(y_onehot,z) # 计算损失
  • 𝑜𝑖 ∈ [−1, 1] 输出值在[-1, 1]之间

误差计算

  • o = tf.random.normal([2,10]) # 构造网络输出 
    y_onehot = tf.constant([1,3]) # 构造真实值 
    y_onehot = tf.one_hot(y_onehot, depth=10) 
    loss = keras.losses.MSE(y_onehot, o) # 计算均方差 
    # 特别要注意的是,MSE 函数返回的是每个样本的均方差,需要在样本维度上再次平均来获 得平均样本的均方差,实现如下
    loss = tf.reduce_mean(loss) # 计算 batch 均方差
    

results matching ""

    No results matching ""