MNIST手写数字辨识-cnn网路 (机器学习中的hello world,加油)

这篇具有很好参考价值的文章主要介绍了MNIST手写数字辨识-cnn网路 (机器学习中的hello world,加油)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

用PyTorch实现MNIST手写数字识别(非常详细) - 知乎 (zhihu.com)

参考来源(这篇文章非常适合入门来看,每个细节都讲解得很到位)

一、模块函数用法-查漏补缺:
1.关于torch.nn.functional.max_pool2d()的用法:

MNIST手写数字辨识-cnn网路 (机器学习中的hello world,加油),人工智能,cnn,人工智能,神经网络MNIST手写数字辨识-cnn网路 (机器学习中的hello world,加油),人工智能,cnn,人工智能,神经网络

上述示例中,输入张量 input 经过最大池化操作后,使用了 kernel_size=2stride=2,所以输出张量 output 的高度和宽度均为输入的一半(32/2=16)。

2.pytorch中的view函数的用法:

http://t.csdn.cn/AAhdH

这一篇文章写得非常好

3.关于f.log_softmax(x,dim = -1)这个先进行softmax,再取log的函数的讲解:

http://t.csdn.cn/GIJ7g

这篇文章讲解得非常好,补充一点,dim的default值和softmax一样,都是-1,也就是计算最里面那个维度的softmax的结果

4.原来loss和counter计数器数组有这个作用:
train_losses = []
train_counter = []
test_losses = []
test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)]

MNIST手写数字辨识-cnn网路 (机器学习中的hello world,加油),人工智能,cnn,人工智能,神经网络

5.关于F.nll_loss这个损失函数:

http://t.csdn.cn/ZoruZ

总的来说就是一句话“损失函数 nn.CrossEntropyLoss() 与 NLLLoss() 相同, 唯一的不同是它为我们去做 log_softmax.”

这篇文章讲述得非常清楚

6.关于loss.item()的作用:

http://t.csdn.cn/AvrnJ

这篇文章讲得非常清楚:

就是输出loss这个数值,但是呢,是用非常高的精度进行输出的,一般我们进行一各batch的训练后,就会得到这一次的loss单个数值,需要输出的话,最好就用item()

7.with torch.no_grad()的用法:

http://t.csdn.cn/STaKp

这篇文章讲述得非常清楚,就是不会进行gradient_descend操作,极大的节省了运算开销

8.data.max()函数的用法:

http://t.csdn.cn/aBmin

MNIST手写数字辨识-cnn网路 (机器学习中的hello world,加油),人工智能,cnn,人工智能,神经网络

上面那里讲得不太好,还是chatGPT比较优秀

MNIST手写数字辨识-cnn网路 (机器学习中的hello world,加油),人工智能,cnn,人工智能,神经网络

9.data.view_as()的用法:

MNIST手写数字辨识-cnn网路 (机器学习中的hello world,加油),人工智能,cnn,人工智能,神经网络

MNIST手写数字辨识-cnn网路 (机器学习中的hello world,加油),人工智能,cnn,人工智能,神经网络

10.torch.eq的用法:

http://t.csdn.cn/Tb0kY

这篇文章讲述得非常清楚,也就是对张量中的数值逐个进行比较,

返回的是同样形状的数据,每个位置要么True要么False,可以用.sum()求和得到True的总数

顺便提一下torch.sum的用法,

x = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(x.sum())

输出的结果是21

二、各个部分的代码和注释:
#设置环境
import torch
import torchvision
from torch.utils.data import DataLoader
#准备数据集
#1.设置必要的参数
n_epochs = 3
batch_size_train = 64 #所以呢,这个64其实就是下面train时候的batch_size大小
batch_size_test = 1000
learning_rate = 0.01
momentum = 0.5
log_interval = 10 #这个就是后面用来输出的间隔
random_seed = 1
torch.manual_seed(random_seed)

 

#利用pytorch直接加载对应的train_data集 和 test_Data集
train_loader = torch.utils.data.DataLoader( #这里调用的是torch.utils.data.DataLoader的对象,实例化出train_dataloader
    #限免设置各个参数,比如,第一个就是Dataset参数,这里是引用MNIST作为参数,并且设置MNIST中的各个参数
    torchvision.datasets.MNIST('./data/', train=True, download=True, #设为train数据+下载
                               transform=torchvision.transforms.Compose([ #对数据进行transform变换
                                   torchvision.transforms.ToTensor(), #先变tensor后进行Normlize
                                   torchvision.transforms.Normalize(
                                       (0.1307,), (0.3081,))
                               ])),
    batch_size=batch_size_train, shuffle=True) #这个loader的后两个参数batch_size和shuffle
