美文网首页
《动手学深度学习》笔记

《动手学深度学习》笔记

作者: 殇不患_531c | 来源:发表于2020-02-16 17:21 被阅读0次

画一个函数图像:

#以RELU为例
%matplotlib inline
import d2lzh as d2l
from mxnet import autograd, nd

def xyplot(x_vals, y_vals, name):
    d2l.set_figsize(figsize=(5, 2.5))
    d2l.plt.plot(x_vals.asnumpy(), y_vals.asnumpy())
    d2l.plt.xlabel('x')
    d2l.plt.ylabel(name + '(x)')
x = nd.arange(-8.0, 8.0, 0.1)
x.attach_grad()
with autograd.record():
    y = x.relu()
xyplot(x, y, 'relu')

#先对参数attach_grad(),然后with autogard_record():,下面写计算loss的过程,最后对loss做
#backward(),参数的grad就自动在参数这个对象中生成了,调用参数.grad即可

y.backward()
xyplot(x, x.grad, 'grad of relu')
结果: image.png
image.png

画一组features和labels的散点图

import d2lzh
plt.scatter(features[:, 1].asnumpy(), labels.asnumpy(), 1);
image.png

细节:在做loss的时候记得reshape,因为label通常是一个vector,但net的输出经常是一个batch_size*1的矩阵


image.png
def squared_loss(y_hat, y):  # 本函数已保存在d2lzh包中方便以后使用
    return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2

丢弃法:避免过拟合的办法
思想是在计算的时候有一定的几率将部分单元暂时丢弃,使得最后的输出不能总是依赖于个别单元,从而实现正则化(?)

import d2lzh as d2l
from mxnet import autograd, gluon, init, nd
from mxnet.gluon import loss as gloss, nn

def dropout(X, drop_prob):
    assert 0 <= drop_prob <= 1
    keep_prob = 1 - drop_prob
    # 这种情况下把全部元素都丢弃
    if keep_prob == 0:
        return X.zeros_like()
    mask = nd.random.uniform(0, 1, X.shape) < keep_prob
    print(mask)
    return mask * X / keep_prob

def net(X):
    X = X.reshape((-1, num_inputs))
    H1 = (nd.dot(X, W1) + b1).relu()
    if autograd.is_training():  # 只在训练模型时使用丢弃法
        H1 = dropout(H1, drop_prob1)  # 在第一层全连接后添加丢弃层
    H2 = (nd.dot(H1, W2) + b2).relu()
    if autograd.is_training():
        H2 = dropout(H2, drop_prob2)  # 在第二层全连接后添加丢弃层
    return nd.dot(H2, W3) + b3

生成掩码(mask)的办法:将随机生成的标准正态矩阵与0-1数值作比较从而生成0或1的对应矩阵

    mask = nd.random.uniform(0, 1, X.shape) < keep_prob

简洁实现即添加dropout层:

net = nn.Sequential()
net.add(nn.Dense(256, activation="relu"),
        nn.Dropout(drop_prob1),  # 在第一个全连接层后添加丢弃层
        nn.Dense(256, activation="relu"),
        nn.Dropout(drop_prob2),  # 在第二个全连接层后添加丢弃层
        nn.Dense(10))
net.initialize(init.Normal(sigma=0.01))

weigh-decay:避免过拟合的另一个方法
思想是对于绝对值较大的参数值,它们的影响力太大了因而做一定的惩罚,在损失函数上增加norm()
简洁实现:

def fit_and_plot_gluon(wd):
    net = nn.Sequential()
    net.add(nn.Dense(1))
    net.initialize(init.Normal(sigma=1))
    # 对权重参数衰减。权重名称一般是以weight结尾
    trainer_w = gluon.Trainer(net.collect_params('.*weight'), 'sgd',
                              {'learning_rate': lr, 'wd': wd})
    # 不对偏差参数衰减。偏差名称一般是以bias结尾
    trainer_b = gluon.Trainer(net.collect_params('.*bias'), 'sgd',
                              {'learning_rate': lr})
    train_ls, test_ls = [], []
    for _ in range(num_epochs):
        for X, y in train_iter:
            with autograd.record():
                l = loss(net(X), y)
            l.backward()
            # 对两个Trainer实例分别调用step函数,从而分别更新权重和偏差
            trainer_w.step(batch_size)
            trainer_b.step(batch_size)
        train_ls.append(loss(net(train_features),
                             train_labels).mean().asscalar())
        test_ls.append(loss(net(test_features),
                            test_labels).mean().asscalar())
    d2l.semilogy(range(1, num_epochs + 1), train_ls, 'epochs', 'loss',
                 range(1, num_epochs + 1), test_ls, ['train', 'test'])
    print('L2 norm of w:', net[0].weight.data().norm().asscalar())

