我的博客:我的博客
原文:大三网络安全人工智能实验报告
《人工智能》课程
实验报告
XXXX
班 级: XXXXXX
姓 名: XXX
学 号: XXXXXXXX
提交时间: XXXXXX
基于神经网络的MNIST手写数字识别
**一、**实验目的
-
掌握运用神经网络模型解决有监督学习问题
-
掌握机器学习中常用的模型训练测试方法
-
了解不同训练方法的选择对测试结果的影响
**二、**实验内容
MNIST数据集
本实验采用的数据集MNIST是一个手写数字图片数据集,共包含图像和对应的标签。数据集中所有图片都是28x28像素大小,且所有的图像都经过了适当的处理使得数字位于图片的中心位置。MNIST数据集使用二进制方式存储。图片数据中每个图片为一个长度为784(28x28x1,即长宽28像素的单通道灰度图)的一维向量,而标签数据中每个标签均为长度为10的一维向量。
分层采样方法
分层采样(或分层抽样,也叫类型抽样)方法,是将总体样本分成多个类别,再分别在每个类别中进行采样的方法。通过划分类别,采样出的样本的类型分布和总体样本相似,并且更具有代表性。在本实验中,MNIST数据集为手写数字集,有0~9共10种数字,进行分层采样时先将数据集按数字分为10类,再按同样的方式分别进行采样。
神经网络模型评估方法
通常,我们可以通过实验测试来对神经网络模型的误差进行评估。为此,需要使用一个测试集来测试模型对新样本的判别能力,然后以此测试集上的测试误差作为误差的近似值。两种常见的划分训练集和测试集的方法:
留出法(hold-out)直接将数据集按比例划分为两个互斥的集合。划分时为尽可能保持数据分布的一致性,可以采用分层采样(stratified sampling)的方式,使得训练集和测试集中的类别比例尽可能相似。需要注意的是,测试集在整个数据集上的分布如果不够均匀还可能引入额外的偏差,所以单次使用留出法得到的估计结果往往不够稳定可靠。在使用留出法时,一般要采用若干次随机划分、重复进行实验评估后取平均值作为留出法的评估结果。
k折交叉验证法(k-fold cross validation)先将数据集划分为k个大小相似的互斥子集,每个子集都尽可能保持数据分布的一致性,即也采用分层采样(stratified sampling)的方法。然后,每次用k-1个子集的并集作为训练集,余下的那个子集作为测试集,这样就可以获得k组训练集和测试集,从而可以进行k次训练和测试。最终返回的是这k个测试结果的均值。显然,k折交叉验证法的评估结果的稳定性和保真性在很大程度上取决于k的取值。k最常用的取值是10,此外常用的取值还有5、20等。
三、实验方法设计
实验环境
1.VSCODE
2.anaconda==4.14.0
3.python==3.7
4.TensorFlow–gpu==1.15.0
5.Keras==2.3.1
6.实验报告编辑器:typora
介绍实验中程序的总体设计方案、关键步骤的编程方法及思路,主要包括:
因为之前用过pytorch进行机器学习的训练和学习,所以本作业使用pytorch进行建模和训练。
标准训练流程如下:导入包->设定初始值->加载数据集(预处理)->建立模型->训练->测试->评估
其中需要对加载数据集进行处理,把留出法的比例进行调整来观察结果。
其次要使用k折交叉验证法进行对比测试。
为了表明k折交叉验证法与留出法的效果对比,我建立了连个模型,一个是按照标准流程建立的优秀的模型。一个是用作对比k折交叉验证法与留出法效果对比的劣质模型。
含有tensorflow部分代码,在四、4中。
- 设置初始值
mean = [0.5] std = [0.5] # batch size BATCH_SIZE =128 Iterations = 1 # epoch learning_rate = 0.01
- 优化器与损失函数
criterion = torch.nn.CrossEntropyLoss() optimizer = torch.optim.SGD(model.parameters(),learning_rate)
- 训练代码
def train(model, optimizer,criterion,epoch): model.train() # setting up for training for batch_idx, (data, target) in enumerate(train_loader): # data contains the image and target contains the label = 0/1/2/3/4/5/6/7/8/9 data = data.view(-1, 28*28).requires_grad_() optimizer.zero_grad() # setting gradient to zero output = model(data) # forward loss = criterion(output, target) # loss computation loss.backward() # back propagation here pytorch will take care of it optimizer.step() # updating the weight values if batch_idx % 100 == 0: print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format( epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item()))
- 测试代码
def test(model, criterion, val_loader, epoch,train= False): model.eval() test_loss = 0 correct = 0 with torch.no_grad(): for batch_idx, (data, target) in enumerate(val_loader): data = data.view(-1, 28*28).requires_grad_() output = model(data) test_loss += criterion(output, target).item() # sum up batch loss pred = output.max(1, keepdim=True)[1] # get the index of the max log-probability correct += pred.eq(target.view_as(pred)).sum().item() # if pred == target then correct +=1 test_loss /= len(val_loader.dataset) # average test loss if train == False: print(