区块链网站可以做哪些活动网页版微信二维码不能直接识别
区块链网站可以做哪些活动,网页版微信二维码不能直接识别,建设棋牌类网站要多少钱,网络营销策划方案书本文讨论了深度学习中常用的损失函数#xff0c;包括交叉熵损失函数、余弦相似度损失函数和双曲余弦对数损失函数#xff0c;并对它们在PyTorch中的应用细节进行了介绍#xff0c;通过MNIST手写体数字识别实验展示它们的应用。损失函数有很多#xff0c;读者可以在了解基本…本文讨论了深度学习中常用的损失函数包括交叉熵损失函数、余弦相似度损失函数和双曲余弦对数损失函数并对它们在PyTorch中的应用细节进行了介绍通过MNIST手写体数字识别实验展示它们的应用。损失函数有很多读者可以在了解基本知识的基础上要求AI大模型给出相关损失函数的原理细节并给出相应的应用代码供使用或参考。本专栏之三中简要讨论了损失函数的概念及最容易理解的损失函数MSEMSE是基于欧氏距离的损失函数。多层神经网络中常用的损失函数还有KLKullback-Leibler Divergence散度损失函数、交叉熵Crossentropy损失函数、余弦相似度损失函数、双曲余弦对数logarithm of the hyperbolic cosine损失函数等。了解不同损失函数对优化的影响以及它们应用的特点是设计深度学习模型、指导AI大模型调整模型的重要知识。本文还进一步讨论了凸函数理论供想深入研究的读者参考。1.相对熵损失函数和交叉熵损失函数交叉熵可以用来衡量两个分布之间的差距还是以示例入手讨论。在本专栏之五的讨论误差反向传播学习算法时使用了一个用神经网络模拟异或运算的例子其中使用的示例的最后预测输出与实际标签值的对比如下a[ 0.07158904 0.92822515 ] - [ 0. 1.]b[ 0.9138734 0.08633152 ] - [ 1. 0.]c[ 0.91375259 0.08644981 ] - [ 1. 0.]d[ 0.11774177 0.88200493 ] - [ 0. 1.]对于a和d两项输出标签值都是[ 0. 1.]直观来看a的预测应该更准一些。如何形式化地度量它们与标签值的差距呢将预测输出值看作概率如 a 项中预测为 1 的概率为 0.07158904预测为 0 的概率为 0.92822515。信息熵有关信息熵及其在机器学习领域中的应用可参考文献[1]中的4.1节的定义为H(X)−∑i1npilogpiH(X) -\sum_{i1}^n p_i \log p_iH(X)−∑i1npilogpi。用pip_ipi表示第 i 个输出的标签值即真实值用qiq_iqi表示第 i 个输出值即预测值。将它们都视为概率值pip_ipi与qiq_iqi之间的对数差在pip_ipi上的期望值称为相对熵DKL(p∣∣q)Ep(logpi−logqi)∑i1npi(logpi−logqi)∑i1npilogpiqi(式10-1) D_{KL}(p||q) E_p(\log p_i - \log q_i) \sum_{i1}^n p_i (\log p_i - \log q_i)\sum_{i1}^n p_i \log \frac{p_i}{q_i}\tag{式10-1}DKL(p∣∣q)Ep(logpi−logqi)i1∑npi(logpi−logqi)i1∑npilogqipi(式10-1)将上述与熵的定义式进行对比可见是用logqi−logpi\log q_i - \log p_ilogqi−logpi代替了logpi\log p_ilogpi用来度量两个分布之间的差异。计算 a 和 d 两项输出的相对熵Da0×log00.071589041×log10.928225150.07447962 D_a 0 \times \log \frac{0}{0.07158904} 1 \times \log \frac{1}{0.92822515} 0.07447962Da0×log0.0715890401×log0.9282251510.07447962Dd0×log00.117741771×log10.882004930.12555622 D_d 0 \times \log \frac{0}{0.11774177} 1 \times \log \frac{1}{0.88200493} 0.12555622Dd0×log0.1177417701×log0.8820049310.12555622式中0×log00 \times \log 00×log0计为 0。可见与直接观察的结论相同。相对熵越大的输出与标签值差距越大。如果pip_ipi与qiq_iqi相同那么DKL(p∣∣q)0D_{KL}(p||q) 0DKL(p∣∣q)0。值得注意的是相对熵不具有对称性。相对熵又称为 KL 散度。将相对熵的定义式 10-1 进一步展开DKL(p∣∣q)∑i1npi(logpi−logqi) D_{KL}(p||q) \sum_{i1}^{n} p_i(\log p_i - \log q_i)DKL(p∣∣q)i1∑npi(logpi−logqi)∑i1npilogpi[−∑i1npilogqi](式10-2) \sum_{i1}^{n} p_i\log p_i \left[ -\sum_{i1}^{n} p_i\log q_i \right]\tag{式10-2}i1∑npilogpi[−i1∑npilogqi](式10-2)−H(pi)[−∑i1npilogqi] -H(p_i) \left[ -\sum_{i1}^{n} p_i\log q_i \right]−H(pi)[−i1∑npilogqi]前一项正好是标签分布熵的负值保持不变因此一般用后一项作为两个分布之间差异的度量称为交叉熵H(p,q)−∑i1npilogqi(式10-3) H(p,q) -\sum_{i1}^{n} p_i\log q_i\tag{式10-3}H(p,q)−i1∑npilogqi(式10-3)如果只有正负两个分类标签记为 1 和 0记第iii个输出的标签值为yiy_iyi记它被预测为正类的概率为pip_ipi那么上式为H(y,p)−1n∑i1n[yilogpi(1−yi)log(1−pi)] H(y,p) -\frac{1}{n}\sum_{i1}^{n} [y_i\log p_i (1-y_i)\log(1-p_i)]H(y,p)−n1i1∑n[yilogpi(1−yi)log(1−pi)]交叉熵损失函数在梯度下降法中可以改善 MSE 学习速率降低的问题得到了广泛的应用。PyTorch中实现的交叉熵损失函数有多分类交叉熵损失函数torch.nn.CrossEntropyLoss、 二元交叉熵损失函数torch.nn.BCELoss和带Sigmoid的二元交叉熵损失函数torch.nn.BCEWithLogitsLoss等实现KL散度损失函数的有torch.nn.KLDivLoss()。使用CrossEntropyLoss时不需要提前将标签值转换成独热编码这是使用它的一个便利特性。仍然采用MNIST数据集进行手写体数字识别实验示例如代码10-1.1 所示采用SGD优化方法三层分别采用relu、relu和softmax激活函数训练 10 轮不同的损失函数会有不同的识别率。要注意的是本示例仅示意各损失函数的差异并没有严格地定义实验条件因此结果并不具备广泛性。代码10-1.1 损失函数应用示例### 1.导入和设置环境importtorchimporttorch.nnasnnimporttorch.optimasoptimfromtorch.utils.dataimportDataLoader,TensorDatasetimportdatetimefromtorchvisionimportdatasets,transforms# 设置随机种子torch.manual_seed(0)### 2.训练样本和验证样本数据预处理# 数据预处理方式transformtransforms.Compose([transforms.ToTensor(),# 转换为 torch.Tensor])# 加载MNIST数据集train_datasetdatasets.MNIST(./data,trainTrue,downloadTrue,transformtransform)val_datasetdatasets.MNIST(./data,trainFalse,transformtransform)# 样本拉平、归一化后X_traintrain_dataset.data.float().view(-1,784)/255.0y_traintrain_dataset.targets X_valval_dataset.data.float().view(-1,784)/255.0y_valval_dataset.targets# 转换为独热编码y_traintorch.nn.functional.one_hot(y_train,num_classes10).float()y_valtorch.nn.functional.one_hot(y_val,num_classes10).float()# 创建数据加载器batch_size200train_loaderDataLoader(TensorDataset(X_train,y_train),batch_sizebatch_size,shuffleTrue)val_loaderDataLoader(TensorDataset(X_val,y_val),batch_sizebatch_size)### 3.定义神经网络模型# relu-relu-softmaxclassMNISTModel(nn.Module):def__init__(self):super(MNISTModel,self).__init__()self.fc1nn.Linear(784,784)self.fc2nn.Linear(784,784)self.fc3nn.Linear(784,10)self.relunn.ReLU()self.softmaxnn.Softmax()defforward(self,x):xself.relu(self.fc1(x))xself.relu(self.fc2(x))xself.softmax(self.fc3(x))returnx### 4.采用不同的损失函数进行对比试验criterionnn.CrossEntropyLoss()# 定义损失函数modelMNISTModel()# 实例化模型类得到模型对象optimizeroptim.SGD(model.parameters(),lr0.15)# 定义优化器# 训练模型开始计时start_timedatetime.datetime.now()epochs10forepochinrange(epochs):# 每轮中的训练model.train()train_loss0.0forbatch_X,batch_yintrain_loader:optimizer.zero_grad()outputsmodel(batch_X)losscriterion(outputs,batch_y)loss.backward()optimizer.step()train_lossloss.item()# 看一下该轮训练后的效果model.eval()correct0total0withtorch.no_grad():forbatch_X,batch_yintrain_loader:outputsmodel(batch_X)_,predictedtorch.max(outputs.data,1)# 模型预测值的独热编码_,labelstorch.max(batch_y.data,1)# 真实标签值的独热编码totallabels.size(0)correct(predictedlabels).sum().item()# 准确率print(fEpoch{epoch1}/{epochs}, 对训练样本进行预测的准确率Train Acc:{100*correct/total:.2f}%)# 训练结束终止计时end_timedatetime.datetime.now()print(f训练用时:{end_time-start_time})输出Epoch 1/10, 对训练样本进行预测的准确率Train Acc: 64.97% Epoch 2/10, 对训练样本进行预测的准确率Train Acc: 82.14% Epoch 3/10, 对训练样本进行预测的准确率Train Acc: 83.63% Epoch 4/10, 对训练样本进行预测的准确率Train Acc: 84.34% Epoch 5/10, 对训练样本进行预测的准确率Train Acc: 84.81% Epoch 6/10, 对训练样本进行预测的准确率Train Acc: 91.00% Epoch 7/10, 对训练样本进行预测的准确率Train Acc: 91.88% Epoch 8/10, 对训练样本进行预测的准确率Train Acc: 92.22% Epoch 9/10, 对训练样本进行预测的准确率Train Acc: 93.04% Epoch 10/10, 对训练样本进行预测的准确率Train Acc: 93.51% 训练用时: 0:01:25.518433通过设置MSE损失函数、多分类交叉熵损失函数、二元交叉熵损失函数、带Sigmoid的二元交叉熵损失函数BCEWithLogitsLoss损失函数、KL散度损失函数进行试验对训练样本的预测准确率为89.14%、93.51%、93.23%、68.93%、56.66%详见本文所附代码文件。交叉熵系列损失函数中还可以通过设置weight和pos_weight参数来处理样本类别不平衡的问题。样本类别不平衡问题详见本专栏之九的文章。2.余弦相似度损失函数余弦相似度刻画的是两个向量之间的夹角它适合于与向量方向相关的距离度量。设特征空间X\mathcal{X}X是nnn维实数向量空间Rn\mathbb{R}^nRn点xi,xj∈X\mathbf{x}_i , \mathbf{x}_j \in \mathcal{X}xi,xj∈Xxi(xi,1,xi,2,…,xi,m)\mathbf{x}_i (x_{i,1}, x_{i,2}, \dots, x_{i,m})xi(xi,1,xi,2,…,xi,m)xj(xj,1,xj,2,…,xj,m)\mathbf{x}_j (x_{j,1}, x_{j,2}, \dots, x_{j,m})xj(xj,1,xj,2,…,xj,m)。点xi,xj\mathbf{x}_i, \mathbf{x}_jxi,xj的余弦相似度为cosθxi⋅xj∥xi∥∥xj∥∑k1nxi(k)xj(k)∑k1n(xi(k))2∑k1n(xj(k))2(式10-4) \cos \theta \frac{\mathbf{x}_i \cdot \mathbf{x}_j}{\|\mathbf{x}_i\|\|\mathbf{x}_j\|} \frac{\sum_{k1}^n x_i^{(k)} x_j^{(k)}}{\sqrt{\sum_{k1}^n (x_i^{(k)})^2} \sqrt{\sum_{k1}^n (x_j^{(k)})^2}} \quad \tag{式10-4}cosθ∥xi∥∥xj∥xi⋅xj∑k1n(xi(k))2∑k1n(xj(k))2∑k1nxi(k)xj(k)(式10-4)将标签和预测看作值向量可用式10-4计算得到余弦相似度作为损失函数Cosine Similarity Loss。余弦相似度损失函数主要用于需要衡量向量方向一致性的任务特别适用于处理高维特征且关注相对关系的场景主要有图像分类与人脸识别、文本检索与语义匹配、推荐系统等。使用余弦相似度损失函数的示例如代码10-1.2所示。代码10-1.2 余弦相似度损失函数应用示例### 使用余弦相似度损失函数需要先自定义一个适配器classCosineLossAdapter(nn.Module):def__init__(self,margin0.5):super(CosineLossAdapter,self).__init__()self.cosine_lossnn.CosineEmbeddingLoss(marginmargin)defforward(self,predictions,targets):# CosineEmbeddingLoss需要两个输入张量和一个目标张量# 我们将预测视为第一个输入目标视为第二个输入# 目标标签设为1表示我们希望它们相似target_labelstorch.ones(predictions.size(0)).to(predictions.device)# 计算损失lossself.cosine_loss(predictions,targets,target_labels)returnloss criterionCosineLossAdapter(margin0.5)# 使用适配器modelMNISTModel()# 实例化模型类得到模型对象optimizeroptim.SGD(model.parameters(),lr0.15)# 定义优化器# 训练模型开始计时start_timedatetime.datetime.now()epochs10forepochinrange(epochs):# 每轮中的训练model.train()train_loss0.0forbatch_X,batch_yintrain_loader:optimizer.zero_grad()outputsmodel(batch_X)losscriterion(outputs,batch_y)# 现在只需要两个参数loss.backward()optimizer.step()train_lossloss.item()# 看一下该轮训练后的效果model.eval()correct0total0withtorch.no_grad():forbatch_X,batch_yintrain_loader:outputsmodel(batch_X)_,predictedtorch.max(outputs.data,1)# 模型预测值的独热编码_,labelstorch.max(batch_y.data,1)# 真实标签值的独热编码totallabels.size(0)correct(predictedlabels).sum().item()# 准确率print(fEpoch{epoch1}/{epochs}, 对训练样本进行预测的准确率Train Acc:{100*correct/total:.2f}%)# 训练结束终止计时end_timedatetime.datetime.now()print(f训练用时:{end_time-start_time})输出Epoch 1/10, 对训练样本进行预测的准确率Train Acc: 89.40% Epoch 2/10, 对训练样本进行预测的准确率Train Acc: 91.37% Epoch 3/10, 对训练样本进行预测的准确率Train Acc: 92.52% Epoch 4/10, 对训练样本进行预测的准确率Train Acc: 93.10% Epoch 5/10, 对训练样本进行预测的准确率Train Acc: 93.67% Epoch 6/10, 对训练样本进行预测的准确率Train Acc: 94.39% Epoch 7/10, 对训练样本进行预测的准确率Train Acc: 94.86% Epoch 8/10, 对训练样本进行预测的准确率Train Acc: 95.37% Epoch 9/10, 对训练样本进行预测的准确率Train Acc: 95.69% Epoch 10/10, 对训练样本进行预测的准确率Train Acc: 96.10% 训练用时: 0:01:13.8352993. 双曲余弦对数损失函数双曲余弦对数Log-Cosh Loss的计算方法为logcosh(p,q)∑i1nlog(eqi−pie−(qi−pi)2)∑i1nlog(eqi−pi⋅(1e−2(qi−pi))/2)∑i1n[log(eqi−pi)log(1e−2(qi−pi))−log(2)]∑i1n[(qi−pi)log(1e−2(qi−pi))−log(2)]∑i1n[(qi−pi)softplus(−2(qi−pi))−log(2)](式10-5) \begin{align*} \log \cosh(p, q) \sum_{i1}^n \log\left(\frac{e^{q_i - p_i} e^{-(q_i - p_i)}}{2}\right) \\ \sum_{i1}^n \log(e^{q_i - p_i} \cdot (1 e^{-2(q_i - p_i)})/2) \\ \sum_{i1}^n [ \log(e^{q_i - p_i}) \log(1 e^{-2(q_i - p_i)}) - \log(2)] \\ \sum_{i1}^n [ (q_i - p_i) \log(1 e^{-2(q_i - p_i)}) - \log(2) ]\\ \sum_{i1}^n [ (q_i - p_i) \text{softplus}(-2(q_i - p_i)) - \log(2)] \end{align*} \tag{式10-5}logcosh(p,q)i1∑nlog(2eqi−pie−(qi−pi))i1∑nlog(eqi−pi⋅(1e−2(qi−pi))/2)i1∑n[log(eqi−pi)log(1e−2(qi−pi))−log(2)]i1∑n[(qi−pi)log(1e−2(qi−pi))−log(2)]i1∑n[(qi−pi)softplus(−2(qi−pi))−log(2)](式10-5)双曲余弦对数损失函数相似于 MSE但比 MSE 相对稳定。主要应用于对异常值敏感度低、且需要良好数值稳定性的回归任务中特别适合金融预测、医疗诊断等对误差分布有严格要求的领域。其核心优势在于结合了均方误差MSE和平均绝对误差MAE预测标签值与真实标签值之差的绝对值的平均值的优点在小误差时类似MSE优化更平滑在大误差时类似MAE对异常值不敏感且处处可微便于使用牛顿法等二阶优化算法后文讨论。使用双曲余弦对数损失函数的示例如代码10-1.3所示。代码10-1.3 双曲余弦对数损失函数应用示例### 定义双曲余弦对数损失函数LogCoshLossimportmathclassLogCoshLoss(nn.Module):def__init__(self,reductionmean):super(LogCoshLoss,self).__init__()self.reductionreductiondefforward(self,y_pred,y_true):# y_pred: 模型输出的概率分布 (经过softmax)# y_true: 目标概率分布 (独热编码)# 计算残差diffy_pred-y_true# 数值稳定的log(cosh(x))实现# log(cosh(x)) x softplus(-2x) - log(2) 式10-5lossdifftorch.nn.functional.softplus(-2.0*diff)-math.log(2.0)# 对每个样本的所有类别求平均lossloss.mean(dim1)ifself.reductionmean:returnloss.mean()elifself.reductionsum:returnloss.sum()else:# nonereturnloss### 采用双曲余弦对数损失函数进行训练criterionLogCoshLoss()# 定义损失函数改用LogCoshLossmodelMNISTModel()# 实例化模型类得到模型对象optimizeroptim.SGD(model.parameters(),lr0.15)# 定义优化器# 训练模型开始计时start_timedatetime.datetime.now()epochs10forepochinrange(epochs):# 每轮中的训练model.train()train_loss0.0forbatch_X,batch_yintrain_loader:optimizer.zero_grad()outputsmodel(batch_X)# 这里使用LogCoshLoss接口与CrossEntropyLoss一致losscriterion(outputs,batch_y)loss.backward()optimizer.step()train_lossloss.item()# 看一下该轮训练后的效果model.eval()correct0total0withtorch.no_grad():forbatch_X,batch_yintrain_loader:outputsmodel(batch_X)_,predictedtorch.max(outputs.data,1)# 模型预测值的独热编码_,labelstorch.max(batch_y.data,1)# 真实标签值的独热编码totallabels.size(0)correct(predictedlabels).sum().item()# 准确率print(fEpoch{epoch1}/{epochs}, 对训练样本进行预测的准确率Train Acc:{100*correct/total:.2f}%)# 训练结束终止计时end_timedatetime.datetime.now()print(f训练用时:{end_time-start_time})Epoch 1/10, 对训练样本进行预测的准确率Train Acc: 20.26% Epoch 2/10, 对训练样本进行预测的准确率Train Acc: 44.26% Epoch 3/10, 对训练样本进行预测的准确率Train Acc: 56.87% Epoch 4/10, 对训练样本进行预测的准确率Train Acc: 56.84% Epoch 5/10, 对训练样本进行预测的准确率Train Acc: 50.69% Epoch 6/10, 对训练样本进行预测的准确率Train Acc: 42.39% Epoch 7/10, 对训练样本进行预测的准确率Train Acc: 43.74% Epoch 8/10, 对训练样本进行预测的准确率Train Acc: 54.14% Epoch 9/10, 对训练样本进行预测的准确率Train Acc: 56.65% Epoch 10/10, 对训练样本进行预测的准确率Train Acc: 57.79% 训练用时: 0:01:10.519077损失函数还有很多读者可在了解基本知识后要求AI大模型给出不同损失函数的细节供参考。参考文献[1] 王衡军,机器学习[M].北京:清华大学出版社,2020.