为什么要学

论文代码看不懂啊,准备把tensorflow和pytorch的课程都看一下,也不用看太深,能从头到尾写个简单的深度学习流程就行。

简介

为什么要使用TensorFlow

  • GPU加速

    • gpu加速表现在,对于大规模矩阵相乘和相加,gpu并行计算比cpu串行计算快很多
  • 自动求导

    自动求出每一层参数的梯度,更新参数,例如:

    ## 求解所有参数的梯度
    grads = tape.gradient(loss,model.trainable_variables)
    ## 更新参数
    optimizer = optimizers.SGD(learning_rate=0.001)
    optimizer.apply_gradients(zip(grads,model.trainable_variables))
    
  • 神经网络Layers

    调用TensorFlow的api完成复杂神经网络的搭建

安装

  • Anaconda
  • CUDA Nvidia运算平台,实现并行计算
  • cuDNN 面向神经网络的加速库

应用

以手写数字识别为例,训练神经网络的步骤为

  1. 准备数据集minist
  2. 前向传播计算h1、h2、out
  3. 由y和out计算loss
  4. 由loss计算梯度,更新参数w1、b1、w2、b2、w3、b3
  5. 跳到第二步,用更新好的参数继续计算

以具体的例子可以对比使用tensorflow前后的不同

note

  • 要使用GPU加速,要将numpy转换为tensor

  • 为了解决高维数据的吞吐和运算,list——>numpy.array

    为了支持GPU运算和自动求导, numpy.array——>tf.Tensor

  • tf.varible()是专门为神经网络的参数设置的属性,为了记录参数的梯度信息

tensorflow基础

基本数据类型和属性

  • 为了解决高维数据的吞吐和运算,list——>numpy.array

  • 为了支持GPU运算和自动求导, numpy.array——>tf.Tensor

  • tf.varible()是专门为神经网络的参数设置的属性,为了记录参数的梯度信息

  • 类型转换:tf.cast

创建Tensor以及不同维度Tensor的应用

  • 创建tensor ,用于初始化

  • []是标量

  • 不同维的Tensor对应不同的应用场景,比如三维用在NLP中,四维用在图片中

  • tf.random.uniform均匀分布的随机数

  • tf.random.norm正态分布的随机数

索引和切片和采样

  • 三种索引方式

维度变换

  • 维度不一致可以用broadcasting,可以自动运算不一致的维度,但是有限制

数学运算

  • +-*/ (元素操作)
  • ** ,pow,square
  • sqrt
  • //,%
  • exp,log
  • @,matmul (矩阵操作)
  • linear layer
  • reduce_mean/max/min/sum (维度操作)

操作

前向传播

张量的高级操作

  • 合并与分割
  • 数据统计
    • tf.norm(a)相当于tf.sqrt(tf.reduce_sum(tf.square(a)))
    • tf.equal和tf.argmax可以用于求解预测的准确性
  • 排序
  • 填充与复制
    • tf.pad 用于对图片数据和语言数据的扩充
    • tf.tile

全连接层

#张量方式实现
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) # 激活函数

#layer方式实现
x = tf.random.normal([4,28*28])
from tensorflow.keras import layers # 导入层模块
fc = layers.Dense(512, activation=tf.nn.relu)  # 创建全连接层,指定输出节点数和激活函数
h1 = fc(x) # 通过 fc 类实例完成一次全连接层的计算,返回输出张量

#多层全连接层
from tensorflow.keras import layers,Sequential
model = Sequential([# 通过 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) , # 创建输出层
])

可视化

  • Tensorboard

    #在存放数据的文件夹下 cmd 输入 tensorboard --logdir logs
    #build summary
    current_time = datatime.datetime.now().striftime("%Y%m%d-%H%M%S")
    log_dir = 'logs/' + current_time
    summary_writer = tf.summary.create_file_writer(log_dir)
    #fed scalar
    with summary_writer.as_default():
        tf.summary.scalar('loss',float(loss),step=epoch)
        tf.summary.scalar('accuracy',float(train_accuracy),step=epoch)
    #fed single Image
    with summary_writer.as_default():
        tf.summary.image("Training sample:",sample_image,step = 0)
    
  • visdom

keras高层接口

主要接口与接口下的函数

