吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3281|回复: 15
收起左侧

[Python 转载] 从零开始写一个神经网络(第一篇)

  [复制链接]
fengchuan 发表于 2021-1-25 16:17
本帖最后由 fengchuan 于 2021-1-25 16:19 编辑

从零开始写一个神经网络(第一篇)

​        本系列是根据哔哩哔哩up大野喵渣的系列教程《从零开始写一个神经网络》所做的学习笔记,起初看到这个系列教程是在19年,但是当时由于一些知识不懂,就搁置了。这次已经跟着做完了大部分环节,现在就将自己的理解和课上的代码做成笔记,记录下来~

​        由于都是我自己粗浅的理解,如果想要理解的更详细一些,真的建议大家去看一看这个系列视频,不仅仅是能学到怎么做一个神经网络,在这个过程中,你更能学习到up是怎么思考的,代码是怎么写的,up的代码写的真的太好了!!强烈推荐!!

哔哩哔哩视频地址:https://space.bilibili.com/28496477/channel/detail?cid=75370

本教程全部采用python进行编程

目标

​        训练一个识别手写数字的模型

所需知识

  • python基本语法

准备工作

数据集

数据获取

​        数据集是从THE MNIST DATABASE这个网站上下载的,数据集共包含60,000个例子的训练集、10,000个例子的测试集。此外,网站还介绍了根据这个样本,很多种的学习框架的正确率。

数据格式

​        根据网站的介绍,有四个数据文件,分别为两个数据和两个标签。下面是网站关于数据的介绍,这里我只选取了训练集,测试集同理。

TRAINING SET LABEL FILE (train-labels-idx1-ubyte):

[offset] [type]     [value]     [description]`
`0000   32 bit integer 0x00000801(2049) magic number (MSB first)`
`0004   32 bit integer 60000      number of items`
`0008   unsigned byte  ??        label`
`0009   unsigned byte  ??        label`
`........`
`xxxx   unsigned byte  ??        label
The labels values are 0 to 9.

TRAINING SET IMAGE FILE (train-images-idx3-ubyte):

[offset] [type]     [value]     [description]`
`0000   32 bit integer 0x00000803(2051) magic number`
`0004   32 bit integer 60000      number of images`
`0008   32 bit integer 28        number of rows`
`0012   32 bit integer 28        number of columns`
`0016   unsigned byte  ??        pixel`
`0017   unsigned byte  ??        pixel`
`........`
`xxxx   unsigned byte  ??        pixel

Pixels are organized row-wise. Pixel values are 0 to 255. 0 means background (white), 255 means foreground (black).

​        根据介绍,可以知道文件并不是以图片的形式进行存储的,而是以字节的形式进行存储。在LABEL SET中,0-3字节表示magic number(magic number表示幻数,可以理解为一种标记,但是具体是做什么的我还不太清楚),4-7字节表示数据的大小,在TRAINING SET LABEL中则是60,000,后面每一个字节表示一个标签;在IMAGE SET中,0-3字节表示magic number,4-7字节表示数据的大小,8-11字节和12-15字节分别表示图片所占的行数和列数,即28*28的图片。

​        既然我们已经知道了数据的格式,那么下面就来用代码处理数据吧

数据处理

​        首先我们将数据下载到电脑上,解压之后得到四个文件,我们引用Path这个包进行数据的处理,为什么要引用path这个包呢?通过下面的代码我们可以看出path这个包将目录结构展示的很清楚,路径更加直观的表现出来。

from pathlib import Path
#数据集的路径
dataset_path = Path('./MNIST') #数据集路径
train_img_path = dataset_path/'train-images.idx3-ubyte' #训练集图片路径
train_lab_path = dataset_path/'train-labels.idx1-ubyte' #训练集label路径
test_img_path = dataset_path/'t10k-images.idx3-ubyte' #测试集图片路径
test_lab_path = dataset_path/'t10k-labels.idx1-ubyte' #测试集label路径

​                获取到路径之后,就是数据的读入,这里定义了三个变量 train_num、valid_num和test_num,将数据划分为训练集、验证集和测试集,也就是在原数据的基础上,中间添加了一个验证集,为什么要中间添加一个验证集呢?每一个数据集的作用又是什么呢?等我们把数据处理完之后,我们再来说一说这个问题。

​        要处理数据,我们要知道我们需要那些数据。首先,前面的magic number、数据集的大小和图片的大小其实我们是可以不需要的,我们在代码里直接写死就好。这里引用了struct包进行数据的解包,struct.unpack('>4i',f.read(16))中,'>'表示数据是按照大端存储的,即较低的有效字节存放在较高的存储器地址中,较高的有效字节存放在较低的存储器地址,下面我也放了一个大小端存储的例子,采用大端存储更符合人们的阅读习惯,这里就不详细展开了,如果想要更加深入的了解,请参考我最后面的参考文献。'4'表示读取4个。'i'表示integer。这样我们就把前面用不到的数据都出来了,不需要对这些数据做什么处理。

地址偏移 大端模式 小端模式
0x00 12 78
0x01 34 56
0x02 56 34
0x03 78 12

​        接下来就是读取真正有用的数据,以train image为例,这里用numpy进行了数据处理操作,将读取的数据变成了一个1x784的矩阵,后面我们计算要用到。

import struct
#载入数据集
train_num = 50000 #训练集大小
valid_num = 10000 #验证集大小
test_num = 10000 #测试集大小

with open(train_img_path,'rb') as f:
    struct.unpack('>4i',f.read(16))
    temp_img = np.fromfile(f,dtype=np.uint8).reshape(-1,28*28)
    train_img = temp_img[:train_num]
    valid_img = temp_img[train_num:]

