精华内容
下载资源
问答
  • 06_2_神经网络与全连接层_全连接层&输出方式&误差计算 全连接层 deep learning最基本的层:全连接层,也就是线性层 Outline Matmul 矩阵形式 ->迭代到 Neural Network 神经网络结构 ->引入 Deep ...

    06_2_神经网络与全连接层_全连接层&输出方式&误差计算

    全连接层

    deep learning最基本的层:全连接层,也就是线性层

    Outline

    • Matmul 矩阵形式
    • ->迭代到 Neural Network 神经网络结构
    • ->引入 Deep Learning 概念
    • ->最后实现一个 Multi-Layer

    Recap

    out = f(X@W+b)

    f为非线性因子,一般指relu函数或者SIGMOD函数

    X@W+b

    h 0 0 = x 0 0 ∗ W 0 0 + x 1 0 ∗ W 0 1 + x 2 0 ∗ W 0 2 h_0^0 = x_0^0*W_0^0 + x_1^0*W_0^1 + x_2^0*W_0^2 h00=x00W00+x10W01+x20W02。相当于下图的连线,还有一个 b 0 b_0 b0没有画出来。

    σ \sigma σ符号统指激活函数,左边是输入,右边是输出。

    在这里插入图片描述

    Black Magic!

    上标表示层的概念。

    在这里插入图片描述

    Layers

    输入层、隐藏层、输出层。

    一层包括了权值W、偏置b、激活函数 σ \sigma σ等概念。

    Here comes Deep Learning!

    过去叫Neural Network,一般是3~5层。

    在这里插入图片描述

    现在大概是1200层,是过去3~5层不停地堆叠。

    大概2000年代,更多的是工程paper,很难解释其中的原理机制。目前还是和neural network本质上没有什么区分,更多的是深度的增加。

    在这里插入图片描述

    Why?

    在过去80年代,计算能力弱。

    在这里插入图片描述

    Heroes

    • BigDATA 大量的图片、音频、视频数据
    • ReLU函数,比较好的解决了梯度离散的现象
    • Dropout
    • BatchNorm
    • ResNet 10~20层->100++的可行性
    • Xavier Initialization 初始化方案
    • Caffe/TensorFlow/PyTorch 深度学习加速库使一般人更方便

    Fully connected layer

    tf.keras是TensorFlow内部的keras,它是TensorFlow对keras的实现,keras本质上是一种api的协议,TensorFlow对keras有具体的实现,位于tf.keras下。

    tf.keras.layers.Dense(512) #512:输出的维度

    输入的维度会自动识别,在例子中,W是[784,512],b是[512]

    在这里插入图片描述

    w和b是通过build创建的,并且可以多次创建。

    input_shape=(None,4)。None为batch,4为输入的维度

    刚刚上图没有调用build函数,我们在调用net(x)实例的时候,它会自动判断如果没有w和b,会自动调用build函数。

    在这里插入图片描述

    input的shape和创建的shape不一致的例子:

    build的时候输入的维度是20维,喂的是12维,这样会产生error。需要给正确的shape。

    现在讲解的是单层的Dense层,也就是一个全连接层,每个输出节点都和每个输入节点相连接,也就是Dense,稠密。

    在这里插入图片描述

    Multi-Layers

    如果要创建多层,我们只需要创建容器:

    keras.Sequential([layer1,layer2,layer3])

    在这里插入图片描述

    具体的实现:

    输入是3,变成2维,再变成2维,再变成2维。

    这里input_shape是3

    model.summary() 其实是print的意思,返回模型的信息。

    model.trainable_variables 会返回 w1,b1,w2,b2,w3,b3

    在这里插入图片描述

    实战:

    import os
    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
    
    import tensorflow as tf
    from tensorflow import keras
    
    x = tf.random.normal([2,3])
    
    #网络结构
    model = keras.Sequential([
        keras.layers.Dense(2,activation='relu'),
        keras.layers.Dense(2,activation='relu'),
        keras.layers.Dense(2)
    ])
    model.build(input_shape=[None,3])
    model.summary()
    #第一层的8是因为输入为3,输出为2,一共3*2个w,再加上2个b;后面两层类似
    # Model: "sequential"
    # _________________________________________________________________
    # Layer (type)                 Output Shape              Param #
    # =================================================================
    # dense (Dense)                multiple                  8
    # _________________________________________________________________
    # dense_1 (Dense)              multiple                  6
    # _________________________________________________________________
    # dense_2 (Dense)              multiple                  6
    # =================================================================
    # Total params: 20
    # Trainable params: 20
    # Non-trainable params: 0
    # _________________________________________________________________
    
    for p in model.trainable_variables:
        print(p.name,p.shape)
    # dense/kernel:0 (3, 2)
    # dense/bias:0 (2,)
    # dense_1/kernel:0 (2, 2)
    # dense_1/bias:0 (2,)
    # dense_2/kernel:0 (2, 2)
    # dense_2/bias:0 (2,)
    

    输出方式

    Outline

    原因:因为神经网络是面向不同的应用的,不同的应用有不同的输出的范围的要求

    有时候是实数集
    有时候是概率的输出
    有些概率还要求输出和是1
    输出在-1~1

    • y ∈ R d y \in R^d yRd
    • y i ∈ [ 0 , 1 ] y_i \in [0,1] yi[0,1]
    • y i ∈ [ 0 , 1 ] , ∑ i = 0 y y i = 1 y_i \in [0,1], \sum_{i=0}^y y_i = 1 yi[0,1],i=0yyi=1
    • y i ∈ [ − 1 , 1 ] y_i \in [-1,1] yi[1,1]

    1. y ∈ R d y \in R^d yRd

    linear regression x@w+b,如果要求正数,可以简单地加relu激活函数。一般来说最后一层是不加激活函数的,不加激活函数的输出值叫logits

    分类问题,一般是用0~1的输出范围,但是MSE误差的话也可以不加这样范围的约束,直接用它去逼近。

    实数集做输出的话,一般来讲不需要做额外的处理。

    在这里插入图片描述

    2. y i ∈ [ 0 , 1 ] y_i \in [0,1] yi[0,1]

    • 二分类,一般有2种设定,第一种是输出节点只有1个,大于0.5判定为1;小于0.5判定为0。另外一种设定是把二分类也理解为多分类的问题,两个输出节点,P(y=0|x)和P(y=1|x),和其他多分类问题没有什么区别。
    • 图片的生成,rgb是0~255范围压缩到0~1的范围,利于神经网络的优化,所以生成以后也是0~1的输出,表达是灰度或rgb的信息。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zTNX8I44-1615782848391)(06_2_神经网络与全连接层_全连接层&输出方式&误差计算.assets/image-20210307210845874.png)]

    sigmoid函数,它的x范围是整体实数空间,y是从0~1。

    通过out' = sigmoid(out),原来out是整个实数范围,变成0~1的范围。它不仅仅是激活函数的功能,更多的是输出值范围压缩的功能。

    在这里插入图片描述

    sigmoid

    具体形式:

    f ( x ) = 1 1 + e − x f(x) = \frac{1}{1+e^{-x}} f(x)=1+ex1

    tf.sigmoid

    在这里插入图片描述

    把很宽的实数空间重映射到0~1的空间去,对于图片,希望能把它压缩到RGB的表示范围,也就是0~1

    在这里插入图片描述

    3. y i ∈ [ 0 , 1 ] , ∑ i = 0 y y i = 1 y_i \in [0,1], \sum_{i=0}^y y_i = 1 yi[0,1],i=0yyi=1

    对MNIST,10分类属于0~9,给出数据集中的任何一张图片,它肯定是0~9之间的1类,同时要求输出之和的 ∑ i ∈ [ 0 , 9 ] P ( y = i ∣ x ) = 1 \sum_{i \in [0,9]} P(y=i|x) = 1 i[0,9]P(y=ix)=1

    sigmoid函数并没有实现这个功能。

    所有概率之和为1的功能,另外1个函数叫做softmax。

    在这里插入图片描述

    softmax

    一般,没有加激活函数的输出叫Logits。

    softmax,把强的变得更强,把弱的变得更弱。在分类中使用的非常广泛,交叉熵也使用了softmax。

    在这里插入图片描述

    Classification

    有个logits,有1个实例,10个分类,值在-2~2之间。

    prob = tf.nn.softnax(logits,axis=1)

    每个点代表P(y=i|x),因此名字为prob

    在这里插入图片描述

    4. y i ∈ [ − 1 , 1 ] y_i \in [-1,1] yi[1,1]

    tanh:Sigmoid函数通过平移,在y的轴上进行放大,0~2,然后再下移,变成-1~1的空间。

    在这里插入图片描述

    例子:

    在这里插入图片描述

    误差计算(损失函数)

    Outline

    • MSE 均方差
    • Cross Entropy Loss 专门应对于分类问题的误差计算
    • Hinge Loss 用于SVM支持向量机中Maximum margin多一些

    ∑ i m a x ( 0 , 1 − y i ∗ h θ ( x i ) \sum_i max(0,1-y_i * h_\theta(x_i) imax(0,1yihθ(xi)

    MSE

    平方差的和。输出值和真实值的差-的平方-累加,再average( 1 N \frac{1}{N} N1)(可选,一般加)。-》一般来说,加learning rate的目的就是要衰减更新步长,因为我们计算的梯度往往是比较大的数值,所以才需要衰减更新的步长,如果loss计算比较大,梯度往往也比较大,所以有average操作。

    N一般指batch,实际上它们往往还会在向量维度上进行average,loss不仅仅除以N,还会除以10(10类、vector length)。也就是说它是求一个sample的输出node的平均的average loss。

    batch和10除不除都不是强制的。

    2范数(2-norm)和MSE有些相似,在某种程度上是可以相互转换的。

    在这里插入图片描述

    具体的实例:

    三种方式都可以求出MSE

    loss1 = tf.reduce_mean(tf.square(y-out)) #按上图的第一个公式
    loss2 = tf.square(tf.norm(y-out)) / (5*4) #按第二个公式,利用范数的平方除以(N*类别)
    loss3 = tf.reduce_mean(tf.losses.MSE(y-out)) #利用tf.losses.MSE(a,b)求出shape为[b]的Tensor,再利用reduce_mean求出loss
    

    在这里插入图片描述


    Entropy(熵)

    不确定性,事件发生的概率的确定性和不确定性是比较抽象的概念,同时需要数据来量化不确定度。

    E n t r o p y = − ∑ P ( i ) log ⁡ P ( i ) Entropy = - \sum P(i)\log P(i) Entropy=P(i)logP(i)

    因此,有以下公式,通过发生的概率P(i)乘以logP(i)求和,加上符号。这个数值用来衡量某个分布的不确定度(惊喜度)。当熵越小的时候,意味着确定度越大,事件发生的确定性更高。

    因为概率的数值范围为0~1,logP(i)为负数,P(i)为正数,前面有负号,因此整个的值>=0,再求和。

    当猫和狗的概率为0和1,因为熵越低,表示越确定,因此得到的熵接近于0
    当猫和狗的概率都为0.5,说明非常不确定,不确定性很高,熵远远大于0

    在这里插入图片描述

    越有把握,熵越接近于0

    Lottery(彩票) - 例子

    都是0.25,熵很高
    0.1,0.1,0.1,0.7,熵为1.35
    0.97,熵为0.24

    下面为手写公式计算熵

    在这里插入图片描述

    Cross Entropy交叉熵

    是指两个分布之间信息衡量的标准, H ( p , q ) = − ∑ p ( x ) log ⁡ q ( x ) H(p,q) = -\sum p(x) \log q(x) H(p,q)=p(x)logq(x)

    也可以推导成 H ( p , q ) = H ( p ) + D K L ( p ∣ q ) H(p,q) = H(p) + D_{KL} (p|q) H(p,q)=H(p)+DKL(pq),其中 D K L ( p ∣ q ) D_{KL}(p|q) DKL(pq),中文名叫散度,这个是衡量p和q之间的距离。

    当p=q, D K L ( p ∣ q ) D_{KL}(p|q) DKL(pq)为0,H(p,q) = H§。

    如果p是one-hot encoding,我们知道y一般是one-hot encoding过的,所以y的分布可能是[0,1,0…],它表示label为1的概率是100%,label是其他的概率是0。那么如果把y的分布理解为p,那么对于 h ( p : [ 0 , 1 , 0 ] ) = − 1 l o g 1 = 0 h(p:[0,1,0]) = -1log1 = 0 h(p:[0,1,0])=1log1=0。也就是确定性非常大,对其他的概率是不可能的。

    那么再看交叉熵,如果把p当做one-hot encoding放在前面的话,q是我们的output,也就是prob。这样利用公式2, H ( [ 0 , 1 , 0 ] , [ p 0 , p 1 , p 2 ] ) = 0 + D K L ( p ∣ q ) = − 1 l o g q 1 H([0,1,0],[p0,p1,p2]) = 0+D_{KL}(p|q) = -1logq_1 H([0,1,0],[p0,p1,p2])=0+DKL(pq)=1logq1

    因此对于one-hot encoding来说,p和q之间的交叉熵其实退化为一个 D K L ( p ∣ q ) D_{KL}(p|q) DKL(pq) D K L ( p ∣ q ) D_{KL}(p|q) DKL(pq)的最小值就是p=q的时候,这也说明了我们为什么使用h(p,q)作为loss的时候是合理的,当针对分类问题来说,我们希望预测的分布q: prob(预测的分布),p: [0,1,0,…](真实的分布),我们希望q能逼近于真实的分布p,那么什么时候能逼近?也就是交叉熵的最小值 D K L ( p ∣ q ) D_{KL}(p|q) DKL(pq)等于0的时候,也就是p和q完全相等的时候,那就意味着如果预测q的分布能够真实的p的分布一样的话,那么这个时候的交叉熵就退化为 D K L ( p ∣ q ) D_{KL}(p|q) DKL(pq),也就退化为0,也是loss取的最小的时候,输出q和真实p是完全一样的,这时候的w参数就是最好的参数。这样我们证明了采用交叉熵作为loss得到的最优化的值刚好是使得 D K L ( p ∣ q ) D_{KL}(p|q) DKL(pq)等于0的时候,也就是p=q的时候。

    在这里插入图片描述

    具体分类问题的交叉熵的求解方法:

    Binary Classification二分类

    有两种设计格式:

    第1个是把二分类当做多分类求解,比如第1个节点表示P(y=0|x),第2个节点表示P(y=1|x),这个时候和二、三…分类完全一样。

    第2个只有一个输出节点,这个节点P(y=1|x),那么P(y=0|x) = 1 - P(y=1|x)。这种方式减少了参数量(没太大关系)。

    在这里插入图片描述

    Single output(1个节点)

    D K L ( p ∣ q ) = − 1 l o g q 1 D_{KL}(p|q) = -1logq_1 DKL(pq)=1logq1的原因:因为 D K L ( p ∣ q ) = − ∑ p i log ⁡ q i D_{KL}(p|q) = -\sum p_i\log q_i DKL(pq)=pilogqi p i p_i pi等于0,那么 p i log ⁡ q i p_i\log q_i pilogqi就等于0, p i p_i pi不等于0的时候,就等于1,10个数字(举例)间只有1个这样的项,因此以上。(p=1时候的q)
    l o s s = H ( p , q ) p : o n e − h o t = 0 + D K L ( p ∣ q ) = − 1 log ⁡ q i loss = H(p,q) \quad p:one-hot\\ = 0 + D_{KL}(p|q)\\ = -1\log q_i loss=H(p,q)p:onehot=0+DKL(pq)=1logqi
    要最小化loss,就要最大化 q i q_i qi,q表示当前节点的label是i的话,在i号节点输出的概率q,比如说 q ( y = i ∣ x ) q(y=i|x) q(y=ix)越大越好,最大的可能值是1,这个时候就和p完全一样了,因为p的真实节点[0,1,0,…]也在这个下标,若q的预测值是[0,1,0,…],这个时候p和q完全相等,loss等于0。

    以上我们推导了对于一个**多分类(上图类型1)**问题的loss的计算方式。

    在这里插入图片描述

    对于一个**单号节点(上图类型2)**输出的二分类问题的求解:

    展开,首先因为对于单分类问题来说,它不是one-hot encoding,因为单一的输出是没有one-hot encoding的,所以,
    H ( P , Q ) = − P ( c a t ) log ⁡ Q ( c a t ) − P ( ! c a t ) l o g ( Q ( ! c a t ) ) 因 为 二 分 类 P ( ! c a t ) = 1 − P ( c a t ) , q 同 理 = − P ( c a t ) log ⁡ Q ( c a t ) − ( 1 − P ( c a t ) ) log ⁡ ( 1 − Q ( c a t ) ) = − ( y l o g ( p ) + ( 1 − y ) l o g ( 1 − p ) ) H(P,Q) = -P(cat)\log Q(cat) - P(!cat)log(Q(!cat))\\ 因为二分类 \quad P(!cat)=1-P(cat), q同理\\ =-P(cat)\log Q(cat) - (1-P(cat))\log(1-Q(cat))\\ =-(ylog(p) + (1-y)log(1-p)) H(P,Q)=P(cat)logQ(cat)P(!cat)log(Q(!cat))P(!cat)=1P(cat),q=P(cat)logQ(cat)(1P(cat))log(1Q(cat))=(ylog(p)+(1y)log(1p))
    p是神经网络输出节点的概率值,因此对于一个二分类的问题来说,y已知,p已知,我们可以简单的把loss归化为交叉熵H(P,Q)。当y(cat)=1,前项存在,后项不存在,为 − y l o g ( p ) -ylog(p) ylog(p);当y(cat)=0,则相反,为 − ( 1 − y ) l o g ( 1 − p ) -(1-y)log(1-p) (1y)log(1p)

    在这里插入图片描述

    然后我们看更加通用的多分类,也就是多号输出节点(0,1,2,…9):

    Classification

    根据二分类中的多分类推导情况,可知:
    H ( [ 0 , 1 , 0 ] , [ p 0 , p 1 , p 2 ] ) = 0 + D K L ( p ∣ q ) = − 1 log ⁡ q 1 H([0,1,0],[p_0,p_1,p_2]) = 0 + D_{KL}(p|q)= -1\log q_1 H([0,1,0],[p0,p1,p2])=0+DKL(pq)=1logq1

    也就是当前x=1的话,其实概率就为-logP(y=1|x),这个节点的概率希望你越大越好,比如q为 q 1 q_1 q1的时候 log ⁡ q 1 \log q_1 logq1等于0,这时候loss取最小值。

    在这里插入图片描述

    具体情况:

    这里是五分类,真实是一只小狗。图片x=0。

    第一种输出 Q 1 = [ 0.4 , 0.3 , 0.05 , 0.05 , 0.2 ] Q_1 = [0.4,0.3,0.05,0.05,0.2] Q1=[0.4,0.3,0.05,0.05,0.2],可以判定预测为狗的概率最大,输出为狗,只是没有很大的置信度。这样网络不算太好,但是预测对了。
    这样情况的loss(也是交叉熵),为0.916,loss(交叉熵)较大。

    如果输出为[0.98…],这个时候的loss(交叉熵)是0.02,较小。

    通过这样的情况,就可以更新参数,直到满足loss足够小。

    在这里插入图片描述

    更多的计算实例:

    Categorical Cross Entropy(分类问题的交叉熵)

    tf.losses.categorical_crossentropy([0,1,0,0],[0.25,0.25,0.25,0.25])

    第一个参数是y_true(one-hot),第二个是预测值prob(predict)。
    四个例子表示不同预测情况与肯定度的交叉熵(loss)值各不相同(正确且肯定的交叉熵小,不确定且肯定的交叉熵大……),也说明了Cross Entropy是合理的。

    在这里插入图片描述

    例子:

    交叉熵有两种形式:

    1. tf.losses.categorical_crossentropy([0,1,0,0],[0.25,0.25,0.25,0.25])是函数形式。
    2. 还有一种类的形式,criteon = tf.keras.losses.CategoricalCrossentropy(),首先声明类,然后对对象进行一个调用(对类实例criteon传入参数[y],[predict])。

    第三部分是二分类但是只有1个输入节点的。例子中真实值为1,输出概率为0.1,交叉熵较大。

    第四部分是函数的形式,和第三部分类似。

    在这里插入图片描述

    Why not MSE?

    当sigmoid和MSE结合,会出现gradient vanish的现象,因为值大的时候梯度为0,小的时候梯度为0,这样很容易会出现前期更新非常慢,甚至出现loss很大,但是一直没更新的情况。

    实践证明cross entropy收敛更加地快,在图中,预测值(概率)比较错误的情况下的梯度,当预测错误时候的概率,在刚开始的时候概率非常大,有助于前期收敛的非常快,这是它作为loss非常好的地方。

    (我理解图中的梯度为斜率,这个函数是loss函数,loss函数可以是MSE,也可以是cross entropy,但是cross entropy在初期识别能力弱的时候,也就是predicted prob小的时候,它的梯度-斜率大,在前期能比较快的更新w-参数值,通过函数 w = w − l r ∗ δ l o s s δ w w = w - lr * \frac{\delta loss}{\delta w} w=wlrδwδloss

    不过在meta-learning等一些学科,发现MSE更加稳定合理,交叉熵则不稳定,根据实际情况来说。

    在这里插入图片描述

    分类问题的pipeline:

    logits->CrossEntropy

    首先是从输入经过一系列网络得到输出(LOGIT)(一般指最后一层没有加激活函数),如果是分类问题,经过softmax,再经过cross entropy得到loss。

    如果这么做会发现,有数值不稳定的过程,会出现处理错误error(not a number或infinity),为了处理这个问题,通常利用隔断,将黑色的区域统一在一起作为1个函数,函数内部已经做好了优化,防止出现数据不稳定的过程。

    在这里插入图片描述

    Numerical Stability(为数据稳定加参数from_logits)

    所以做分类问题,不需要先softmax再cross entropy。直接交给TensorFlow稳定处理的函数,这个函数名字为原来的函数,只是加了参数from_logits=True,一般情况都加这个参数。

    总结注意两点:

    1. 第四部分的第一个参数必须要one-hot encoding
    2. 设定from_logits

    当然,在第三部分经过softmax,第五部分from_logits设置为False,理论上讲和第四部分是一样的,但是不推荐,会出现数值不稳定的问题。

    在这里插入图片描述

    展开全文
  • 之前在看论文看代码的时候,我经常看到把神经网络的中间结果输入全连接层。但是在我的印象中全连接层就是类似于BP神经网络的样子,于是我就很疑惑把一个三维或者是二维的矩阵输入一个BP神经网络里面到底是什么...

    前言

    最近一段时间在看研究生导师发的资料,因为导师是做自然语言处理和知识图谱方向的,所以之前学的CNN的知识暂时用不上啦。NLP和KG方面的知识我之前没怎么接触过,所以最近打算写一系列博文来记录一下学习过程,如果有说得不对的地方请大佬指正。

    Feedforward层(全连接层)

        之前在看论文和看代码的时候,我经常看到把神经网络的中间结果输入到全连接层。但是在我的印象中全连接层就是类似于BP神经网络的样子,于是我就很疑惑把一个三维或者是二维的矩阵输入一个BP神经网络里面到底是什么样的。首先给出结论:全连接层=矩阵运算。

    一个简单的全连接层

        可以看到上图是一个简单的全连接层,输入三个元素输出两个元素。可以看到输入和输出的对应关系为:b_{1}=a_{1}w_{11}+a_{2}w_{21}+a_{3}w_{31}b_{2}=a_{1}w_{12}+a_{2}w_{22}+a_{3}w_{32}(不添加偏置)。我们把输入写成A=[a_{1},a_{2},a_{3}],输出写成B=[b_{1},b_{2}]。再把权重写成W=\begin{bmatrix} w_{11},w_{12}&\\ w_{21},w_{22}&\\ w_{31},w_{32} & \end{bmatrix},很明显B=A\times W是一个标准的矩阵运算。这时候有同学可能就要问了,如果遇到A=\begin{bmatrix} a_{11},a_{12},a_{13}&\\ a_{21},a_{22},a_{23}&\\ a_{31},a_{32},a_{33} & \end{bmatrix}怎么办,很简单我们只要按行把A矩阵拆分成[a_{11},a_{12},a_{13}][a_{21},a_{22},a_{23}][a_{31},a_{32},a_{33}],然后在依次把他们喂入全连接层中就可以了,如下图所示。

        在实际的计算中我们可能还会遇到batchsize大于1的情况(比如CNN中同时输入多张图片训练,transformer中同时输入多个句子),这个时候输入的是一个三维的矩阵,那就要构建多组全连接层,没个全连接层输入一张图片或是一个句子,如图所示。(个人理解如果说得不对,请指正)

     

    展开全文
  • 模型输入层和输出层的维度一定要对住,否则会报错。 模型中间只用给定输出维度 import numpy as np import tensorflow as tf print(tf.__version__) 2.3.0 # Without InputLayer and let the first layer to ...

    模型输入层和输出层的维度一定要对住,否则会报错。
    模型中间层只用给定输出维度

    import numpy as np
    import tensorflow as tf
    print(tf.__version__)
    
    2.3.0
    
    # Without InputLayer and let the first layer to have the input_shape.
    # Keras will add a input for the model behind the scene.
    model = tf.keras.Sequential([
      tf
    展开全文
  • 全连接层与 GAP

    2021-08-01 20:22:36
    如果说卷积层、池化层激活函数层等操作是将原始数据映射到隐层特征空间的话,全连接层则起到将学到的“分布式特征表示”映射到样本标记空间的作用。 在实际使用中,全连接层可由卷积操作实现: 对前层是全连接的...

    全连接层

    全连接层一般会放在网络的最后,作用是用来综合所有信息。先把卷积层生成的图像降维成一维向量,然后全连接层把一维向量转化成指定个数的单元值
    在这里插入图片描述
    如果说卷积层、池化层和激活函数层等操作是将原始数据映射到隐层特征空间的话,全连接层则起到将学到的“分布式特征表示”映射到样本标记空间的作用。

    在实际使用中,全连接层可由卷积操作实现:

    对前层是全连接的全连接层可以转化为卷积核为1x1的卷积;
    前层是卷积层的全连接层可以转化为卷积核为 h * w 的全局卷积,h和w分别为前层卷积结果的高和宽。

    (1)展平操作

    卷积层之后是无法直接连接全连接层的,需要把卷积层产生的 feature map 进行压平(Flatten),也就是把 (height,width,channel)的数据压缩成长度为 height × width × channel 的一维数组,然后就可以直接进入全连接层了
    在这里插入图片描述
    可以从图中看到,随着网络的深入,我们的图像(严格来说中间的那些不能叫图像了,但是为了方便,还是这样说吧)越来越小,但是channels却越来越大了。在图中的表示就是长方体面对我们的面积越来越小,但是长度却越来越长了。

    展平操作的 Pytorch 实现:

    torch.flatten(input, start_dim=0, end_dim=-1)
    

    input::一个 tensor,即要被“推平”的 tensor;
    start_dim: “推平”的起始维度;
    end_dim: “推平”的结束维度;
    首先如果按照 start_dim 和 end_dim 的默认值,那么这个函数会把 input 推平成一个 shape 为 [n] 的tensor,其中 n 即 input 中元素个数。

    (2)Pytorch 中全连接层的实现

    linear 函数

    class torch.nn.Linear(in_features: int, out_features: int, bias: bool = True)
    

    Linear() 用矩阵乘法的形式实现对所有输入的加权求和,如下式,由于x出现在权值矩阵左方,如果输入的是一维数据(一个样本),它应该是一个行向量,此时输入尺寸就等于向量长度。
    在这里插入图片描述

    PyTorch的 nn.Linear() 是用于设置网络中的全连接层的,需要注意在二维图像处理的任务中,全连接层的输入与输出一般都设置为二维张量,形状通常为 [batch_size, size],不同于卷积层要求输入输出是四维张量。
    in_features 指的是输入的二维张量的大小,即输入的 [batch_size, size] 中的 size;out_features 指的是输出的二维张量的大小,即输出的二维张量的形状为 [batch_size,output_size],当然,它也代表了该全连接层的神经元个数。

    从输入输出的张量的shape角度来理解,相当于把一个输入为 [batch_size, in_features] 的张量变换成了 [batch_size, out_features] 的输出张量
    在这里插入图片描述

    (3)全连接层的 dropout

    dropout 是指在深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃。对于随机梯度下降来说,由于是随机丢弃,故而每一个mini-batch都在训练不同的网络。
    dropout 是 CNN 中防止过拟合提高效果的一个大杀器。

    class torch.nn.Dropout(p=0.5, inplace=False)
    

    以 p 概率随机将全连接层的部分神经元失活。对于每次前向传播,失活的神经元都是随机的。

    二、全局平均池化(GAP)

    全连接存在的问题:参数量过大,降低了训练的速度,且很容易过拟合。
    全连接层将卷积层生成的 feature map 展平成一维向量之后再进行分类,而 GAP 的思路就是将上述两个过程合二为一,如图所示:
    在这里插入图片描述

    其实也就是通过池化层将原有的输入为 [b,c,h,w] 减少成 [b,c,1,1] 的尺寸,也即将 [w,h] 的 feature map 进行平均池化变为一个单元(池化层的过滤器大小为w * h)

    这两者合二为一的过程我们可以探索到 GAP 的真正意义是:对整个网路在结构上做正则化防止过拟合。其直接剔除了全连接层中黑箱的特征,直接赋予了每个 channel 实际的内别意义。

    (1)全连接层与 GAP 的对比

    计算量的对比

    全连接先把特征图压缩成1列,然后接两层全连接故计算量 k * k * k * k

    GAP只在gap得到的特征后直接softmax,故计算量 k * k

    输入大小、感受野、参数量、特征信息对比

    GAP 去除了对输入大小的限制。
    ● 全局平均池化操作,从而使其具有全局的感受野,使得网络低层也能利用全局信息
    ● 全连接的目的,因为传统的网络我们的输出都是几个类别的概率,那么全连接层就是高度提纯的特征了,方便交给最后的分类器或者回归。但是全连接的参数实在是太多了;GAP减少了参数的数量,可以减轻过拟合的发生
    FC会导致 feature map 损失空间位置信息,而GAP则不会
    (如果在图像的某一位置有高响应,则经过FC之后,根据整个feature并不能分辨出刺激源于左上角还是右下角还是什么其他的地方,而通过GAP就可以,因为其保留了空间位置信息)

    (2)GAP 的 Pytorch 实现

    class torch.nn.AdaptiveAvgPool2d(output_size)
    

    output_size:输出信号的尺寸,可以用(H,W)表示H*W的输出,也可以使用耽搁数字 H 表示 H * H 大小的输出。

    (3)GAP 后进行分类

    GAP 层不能不能改变输出单元个数,因此后面再接一个 FC 进行分类:
    在这里插入图片描述

    展开全文
  • 通俗易懂的说就是当输入一个数据后,对全连接层进行循环遍历的操作,每次遍历时对每层进行卷积运动若每层中有相似数据则记录为1,然后遍历完所有层后将所有记录值集合成一个值输出。 下面用一个简单的例子来看: ...
  • 全连接层调参tricks

    2021-05-13 16:55:00
    全连接层的设置将最大化的挖掘模型的性能,怎么设置全连接层成了一个重点难点。 结合自身经验,以下是个人认为的tricks: 隐藏层层数:视情况而定,模型的复杂性成反比。 我们都知道全连接层一般越多越好,...
  • 在卷积神经网络的最后,往往会出现一两层全连接层,全连接一般会把卷积输出的二维特征图转化成一维的一个向量,全连接层的每一个节点都与上一层每个节点连接,是把前一层的输出特征都综合起来,所以该层的权值参数是...
  • 全连接层和卷积层实际上是可以相互转换的 1、卷积层替换全连接层的可行性 *、卷积层是局部连接 *、它的特点是稀疏连接权值共享, *、全连接是全局信息 2、全连接层到卷积层的转换 、卷积核大小和输入特征图尺寸...
  • 1. 池化在卷积网络中, 通常会在卷积层之间增加池化(Pooling) , 以降低特征图的参数量, 提升计算速度, 增加感受野, 是一种降采样操作。池化是一种较强的先验, 可以使模型更关注全局特征而非局部出现的位置...
  • 神经网络:全连接层

    千次阅读 2021-02-06 17:22:36
    (所以用特征图尺寸一样大小的卷积核做卷积,提取全图范围特征,全连接层,计算过程是等效的,输入输出,参数量完全一样) 全连接之所以失宠: 有人说是参数量大的原因。其实如果特征图压缩的足够小再做全连接...
  • 全连接层和卷积层如何相互转化?

    千次阅读 2021-03-16 12:02:00
    全连接层和卷积层之间唯一的不同就是卷积层中的神经元只与输入数据中的一个局部区域连接,且参数共享。然而不管在卷积FC层中,神经元都是计算点积,所以它们的函数形式是一样的。因此,将此两者相互转化是可能的:...
  • 全连接层

    2021-02-24 11:53:03
    2、全连接层的主要作用是将输入图像在经过卷积池化操作后提取的特征进行压缩,并且根据压缩的特征完成模型的分类功能;在整个卷积神经网络中起到“分类器”的作用,如果说卷积层、池化层激活函数等操作是将原始...
  • 在卷积神经网络的最后,往往会出现一两层全连接层,全连接一般会把卷积输出的二维特征图转化成一维的一个向量,这是怎么来的呢?目的何在呢?
  • 今天发现一个有意思的地方 输入shape为:torch.Size([1, 8, 64]) 全连接层: nn.Linear(64, 1) 居然没有报错,而且输出为torch.Size([1, 8, 1])!nb
  • dropout要解决的问题:在机器学习的一些模型中,如果模型的参数太多,而训练样本又太少的话,这样训练出来的模型很容易产生过拟合现象。内容:在训练时, 每个神经元以概率p保留, 即以1-p的概率停止工作, 每次前...
  • PyTorch的nn.Linear()全连接层

    千次阅读 2021-06-29 07:34:14
    PyTorch的nn.Linear()是用于设置网络中的全连接层的,需要注意的是全连接层的输入与输出都是二维张量,一般形状为[batch_size, size],不同于卷积层要求输入输出是四维张量。 ![在这里插入图片描述]...
  • 全连接层可以视作一种特殊的卷积考虑下面两种情况:特征图和全连接层相连,AlexNet经过五次池化后得到7*7*512的特征图,下一层全连接连向4096个神经元,这个过程可以看做有4096个7*7*512的卷积核7*7*512的特征图...
  • 首先说明:可以不用全连接层的。理解1:卷积取的是局部特征,全连接就是把以前的局部特征重新通过权值矩阵组装成完整的图。因为用到了所有的局部特征,所以叫全连接。理解2:从卷积网络谈起,卷积网络在形式上有一...
  • 如果说卷积层、池化层激活函数层等操作是将原始数据映射到隐层特征空间的话,全连接层则对前面的特征(通过“全局平均值global average pooling”的方法减少全连接的参数)做加权,将学到的“分布式特征表示”...
  • 我们用pytorch写一个...问题:下面的的第一个全连接层输入神经元个数是多少呢? net = nn.Sequential( nn.Conv2d(1, 32, 3),nn.ReLU(),nn.MaxPool2d(2,2), nn.Conv2d(32, 64, 3),nn.ReLU(),nn.MaxPool2d(2,2...
  • 如果说卷积层、池化层激活函数层等操作是将原始数据映射到隐层特征空间的话,全连接层则起到将学到的“分布式特征表示”映射到样本标记空间的作用。在实际使用中,全连接层可由卷积操作实现:对前层是全连接的...
  • 一、池化:对信号进行收集并总结。 (目标:冗余信息的提出,减少后面的信息量) 收集:多变少 总结:最大值/平均值(max/average) 1 nn.MaxPool2d(功能对二维信号-图像进行最大池化) 常见参数:kernel_size:...
  • 全连接层(线性层)-Linear

    千次阅读 2021-01-26 15:02:14
    原理: #%% import torch import torch.nn as nn #%% 输入数据 ...input = torch.arange(in_...#%% 线性层输出(pytorch) connect1 = nn.Linear(in_features=in_features,out_features=out_features,bias=Tr
  • 我们以VGG-16为例,来探讨一下如何计算卷积层、全连接层的参数量、计算量。为了简单、直观地理解,以下讨论中我们都会忽略偏置项,实践中必须考虑偏置项。【卷积层的参数量】什么是卷积层的参数?卷积层的基本原理...
  • 一、全连接层tensorflow中用tf.keras.layers.Dense()这个类作为全连接的隐藏层,下面是参数介绍:tf.keras.layers.Dense()inputs = 64, # 输入该网络层的数据units = 10, # 输出的维度大小activation = None, # 选择...
  • 卷积层池化的理解 外加个人理解。仅作为本人笔记便于速览,如有侵权,联系立删。 正文: 人工神经网络中,单个神经元一般模型是这样的,从左到右分别是输入输入权重,输入乘以输入权重求和,这里-1应该是偏置...
  • 全连接层可以看成拿4096个卷积核,卷积核的大小为335 去原始数据卷积 生成 每个卷积核和输入图像进行这样的卷积(蓝色部分去掉)生成一个数 最后生成1*4096个数 (曾经的思维误区: 认为卷积核必须是nn的二维图像...
  • 在神经网络的计算模型中,输入信号就是我们的输入数据,模型的参数就相当于突触,然后输入信号传入神经元就像是输入的数据模型参数进行线性组合,然后经过激活函数,最后传出模型。 1.2单层神经网络分类器 一...
  • 需要注意在二维图像处理的任务中,全连接层的输入与输出一般都设置为二维张量, 形状通常为[batch_size, size],不同于卷积层要求输入输出是四维张量。 ''' # in_features由输入张量形状决定 , out_features决定了...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 159,595
精华内容 63,838
关键字:

全连接层的输入和输出