当前位置: 首页 > 科技观察

超简单的神经网络搭建方法,你也可以做到!

时间:2023-03-20 21:35:46 科技观察

本文转载自公众号《读书芯》(ID:AI_Discovery)人工智能、深度学习,这些词是不是听起来高大上,充满神秘色彩?好像是只对数学博士开放的进阶。场地?错误的!现在B站变成了学习网站,网上有什么教程是找不到的?深度学习从来没有这么好用过,至少实用部分是这样的。如果您只是了解人工神经网络的基本理论,但从未涉足如何编写它们,请尝试阅读本文。您将基本了解如何在PyTorch库中执行人工神经网络操作以对以前看不见的数据进行预测。这篇文章最多可以在10分钟内阅读;如果你想跟着代码一步一步来,只要你安装了必要的库,那么只需要15分钟。相信我,这并不难。长话短说,让我们开始吧!导入语句和数据集这个简单的例子会用到几个库:Pandas:用于数据加载和处理Matplotlib:用于数据可视化PyTorch:用于模型训练Scikit-learn:用于拆分训练集和测试集,如果你只是想复制粘贴,以下导入语句供参考:importtorchimporttorch.nnasnnimporttorch.nn.functionalasFimportpandasaspdimportmatplotlib.pyplotaspltfromsklearn.model_selectionimporttrain_test_split至于数据集,Iris数据集可以在这个网址找到。以下是将其直接导入Pandas的方法:iris=pd.read_csv('https://raw.githubusercontent.com/pandas-dev/pandas/master/pandas/tests/data/iris.csv')iris.head()前几行如下图所示:现在您需要将名称列中鸢尾花的物种名称更改或重新映射为分类值。——也就是0、1、2。以下是步骤:mappings={'Iris-setosa':0,'Iris-versicolor':1,'Iris-virginica':2}iris['Name']=iris['Name'].apply(lambdax:mappings[x])执行以上代码得到的DataFrame如下:恭喜你,你成功迈出了第一步!拆分训练集和测试集在这个环节中,将使用Scikit-Learn库来拆分训练集和测试集。随后,拆分数据从Numpy数组转换为PyTorchtensors。首先,Iris数据集需要分为“特征”和“标签集”——或者x和y。Name列是因变量,其余是“特征”(或自变量)。接下来,我也会使用随机种子,所以下面的结果可以直接重现。代码如下:X=iris.drop('Name',axis=1).valuesy=iris['Name'].valuesX_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=42)X_train=torch.FloatTensor(X_train)X_test=torch.FloatTensor(X_test)y_train=torch.LongTensor(y_train)y_test=torch.LongTensor(y_test)如果你检查从X_train开始的前三行,你会得到以下结果:startfromy_trainyouget结果如下:基础打好了,接下来的环节将正式开始搭建神经网络。定义神经网络模型的架构很简单。亮点在于神经网络的架构:输入层(4个输入特征(即X包含的特征个数),16个输出特征(随机))全连接层(16个输入特征(即X包含的特征个数)输入层输出特征的个数),12个输出特征(随机))输出层(12个输入特征(即全连接层输出特征的个数),3个输出特征(即不同品种的个数)大致是这样的这个。另外会用到ReLU作为激活函数。下面展示如何在代码中实现这个激活函数。classANN(nn.Module):def__init__(self):super().__init__()self.fc1=nn.Linear(in_features=4,out_features=16)self.fc2=nn.Linear(in_features=16,out_features=12)self.output=nn.Linear(in_features=12,out_features=3)defforward(self,x):x=F.relu(self.fc1(x))x=F.relu(self.fc2(x))x=self.output(x)returnxPyTorch使用的面向对象的模型声明方式非常直观。在构造函数中,您需要定义所有层及其架构,如果使用forward(),则需要定义前向传播。然后创建一个模型实例,验证其架构是否与上面提到的架构匹配:model=ANN()model在训练模型之前,需要注意以下几点:评估标准:主要使用CrossEntropyLoss来计算损失优化器:使用Adam学习率为0.01的优化算法下面展示了如何在代码中实现CrossEntropyLoss和Adam:criterion=nn.CrossEntropyLoss()optimizer=torch.optim.Adam(model.parameters(),lr=0.01)令人兴奋的长-期待已久的部分终于来了——模型训练!模型训练部分也相当简单。模型训练将运行100个时期,跟踪时间和损失。当前状态每10轮输出到控制台-以指示当前轮次和当前损失。代码如下:%%timeepochs=100loss_arr=[]foriinrange(epochs):y_hat=model.forward(X_train)loss=criterion(y_hat,y_train)loss_arr.append(loss)ifi%10==0:print(f'Epoch:{i}Loss:{loss}')optimizer.zero_grad()loss.backward()optimizer.step()好奇最后三行是做什么用的?答案很简单——反向传播——权重和偏差设置的更新让模型真正地“学习”。以下是运行上述代码的结果:快速进展-但不要掉以轻心。如果你真的对纯数字不感兴趣,下图是loss曲线的可视化(x轴是整数,y轴是loss):模型已经训练好了,我们该怎么办现在?当然是模型评价。这个模型需要以某种方式在以前看不见的数据上进行评估。模型评估在评估过程中,希望以某种方式跟踪模型所做的预测。您需要迭代X_test并进行预测,然后将预测值与实际值进行比较。我们将在这里使用torch.no_grad()因为它只是评估——不需要更新权重和偏差。总而言之,代码如下所示:preds=[]withtorch.no_grad():forvalinX_test:y_hat=model.forward(val)preds.append(y_hat.argmax().item())预测数组。可以使用以下三个值构造PandasDataFrame。Y:实际值YHat:预测值正确:对角线,对角线的值为1表示Y和YHat匹配,值为0表示不匹配代码如下:df=pd.DataFrame({'Y':y_test,'YHat':preds})df['Correct']=[1ifcorr==predelse0forcorr,predinzip(df['Y'],df['YHat'])]的前五行df如下图所示:下一个问题是的,你实际上是如何计算准确率的?这很简单——只需计算Correct列的总和并除以df的长度:df['Correct'].sum()/len(df)>>>1.0该模型适用于以前未见过的数据的100%准确度.但需要注意的是,这完全是因为Iris数据集非常容易分类,并不意味着神经网络是Iris数据集的最佳算法。NN对于这类问题有点矫枉过正,但这是以后讨论的话题。这可能是您编写过的最简单的神经网络,具有完美紧凑的数据集、无缺失值、最少的层和神经元!本文没有什么高深深奥的内容,相信你一定能够掌握。