2020.10.3-2020.10.9(手写数字体识别)

简单的回归问题

加入噪声后:

    y=w*x+b+\varepsilon

    \varepsilon ~N(0.01,1)

     loss=(WX+b-y)^2——这是一个矩阵形式

    loss=\sum\nolimits_{i}(w*x_{i} +b-y_{i} )^2

    Minimize loss

    w'*x+b'\rightarrow y

例:y=1.477*x+0.089+\varepsilon


points是一系列的x和y的组合,对每一个点进行循环迭代。然后去每个点的x和y值,用wx+b预测的值和实际值y相加求出平方和。最后对totalError求一个平均。



接着计算梯度信息。由loss function,然后分别对W和b进行求导。因为代码中将导数进行了累加,所以我们要进行average,除以N

对梯度进行迭代。num_iterations为迭代次数。迭代完之后,将最后一组的w,b返回,就是我们要求的最优解


这是用numpy生成的100组x和y(这里只截了一部分)


这是总的函数,先把points用numpy导入进来,然后用gradient_descent_runner跑100个epoch


最后的结果可以看出b和w与真实的值很接近,说明拟合的很好

手写数字体——MNIST

0-9十个数字,对应10个类别,每一类有7000张照片,一共有70k张。如果全部用于训练,则会导致过拟合。即可能只是记住了这70k张照片,但是对于新的数据集来说,识别效果并不好。所以我们将70k张照片,60k用于训练,10k用于测试。

因此将矩阵打平



运用了三层网络迭代的方式,H3做为输出层。又由于如果传统的123来进行编码的话,会存在1<2<3的大小关系,而在标签分类中,不同类之间并没有什么相关性,所以引入one-hot编码的方式贴标签。


loss function的计算,引入欧氏距离,用预测值与真实值相减,求平方。这种方法对于手写数字体识别来说,效果可能并不太好,因为字体可能倾斜或者扭曲,这些非线性因素必须考虑,所以引入非线性参数(Non-Linear Factor)

这里的ReLU函数,可以看到,随着输入的变化,输出变化也相同。

接下来用梯度下降,找到一组w,b,使得对于任意的x,都有\sum\nolimits(pred-Y)^2最小,这就是loss function最小

max与argmax(pred)区别:max=0.8,则armax(pred)=1(对于概率最大的标签号)。




首先,导入我们需要的工具包。

    nn 用于神经网络的相关工作

    optim 用于优化的一个工具包

    torchvision 为了可视化的一个工具包

    utils 里面有着几个绘图函数,plot_curve——绘制下降曲线,plot_image——绘制图片,显示6张图片,按照两行三列摆放。one_hot,用one_hot的编码方式贴标签。如果一个标签直接是索引并不是一维张量的话,就可以调用这个函数,先用zero初始化好这个矩阵,然后在指定的维度上面根据索引填充1就好了,那必然未被填充到的肯定是默认值,就是为0。

加载数据集


加载数据集,给一个mnist_data的路径。这里的数据用于训练,数据从网上下载下来。接着读取数据时,讲numpy数据类型转化成tensor,作为pytorch的一个数据载体,并进行正则化,使得让数据在0的附近均匀分布。同理,后半段数据作为测试数据,进行相同的数据类型转换。

batch_size表示一次性加载的图片数量,shuffle表示是否对图片进行打散

对训练的数据进行迭代,被next函数不断调用返回下一个值。

输出结果范围在0的左右附近,总共读取了512张图片

这是训练匹配的结果。一般都会是正确匹配的。

创建网络


首先初始化网络,一共有三层网络,用nn.Linear函数创建。28*28和10作为第一层输入和最后一次输出是由题目确定的,其他数据都是自己随意确定的。

接着创建计算的过程 def forward(self,x):

x:[b,1,28,28]

其中对每层加入非线性单元F.relu()。

训练阶段



首先,我们对数据集会迭代3次,然后里面那层,相当于对一个batch(512张图片)迭代1遍,可以看到结果x和y分别是512张图片  x:[b, 1, 28, 28], y: [512]