#同样的道理设置test_data_loader
test_loader = torch.utils.data.DataLoader(
    torchvision.datasets.MNIST('./data/', train=False, download=True,
                               transform=torchvision.transforms.Compose([
                                   torchvision.transforms.ToTensor(),
                                   torchvision.transforms.Normalize(
                                       (0.1307,), (0.3081,))
                               ])),
    batch_size=batch_size_test, shuffle=True)
#查看一条数据:
examples = enumerate(test_loader) #enumerate返回一个(index,data)的元组,本身是一个迭代器,可以用于遍历test_loader
batch_idx, (example_data, example_targets) = next(examples)
print(example_targets) #输出测试(这里的test是有answer作为label的)的1000各answer
print(len(example_targets)) #总共1000各target
print(example_data.shape) #一共有1000张28*28的黑白灰度图
#利用matplotlib进行绘制得到某些数据的可视化结果
import matplotlib.pyplot as plt
fig = plt.figure() #创建一个fig对象
for i in range(6):
  plt.subplot(2,3,i+1) #按照2行3列绘制6张图片
  plt.tight_layout() #设置紧密相连
  plt.imshow(example_data[i][0], cmap='gray', interpolation='none') #利用imshow在下方直接输出图像
  plt.title("Ground Truth: {}".format(example_targets[i]))#设置标题,就是label的数值
  plt.xticks([])
  plt.yticks([])
plt.show()
#定义neural network的结构
import torch.nn as nn #引入neural network的库
import torch.nn.functional as F #引入nn总的常用Func
import torch.optim as optim #引入torch中的optimizer

class Net(nn.Module): #继承nn中的module
    def __init__(self):  #定义这个网络结构的构造函数
        super(Net, self).__init__() #继承nn.Module的初始化构造
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)#参数:输入channel、输出channel、卷积核5*5(filters),strdie(default =1),padding(default=0)
        #所以1*28*28的图像通过后,10*21*21(10是filters的数量)
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        self.conv2_drop = nn.Dropout2d() #这个函数http://t.csdn.cn/xK6og这篇文章讲得挺好的,就是让部分filters在某一层不工作,效果是有效防止overfit
        self.fc1 = nn.Linear(320, 50) #定义一个320 -->50 的Linear层函数
        self.fc2 = nn.Linear(50, 10)  #定义一个50 -->10  的Linear层函数
    def forward(self, x): #下面就是直接进行整个network的作用过程定义了 , 输入1*28*28的灰度图
        x = F.relu(F.max_pool2d(self.conv1(x), 2)) #经过一个conv1卷积层后,经过1次2*2窗口的pooling得到,默认??padding=1,之后再算好了
        x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) #再通过conv2之后->通过conv2_drop->通过max_pool2d
        x = x.view(-1, 320) #第二维是320,并自动计算第一维
        x = F.relu(self.fc1(x)) #通过一个linear层之后,又通过一个relu的激活函数,最后输出的是第二维是50的结果
        x = F.dropout(x, training=self.training) #只有在training模式下才会调用dropout(让某些神经元“熄火”喵)
        x = self.fc2(x) #再让x通过一个linear层,输出的结果是2维的数据,第二维(共10列)
        return F.log_softmax(x) #最后通过对最里面那一层softmax层后,取log对数
#创建model对象+设置optimizer优化器
network = Net()
optimizer = optim.SGD(network.parameters(), lr=learning_rate,
                      momentum=momentum) #lr和momentum都是上面设置好的

#设置用于存储的数组结构:
train_losses = []
train_counter = [] #估计就是一个计数器的作用
test_losses = []
test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)]
#print(test_counter)输出[0,60000,120000,180000]不知道再干啥,反正上面的n——epoch==3
#定义这个train函数:
def train(epoch): #这里的epoch是传递进来的参数
  network.train() #开启train模式
  for batch_idx, (data, target) in enumerate(train_loader):#迭代器:以batch为单位逐个从train_loader中获取 索引、data图像数据、label作为target数据
    optimizer.zero_grad() #因为torch中的grad是累加的,所以需要在每个batch训练之前利用optimizer.zero_grad()清零
    output = network(data) #将data图像数据通过network网络得到output输出结果
    loss = F.nll_loss(output, target) #这个loss_func只是比cross_entropy少一个对输入数据的log_softmax操作
    loss.backward()
    optimizer.step() #loss.backward + optimizer.step()常规更新模型参数的操作
    
    if batch_idx % log_interval == 0: #下面都是没啥用的间隔输出操作,上面设置的log_interval =10
      #每经过10各batch处理输出一次:
      #第几个epoch,第几个图像,总共的train有多少图像,已经完成了百分之几的batch,这个batch的loss值
      print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
        epoch, batch_idx * len(data), len(train_loader.dataset),
        100. * batch_idx / len(train_loader), loss.item())) 
      #将这个batch的loss值添加到train_losses数组中(注意,这里好像是每隔10个batch记录一次loss)
      train_losses.append(loss.item())
      train_counter.append(  #在counter中记录这个batch在考虑epoch情况下的位置
        (batch_idx*64) + ((epoch-1)*len(train_loader.dataset))) #这个64是train时候的batch_size上面写了
      #将当前的network的参数状态state_dice存储到对应的路径下, 同时optimizer的状态也要存储?why感觉optim没啥用
      torch.save(network.state_dict(), './model.pth')
      torch.save(optimizer.state_dict(), './optimizer.pth')
          
