ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

人工智能实践

人工智能实践 一、神经网络计算1.1人工智能三学派人工智能让机器具有人的思维意识三学派行为主义平衡行走、符号主义理性思维、连接主义感性思维连接主义 准备数据搭建网络优化参数应用网络1.2神经网络设计过程鸢尾花分类具有四种特征三种类型搭建网络Y X * W b1*3 1*4 4*3 1*3X是输入维数每列是每个特征的特征值W是权重每行为每个特征值对每种类型的权重b为偏移量Y输出维度每列为每种类型的概率损失函数表示预测值和真实值差距目的找一组w,b使得损失函数最小梯度下降沿损失函数梯度下降的方法反向传播从后向前逐层求损失函数偏导更新参数1.3张量生成张量从0阶到n阶的数组0阶是标量1阶是列表1.4TF2常用函数11.5TF常用函数21.6鸢尾花数据集读入数据集Iris包括四个输入特征三种标签共150组1.7鸢尾花分类实现import tensorflow as tf from sklearn import datasets from matplotlib import pyplot as plt import numpy as np x_data datasets.load_iris().data y_data datasets.load_iris().target np.random.seed(116) np.random.shuffle(x_data) np.random.seed(116) np.random.shuffle(y_data) tf.random.set_seed(116) x_trainx_data[:-30] y_trainy_data[:-30] x_testx_data[-30:] y_testy_data[-30:] train_dbtf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32) test_dbtf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32) w1tf.Variable(tf.random.truncated_normal([4,3],stddev0.1,seed1,dtypetf.float64)) b1tf.Variable(tf.random.truncated_normal([3],stddev0.1,seed1,dtypetf.float64)) Ir0.1 train_loss_results[] test_acc[] epoch100 loss_all0 for epoch in range(epoch): for step,(x_train,y_train) in enumerate(train_db): with tf.GradientTape() as tape: ytf.matmul(x_train,w1)b1 ytf.nn.softmax(y) y_tf.one_hot(y_train,depth3) y_ tf.cast(y_, tf.float64) losstf.reduce_mean(tf.square(y_-y)) loss_allloss.numpy() gradstape.gradient(loss,[w1,b1]) w1.assign_sub(Ir*grads[0]) b1.assign_sub(Ir*grads[1]) print(Epoch{},loss{}.format(epoch,loss_all/4)) train_loss_results.append(loss_all/4) loss_all0 total_correct,total_number0,0 for x_test,y_test in test_db: ytf.matmul(x_test,w1)b1 ytf.nn.softmax(y) predtf.argmax(y,axis1) predtf.cast(pred,dtypey_test.dtype) correcttf.cast(tf.equal(pred,y_test),dtypetf.int32) correcttf.reduce_sum(correct) total_correctint(correct) total_numberint(x_test.shape[0]) acctotal_correct/total_number test_acc.append(acc) print(Test Accuracy:{}.format(acc)) plt.title(Loss Function) plt.plot(train_loss_results) plt.xlabel(Epoch) plt.ylabel(Loss) plt.show()二、神经网络优化2.1储备知识梯度表示为一个向量每个分量是函数对每个变量的偏导。方向是函数值增加最快的方向。一元函数中梯度就是导数二元及以上就是对各个变量的偏导组成的向量。同时梯度的每个分量也表示变化率如多元函数代入具体点后得到1,-2这个梯度含义是沿x轴正方向走一个单位函数值增加1沿y轴负方向走一个单位函数值增加2。 所以1-2所指的是向x轴正方向走1向y轴负方向走2。最终合成的方向才是梯度的方向梯度下降参数更新的方式自更新方式为减去梯度乘学习率让损失函数更快减小如果导数大于0说明增大参数会让函数增大所以我们减去导数让参数减小如果导数小于0说明增大参数会让函数减小所以我们减去导数让参数增大学习率激活函数为神经网络引入非线性没有激活函数再深的神经网络都无法拟合复杂的规律。首先激活函数要是非线性的其次不能过于复杂否则在较深的模型前向传播时消耗算力值域不要过大可能会数据爆炸梯度不要过大反向传播梯度爆炸。同时激活函数最好具备可微性几乎处处可导满足反向传播梯度下降的求导需求才能完成权重 w、偏置 b 的参数更新输出数值范围也要合理避免输出无限制疯狂增大防止梯度消失、梯度爆炸问题。理想情况下最好具备单调性单层网络损失函数为凸函数优化更容易收敛。sigmoid激活函数优点具有单调性能保持输入输出的大小关系一致性。函数范围在0-1符合概率范围适合二分类任务。缺点梯度取值范围在0-0.25在大模型中容易造成梯度消失。且不靠近0的部分梯度饱和趋于零那么ww-梯度会导致参数不更新或更新极慢。指数计算会消耗算力。另外sigmoid的输出是全大于0的因此会导致同一个神经元上的不同参数更新时只能同增或同减减慢收敛速率。是损失对这个神经元输出求的偏导。再乘对wi的偏导等于xi就是损失对wi的偏导。已知xi为上一层通过sigmoid的输出一定为正而同一神经元相同所以同一神经元的所有wi只能同时蹭大或减少。会导致本来一增大一减小可以走绿色直线快速收敛现在只能走z字型线段。tanh激活函数是对sigmoid的改进输出值在-1~1解决了z字型收敛慢问题。梯度在0-1改善了梯度消失问题但两端仍存在梯度饱和梯度消失仍然存在。另外函数幂运算过于复杂消耗算力。relu函数优点函数简单计算快。解决了正半轴的梯度消失问题。收敛速度比sigmoidtanh快。缺点函数输出都为非负值限制了收敛速度。当神经元对函数输入小于零时该神经元的参数将停止更新。为防止出现大量神经元死亡可以尝试多次初始化避免过多负数送入relu函数。学习率同时设小避免参数变化过大导致大量神经元输出变负。relu同样输出是非负的会造成锯齿状路径需要迭代更多次才能收敛稀疏激活性有观点认为令部分神经元死亡简化掉过拟合部分是优点。leaky relurelu的改善版本解决relu输入为负梯度消失的问题。模型训练前向传播损失函数反向传播2.2复杂度 学习率2.3激活函数首选relu因为效果普遍更好学习率设置较小值为了不让参数跨度太大导致神经元输出跨度太大变成负输出会导致神经元死亡。输入特征标准化能统一不同特征的尺度防止最后参数初始化是为了让参数有正有负并且控制参数变化幅度避免各个神经元输出的变化幅度过大导致进入激活函数的饱和区梯度消失而导致收敛过慢2.4损失函数一般用于回归任务预测连续的实数结果可以是任意大小的数字。平方的作用可以放大误差原本误差是2可以变成4。还可以防止正负抵消如果一个批次的误差有正负四防止抵消。用绝对值正负两边的梯度会变成定值不利于找最低点。自定义损失可以根据自己的需求为不同情况加上权重。一般用于分类任务输出为向量每个分量是每种可能的概率真实标签是一个一个分量为1其余为0的向量。公式中只剩y-为1的那一项-lnyy越小-lny越大交叉熵损失函数越大效果越差。2.5缓解过拟合增加特征项和参数让网络学到更多的更复杂的特征减小正则化参数减小了对大参数的惩罚 w增大后可以增强参数(自变量x)变化对函数值的影响让模型更敏锐学到更多细节。从而缓解欠拟合。过拟合可能是数据本身有问题导致的可以数据清洗去除错误标签剔除离群异常样本去除重复样本缓解过拟合。增大训练集如果训练数据很少 真实规律 少量样本自带的随机噪声混在一起。模型分不清哪个是真规律、哪个是噪声大量数据放一起噪声会互相抵消真正的底层规律会反复大量出现。采用正则化惩罚过大的参数w减小后缩小w之间的差距可以减弱个别输入特征变化对函数值的影响使函数不容易突变并学习到大多数特征所具有的规律。增大正则化系数是在正则化的基础上加大了对过大参数的惩罚均方误差加入L2正则化代码2.6优化器优化器接收参数w,b。反向传播更新wb使得loss减小随机梯度下降SGDBGD和MBGD优化时要先求每个的损失然后然后求平均。用平均梯度去更新参数SGD则省去求平均这一步。缺点补充1.在平坦区域梯度小更新慢。2.学习率固定可能在最优值附近左右横跳。3.非凸函数只能找到局部最优点4.不能适应复杂地形遇到断崖剃度猛增错过最优值SGDM参数更新不仅由梯度决定也与之前的梯度有关αβ为超参数a为模型参数wm为动量且初始为0。优点1.缓坡区域梯度小参数更新还收之前梯度影响收敛快2.遇到小坑能冲出去找到全局最优3.在最优点附近左右震荡时前一刻梯度与后一刻异号会使下次更新幅度减少进而摆脱震荡。4.同样在跳崖问题因为削弱了当前梯度对更新参数的影响所以应对复杂地形表现更好。AdaGradg是损失函数对参数a的梯度v是所有梯度的平方和α为学习率。AdaGrad可以随参数更新次数减小学习率帮助更快收敛。并使每个参数具有独立的学习率在遭遇梯度极小的缓坡把梯度g乘到分子上会增大参数的更新幅度加快收敛但分母无限的累加会将学习率带到接近于0故不适合大量的迭代。类似的在前期进入局部最小值点能依靠把梯度g乘到分子上会增大参数的更新幅度脱离小坑。但后期由于分子过大遇到小坑会乏力。跳崖问题虽然梯度g很大但因为学习率存在一个累加梯度的分母故有一定缓解。RMSProp与AdaGrad相比把权重平方和换成了上一刻动量与此刻的加权和。它的特点也是动态改变学习率且仅与上一刻和此刻有关不会造成AdaGrad学习率一直减小。另外他还有AdaGrad优点Adam刚开始的几步把大部分权重给了v和m而v0m0初始为0使得初始的vm太小了偏差修正是为了放大这几步。缝合了动量的m和RMSProp的v优点缓坡时v会减小m增大度过缓坡局部最小区域同上复杂地形悬崖m会被抑制增长v会一定程度增大最优值点附近横跳m会反复改变方向抵消进而减小adam是一个有效的缓冲保护参数更新不受突然出现的特殊梯度影响更新幅度减小时它会往大了拉增大时会往小了拽。三、神经网络八股3.1搭建网络八股sequential概述import导入模块-train,test(加载、划分数据集)-sequntial/class搭建网络-compile设置训练方法-fit(训练模型)sequential搭建网络结构compile:配置网络的训练方法。fit执行训练过程。validation_data和validation_split只用填一个summary打印网络结构和参数统计以鸢尾花为例依次调用以上函数3.2搭建网络八股class把网络搭建在call函数里面能实现更复杂的网络应用时只需要创建出对象fit函数会自动调用call3.3MNIST数据集3.4fishion数据集四、网络八股拓展4.1搭建网络八股总览引入模块-》导入、加载数据集-》数据增强-》搭建网络-》设置训练方法-》训练-》可视化-》记录参数-》预测实物工能扩展4.2自制数据集train_path: 所有图像所在文件夹路径train_txt: 所有图像标签所在txt文件路径,文本格式是每行前部分是图片名后部分是标签中间用空格隔开。x_train_savepath: 将图像转换为数字特征的存储地址形状为图像数*28^2,每行是一幅图像像素的拉直。这个是用save函数去保存的。y_train_savepath: 仅包含标签一维列表样本数由save函数生成。首先判断由save函数生成的四个文件用于训练和测试的数字特征以及标签是否存在若存在加载这四个数据集并把数字特征集的形状修改回样本数*28*28然后按照之前的顺序搭建网络选择优化方式用fit训练即可。否则需要借助新函数生成这四个数据集。新函数如上输入参数是图片文件夹所在的路径和标签txt的路径。它用图像文件夹路径加图像名得到每个图像的路径并归一化。返回的x样本数28*28y样本数4.3数据增强前面一大串设置数据增强器image_gen_train,后调用它的fit函数对训练集增强注意在增强之前要把训练集改成四维。增强后的数据集在调用model.fit时也要又所在更新把x_train,y_train,batch_size调用flow函数写入fit中4.4断点续训用于保存模型训练过的参数并可以读取继续训练先判断保存参数的地址上的文件是否存在是就直接读取否则设置cp_callback函数并在fit中增加callbacks参数保存。4.5参数提取首先通过set_printoptions()设置输出不省略数字在训练完成后printmodel.trainable_variables就能输出完整的参数矩阵了后面是将权重记录到txt中每个v是模型每层的w或b存储格式名字哪一层的w或b形状参数矩阵4.6 accloss可视化history中记录了训练集和测试集的损失和准确率subplot设置一行两列的画布最后一维表示当前代码画在第几列2.7给图识物用前向传播predict函数预测结果复现网络并加载训练好的参数根据你输入的图像数量prenum输入相应个数的地址大小变成28*28重构尺寸用ANTIALLAS函数并转为灰度图因为训练是黑底白字现在预测是白底黑字所以做一个预处理接着归一化。第三句是在增加了一个维度表示样本数1因为predict接受三维矩阵。五、卷积神经网络5.1卷积计算过程每层网络之间都用全连接会有大量的参数每层参数个数前层神经元个数*后层神经元个数后层神经元个数。因此引入卷积先提取局部特征再进入全连接层。对于RGB三通道图像我们的的卷积核也是三维的三个二维输出是三个二维卷积核与对应重合元素相乘全部相加最终输出的是二维的。5.2感受野例如如图原图为5*5卷积核为5*5时输出一个像素点那么这个像素点的感受野是5*55*5的原图经过一个3*3卷积核后会变成3*3再用第二个3*3后会变成1*1。那么两种方法哪种计算量小呢一x-2*x-2*9x-4*x-4*9二x-4*x-4*255.3全零填充为了让输出图像的像素和输入图像尺度相同我们在边缘填充0的行为是全零填充。黄色部分是是否使用全零填充输出尺寸的计算公式下图为例子5.4tf描述卷积层实例5.5批标准化神经网络对0附近的特征效果比较好数据初始标准化后随着往深层网络的迭代输入到更深层的特征可能会偏离均值为0方差为一的标准正态分布。因此在卷积层后面加入批标准化如图每个输出特征要减去对应卷积核处理数据的均值除对应方差。解释一下为什么网络对0附近的特征效果好因为我们特征的输出是要经过激活函数例如tanh函数远离0的部分全部为正负一模型对输出同为一的特征感受不到区别学不到东西。而在0附近通过激活函数不同的特征会有区别。模型就能感知到差异。但是简单的标准化公式又太绝对的把特征限制在了激活函数的线性部分损失了我们最初引入激活函数的目的非线性性因此我们又加了两个参数去对归一化的特征的胖瘦和位置做一些修改初始标准化后分布为虚线人话又怕特征太偏又怕太正批标准化层BN位于卷积层和激活函数之间代码示例5.6池化如图分为最大池化和平均池化最大池化区每个块里的最大值平均池化取平均值。最大池化取了每个区域的最大最重要信息最后的输出强调的是边缘轮廓纹理边缘纹理处的像素点都是由浅变深或者由深变浅。而平均池化提取的平均信息提取的是让图像的整体更平均的背景。池化可以减少数据特征防止过拟合减少计算量增加网络性能。还具有平移不变形性。如下图卷积对输入的位置很敏感导致相似的特征由于位置不同得到不同的输出。而我们识别图片最重要在于判断特征是否存在特征的位置判断可以适当放宽。因此加入池化如上加入策划后相比之前在左边多了一列1也就是说初始图的1向右移动一位后输出的第二列仍是1。这就是池化的平移不变性。以上为tensorflow提供的池化函数5.7dropoutdropout也算一种正则化减少模型复杂度防止过拟合5.8卷积神经网络卷积就是卷积批标准化激活池化dropout5.9cifar10数据集plt.imshow()将数字矩阵转换为图像plt.show()输出图像5.10卷积神经网络搭建示例先是六个5*5的卷积核和两个2*2池化接着是两个分别有128和10个神经元的全连接用class搭建网络如上完整网络如上接下来逐层分块讲解引入模块并导入数据集搭建网络设置模型训练方法判断是否存在已训练的参数可以加载设置保存参数的对象训练模型可视化模型保存模型训练参数可视化训练集和测试集的准确率和损失5.11LeNet先用卷积层学习局部特征再用池化层降低敏感度最后全连接将学到的特征转换到10维类别空间。用卷积核实现了参数共享减少网络参数。5.12AlexNet相较于LeNet加入dropout激活函数由sigmoid变为relu池化由平均池化变为最大池化5.13VGGNet引入VGG块若干3*3卷积一个池化重复若干次加三个全连接变成更大更深AlexNet。引入小尺寸的卷积核减小计算量。5.14InceptionNet池化层只能改变长宽尺寸而不能改变通道数对于1*1卷积不会改变图像的长宽尺寸可以通过1*1卷积核的个数改变通道数。InceptionNet的特点在引入了Inception块从不同的感受野去学习图像的特征最后对输出做一个通道数上的叠加。同时他也更大更深。在每层应用不同尺寸的卷积核提升感知能力。使用批标准化缓解梯度消失。C:卷积层B批量标准化A:激活函数P池化Ddropout代码实现如下封装一个类将连续的卷积批标准化激活函数封装成一条语句inception块类c1c2,c3,c4分别对应四个通道。类内call函数执行网络。5.15ResNet研究发现大量一味增加网络层数会让模型退化效果变差即深层网络很难把前面层学到的信息完整传送到后面多层反复卷积原始信息慢慢丢失越学越差。层间跳连引入前方信息缓解模型退化跳连另外有一条跳连的捷径直接把最开始的原始输入不加修改直接加到卷积输出上面。“引入前方信息”就是把前面没经过卷积处理的原始信号直接绕路送到后面层不让信息被多层卷积 “磨没”。ResNet引入ResNet块不同于InceptionNet堆叠通道数ResNet选择生成多个相同尺寸通道的特征图简单一一对应相加。如下一般ResNet块有两种情况经过卷积后通道数改变了或者没改变。第一种情况想要原始特征图和卷积后的特征图相加就要用1*1卷积核改变原始特征图的通道再相加如虚线通道数没改变的情况直接相加即可是实线的情况。下图设计类封装了这两种情况在初始化类的时候通过传入参数residual_path为true或false去设置是否增加对原始特征做1*1卷积的分路红色部分。以下代码一次只能生成一个小的黄色块部分。如下为ResNet18,包括1个卷积8ResNet块1全连接网络搭建如下紫色部分搭建最前面的卷积根据上图模块的规律第一个模块不用1*1卷积后面模块每个都只是第一个需要1*1卷积黄色部分根据这个规律调用前面的模块类生成八个模块。后面部分加上全局池化和全连接。5.16经典神经网络小结六、循环神经网络6.1-6.2循环核循环神经网络有三个待训练参数w每个时刻t的输入是x乘对应权重送到h此外h还要接收上一时刻h送来的值*权重。最后加上偏置通过激活函数作为送往输出层和下一时刻h的特征。而t时刻的输出就是t时刻的h输出*权重偏置经激活函数提取到的时间特征再送到全连接网络中。优点卷积神经网络的输入往往是定长的而RNN可以解决不定长输入的问题每次输入一个token 就是把长句子切成一小块一小块循环的调用同一个循环体也就是他们的参数都是一样的6.3循环计算层根据需要可以每层可以设置多个h设置多个记忆体一个h那么h的输出是1*1的两个h输出是1*2的。6.4tensorflow表述循环层每个循环核输出ht只有最后输出ht输入样本本的维度必须是三维如下样本数 2一共有 2 条独立数据。样本 10.41.70.6样本 20.70.91.6时间步数 1每次输入输入一整个样本0.41.70.6或0.70.91.6因此一步就得到了一个样本的结果步数为1特征数 3每步输入1个样本而一个样本有三个特征三个数因此一步输入特征数是三。再如第二个例子它是把一个样本拆成四部分每部分两个特征来输入的。因此第一维度样本数为一循环核时间步数要四步才完成一个样本的输出故为四每一步又输入两个数字即两个特征。6.5循环计算过程未按时间步展开输入一个立即得到一个输出先将问题中的字母用数字编码初始化参数矩阵输入b更新ht更新yt6.6字母预测示例未按时间步展开我们训练RNN使得输入前面的字母输出后面的字母a,b,c,d,e输入e时输出a导入库自制数据集将a,b,c,d,e编码0,1,2,3,4再变成独热编码输入特征为字母的独热编码标签为对应下一个字母对应的数字打乱数据就循序将输入特征变为规定的维度样本数一个样本分几次输入每次输入特征数构建模型有三个记忆体同一时刻三个记忆体不传输特征t时刻三个记忆体会和上一时刻三个记忆体全连接传输。最后时刻的三个记忆体和五个神经元全连接。设置模型训练方法尝试加载参数训练打印模型保存参数accloss可视化做预测prenum为预测次数接着将输入字母转为独热编码输入预测、6.7循环计算过程2拿训练好的参数演示在四个时间步输入后仅在最后输出预测的计算过程6.8字母预测多步输入版导入模块自制数据集如特征abcd标签是e随机化打乱顺序更改训练集维度搭建网络设置训练方法载入参数训练模型保存参数可视化accloss对输入做预测predict加【】是因为predict函数是设计可以一次性预测多个老师为了展示方便选择一次预测一个只想预测一个则必须构造一个列表将唯一数据放进去这样predict函数用for遍历的时候才不会出问题6.9embedding独热码问题映射之间没有关联性embedding编码不仅降低了编码所需的维度也增加了相关性。样本数量100个用几维编码形成词汇表大小*编码长度个参数进行训练。训练完成做预测时输入一个编号为i的样本网络会取当前参数的第i行为该样本编码进入下一层6.10加入embedding层的网络预测实现导入块给特征编号制作训练集和标签乱序设置为embedding需要的输入形状搭建网络第一层为embedding设置训练方法载入参数训练保存参数可视化lossacc对输入预测主要就是设置一下输入的形状6.11用带embedding层网络预测多时间步输入问题示例问题输入前四个字母输出第五个字母注意embedding函数第一维是词库数26不是送入样本数22主要predict由于可以执行对多个输入的预测所以输入是2维列表alphabet是一维因此要再加一层括号【】6.13LSTM对于多步态的序列RNN很难保留原始输入的记忆并且随着层数增加后时刻受最初时刻输入的影响也越来越小。反向向传播时循环过多也容易梯度消失或爆炸因此引入LSTM。每时刻输入的上时刻记忆c对位乘遗忘门得到剩下的记忆再加上输入门乘候选态得到此时刻的记忆。上一刻记忆只与遗忘门进行了简单的乘法。他为下一时刻多提供了上一时刻记忆的一个特征并且无需经过复杂的线性变换矩阵乘和非线性变换激活函数因此能保留的上一时刻信息的限度更大。对多步态的序列模型可以学习到一个接近1的遗忘门最大程度保留原始时刻的信息。反向传播求导时Ct对Ct-1的导数就是遗忘门如果遗忘门接近1多次连乘也不会出现梯度消失。如果遗忘门接近0那么说明更早的记忆本就无用不会影响损失不必更新。但输出h中仍存在RNN中的问题6.14GRULSTM参数多复杂容易过拟合。我们简化模型引入GRUr重置门z更新门三种结构缺点只能串行计算速度慢梯度传播仍会消失例如反向传播要链式法则乘zt仍会梯度消失。最后就是再长的序列信息最后都被存储到一个定长的向量里存多了肯定要被压缩模糊之前的信息。想表示早期的信息要一步步倒推回去。
返回列表