一般使用模型训练的步骤:

#读取数据
from mxnet.gluon import data as gdata
batch_size = 10
# 将训练数据的特征和标签组合
dataset = gdata.ArrayDataset(features, labels)
# 随机读取小批量
data_iter = gdata.DataLoader(dataset, batch_size, shuffle=True)

#定义模型
from mxnet.gluon import nn
net = nn.Sequential()
net.add(nn.Dense(1))
#初始化
from mxnet import init
net.initialize(init.Normal(sigma=0.01))
#损失函数
from mxnet.gluon import loss as gloss
loss = gloss.L2Loss()  # 平方损失又称L2范数损失
#训练
from mxnet import gluon
trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.03})
num_epochs = 3
for epoch in range(1, num_epochs + 1):
    for X, y in data_iter:
        with autograd.record():
            l = loss(net(X), y)
        l.backward()
        trainer.step(batch_size)
    l = loss(net(features), labels)
    print('epoch %d, loss: %f' % (epoch, l.mean().asnumpy()))

总结一下:读取数据用到gluon中data包的ArrayDataset和DataLoader、模型用了gluon中的nn包中Sequential和Dense、初始化、训练是先拿到trainer再对每个epoch:反复取batch大小的数据做迭代(trainer.step(batch_size)),取完输出一下结果。
注意:这里的step过程中内部对loss做了项数为batch_size的平均,也就是说不需要再在计算loss的时候做平均。如果loss已经做平均了,则应为trainer.step(batch_size)

softmax:
对于简单的情况,softmax是对于一张图片的长宽像素做flatten然后与矩阵相乘加上bias得到输出,再加上softmax函数得到概率:


image.png

上图其中的w的每一列代表一个类别
在softmax问题中就不好用L2Loss做,应该用cross_entropy,因为实际上不需要预测概率值与真实概率值(?)接近,只需要预测结果与真实一样就行了


image.png
其中j就是那个label中标定为真的类别,也就是说loss唯一的项其实是那个label中为真的那一项在模型参数中取log的值,这个值越大也就是预测的越准
例子: image.png

一个数组存着index,在一个数组中的每个子数组存着内容,怎么用index取出对应子数组中的元素值:nd.pick()


image.png

则cross_entropy:

def cross_entropy(y_hat, y):
    return -nd.pick(y_hat, y).log()

相关文章

  • 2022-02-15

    《动手学深度学习》环境搭建教程指南—windows10系统 本文在李沐博士的《动手学深度学习》 — 动手学深度学习...

  • 《动手学深度学习》笔记

    画一个函数图像: 画一组features和labels的散点图 细节:在做loss的时候记得reshape,因为l...

  • 动手学深度学习笔记(一)

    一、使用NDArray来处理数据 首先从 MXNet 导入ndarray模块。nd是ndarray的缩写形式。fr...

  • 动手学深度学习笔记(二)

    从零开始写多层感知机 多层感知机 本节中,我们将以多层感知机(multilayer perceptron,简称 M...

  • mxnet:如何对多维NDArray按维度操作?

    参考: 动手学深度学习第3.6.3章节.

  • 动手学深度学习

    线性回归 一.主要内容包括: 1.线性回归的基本要素 2.线性回归模型从零开始的实现 3.线性回归模型使用pyto...

  • 使用PyTorch动手实现线性回归

    本系列文章是笔者在学习《动手学深度学习》这本书的学习笔记,希望大家多多指教~ 学习过程中有参考到一些有用的资源链接...

  • 2019-11-29 复习深度学习基础

    1.吴恩达老师机器学习教程中文笔记-在线版2.《动手学深度学习》 关键词:正向传播 反向传播 优化算法 经典网络

  • 线性回归的实现

    选自 李沐 《动手学深度学习》 第三章。 3.3 线性回归的简洁实现 随着深度学习框架的发展,开发深度学习应用变得...

  • 《动手学深度学习》PDF

    用户下载说明: 电子版仅供预览,下载后24小时内务必删除,支持正版,喜欢的请购买正版书籍 《动手学深度学习》PDF...

网友评论

      本文标题:《动手学深度学习》笔记

      本文链接:https://www.haomeiwen.com/subject/iegpfhtx.html