#train(1) #传递参数epoch=1进行train一次
#这里的train有个地方很有意思,它只是输出loss,没有利用argmax计算出对应的one-hot vec,从而没法和label进行比较得到acc
#定义test函数,并且进行test测试 (不用想,大概率和train的内容没有太大的区别,不过是少了backward和step的更新)
def test():
  network.eval() #开启model的eval模式
  test_loss = 0 #设置loss和acc初值
  correct = 0
  with torch.no_grad(): #不计算SGD
    for data, target in test_loader: #非enumerate,非迭代器版本,不会返回索引,获取data图像batch和target的labels数值
      output = network(data) #调用network获取output结果

      test_loss += F.nll_loss(output, target, size_average=False).item() #这里计算出这一次的 output和target之间的loss

      pred = output.data.max(1, keepdim=True)[1] #通过data.max函数获取对应的索引,这是一个索引的数组,因为是一个batch一起预测的
      correct += pred.eq(target.data.view_as(pred)).sum() #如果pred和target数组对应位置比较,计算总共相等的位置的数量
  test_loss /= len(test_loader.dataset) #计算平均的loss
  test_losses.append(test_loss) #将这一次的平均loss加入到test_losses数组中
  
  #输出:
  #这一次的平均loss,总数中正确预测的数目,正确率
  print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
    test_loss, correct, len(test_loader.dataset),
    100. * correct / len(test_loader.dataset)))
    
#test()#调用上述定义的test函数
#再调用一次test()
test()
for epoch in range(1, n_epochs + 1): #调用n_epochs个数的train和测试结果
  train(epoch)
  test()

#下面对上述获取到的数据进行图像的绘制
#绘制图像一开始出错了,我怀疑是我多进行了一次test(),导致x和y的大小不对应
import matplotlib.pyplot as plt
fig = plt.figure()       #创建figure对象 
plt.plot(train_counter, train_losses, color='blue') #绘制曲线图,x是train计数,y是trainloss
#plt.scatter(test_counter, test_losses, color='red') #绘制散点图,x是test_counter计数,y是test_losses数据
plt.legend(['Train Loss', 'Test Loss'], loc='upper right')
plt.xlabel('number of training examples seen') #x轴标题
plt.ylabel('negative log likelihood loss')     #y轴标题
plt.show() #绘制结果
#抽取几个直观的例子进行测试:

examples = enumerate(test_loader) #获取test_loader的迭代器
batch_idx, (example_data, example_targets) = next(examples) #获取第一个test_loader中的batch
with torch.no_grad():
  output = network(example_data) #将example_data数据通过network得到output
fig = plt.figure() #创建figure对象
for i in range(6): #构建2行3列的图像排列
  plt.subplot(2,3,i+1)
  plt.tight_layout() #紧密排列
  plt.imshow(example_data[i][0], cmap='gray', interpolation='none') #利用imshow输出example图像
  plt.title("Prediction: {}".format(
    output.data.max(1, keepdim=True)[1][i].item())) #输出预测结果,结果非常美妙
  plt.xticks([])
  plt.yticks([])
plt.show() #绘制-这个似乎可以不用
#为了能够持续训练,这里考虑 获取 上一次的 model_dict 和 optim_dict
continued_network = Net()
continued_optimizer = optim.SGD(network.parameters(), lr=learning_rate,
                                momentum=momentum)

network_state_dict = torch.load('model.pth')
continued_network.load_state_dict(network_state_dict)
optimizer_state_dict = torch.load('optimizer.pth')
continued_optimizer.load_state_dict(optimizer_state_dict)

#再接着上面练上6次
for i in range(4, 9):
    test_counter.append(i*len(train_loader.dataset))
    train(i)
    test()
#同样进行图像的绘制
fig = plt.figure()
plt.plot(train_counter, train_losses, color='blue')
plt.scatter(test_counter, test_losses, color='red') #因为之前多test了一次,所以这里应该还是会出错
plt.legend(['Train Loss', 'Test Loss'], loc='upper right')
plt.xlabel('number of training examples seen')
plt.ylabel('negative log likelihood loss')
plt.show()

第一个再vscode完成的神经网络训练, 撒花庆祝!!🎉文章来源地址https://www.toymoban.com/news/detail-707091.html

