#以一个简单的神经网络为例,来实现求损失函数关于权重参数的梯度
#刚开始看 记录一下笔记
import sys, os
sys.path.append(os.pardir)
import numpy as np
from common.functions import softmax, cross_entropy_error # softmax 交叉熵函数
from common.gradient import numerical_gradient # 求梯度函数
class simpleNet:
def __init__(self): # 用高斯分布进行初始化 2X3 输入层2个 输出层3个神经元
self.W = np.random.randn(2,3)
def predict(self, x):
return np.dot(x, self.W) # NN计算
def loss(self, x, t): # 求损失函数
z = self.predict(x)
y = softmax(z)
loss = cross_entropy_error(y, t)
#print (x,t,fz)
return loss
x = np.array([0.6, 0.9])
t = np.array([0, 0, 1])
#fz=3
net = simpleNet()
#lambda创建匿名函数
#lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数
#这里定义的参数w是一个伪参数。因为numerical_gradient(f,x)会在内部执行f(x),为了与之兼容而定义了f(W) 。(因为numerical_gradient中调的是f(x),所以只能有一个参数)
f = lambda w: net.loss(x, t)
#传参时并没有直接执行它,此时检测f的类型就是function,是一个函数而不是一个值,loss()函数作为一个(可求偏导的)变量来计算梯度
#这里的梯度就是损失函数f对权重net.W的偏微分
dW = numerical_gradient(f, net.W)
print(dW)
#f(0)也可以正常运行获取到x,t,另设fz变量也可以被获取到
#所以与其他无关 simpleNet它本身可以获取到x与t
#类本身获取全局变量√,所以传参时可以不传