単純なニューラルネットワークをNumpyで実現


この例はPyTorchの公式サイトのwarm-upの小さな例から来ており、代表的なものだと思います.ここでは単独で記録しておきます.numpyにとって、計算図、深さ学習、勾配などの概念はほとんど知られていませんが、単純なニューラルネットワークの具体的な構造を理解すれば、numpyでこの単純なネットワークを簡単に実現することができます.これに対して、私たちは通常、順方向計算と逆方向計算の論理を実現するために、2つの隠し層を持つ単純なネットワークを実現する必要があります.
import numpy as np

# N  batch size, D_in      
# H        , D_out       
N, D_in, H, D_out = 64, 1000, 100, 10

#             
x = np.random.randn(N, D_in) # N × D_in    
y = np.random.randn(N, D_out) # N × D_out    

#       w1,w2     
w1 = np.random.randn(D_in, H)
w2 = np.random.randn(H, D_out)

#      
learning_rate = 1e-6
for t in range(500):
    #     :        y_pred
    h = x.dot(w1) # x   64 × 1000, w1    1000 × 100,      , h    64 × 100
    h_relu = np.maximum(h,0)
    y = h_relu.dot(w2) # h_relu    64×100, w2   100×10, y    64×10

    #     
    loss = np.square(y_pred - y).sum()
    print(t, loss)

    #       loss  w1 w2  
    grad_y_pred = 2.0*(y_pred - y) #  y_pred  
    grad_w2 = h_relu.T.dot(grad_y_pred) #  w2  ,        w2 size  
    grad_h_relu = grad_y_pred.dot(w2.T) #  h_relu  
    grad_h = grad_h_relu.copy()
    grad_h[h < 0] = grad_h_relu #   relu,    0    0
    grad_w1 = x.T.dot(grad_h)

    # Update weights
    w1 = w1 - learning_rate * grad_w1
    w2 = w2 - learning_rate * grad_w2


上記のコードを実行する後、w1w2の値は、予測されるpred_yyとの間の二乗損失がますます小さくなる.