前言
青训营中我们学习了langchain快速部署基于各种LLM的API的应用,但我认为这样还不够深入人工智能。于是我自学了有关人工智能的入门内容,在此分享。
流程图
数据的分类
分为训练数据和测试数据两种。使用训练数据进行学习,寻找最优的参数;然后使用测试数据评价训练得到的模型的实际能力。
与之对应的是训练标签和测试标签。
t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
#比如这里对应0-9,那么这里的答案就是“2”
这样,正确答案为1,其他为0的标签表示方式为one-hot表示(后面损失函数会有用)。
仅仅用一个数据集去学习和评价参数,是无法进行正确评价的。 这样会导致可以顺利地处理某个数据集,但无法处理其他数据集的情况。
只对某个数据集过度拟合的状态称为过拟合。
问题的分类
回归问题:根据各种数据预测数据
分类问题:字面意思
隐藏层激活函数
神经网络中的激活函数使用平滑变化的sigmoid函数或ReLU函数。
Sigmoid
阶跃函数
为什么神经网络不用它?
阶跃函数的导数在绝大多数地方(除了0以外的地方)均为0。也就是说,如果使用了阶跃函数,那么即便将损失函数作为指标,参数的微小变化也会被阶跃函数抹杀,导致损失函数的值不会产生任何变化。
ReLu
输出层激活函数
恒等函数
不变,一般用于回归问题
softmax
容易知道每组所有的输出和为1,可以将它解释为“概率”
一般用于分类问题
损失函数
非常重要的概念!!!
它的数值越大,神经网络越不拟合
在进行神经网络的学习时,不能将识别精度(正确率)作为指标。因为如果以识别精度为指标,则参数的导数在绝大多数地方都会变为0。
均方误差
tk是one-hot表示。
交叉熵误差
底数为e。yk为softmax的结果,所以yk在[0,1]之间。
logyk<0。而tk是one-hot表示,正确解只有一个的时候相当于只计算了这一个。
Batch
输入数据的集合,中文为批。以批为单位运算能提高效率。
Mini-batch
从所有的数据中随机抽取一批数据。
numpy.random.choice(train_size,batch_size)
从0-(train_size-1)中抽取batch_size个,返回数组
梯度下降法简单演示
为什么要使用它?
梯度简单来说就是函数对向量求导得到的向量,它指向的方向是这个点函数值增加最快的方向,反方向就是减小最快的方向。
对于机器学习,我们最终目标是要求得损失函数最小值,利用梯度求得最小值的方法就是梯度法。然而,梯度指向的方向不一定就是最小值,或者说,在复杂的函数中,梯度的方向基本上不是函数最小值处。
虽然如此,但仍然要以它为线索寻找损失函数最小值。我们可以沿着这个方向走一段,停下来求导,再走一段,如此反复循环,不断接近最小值,这就是梯度法。
数学式表达
η是个关键参数,学习率。它决定了每次学习学多少,多大程度上更新参数。
像学习率这样的参数称为超参数。这是一种和神经网络的参数(权重和偏置)性质不同的参数。相对于神经网络的权重参数是通过训练数据和学习算法自动获得的,学习率这样的超参数则是人工设定的。 一般来说,超参数需要尝试多个值,以便找到一种可以使学习顺利进行的设定。
演示
函数本身:
ff(x): return x[0][0]**2+x[0][1]**2+x[1][0]**2+x[1][1]**2
容易得到在(0,0
0,0)的时候取得最小值
def get_grad(f,x):
h=1e-4
grad=np.zeros_like(x)
for i in np.ndindex(x.shape):
tmp=x[i]
x[i]=tmp+h
fxh1=f(x)
x[i]=tmp-h
fxh2=f(x)
grad[i]=(fxh1-fxh2)/(2*h)
x[i]=tmp
return grad
求导函数。一些细节要注意:
- h不能太小,否则python约等于0
- grad=np.zeros_like(x)创建了形状同x的矩阵
- for i in np.ndindex(x.shape):这样就可以遍历多维数组,即使后面是x[i]
- 注意到是预存x[i]的值到额外的容器中,再把加上h和减去h的值分别赋给x[i],这是因为f(x)直接调用x[i]
- 最后要还原x[i]
def grad_des(f,init_x,lr=0.01,step_n=10000):
x=init_x
#h=1e-4
for i in range(step_n):
grad=get_grad(ff,x)
x-=lr*grad
return x
def ff(x):
return x[0][0]**2+x[0][1]**2+x[1][0]**2+x[1][1]**2
init_x=np.array([[-3.0,4.0],
[1.0,2.0]])
grad_des(ff,init_x)
'''
array([[-6.58435768e-21, 6.68692807e-21],
[ 6.69354552e-21, 6.56119662e-21]])
'''
- grad_des中lr为步长,step_n为学习次数
- 注意结果后面的e-21,说明非常接近0
随机梯度下降(SGD)
随机选择一部分训练数据(通常是单个样本或一小批样本,称为mini-batch)来计算梯度,而不是使用整个训练数据集。
迭代周期(epoch)
是一个单位。一个epoch表示学习中所有训练数据均被使用过一次时的更新次数。比如,对于10000笔训练数据,用大小为100笔数据的mini-batch进行学习时,重复随机梯度下降法100次,所有的训练数据就都被“看过”了。
一般的做法是,事先将所有训练数据随机打乱,然后按指定的批次大小,按序生成mini-batch。这样每个mini-batch均有一个索引号,然后用索引号可以遍历所有的mini-batch。遍历一次所有数据,就称为一个epoch。