2層ニューラルネットワークの実現(relu励起方程式の逆伝播導出プロセスを含む)

ニューラルネットワークの一般的な処理は次のとおりです。

  1. 学習可能なパラメータのネットワーク構造を定義します(レイヤーのスタックとレイヤーデザイン)。
  2. データセットの作成と入力。
  3. 入力を処理します(定義されたネットワーク層によって処理されます)。これは主にネットワークの順方向伝搬に反映されます。
  4. 損失を計算します。これは、損失レイヤーによって計算されます。
  5. 勾配を見つけるための逆伝播。
  6. 勾配に従ってパラメータ値を変更します。実装する最も簡単な方法(SGD)は次のとおりです
    。weight= weight-learning_rate * gradient

pytorchとauto_grad(トーチ自動派生関数)を使用します。

import torch
#import numpy
#from torch.autograd import Variable
EPOCH = 500
LEARNING_RATE = 1e-6
N , D_in , H , D_out = 64 , 1000, 100 , 10
# N代表的是样本个数,D_in是样本的维度,H是隐藏层的维度,D_out是输出层的维度
X = torch.randn(N,D_in)
Y = torch.randn(N,D_out)

# 先用随机值初始化两层神经网络的权重
w1 = torch.randn(D_in,H,requires_grad=True)
w2 = torch.randn(H,D_out,requires_grad=True)

"""h = w1 * x
h_relu = relu(h)
y = w2 * x"""


for step in range(EPOCH):
    #前向传播
    h = torch.mm(X, w1)  # 隐层  h = w1 * x
    h_relu = h.clamp(min=0)  # relu 将小于0的部分修正为0 大于0的部分则不变
    y_pred = torch.mm(h_relu, w2)  # 输出层  y = w2 * h_relu
    
    
    # 损失函数计算误差
    loss = (y_pred - Y).pow(2).sum()
    if step % 100 == 0:
        print('epoch: {} loss: {:.5f}'.format(step, loss.item()))#loss为(1,)的tensor

    
    # 反向传播 计算导数
    loss.backward() # 会自动计算所有参数的导数(包括W1、W2、X)
    
    
    #更新参数
    with torch.no_grad():
        #随机梯度下降
        w1 -= LEARNING_RATE * w1.grad
        w2 -= LEARNING_RATE * w2.grad
        #更新完梯度之后要手动置0。不置0会一直叠加
        w1.grad.zero_()
        w2.grad.zero_()

pytorchを使用します(逆伝播には独自の派生が必要です):

import torch

EPOCH = 500
LEARNING_RATE = 1e-6
#超参数初始化
N , D_in , H , D_out = 64 , 1000, 100 , 10 # N代表的是样本个数,D_in是样本的维度,H是隐藏层的维度,D_out是输出层的维度

#训练数据和参数初始化
X = torch.randn(N,D_in)
Y = torch.randn(N,D_out)

# 先用随机值初始化两层神经网络的权重
w1 = torch.randn(D_in,H)
w2 = torch.randn(H,D_out)
#print("X:",X,"Y:",Y,w1,w2)

for step in range(500): 
    #前向传播
    h = X.mm(w1) #(N,H)
    h_relu = h.clamp(min=0)#(N,H)
    y_pred = h_relu.mm(w2) #(N,D_out)
    
    
    #定义损失函数
    loss = (y_pred - Y).pow(2).sum().item()
    if step % 100 == 0:
        print('epoch: {} loss: {:.5f}'.format(step, loss))#loss为(1,)的tensor

    #反向传播
    grad_y_pred = 2.0 * (y_pred - Y)#(N,D_out)
    grad_w2 = h_relu.t().mm(grad_y_pred)#(H,D_out)
    grad_h_relu = grad_y_pred.mm(w2.t())#(N,H)
    grad_h[h > 0] = grad_h_relu[h > 0].clone()#大于0时导数不变
    grad_h[h < 0] = 0#小于0时导数变0
    grad_w1 = X.t().mm(grad_h)#要grad_w1的矩阵维度和w1维度相同,才能相减

    #参数更新
    w1 -= LEARNING_RATE * grad_w1
    w2 -= LEARNING_RATE * grad_w2

