-
激活函数
激活函数的存在,是神经网络与感知机不同的地方。
神经网络的激活函数必须使用非线性函数!
- sigmoid函数
g(x)=1/(1+exp(−x))g(x)=1/(1+exp(-x) ) g(x)=1/(1+exp(−x))
![sigmoid函数表达式为:g(x)=1/(1+e^(-x) );](https://secure1.wostatic.cn/static/81mgxiAPGXreqKe11SLQfY/sigmoid.jpg)
Sigmoid函数其定义域在全体实数,值域在[0,1]之间,并且在0点位置为0.5。 当x的取值为[-∞,0]时,g(x)<=0; 当x的取值为[0,+∞]时,g(x)>=0; Sigmoid函数具有两个非常好的性质: (1):当x趋近于正无穷时,g(x)趋近于1,当x趋近于负无穷时,g(x)趋近于0.这一点非常适合做分类概率模型。 (2):除此之外,sigmoid函数还具有一个很到的导数性质,即sigmoid函数时任意阶可导的凸函数。
** 2. ReLu函数**
ReLu函数是最近才开始使用的函数,**ReLu函数在输入大于0时,直接输出该值;在输出小于等于0时,输出0。**
- softmax函数
softmax函数一般用于神经网络的输出层,softmax函数的性质是:softmax函数的输出是0.0~1.0之间的实数,并且softmax函数的输出值的总和是1**。**因此我们可以把softmax函数的输出解释为“概率”。
即便是使用softmax函数,输出值最大的神经元的位置也不会改变。
sigmoid激活函数
def sigmoid(x):
return 1/(1+np.exp(-x))
#ReLu激活函数
def ReLu(x):
if x < 0:
return 0
else:
return x
#softmax激活函数(输出层)
def softmax(x):
exp_x = np.exp(x)
sum_exp_x = np.sum(exp_x)
y = exp_x/sum_exp_x
return y
-
损失函数
神经网络以某个指标为线索寻找最优权重参数。神经网络的学习中所用的指标成为损失函数(loss function)。这个损失函数可以使用任意的函数表示,但是一般来说都使用均方误差和交叉熵误差等。
在寻找最优参数(权重和偏置)时,要寻找使得损失函数的值尽可能小的参数。为了寻找到使得损失函数的值尽可能小的地方,需要计算参数的导数(确切地将时梯度),然后以这个导数为指引,逐步更新参数的值。
#均方误差损失函数
def mean_squared_error(y,t):
return 0.5*np.sum((y-t)**2)
#交叉熵损失函数
def cross_entropy_error(y,t):
delta = 1e-7
return -np.sum(np.array(t)*np.log(np.array(y)+delta))
-
梯度
变量的偏导数汇总而成的向量称为梯度(gradient)。
机器学习的主要任务是在学习中寻找最优参数。同样地,神经网络也必须在学习时找到最优参数(权重和偏置)。这里所说的最优参数是指损失函数取最小值时的参数。
通过梯度来寻找函数最小值(或者尽可能小的值)的方法就是梯度法。
寻找最小值的梯度法为梯度下降法,寻找最大值的梯度法称为梯度上升法。(神经网络学习中,梯度法主要是指梯度下降法)。
![](https://secure1.wostatic.cn/static/5dJy2FASPV6sm1b79jPcPU/捕获 1.jpg)
其中η表示更新量,在神经网络的学习中,称为学习率(learning rate)。(学习率过大或者过小都无法得到好结果)
#求梯度
def numerical_gradient(f,x):
h = 1e-4
grad = np.zeros_like(x)
for i in range(x.size):
tmp = x[i]
x[i] = tmp + h
fxh1 = f(x)
x[i] = tmp - h
fxh2 = f(x)
grad[i] = (fxh1 - fxh2) / (h*2)
x[i] = tmp
return grad
#梯度下降法
def gradient_descent(f, init_x, lr=0.01, step_num=100):
x = init_x
for i in range(step_num):
grad = numerical_gradient(f, x)
x -= lr * grad
return x
-
总结 学习算法的实现
前提
神经网络存在合适的权重和偏置,调整权重和偏置以便拟合训练数据的
过程称为“学习”。神经网络的学习分成下面4个步骤。
步骤1( mini-batch)
从训练数据中随机选出一部分数据,这部分数据称为mini-batch。我们
的目标是减小mini-batch的损失函数的值。
步骤2(计算梯度)
为了减小mini-batch的损失函数的值,需要求出各个权重参数的梯度。
梯度表示损失函数的值减小最多的方向。
步骤3(更新参数)
将权重参数沿梯度方向进行微小更新。
步骤4(重复)
重复步骤1、步骤2、步骤3。
- 两层神经网络编程实现(采用前向传播)
变量 | 说明 |
---|---|
params | 保存神经网络的参数的字典型变量(实例变量)。 params['W1']是第1层的权重, params['b1']是第1层的偏置。 params['W2']是第2层的权重, params['b2']是第2层的偏置 |
grads | 保存梯度的字典型变量( numerical_gradient()方法的返回值)。grads['W1']是第1层权重的梯度, grads['b1']是第1层偏置的梯度。grads['W2']是第2层权重的梯度, grads['b2']是第2层偏置的梯度。 |
方法 | 说明 |
---|---|
init(self, input_size,hidden_size, output_size) | 进行初始化。 参数从头开始依次表示输入层的神经元数、隐藏层的神经元数、输出层的神经元数 |
predict(self, x) | 进行识别(推理)。 参数x是图像数据。 |
loss(self, x, t) | 计算损失函数的值。 参数 x是图像数据, t是正确解标签(后面3个方法的参数也一样)。 |
accuracy(self, x, t) | 计算识别精度。 |
numerical_gradient(self, x, t) | 计算权重参数的梯度。 |
gradient(self, x, t) | 计算权重参数的梯度。 |
**权重的初始化使用符合高斯分布的随机数进行初始化,偏置使用0进行初始化**
-
mini-batch的实现
mini-batch学习就是i从训练数据中,随机选择一部分数据(这部分数据称之为mini-batch),再以这部分数据为对象,使用梯度法更新参数。
#2层神经网络的分类
#输入层激活函数sigmoid
def sigmoid(x):
return 1/(1+np.exp(-x))
#输出层激活函数softmax
def softmax(x):
exp_x = np.exp(x)
sum_exp_x = np.sum(exp_x)
y = exp_x/sum_exp_x
return y
#交叉熵损失函数
def cross_entropy_error(y,t):
delta = 1e-7
return -np.sum(np.array(t)*np.log(np.array(y)+delta))
#求梯度
def numerical_gradient(f,x):
h = 1e-4
grad = np.zeros_like(x)
for i in range(x.size):
tmp = x[i]
x[i] = tmp + h
fxh1 = f(x)
x[i] = tmp - h
fxh2 = f(x)
grad[i] = (fxh1 - fxh2) / (h*2)
x[i] = tmp
return grad
class twolayernet:
def __init__(self,input_size,hidden_size,output_size,weight_init_std=0.01):
#初始化权重
self.params = {}
self.params['w1'] = weight_init_std * np.random.randn(input_size,hidden_size)
self.params['b1'] = np.zeros(hidden_size)
self.params['w2'] = weight_init_std * np.random.randn(hidden_size,output_size)
self.params['b2'] = np.zeros(output_size)
def predict(self,x):
w1,w2 = self.params['w1'],self.params['w2']
b1,b2 = self.params['b1'],self.params['b2']
a1 = np.dot(x,w1)+b1
z1 = sigmoid(a1)
a2 = np.dot(z1,w2)+b2
y = softmax(a2)
return y
def loss(self,x,t):
y = self.predict(x)
return cross_entropy_error(y,t)
def accuracy(self,x,t):
y = self.predict(x)
y = np.argmax(y,axis=1)
t = np.argmax(t,axis=1)
accuracy = np.sum(y == t) / float(x.shape[0])
return accuracy
#x:输入数据 y:监督数据
def numerical_gradient(self,x,t):
loss_w = lambda w:self.loss(x,t)
grads = {}
grads['w1'] = numerical_gradient(loss_w,self.params['w1'])
grads['b1'] = numerical_gradient(loss_w, self.params['b1'])
grads['w2'] = numerical_gradient(loss_w, self.params['w2'])
grads['b2'] = numerical_gradient(loss_w, self.params['b2'])
return grads