with open(test_img_path,'rb') as f:
    struct.unpack('>4i',f.read(16))
    test_img = np.fromfile(f,dtype=np.uint8).reshape(-1,28*28)

with open(train_lab_path,'rb') as f:
    struct.unpack('>2i',f.read(8))
    temp_lab = np.fromfile(f,dtype=np.uint8)
    train_lab = temp_lab[:train_num]
    valid_lab = temp_lab[train_num:]

with open(test_lab_path,'rb') as f:
    struct.unpack('>2i',f.read(8))
    test_lab = np.fromfile(f,dtype=np.uint8)

​        这样,我们就成功的把数据全部都读取出来了,可以用matplotlib画出来看看数据是什么样子的~

import matplotlib.pyplot as plt
#展示数据集
def show_train(index):
    plt.imshow(train_img[index].reshape(28,28),cmap='gray')
    print('label:{}'.format(train_lab[index]))

def show_valid(index):
    plt.imshow(valid_img[index].reshape(28,28),cmap='gray')
    print('label:{}'.format(valid_lab[index]))

def show_test(index):
    plt.imshow(test_img[index].reshape(28,28),cmap='gray')
    print('label:{}'.format(test_lab[index]))

11.png

​        到这我们就把数据集拿到了,后面就可以从train_img、train_lab中取数据进行后面的运算操作了。然后我们再来看一下刚才留下的问题,问什么要把训练集再分成两份,变成一个测试集和一个验证集,验证集的作用是什么呢?

​        训练集,顾名思义就是用来训练我们最后写好的神经网络框架的数据集,让框架根据训练集的数据更好的调整自己的参数,得到一个对训练集拟合度更高的模型。

​        验证集,就是我们知道标签,只给训练好的框架图片,让他进行识别,验证集不用来调整参数

​        测试集,用来最终测试框架的正确率。

​        举个例子来说比如我们的框架就是一个学生,我们让这个框架做的事情就是学习课本上的知识,训练集就相当于一个课本,我们不断地让他去学习这一个课本,随着学习次数的增加,他对课本的掌握程度肯定会不断提高(当然他的掌握程度提高是我们非常乐意看到的事情),当经过几次的训练之后,我们再去用课本对他进行考试,他的正确率就会变得很高。但是这并不能反映出他学习的真实水平,因为还有一种可能是因为他把整个书本都背诵下来了(这就是发生了过拟合现象),我们再去用这本书考他就没有多大的意义。这时候老师们就发明了小测验,找一个课本上没有出现过的题目,让这个学生来进行回答,这个时候学生是不知道答案的,他需要根据他所学的知识来进行作答,这样作答的结果更能反映他学习的成果。

​        这里的小测验就是相当于验证集,我们知道正确的答案,但是模型不知道,我们需要根据模型给出的答案来进行判断他的学习成果怎么样,但是这个结果也不能作为模型评价好坏的标准。假如参与测验的学生有好几个(对应不同的训练框架)根据你出的题目,每个学生进行作答,可能某个学生恰好很会瞎猜,恰好你出的题目他全都猜对了,在你的主观感觉里这个学生他就是个学习好的学生,但是其实他也只是恰好猜得准。所以我们还需要测试集,也就是在最后再出一个考试,把你的主观情感也排除,你也不知道答案,就让学生去做答,然后和正确答案进行比对,这样才能更减少主观带来的影响。

​        过拟合现象,在我们上述的例子中,就是指同学将课本的知识全部都背诵了下来,对书本的问题回答得非常的好,但是一做测验,就什么都不会了,这就是发生了过拟合现象,并没有掌握真正的脉络和本质。

​        好了,上面就是我对数据处理的一些总结。

​        

参考文献

  1. 大小端 https://blog.csdn.net/lis_12/article/details/52698634
  2. python之struct详解  https://blog.csdn.net/qq_30638831/article/details/80421019
  3. Python使用struct处理二进制(pack和unpack用法 https://blog.csdn.net/jackyzhousales/article/details/78030847
  4. numpy.reshape(-1,1)  https://blog.csdn.net/qq_42804678/article/details/99062431

免费评分

参与人数 8吾爱币 +17 热心值 +7 收起 理由
Wumai + 1 + 1 用心讨论,共获提升!
鸠山一茶 + 1 + 1 用心讨论,共获提升!
coolcalf + 1 + 1 用心讨论,共获提升!
苏紫方璇 + 10 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
fengyuan666 + 1 我很赞同!
1750249993 + 1 + 1 用心讨论,共获提升!
liuqm + 1 + 1 用心讨论,共获提升!
gdp123gd + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Johan_000 发表于 2021-1-26 09:42
这个就是那本神经网络入门那本书上写的东西吧,这个训练真的看脸的,玄学炼丹。而且要实际写出来还是有点麻烦的,当初学着搓了一个结果准确率惨不忍睹。
这个神经网络规模还算小的了,用来学习基本神经网络原理还是不错的。
garfieldlong 发表于 2021-1-25 16:23
coolsnake 发表于 2021-1-25 16:40
king1299 发表于 2021-1-25 16:48
感觉没能理解。。。。脑子不够用
lanshushu 发表于 2021-1-25 16:50
啥也不说就是牛逼
 楼主| fengchuan 发表于 2021-1-25 16:52
king1299 发表于 2021-1-25 16:48
感觉没能理解。。。。脑子不够用

哪里没理解,可以留言我们讨论下
coolcalf 发表于 2021-1-25 17:03
楼主加油
以后时间合适,也学习一下。
孺子牛_Boil 发表于 2021-1-25 17:12
这个真从零开始了 简直胎教
vethenc 发表于 2021-1-25 18:22
写的挺好
ciker_li 发表于 2021-1-25 20:43
不错不错,学习学习
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 02:28

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表