神经网络:传统神经网络基础学习

1、单层神经网络

1.2 张量方式实现单层全连接层

  在 TensorFlow 中,要实现全连接层,只需要定义好权值张量和偏置张量,并利用TensorFlow 提供的批量矩阵相乘函数 tf.matmul()即可完成网络层的计算。

#张量的实现

#输入3个样本,每个样本的特征长度为4
x = tf.random.normal([3,4])

#特征长度为4,输出节点为5,故权值矩阵的shape为[4,5]
w1 = tf.Variable(tf.random.truncated_normal([4, 5], stddev=0.1))

#偏置向量的shape为[5]
b1 = tf.Variable(tf.zeros([5]))
o1 = tf.matmul(x,w1) + b1 # 线性变换
o1 = tf.nn.relu(o1) # ReLu激活函数
print(o1)

在这里插入图片描述

2.2 层方式实现单层全连接层

  全连接层本质上是矩阵的相乘和相加运算,实现并不复杂。但作为最常用的网络层之一,TensorFlow 中有更高层、使用更方便的层实现方式:layers.Dense(units, activation)。通过 layer.Dense 类,只需要指定输出节点数 Units 和激活函数类型 activation 即可。
  需要注意的是,输入节点数会根据第一次运算时的输入 shape 确定,同时根据输入、输出节点数自动创建并初始化权值张量和偏置张量,因此在新建类 Dense 实例时,并不会立即创建权值张量和偏置张量,而是需要调用 build 函数或者直接进行一次前向计算,才能完成网络参数的创建。其中 activation 参数指定当前层的激活函数,可以为常见的激活函数或自定义激活函数,也可以指定为 None,即无激活函数。

from tensorflow.keras import layers # 导入层模块
x = tf.random.normal([3,4])#输入3个样本,每个样本的特征长度为4
fc = layers.Dense(5, activation=tf.nn.relu) # 创建全连接层,指定输出节点数和激活函数
h1 = fc(x) # 通过fc类实例完成一次全连接层的计算,返回输出张量
print(h1)

fc.kernel # 获取Dense类的权值矩阵
fc.bias # 获取Dense类的偏置向量
fc.trainable_variables # 返回待优化参数列表
fc.variables # 返回所有参数列表

在这里插入图片描述

  可以通过类内部的成员名 kernel 和 bias 来获取权值张量和偏置张量对象。在优化参数时,若需要获得网络的所有待优化的张量参数列表,可以通过类的trainable_variables 来返回待优化参数列表。如果希望获得所有参数列表,可以通过类的 variables 返回所有内部张量列表。在Batch Normalization 层,可以通过non_trainable_variables 成员返回所有不需要优化的参数列表。

2、多层神经网络

2.1 张量方式实现多层全连接神经网络

  以输入层4个样本,每个样本的特征长度为28,含有3程隐藏层,各层输出节点数为[25,28,64],输出层的输出节点数为 10为例。
  在使用 TensorFlow 自动求导功能计算梯度时,需要将前向计算过程放置在tf.GradientTape()环境中,从而利用GradientTape 对象的 gradient()方法自动求解参数的梯度,并利用 optimizers 对象更新参数。

#输入层,4个样本,每个样本的特征长度为28
x = tf.random.normal([4,28])

# 隐藏层 1 张量,特征长度为28,输出节点为25
w1 = tf.Variable(tf.random.truncated_normal([28, 25], stddev=0.1))
b1 = tf.Variable(tf.zeros([25]))

# 隐藏层 2 张量,特征长度为25,输出节点为28
w2 = tf.Variable(tf.random.truncated_normal([25, 28], stddev=0.1))
b2 = tf.Variable(tf.zeros([28]))

# 隐藏层 3 张量,特征长度为28,输出节点为64
w3 = tf.Variable(tf.random.truncated_normal([28, 64], stddev=0.1))
b3 = tf.Variable(tf.zeros([64]))

# 输出层张量,特征长度为64,输出节点为10
w4 = tf.Variable(tf.random.truncated_normal([64, 10], stddev=0.1))
b4 = tf.Variable(tf.zeros([10]))


with tf.GradientTape() as tape: # 梯度记录器
    
    # 隐藏层 1 前向计算,[b, 28] => [b, 25]
    h1 = x@w1 + tf.broadcast_to(b1, [x.shape[0], 25])
    h1 = tf.nn.relu(h1)
    
    # 隐藏层 2 前向计算,[b, 25] => [b, 28]
    h2 = h1@w2 + b2
    h2 = tf.nn.relu(h2)
    # 隐藏层 3 前向计算,[b, 28] => [b, 64] 
    h3 = h2@w3 + b3
    h3 = tf.nn.relu(h3)
    # 输出层前向计算,[b, 64] => [b, 10] 
    h4 = h3@w4 + b4