from tensorflow.keras import optimizers,losses,datasets,layersSequntial,...
  • datasets

  • layers 层模块 包含Dense和Relu等函数

  • losses

  • metrics

  • optimizers

  • Sequential 网络容器,是keras.Model的子类,用于多层神经网络 ,包含build加载模型等函数

    • trainable_varibles

    • call()为network(x)前向计算自动调用的函数

    • compile、fit 和evaluate分别用于模型装配、训练和测试

      ##使用compile、fit之前的模型装配、训练和测试,详细见ch08-Keras高层接口/metrics.py
      network = Sequential([layers.Dense(256, activation='relu'),
                           layers.Dense(128, activation='relu'),
                           layers.Dense(64, activation='relu'),
                           layers.Dense(32, activation='relu'),
                           layers.Dense(10)])
      network.build(input_shape=(None, 28*28))#创建参数,方便在训练之前观察参数,而network(x)可以自动创建参数并实现前向计算
      optimizer = optimizers.Adam(lr=0.01)
      acc_meter = metrics.Accuracy()##准确率
      for step, (x,y) in enumerate(db):
      
          with tf.GradientTape() as tape:
              x = tf.reshape(x, (-1, 28*28))
              out = network(x)
              y_onehot = tf.one_hot(y, depth=10) 
              loss = tf.reduce_mean(tf.losses.categorical_crossentropy(y_onehot, out, from_logits=True))
          grads = tape.gradient(loss, network.trainable_variables)
          optimizer.apply_gradients(zip(grads, network.trainable_variables))
      
          # evaluate
          if step % 500 == 0:
              total, total_correct = 0., 0
              acc_meter.reset_states()
              for step, (x, y) in enumerate(ds_val): 
                  x = tf.reshape(x, (-1, 28*28))
                  out = network(x) 
                  pred = tf.argmax(out, axis=1) 
                  pred = tf.cast(pred, dtype=tf.int32)
                  correct = tf.equal(pred, y)
                  total_correct += tf.reduce_sum(tf.cast(correct, dtype=tf.int32)).numpy()
                  total += x.shape[0]
                  acc_meter.update_state(y, pred)
              print(step, 'Evaluate Acc:', total_correct/total, acc_meter.result().numpy())      
      
      ###使用compile、fit之后的模型装配、训练和测试,详细见ch08-Keras高层接口/nb.py
      network = Sequential([layers.Dense(256, activation='relu'),
                           layers.Dense(128, activation='relu'),
                           layers.Dense(64, activation='relu'),
                           layers.Dense(32, activation='relu'),
                           layers.Dense(10)])
      network.build(input_shape=(4, 28*28))
      from tensorflow.keras import optimizers,losses 
      # 采用Adam优化器,学习率为0.01;采用交叉熵损失函数,包含Softmax
      network.compile(optimizer=optimizers.Adam(lr=0.01),
              loss=losses.CategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'] # 设置测量指标为准确率 
      )
      
      # 指定训练集为db,验证集为val_db,训练5个epochs,每2个epoch验证一次
      history = network.fit(train_db, epochs=5, validation_data=val_db, validation_freq=2)
      network.evaluate(ds_val)
      history.history # 打印训练记录
      

自定义网络和自定义网络层

自定义网络需要继承自keras.Model基类,自定义网络层需要继承自keras.layers.Layer基类

  • 自定义网络层,重写__init__call
  • 自定义网络,重写cal,可以使用Model的compile、fit、evaluate

保存模型

  • 第一种方式,保存模型参数信息
#保存模型参数
model.save_weights('./checkpoints/my_checkpoint')
#重新建立模型
#载入模型参数
network.load_weights('./checkpoints/my_checkpoint')
  • 第二种方式,保存模型结构和模型参数
network.save('model.h5')
del network
network = keras.models.load_model('model.h5')
  • 第三种方式
# 具有平台无关性
tf.saved_model.save(network, 'model-savedmodel')
del network
network = tf.saved_model.load('model-savedmodel')

卷积神经网络

  • 通过滑动窗口和参数共享来减少神经网络的参数,从而加深网络深度
  • 卷积层还起到一个降为的功能,如果stride设的大的话
  • 金字塔的结构一层一层的堆叠的作用:获得低层特征到获得高层抽象特征

参考教程

龙良曲TensorFlow教程