到了这里,关于MNIST手写数字辨识-cnn网路 (机器学习中的hello world,加油)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 从手写数字识别入门深度学习丨MNIST数据集详解

    就像无数人从敲下“Hello World”开始代码之旅一样,许多研究员从“MNIST数据集”开启了人工智能的探索之路。 MNIST数据集(Mixed National Institute of Standards and Technology database)是一个用来训练各种图像处理系统的二进制图像数据集,广泛应用于机器学习中的训练和测试。 作为一

    2024年02月03日
    浏览(45)
  • [深度学习实战]基于PyTorch的深度学习实战(下)[Mnist手写数字图像识别]

    PyTorch——开源的Python机器学习库   首先感谢所有点开本文的朋友们!基于PyTorch的深度学习实战可能要告一段落了。本想着再写几篇关于 PyTorch神经网络深度学习 的文章来着,可无奈项目时间紧任务重,要求 短时间内出图并做好参数拟合 。所以只得转战 Matlab 编程,框架旧

    2024年02月16日
    浏览(55)
  • 【机器学习】VAE算法的pytorch实现-MNIST手写数据识别

    序言 承接上文 VAE变分自编码器学习笔记 一文介绍了VAE算法的设计思路、原理、公式推导以及作者本人对VAE模型的理解 这里继续就VAE算法的实现进行学习,为模型能够应用到工作中做准备 1. 环境配置 (1)我们使用pytorch来训练模型,首先导入必要的库(模块module、包package)

    2024年02月13日
    浏览(48)
  • python与深度学习(六):CNN和手写数字识别二

    本篇文章是对上篇文章训练的模型进行测试。首先是将训练好的模型进行重新加载,然后采用opencv对图片进行加载,最后将加载好的图片输送给模型并且显示结果。 在这里导入需要的第三方库如cv2,如果没有,则需要自行下载。 把MNIST数据集进行加载,并且把训练好的模型也

    2024年02月15日
    浏览(36)
  • 三、MNIST手写数字分类任务项目实战

    分类任务和回归任务本质上并没有太大的区别,只是最终得到的结果和损失函数不同而已。 MNIST手写数字分类任务,最终得到的是10个值,也类似一个one-hot编码格式,表示该图片是0-9数字的概率,概率值最大的就是预测的最终结果 当然标签也得是one-hot编码格式,例如标签图

    2024年02月09日
    浏览(36)
  • 【Pytorch+torchvision】MNIST手写数字识别

    深度学习入门项目,含代码详细解析 在本文中,我们将在 PyTorch 中构建一个简单的卷积神经网络,并使用 MNIST数据集 训练它识别手写数字。 MNIST包含70,000张手写数字图像: 60,000张用于培训,10,000张用于测试。图像是 灰度(即通道数为1) , 28x28像素 ,并且居中的,以减少预

    2024年02月14日
    浏览(41)
  • FPGA实现mnist手写数字识别(软件部分)

    使用的环境:tf1.12,具体配置见here: 首先打开环境tf1.12,,再安装以下的包: opencv 在这里下载“linux-64/opencv3-3.1.0-py36_0.tar.bz2”,通过共享文件夹copy到download文件夹中,在文件夹下打开终端,输入以下命令进行安装: matplotlib(时刻注意是py36) Pillow(貌似不用了,上面已经安

    2023年04月15日
    浏览(80)
  • pytorch 入门 (三)案例一:mnist手写数字识别

    本文为🔗小白入门Pytorch内部限免文章 🍨 本文为🔗小白入门Pytorch中的学习记录博客 🍦 参考文章:【小白入门Pytorch】mnist手写数字识别 🍖 原作者:K同学啊 ​ 如果设备上支持GPU就使用GPU,否则使用CPU 使用dataset下载MNIST数据集,并划分好训练集与测试集 使用dataloader加载数

    2024年02月07日
    浏览(49)
  • 人工智能TensorFlow MNIST手写数字识别——实战篇

    上期文章TensorFlow手写数字-训练篇,我们训练了我们的神经网络,本期使用上次训练的模型,来识别手写数字(本期构建TensorFlow神经网络代码为上期文章分享代码) http://scs.ryerson.ca/~aharley/vis/conv/ 0、插入第三方库 1、图片处理函数

    2024年02月15日
    浏览(59)
  • 用PyTorch实现MNIST手写数字识别(最新,非常详细)

    本文基于 PyTorch 框架,采用 CNN卷积神经网络 实现 MNIST 手写数字识别,仅在 CPU 上运行。 已分别实现使用Linear纯线性层、CNN卷积神经网络、Inception网络、和Residual残差网络四种结构对MNIST数据集进行手写数字识别,并对其识别准确率进行比较分析。(另外三种还未发布) 看完

    2024年02月06日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包