接着进行网络的初始化

为了得到输出,将输入x通过这个网络

这是一个全连接神经网络,它只接受2维的tensor,而我们的x是4维的,所以在通过网络之前,先要做一个mapping。

其中x.size(0)是一个batch512,就是将x映射成一个(b,784)的矩阵。然后通过net,将x映射成=> [b, 10]

然后将真实的y,通过one-hot转化为[b,10],这样和x映射结果都是[b,10]。我们希望out和y_onehot越接近越好。

mse(mean square error)——均方差

所用我们用.mse_loss来计算out和y_onehot之间的均方差,得到 loss。

然后通过loss.backward()函数计算loss的梯度。

为了能够更新梯度,我们使用了optimizer的优化器,net.parameters()返回的是[w1, b1, w2, b2, w3, b3],同时我们还要设置学习率lr=0.01,以及动量momentum=0.9,便于更好的优化。


完整的过程就是,先对梯度进行清零,然后计算梯度,最后更新梯度。然后不停的循环,最终循环结束后,会得到一个较好的[w1, b1, w2, b2, w3, b3]。

epoch表示训练总共有60k张图片,一个batch_size是512。而batch_idx表示batch的缩索引。batch_idx=epoch/batch_size,大约是117次。而这里每10个打印一次,所以一轮打印大约12次。


从结果看,经过对一个batch循环一次后,在对epoch循环三次后,loss明显得到了下降。

为了可视化,将loss数值取出,通过plot_curve绘制成图像。由于loss本身是tensor类型,而为了取出将其转化成numpy类型。

可视化之后,得到了下降误差下降曲线。

测试阶段


进入测试阶段,前半部分和训练阶段类似,将输入x做一个mapping,将它通过net网络输出。即将4维的数据转换成2维的[b,10]。预测值pred就是对应的正确的标签。

最后输出的结果。



CNN+mnist手写数字体识别

引入库函数

预设超参数


加载数据集

这里我们使用dataloader迭代器来加载数据集(迭代器的作用可以减少内存的占用)

将mnist训练集和测试集下载到文件夹data中对数据进行变化,包括转为tensor数据类型,以及为了保证训练集测试集的独立同分布,数据规范化到正态分布;数据分批量存储,顺序打乱,方便后续训练。

设计CNN网络

一个简单的卷积神经网络的结构,一般包括:

卷积层Conv:通过卷积核提取图像特征,得到feature map

池化层Pool:利用卷积核对feature map 降采样,减少尺寸。最大池化层就是取滑动窗口内最大的像素,而平均池化层就是取滑动窗口内平均像素结果。

全连接层:多个linear model + 激活函数 eg:ReLU。

这样就构成了一个基本的CNN了,但是,为了提高模型的泛化能力,进行了:

batch normalization:简单来说就是将上一层的加权求和的所有输出结果再批量归一化(标准正态分布),然后输入一个线性模型,然后再连接到激活函数。

DropOut:在全连接层中,我们通过设定概率随机的让这一层的某些权重为0,相当于神经元无效。

训练前准备

定义模型优化器:输入模型参数,定义初始学习率

定义学习率调度器:输入包装的模型,定义学习率衰减周期step_size,gamma为乘法的衰减因子

在官网上的解释。如果初始学习率lr = 0.05,衰减周期step_size为30,衰减乘法因子gamma=0.01# Assuming optimizer uses lr = 0.05 for all groups

# >>> # lr = 0.05                  if epoch < 30

# >>> # lr = 0.005                if 30 <= epoch < 60

# >>> # lr = 0.0005              if 60 <= epoch < 90

训练模块

把训练模块封装起来,便于多次调用

_model.train()——将模式调成训练模式

_lr_scheduler.step()——设置学习率调度器准备开始更新

预测模块

运行

结果

这里只跑了两个epoch,训练达到一定次数,泛化能力会增强,但是训练过度后,泛化能力会下降(过拟合)。所以,要合理制定epoch。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352