print(h4)

.

2.2 层方式实现多层全连接神经网络

  通过层方式实现,首先新建各个网络层类,并
指定各层的激活函数类型。对于数据依次向前传播的网络,可以通过 Sequential 容器封装成一个网络大类对象,调用大类的前向计算函数一次即可完成所有层的前向计算,使用起来更加方便。

# 导入常用网络层 layers
from tensorflow.keras import layers,Sequential
fc1 = layers.Dense(256, activation=tf.nn.relu) # 隐藏层 1
fc2 = layers.Dense(128, activation=tf.nn.relu) # 隐藏层 2
fc3 = layers.Dense(64, activation=tf.nn.relu) # 隐藏层 3
fc4 = layers.Dense(10, activation=None) # 输出层

# 通过 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) # 前向计算得到输出
print(out)

神经网络:传统神经网络基础学习_第1张图片

3、输出层设计

  网络的最后一层除了和所有的隐藏层一样,完成维度变换、特征提取的功能,还作为输出层使用,需要根据具体的任务场景来决定是否使用激活函数,以及使用什么类型的激活函数等。常见的几种输出类型包括:

  • 输出属于整个实数空间,或者某段普通的实数空间
  • 输出值特别地落在[0, 1]的区间
  • 输出值落在[0,1]的区间,且所有输出值之和为 1
  • 输出值在[-1, 1]之间

3.1 普通实数空间

  这一类问题比较普遍,像年龄的预测、股票走势的预测等都属于整个或者部分连续的实数空间,输出层可以不加激活函数。误差的计算直接基于最后一层的输出和真实值进行计算。

3.2 [0, 1]区间

  输出值属于[0,1]区间也比较常见,通过 Sigmoid 函数可以实现输出值在[0,1]区间。

3.3 [0,1]区间,且和为 1

  通过在输出层添加 Softmax 函数实现输出值在[0,1]区间,且和为0。Softmax 函数不仅可以将输出值映射到[0,1]区间,还满足所有的输出值之和为 1 的特性。通过Softmax函数可以将输出层的输出转译为类别概率,在分类问题中使用的非常频繁。

3.4 [-1, 1]区间

  如果希望输出值的范围分布在(−1,1)区间,可以简单地使用 tanh 激活函数。

4、神经网络类型

  全连接层是神经网络最基本的网络类型,全连接层前向计算流程相对简单,梯度求导也较简单,但是它有一个最大的缺陷,在处理较大特征长度的数据时,全连接层的参数量往往较大,使得深层数的全连接网络参数量巨大,训练起来比较困难。随着时代发展,相继提出了一系列的神经网络变种类型。

4.1 卷积神经网络

  通过利用局部相关性和权值共享的思想,提出了卷积神经网络(Convolutional Neural Network,简称 CNN)。随着深度学习的兴盛,卷积神经网络在计算机视觉中的表现大大地超越了其它算法模型,呈现统治计算机视觉领域之势。

4.2 循环神经网络

  除了具有空间结构的数据外,序列信号也是非常常见的一种数据类型,其中一个最具代表性的序列信号就是文本数据。卷积神经网络由于缺乏 Memory 机制和处理不定长序列信号的能力,并不擅长序列信号的任务。循环神经网络(Recurrent Neural Network,简称 RNN)证明非常擅长处理序列信号。后续又提出了 LSTM 网络,作为 RNN 的变种,它较好地克服了 RNN 缺乏长期记忆、不擅长处理长序列的问题,在自然语言处理中得到了广泛的应用。

4.3 注意力(机制)网络

  随着注意力机制(Attention Mechanism)的提出,克服了 RNN 训练不稳定、难以并行化等缺陷,在自然语言处理和图片生成等领域中逐渐崭露头角。注意力机制最初在图片分类任务上提出,但逐渐开始侵蚀NLP 各大任务。2017 年,Google 提出了第一个利用纯注意力机制实现的网络模型Transformer,随后基于 Transformer 模型相继提出了一系列的用于机器翻译的注意力网络模型。

4.4 图卷积神经网络

  图片、文本等数据具有规则的空间、时间结构,称为 Euclidean Data(欧几里德数据)。卷积神经网络和循环神经网络被证明非常擅长处理这种类型的数据。而像类似于社交网络、通信网络、蛋白质分子结构等一系列的不规则空间拓扑结构的数据,它们显得力不从心。2016 年,Thomas Kipf 等人基于前人在一阶近似的谱卷积算法上提出了图卷积网络(Graph Convolution Network,GCN)模型。GCN 算法实现简单,从空间一阶邻居信息聚合的角度也能直观地理解,在半监督任务上取得了不错效果。

你可能感兴趣的:(神经网络,神经网络,学习,tensorflow)