このように書くと、逆伝播の導出が最大の難しさです。式を導出するために順方向伝搬と逆方向伝搬を理解してから、コードを使用して式を実装する必要があります。逆伝播の計算方法を理解するには、Wu Endaの機械学習ビデオの最初の3つの章(コスト関数と勾配の導出)とニューラルネットワークの部分を見るのが最善です。しかし、そのビデオのアクティベーション機能は異なります。このコードでrelu関数の逆伝播を実現する必要があります。

ここに私は手書きの導出プロセスを投稿しました:

導出プロセス
以下は、次元から理解するために、ニューラルネットワークのいくつかのテンサーの出力です

import torch
lr = 1e-6
EPOCH = 500
LEARNING_RATE = 1e-6
#超参数初始化
N , D_in , H , D_out = 3 , 4, 2 ,1 # N代表的是样本个数,D_in是样本的维度,H是隐藏层的维度,D_out是输出层的维度
#训练数据和参数初始化
X = torch.randn(N,D_in)
Y = torch.randn(N,D_out)
# 先用随机值初始化两层神经网络的权重
w1 = torch.randn(D_in,H)
w2 = torch.randn(H,D_out)

print("X:",X)#3样本 4特征
print("Y:",Y)#3结果
print("w1:",w1)
print("w2",w2)

h = X.mm(w1) 
print("h:",h)
h_relu = h.clamp(min=0)#(N,h_dim)
print("h_relu",h_relu)

経営成績と個人的な理解を添付してください。

X: tensor([[ 1.3393, -0.3668, -0.3531,  1.4490],
        [-0.2834,  0.3056,  1.0691,  1.7448],
        [ 0.1956,  0.9079,  0.4525, -1.1220]])
Y: tensor([[-1.8117],
        [-0.4406],
        [ 1.1850]])
w1: tensor([[ 1.4459, -0.1429],
        [-0.8366, -0.5614],
        [-1.4148, -0.4373],
        [ 0.4911, -1.1529]])
w2 tensor([[-0.6083],
        [-0.2623]])
        
h: tensor([[ 3.4545, -1.5016],
        [-1.3210, -2.6101],
        [-1.6679,  0.5581]])
h_relu tensor([[3.4545, 0.0000],
        [0.0000, 0.0000],
        [0.0000, 0.5581]])
  • ニューラルネットワークの概略図は、変数ではなく、単位としての特徴(寸法)に基づいています。
  • Xには3つの変数があり、各変数には4つの特性(次元)があります。W1には、4つの機能のそれぞれに2つの重みがあります
  • 隠れ層には3つの変数と2つの単位(寸法)があります
  • 変数×重み1の4つの特徴を追加した後、隠れ層ユニットの対応する変数の特徴値1が取得されます。
  • 変数×重み2の4つの特徴を追加した後、隠れ層ユニットの対応する変数の特徴値2が取得されます。

参照:

  1. ウーエンダ機械学習ビデオ:https://www.bilibili.com/video/av50747658?from = search&seid = 8008773056378130405
  2. https://blog.csdn.net/qq_30057549/article/details/103018003
  3. Wu Endaの機械学習ビデオに関する個人的なメモ(次の記事が公開され、Huang Haiguang博士から参照が変更されました)

やっと

実は、これは年初の1月に行われたもので、久しぶりです。今考えてみると、これはまだ入門的な深層学習のベストプラクティスの1つです。入門的な深層学習の最初のコードはこれでなければなりません。

その後、Enda Wuの機械学習ビデオは、今年の前半に終了しました。HaiguangHuang博士のブログにあるEndaWu機械学習ノートを少し変更しました。

しかし、その後、ローカルのマークダウンブログをcsdnに直接表示できず、内部の写真を送信することが困難であることが発見されました。更新されません。必要に応じてご連絡ください。

おすすめ

転載: blog.csdn.net/weixin_44929977/article/details/104110062