神经网络的学习
- 学习:从训练数据中自动获取最优权重参数的过程
- 指标:损失函数
- 目的:以损失函数为基准,找到能使损失函数的值达到最小的权重参数
- 机器学习的方案
- 从图像中提取特征量(可以从输入数据中准确提取本质数据的转换器)
- 用机器学习技术学习特征量的模式
- CV领域常用的特征量包括SIFT,SURF和HOG
- 深度学习有时也成为端到端机器学习(end-to-end machine learning),从原始数据中获得目标结果
- 评价模型
- 泛化能力:处理未被观察过的数据的能力。获得泛化能力是几期学习的最终目标
损失函数
- 在神经网络的学习中,用损失函数作为线索寻找最优权重参数
- 损失函数是表示神经网络性能的“恶劣程度”的指标,即当前的神经网络对监督数据在多大程度上不拟合,在多大程度上不一致。
- one-hot表示:将正确解标签表示为1,其他标签表示为0的表示方法
均方误差
表示神经网络的输出,表示监督数据,表示数据的维数
import numpy as np
#均方误差的实现
def mean_squared_error(y,t):
return 0.5*np.sum((y-t)**2)
t = [0,0,1,0,0,0,0,0,0,0]
y = [0.1,0.05,0.6,0.0,0.05,0.1,0.0,0.1,0.0,0.0]
mean_squared_error(np.array(y),np.array(t))
0.09750000000000003
交叉熵误差
- 是神经网络的输出,是正确解标签(用one-hot表示).
- 该式只计算对应正确解标签的输出的自然对数
- 如果正确解标签对应的输出较小,则函数值较大
#交叉熵误差实现
#y:1*n,t:1*n
def cross_entropy_error(y,t):
delta = 1e-7
return -np.sum(t*np.log(y+delta))
- 在计算np.log是加上了一个微小值delta,当出现np.log(0),会变为负无限大的-inf.
mini-batch学习
- 对于所有训练数据求交叉熵误差
- 假设训练数据有N个,表示第个数据的第个元素的值.
- 是对和进行正规化(normalization),获得和训练数据的数量无关的统一指标
- 从全部数据中选择一部分数据,作为全部数据的"近似"(称为mini-batch,小批量),然后对每个mini-batch进行学习
#mini-batch版交叉熵误差的实现
def cross_entropy_error(y,t):
if y.ndim==1:
t = t.reshape(1,t.size)
y = y.reshape(1,y.size)
batch_size = y.shape[0]
return -np.sum(t*np.log(y+1e-7))/batch_size
为何要设定损失函数
- 用识别精度作为指标,微调参数引起的识别精度的变化是离散的.
- 用损失函数作为指标,微调参数引起的函数值变化是连续的
数值微分
导数
偏导数
梯度
()由全部变量的偏导数汇总而成的向量称为梯度
#梯度计算(可以计算多维)
def numerical_gradient(f, x):
h = 1e-4 # 0.0001
grad = np.zeros_like(x)
it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
while not it.finished:
idx = it.multi_index
tmp_val = x[idx]
x[idx] = float(tmp_val) + h
fxh1 = f(x) # f(x+h)
x[idx] = tmp_val - h
fxh2 = f(x) # f(x-h)
grad[idx] = (fxh1 - fxh2) / (2*h)
x[idx] = tmp_val # 还原值
it.iternext()
return grad
梯度法
称为学习率(learning rate),决定在一次学习中,应该学习多少,以及在多大程度上更新参数.
#梯度下降法的实现
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
- 参数f是要进行最优化的函数,init_x是初始值,lr是学习率learning rate,step_num是梯度法的重复次数.
- 超参数:需要人工设定,尝试多个值以便可以使学习顺利进行的设定
神经网络的梯度
损失函数关于权重参数的梯度
from sourcecode.common.functions import softmax,cross_entropy_error
from sourcecode.common.gradient import numerical_gradient
class simpleNet:
def __init__(self):
self.W = np.random.randn(2,3)#用高斯分布进行初始化
def predict(self,x):
return np.dot(x,self.W)
def loss(self,x,t):
z =self.predict(x)
y = softmax(z)
loss = cross_entropy_error(y,t)
return loss
net=simpleNet()
print(net.W)
x = np.array([0.6,0.9])
p = net.predict(x)
print(p)
print(np.argmax(p))
t = np.array([0,0,1])#正确解标签
print(net.loss(x,t))
[[ 0.96028135 -1.10055385 -1.26426151]
[ 0.4756395 1.3477234 0.45475418]]
[ 1.00424436 0.55261875 -0.34927815]
0
1.992699002936635
#求梯度
def f(W):
return net.loss(x,t)
dW = numerical_gradient(f,net.W)
print(dW)
[[ 0.31663563 0.20156786 -0.51820349]
[ 0.47495345 0.30235179 -0.77730524]]
学习算法的实现
- 前提
神经网络存在合适的权重和偏置. - mini-batch
从训练数据中随机选出一部分数据. - 计算梯度
求出各个权重参数的梯度 - 更新参数
将权重参数沿梯度方向进行微小更新 - 重复2.3.4
- 随机梯度下降法(stochastic gradient descent,SGD)
- epoch是一个单位,一个epoch表示学习中所有训练数据均被使用过一次时的更新次数