import numpy as np
"""
参数的设置在机器学习中十分重要,如果参数比较少还可以通过人为的调整来达到想要的效果,但是实际情况中,参数往往都是成千上万
个,对于层数比较多的神经网络甚至能达到上亿个 ,所以人为调整并不现实,这时候就需要参数根据数据来“自动调整”
机器学习中一般将数据分为:训练数据(也称监督数据)和测试数据。
首先利用训练数据得到参数的取值,再用测试数据来评价训练得到的模型。
最后我们希望得到一个“泛化能力”比较好的模型,泛化能力是指能够处理没有被打上tag的数据的能力,也就是能够实际应用的能力。
比如之前说到的手写数字识别,那么泛化能力是指识别任意一个人写下的任意数字,而不是仅仅局限于所给的数据集当中。
损失函数(loss function)
首先我们的目标是获得能和测试数据的tag最佳拟合的参数,那么如何评估在拟合过程中的参数优劣?这里就要到损失函数
损失函数是指当前的参数设置得到的神经网络的优劣程度,越大代表不符合程度越高,神经网络的性能也就越差。
所以我们追求的是使得损失函数最小的时候的参数设置。
损失函数一般有用均方误差和交叉熵误差
"""
"""
均方误差
E = {∑[(yk-tk)²]} / 2
yk代表神经网络的输出,tk代表测试数据的tag
k代表数据维度
"""
y = np.array([0.1, 0.05, 0.6, 0, 0.05, 0.1, 0, 0.1, 0, 0])
t = np.array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0])
def mean_squared_error(y, t):
return 0.5 * np.sum((y - t) ** 2)
print(mean_squared_error(y, t))
y = np.array([0.1, 0.05, 0.1, 0, 0.05, 0.1, 0, 0.6, 0, 0])
print(mean_squared_error(y, t))
"""
交叉熵误差
E = -∑(tk*logyk) logyk 代表 yk的ln函数值 只有是正确解那个数据标签k,tk索引下的值才会被输出,其他都为0
比如对于上面的测试,当正确解标签索引为2,与之对应的神经网络输出为0.6,那么交叉误差为-(1)ln(0.6) = 0.51
值越大越不好
"""
def cross_entropy_error(y, t):
"""交叉熵误差"""
delta = 1e-7
return -np.sum(t * np.log(y + delta))
y = np.array([0.1, 0.05, 0.6, 0, 0.05, 0.1, 0, 0.1, 0, 0])
t = np.array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0])
print(cross_entropy_error(y,t))
y = np.array([0.1, 0.05, 0.1, 0, 0.05, 0.1, 0, 0.6, 0, 0])
print(cross_entropy_error(y,t))
"""
mini-batch 学习 -----》一种降低损失函数值的方法
为了能够加快学习速度和修改参数速度,我们通常利用随机选取的数据集中的一部分来进行学习,来达到快速修改参数以降低损失值
下面利用MNIST数据集来进行mini-batch学习
"""
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)
print(x_train.shape)
train_size = x_train.shape[0]
batch_size = 10
batch_mask = np.random.choice(train_size, batch_size)
x_batch = x_train[batch_mask]
t_train = t_train[batch_mask]
"""mini-batch的交叉熵误差实现"""
def cross_entropy_error_new(y, t):
"""交叉熵误差"""
if y.ndim == 1:
t = t.reshape(1, t.size)
y = y.reshape(1, y.size)
batch_size = y.shape[0]
delta = 1e-7
return -np.sum(t * np.log(y + delta)) / batch_size