numpyとpytorchは勾配降下を実現し,簡単な2層ニューラルネットワークを実現した.


numpy勾配降下を実現
参考教程:pytorchニューラルネットワーク実践(1):pytorchを初めて使用してニューラルネットワークを構築する実践手書きデジタル識別教程
# -*- coding: utf-8 -*-
"""
              
@author:   _varyshare
"""
#     w1,w2,b   
w1 = 0.666
w2 = 0.333
b = 0.233

def train():
    #        (  )          [x1,x2,g(x1,x2)]
    data = [
            [1,  0,     -1],
            [0,  1,     -1],
            [0,  0,     -1],
            [1,  1,     1]
            ]
    global w1,w2,b #               (            )

    epoch = 20 #          20 
    for _ in range(epoch):
        #         
        for i in data:
            #    i = [x1,x2,g(x1,x2)],  data    
            #        (x1,x2,g(x1,x2))      
            d_w1 = 2*(w1*i[0]+w2*i[1]+b-i[2])*i[0]
            d_w2 = 2*(w1*i[0]+w2*i[1]+b-i[2])*i[1]
            d_b = 2*(w1*i[0]+w2*i[1]+b-i[2])

            #               
            #      ,        
            learning_rate = 0.01
            #       =       -    *   
            w1_next = w1 - learning_rate*d_w1
            w2_next = w2 - learning_rate*d_w2
            b_next = b - learning_rate*d_b

            #      
            w1 = w1_next
            w2 = w2_next
            b = b_next

            pass
        pass

def f(x1,x2):
    """
           (         )
        ,          x1&x2
         w1*x1+w2*x2 + b > 0? 1:0;
            (x0,x1)   。
      0   (x0,x1)     1,  0       0;
    """
    global w1,w2,b #               (            )
    if w1*x1+w2*x2 + b > 0:
        return 1
    else:
        return 0

#          ,                    
train()
#                   
print(w1,w2,b)
"""
  :0.4514297388906616 0.2369025056182418 -0.611635769357402
"""

#       ,                  
print("0&1",f(0,1))
print("1&0",f(1,0))
print("0&0",f(0,0))
print("1&1",f(1,1))
"""
  :
0&1= 0
1&0= 0
0&0= 0
1&1= 1
"""

pytorch勾配降下と線形回帰を実現
# -*- coding: utf-8 -*- 
import torch as torch
#     
data_num = 23
data_dim = 10
data = torch.randn(data_num, data_dim,dtype=torch.float)
label = torch.randn(data_num, data_dim,dtype=torch.float)

#                  
w1 = torch.randn(data_dim, 1, dtype=torch.float,requires_grad=True)

#   f = exp(wx+b)
output= 1/(1+torch.exp(-data.mm(w1)))
#       f w1   
f.backward()

learning_rate = 1e-4
#     
with torch.no_grad():
    w1 -= learning_rate * w1.grad
    #           
    w1.grad.zero_()

pytorchは2層のニューラルネットワークを実現する
# -*- coding: utf-8 -*- 
import torch as torch
#     
data_num = 233
data_dim = 10
data = torch.randn(data_num, data_dim,dtype=torch.float)
label = torch.randn(data_num, data_dim,dtype=torch.float)

#   2     ,          
layer1_in = data_dim
layer1_out = layer2_in = 7
layer2_out = 10

#                  
w1 = torch.randn(layer1_in, layer1_out, dtype=torch.float,requires_grad=True)
w2 = torch.randn(layer2_in, layer2_out, dtype=torch.float,requires_grad=True)

#     
output1 = data.mm(w1)
output2 = output1.clamp(min=0).mm(w2)

#           
loss = (output2 - label).pow(2).sum()
#   loss   
print('loss', loss.item())

#         
loss.backward()

learning_rate = 1e-4
#     
with torch.no_grad():
    w1 -= learning_rate * w1.grad
    w2 -= learning_rate * w2.grad
    #           
    w1.grad.zero_()
    w2.grad.zero_()