深度学习算法学习(二):全连接层(线性层)、激活函数

363 阅读4分钟

全连接层/线性层

  • 全连接层又称线性层

  • 计算公式:y = w * x + b

  • w和b是参与训练的参数,w的维度决定了隐含层输出的维度,一般称为隐单元个数(hidden size)

    隐含层1 的权重维度为 3×5,表示该层将 3维输入映射到 5维输出,因此该层的隐单元个数(hidden size)为 5

    隐含层2 的权重维度为 5×2,表示该层将 5维输入映射到 2维输出,因此该层的隐单元个数(hidden size)为 2

  • 举例:3维映射到5维再映射到2维

    输入:x (维度1 x 3)
    隐含层1:w(维度3 x 5)
    隐含层2:w(维度5 x 2)
    

    image.png

代码

import torch
import torch.nn as nn
import numpy as np

"""
numpy手动实现模拟一个线性层
"""

#搭建一个2层的神经网络模型
#每层都是线性层
class TorchModel(nn.Module):
    # 继承Module执行初始化方法
    def __init__(self, input_size, hidden_size1, hidden_size2):
        super(TorchModel, self).__init__()
        self.layer1 = nn.Linear(input_size, hidden_size1) #w:3 * 5
        self.layer2 = nn.Linear(hidden_size1, hidden_size2) # 5 * 2

    # 前向传播
    def forward(self, x):
        x = self.layer1(x) # 第一层前向传播
        y_pred = self.layer2(x) # 第二层前向传播
        return y_pred

#建立torch模型
print("------------------------建立torch模型----------------------------")
torch_model = TorchModel(3, 5, 2)
print(torch_model.state_dict())
#打印torch模型权重,权重为随机初始化
torch_model_w1 = torch_model.state_dict()["layer1.weight"].numpy()
torch_model_b1 = torch_model.state_dict()["layer1.bias"].numpy()
torch_model_w2 = torch_model.state_dict()["layer2.weight"].numpy()
torch_model_b2 = torch_model.state_dict()["layer2.bias"].numpy()
print("--------------------torch模型中 w1和b1的值------------------------")
# 这里w1输出的是5行3列的矩阵,因为torch存储是对3行5列的矩阵转置存储的
print(torch_model_w1, "torch w1 权重")
"""
这里b1输出的是一个有5个数据的数组,因为这里对应的是5个神经元的偏置(bias)
假设x入参是2行3列的矩阵, w是你定义的5个神经元, 对应3行5列的矩阵

x = [1, 0, 2]
    [3, 1, 0 ]
    
w = [1, 0, 0, 1, 2]
    [0, 1, 0, 1, 2]
    [0, 0, 1, 1, 2]

根据公式 y = w * x + b 在经过第一层线性层发生的过程:
w * x = [(1×1+0×0+2×0), (1×0+0×1+2×0), (1×0+0×0+2×1), (1×1+0×1+2×1), (1×2+0×2+2×2)]
        [(3×1+1×0+0×0), (3×0+1×1+0×0), (3×0+1×0+0×1), (3×1+1×1+0×1), (3×2+1×2+0×2)]

w * x = [1, 0, 2, 3, 6]
        [3, 1, 0, 4, 8]
        
加偏置b(bias)[1, 1, 1, 1, 2]

w * x + b = [2, 1, 3, 4, 8]
            [4, 2, 1, 5, 10]
"""
print(torch_model_b1, "torch b1 权重")

print("--------------------torch模型中 w2和b2的值------------------------")
print(torch_model_w2, "torch w2 权重")
print(torch_model_b2, "torch b2 权重")

#随便准备一个网络输入
x = np.array([[3.1, 1.3, 1.2],
              [2.1, 1.3, 13]])

#使用torch模型做预测
torch_x = torch.FloatTensor(x)
y_pred = torch_model.forward(torch_x)
print("-------------------------torch模型预测结果------------------------")
print(y_pred)

#自定义模型,用自定义模型去模仿torch模型
class DiyModel:
    def __init__(self, w1, b1, w2, b2):
        self.w1 = w1
        self.b1 = b1
        self.w2 = w2
        self.b2 = b2

    def forward(self, x):
        # 第一层前向传播
        # np.dot():矩阵乘法
        # x * w1.T:x 矩阵乘以 w1 的转置矩阵
        hidden = np.dot(x, self.w1.T) + self.b1
        y_pred = np.dot(hidden, self.w2.T) + self.b2
        return y_pred

# 把torch模型权重拿过来自己实现计算过程
diy_model = DiyModel(torch_model_w1, torch_model_b1, torch_model_w2, torch_model_b2)
# 用自己的模型来预测
y_pred_diy = diy_model.forward(np.array(x))
print("--------------------------diy模型预测结果-------------------------")
print(y_pred_diy)

输出

------------------------建立torch模型----------------------------
OrderedDict({'layer1.weight': tensor([[ 0.4222, -0.2010,  0.4468],
        [ 0.4383,  0.2954,  0.3002],
        [-0.1343, -0.1268, -0.0889],
        [-0.5301, -0.1032, -0.3945],
        [-0.1364, -0.3857,  0.4068]]), 'layer1.bias': tensor([ 0.3121,  0.0777, -0.1180,  0.4329, -0.2124]), 'layer2.weight': tensor([[-0.3435, -0.2176,  0.1668, -0.2133,  0.0679],
        [ 0.2116,  0.1089,  0.1543,  0.1814, -0.1473]]), 'layer2.bias': tensor([-0.1794,  0.2779])})
--------------------torch模型中 w1和b1的值------------------------
[[ 0.42215353 -0.2010363   0.44679868]
 [ 0.43831372  0.29535377  0.30020356]
 [-0.13434225 -0.1268093  -0.08890268]
 [-0.5300533  -0.10321763 -0.3945334 ]
 [-0.13641182 -0.38566872  0.40677416]] torch w1 权重
[ 0.31208313  0.07770532 -0.11800259  0.43285227 -0.21239492] torch b1 权重
--------------------torch模型中 w2和b2的值------------------------
[[-0.34354576 -0.21756878  0.16678375 -0.21331859  0.06786793]
 [ 0.21155924  0.10893524  0.15426606  0.1814121  -0.14726591]] torch w2 权重
[-0.17937568  0.27791154] torch b2 权重
-------------------------torch模型预测结果------------------------
tensor([[-1.0957,  0.5579],
        [-2.3748,  0.3056]], grad_fn=<AddmmBackward0>)
--------------------------diy模型预测结果-------------------------
[[-1.09568031  0.5578599 ]
 [-2.37476015  0.30561267]]

激活函数

  • 为模型添加非线性因素,使模型具有拟合非线性函数的能力
  • 无激活函数时 y = w1(w2(w3 * x + b3) +b2) + b1 仍然是线性函数
  • 所以我们可以过一下线性函数后再过非线性函数,这样就是曲线了

image.png

激活函数-Sigmoid

读音:/'sɪgmɔɪd/ (类似“sei格-摩诶德”)

image.png

激活函数-tanh

tanh(双曲正切函数)

  • 读音:/ˈtænʃ/ (类似“坦施'')
  • 图片第一行,跟Sigmoid有映射关系
  • 图片第二行,tanh的公式

image.png

激活函数-Relu

读音:/ˈriːluː/(类似“瑞路”)

image.png

激活函数-Gelu

读音:/'dʒiːluː/(类似“吉卢”)

image.png

激活函数-Softmax

用来做数据的归一化,也就是得到这些数据的映射数据,映射数据相加为1

image.png