当前位置:   article > 正文

Task01:线性回归;Softmax与分类模型、多层感知机_softmax分类器定义多层感知器分类器卷积神经网络分类器分别比较三种方法优缺点,损

softmax分类器定义多层感知器分类器卷积神经网络分类器分别比较三种方法优缺点,损

一、mxnet相关函数用法

mxnet.nd用法对标numpy库

(1) nd.concat

from mxnet import nd
nd.concat(X, Y ,dim=0)
nd.concat(X, Y, dim=1)
  • 1
  • 2
  • 3

X, Y为两个矩阵nd.concat为连接矩阵,dim表示连接的维度,若原来两个矩阵为(4,3),dim=0就表示 新生成矩阵为(8,3)
dim=1表示 新生成矩阵为(4,6)

(2) y += x

y = y + x
这样的算法会新开内存
y += x
而这种算法就可以减少运算的内存开销, 与上面那个式子的含义是一样的都是对y用x进行累加

(3) x.aumpy()

通过 .asumpy() 用法可以使得nd实例转换为 numpy实例
X.asumpy() 就使得X变为 numpy实例

(4) y.backward() xu 修正

若果函数为 y = 2 * x
先设定x
x = nd.array([2])
再调⽤attach_grad函数来申请存储梯度所需要的内存
x.attcach_grad()
调⽤record函数来要求MXNet记录与求梯度有关的计算
with autograd.record():
y = 2 * x
y.backward()则是对其进行反向传播算梯度
x.grad 就是 梯度的值
注意:要先对y进行y.backward(), 才会有x.grad

(5)x.asscalar()

X.asscalar()
将向量X转换成标量,且向量X只能为一维含单个元素的向量

(6)nd.random.normal(0, 1, shape=)

nd.random.normal(0, 1, shape=(3, 4))
是创建⼀个形状为(3,4)的NDArray。它的每个元素都随机采样于均值为0、标准差为1的正态分布。

(7) 查阅文档

http://mxnet.apache.org/ 访问MXNet网站,点击网页顶部的下拉菜单“API”可查阅各个前端语言的接口。此外,也可以在网页右上方含“Search”字样的搜索框中直接搜索函数或类名称。

二、线性回归

线性回归输出是⼀个连续值,因此适⽤于回归问题。回归问题在实际中很常见,如预测房屋价格、气温、销售额等连续值的问题。
简单的来说 就是一个 多元多次方程 , 每一个元 代表一种特征。
我们举个拿房价模型举个例子就是 假设 y(房价) = w1x1(第一种特征,面积) + w2x2(第二种特征,房龄) + b
也就是我们假设,房价可能受 房屋面积和 房龄 的影响, w1 ,w2 都为系数,也就是影响程度,b表示偏差

然后 我们手上有一组 真实的数据集(包含房价,面积和房龄),我们将每组的面积和房龄代入到我们设定的模型当中,得出y_hat(也就是预测值)
y_hat(i)(预测值) = x(i)1 w1 + x(i)2 w2 + b
然后 对 y_hat 和 y(真实的房价,我们也叫做标签)进行误差估计,
这时候,我们会引入 损失函数,来代表 误差的大小, 这次我们使用平方误差函数
误差 = 0.5 * (y - y_hat) ** 2
最后对所有误差进行加总 然后除以 样本个数n
我们最终的目的就是希望通过不变改变 w1, w2以及 b的值 ,来使得 这个误差最小
这样我们就可以得到一个 置信度比较高的房价模型, 对其他房子的价值进行估计。

简单看来 我们这个就像是 一组 多元多次方程 ,可以直接用公式求解。然而很多情况 我们并没有办法求解,所以这里我们又引入一个 **随机梯度下降(批量,小批量,单个)**的方法 来求近似解,就是通过多次对 系数值的 迭代使其逼近最优解。
也就是对 每个方程进行求导,然后让系数值往 导数值相反的方向 (负梯度) 进行一定大小的缩减,最终使其逼近极值点。(这里会有局部最优,也就是有多个极值点的情况,涉及到凸优化,不展开)

注意:这里我们推荐对标签和 特征值都放到矩阵中, 进行矩阵运算, 会大大加快运算速度

引用来源:动手学深度学习
图片引用来源:动手学深度学习

以下是从零实现线性回归:

%matplotlib inline
from IPython import display
from matplotlib import pyplot as plt
from mxnet import autograd, nd
import random


num_inputs = 2
num_examples = 1000
true_w = nd.array([[2],[-3.4]])
true_b = 4.2
features = nd.random.normal(loc=0, scale=1, shape=(num_examples, num_inputs))  ##生成随机特征
labels = nd.dot(features, true_w)  + true_b ##生成线性标签
labels += nd.random.normal(scale=0.01, shape=labels.shape) ##在线性标签上加上正态分布的随机数,使其随机浮动更贴合实际

def data_iter(batch_size, features, labels):    ##生成一个迭代器, 每次获取batch_size大小featurs 和对应的标签值
    num_examples = len(features)
    indices = list(range(num_examples))
    random.shuffle(indices) # 样本的读取顺序是随机的
    for i in range(0, num_examples, batch_size):
        j = nd.array(indices[i: min(i + batch_size, num_examples)])
        yield features.take(j), labels.take(j)

def linreg(X, w, b): ## 根据给定的featurs x,  系数w ,b  ,返回预测值y_hat
    return nd.dot(X, w) + b
def squared_loss(y_hat, y):  ##返回 y_hat(预测值)与标签y 平方损失函数的值
    return 0.5 * (y_hat - y.reshape(y_hat.shape)) ** 2 
def sgd(params, lr, batch_size): # 根据上一轮给出的系数组[w,b] , 用learning_rate 和 batch_size 进行迭代更新
    for param in params:
        param[:] = param - lr * param.grad / batch_size  ##新的 w,b = 原来的w,b - 学习率 * 此时w,b的梯度/ 批量大小

lr = 0.03
num_epochs = 3
net = linreg
loss = squared_loss
batch_size = 10
##初始化w,b 值
w = nd.random.normal(scale=0.01, shape=(num_inputs, 1))
b = nd.zeros(shape=(1,))  ##广播机制
##创建梯度  重要
w.attach_grad()
b.attach_grad()

for epoch in epochs:
	for x,y in data_iter(batch_size, features, labels):
		with autograd.record():   ##重要 记录每次梯度
			l = loss(net(x, w, b), y)
		l.backward()
		sgd([w, b], lr, batch_size)
print(w, b)	
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

以下是运用pytorch实现线性回归:

import torch.utils.data as Data
from torch.nn import init
import torch
from torch import nn
import numpy as np
import torch.optim as optim


num_inputs = 2
num_examples = 1000
batch_size = 10

true_w = [2, -3.4]
true_b = 4.2

features = torch.tensor(np.random.normal(0, 1, (num_examples, num_inputs)), dtype=torch.float)
labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b
labels += torch.tensor(np.random.normal(0, 0.01, size=labels.size()), dtype=torch.float)


dataset = Data.TensorDataset(features, labels)
data_iter = Data.DataLoader(
    dataset = dataset,
    batch_size = batch_size,
    shuffle = True,
    num_workers=2)
net = nn.Sequential(
    nn.Linear(num_inputs,1))
loss = nn.MSELoss()
optimizer = optim.SGD(net.parameters(), lr=0.03)
init.normal_(net[0].weight, mean=0.0, std=0.01)
init.constant_(net[0].bias, val=0.0)
num_epochs = 3
for epoch in range(num_epochs):
    for x,y in data_iter:
        output = net(x)
        l = loss(output, y.reshape(output.shape))
        l.backward()
        optimizer.step()
        optimizer.zero_grad()
    print('epoch %d, loss: %f' % (epoch, l.item()))
        

dense = net[0]
print(true_w, dense.weight.data)
print(true_b, dense.bias.data)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

三、Softmax与分类模型

softmax用于对离散值的预测,一般来说也就是分类问题, 比如判断一个图片是否为猫,是为0,否为1
这就是很简单的离散值输出判别,只有0,1 2个输出值
当然我们可以多有N个输出值判别,可以进行多分类问题

在这里插入图片描述
图片来源:动手学深度学习

就以上图举例, 一般的我们的输出层会是概率, 以此来判别每组特征是属于标签1, 标签2, 标签3哪个概率更大,为了使得输出值是概率,且总和为1,我们对输出值O1,O2,O3再嵌套一个新函数,进行处理,也就是softmax函数
y1 = exp^o1 / (exp^o1 + exp^o2 + exp^o3)
y2 = exp^o2 / (exp^o1 + exp^o2 + exp^o3)
y3 = exp^o3 / (exp^o1 + exp^o2 + exp^o3)
然后我们根据y1,y2,y3中最大值进行输出

当然除了最后的输出函数进行处理了, 分类问题的另一个与上面线性回归问题大不同点,在于损失函数的选择,在分类问题上我们使用交叉熵损失函数(以下公式仅限于0,1问题),仅考虑真实值的判别情况(若样本真,预测假,则会施加一个较大的惩罚,偏离越大,惩罚越高;若样本真,预测真,则无惩罚)
在这里插入图片描述
fashion-mnist代码从0实现: 对一张图片进行识别分类,有10种判别可能
在这里插入图片描述

import torch
import torchvision
import numpy as np
import sys
sys.path.append("/home/kesci/input")
import d2lzh1981 as d2l

batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, root='/home/kesci/input/FashionMNIST2065')

num_inputs = 28*28
num_outputs = 10  ## 10种输出值
##w,b初始化
w = torch.tensor(np.random.normal(0, 0.01, (num_inputs, num_outputs), dtype=torch.float))
b = torch.zeros(num_outputs, dtype=torch.float)
##梯度附加
w.requires_grad_(requires_grad=True)
b.requires_grad_(requires_grad=True)

def softmax(x):
	x_exp = x.exp()
	sum = x_exp.sum(dim=1, keepdim=True)
	return x_exp / sum
def net(x):
	return softmax(torch.mm(x.view(-1, num_inputs), w) + b)
##损失函数
def cross_entropy(y_hat, y):
    return - torch.log(y_hat.gather(1, y.view(-1, 1)))
##准确率
def evaluate_accuracy(data_iter, net):
    acc_sum, n = 0.0, 0
    for X, y in data_iter:
        acc_sum += (net(X).argmax(dim=1) == y).float().sum().item()
        n += y.shape[0]
    return acc_sum / n

num_epochs, lr = 5, 0.1

# 本函数已保存在d2lzh_pytorch包中方便以后使用
def train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size,
              params=None, lr=None, optimizer=None):
    for epoch in range(num_epochs):
        train_l_sum, train_acc_sum, n = 0.0, 0.0, 0
        for X, y in train_iter:
            y_hat = net(X)
            l = loss(y_hat, y).sum()
            
            # 梯度清零
            if optimizer is not None:
                optimizer.zero_grad()
            elif params is not None and params[0].grad is not None:
                for param in params:
                    param.grad.data.zero_()
            
            l.backward()
            if optimizer is None:
                d2l.sgd(params, lr, batch_size)
            else:
                optimizer.step() 
            
            
            train_l_sum += l.item()
            train_acc_sum += (y_hat.argmax(dim=1) == y).sum().item()
            n += y.shape[0]
        test_acc = evaluate_accuracy(test_iter, net)
        print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f'
              % (epoch + 1, train_l_sum / n, train_acc_sum / n, test_acc))

train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs, batch_size, [W, b], lr)
		
	
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

softmax 的简洁实现:

import torch
from torch import nn
from torch.nn import init
import numpy as np
import sys
sys.path.append("/home/kesci/input")
import d2lzh1981 as d2l

batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, root='/home/kesci/input/FashionMNIST2065')

num_inputs = 784
num_outputs = 10



from collections import OrderedDict
net = nn.Sequential(
        OrderedDict([
           ('flatten', nn.Flatten()),
           ('linear', nn.Linear(num_inputs, num_outputs))]) 
        )

init.normal_(net.linear.weight, mean=0, std=0.01)
init.constant_(net.linear.bias, val=0)

loss = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.1)


num_epochs = 5
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, None, None, optimizer)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

四、多层感知器

在这里插入图片描述
图片来自:动手学深度学习
多层感知机中的隐藏层和输出层都是全连接层,也就是 每一个单元都与上一层所有单元有关联
若我们设计
o = ah + c
h = wx + b
联立 o = awx + ab + c
无论添加多少层都是 关于单个x的函数, aw为系数, ab+c 恒为常数
值得注意的是,在多层感知器中,即便再添加更多的隐藏层,以上设计依然只能与仅含输出层的单层神经网络等价。
所以此时我们需要引入其他非线性函数进行变换,我们称之为 激活函数,现在我们一般引入relu函数
ReLU(x) = max(x; 0)
在这里插入图片描述
其他的激活函数还有,
在这里插入图片描述
在这里插入图片描述

总结:多层感知机就是含有⾄少⼀个隐藏层的由全连接层组成的神经⽹络,且每个隐藏层的输出通过激
活函数进⾏变换。一般使用relu函数,用于分类器时,sigmoid函数效果不错。但由于梯度消失问题,sigmoid和tanh函数要慎用

多层感知机从零开始实现

import torch
import numpy as np
import sys
sys.path.append("/home/kesci/input")
import d2lzh1981 as d2l
##初始化参数
num_inputs, num_outputs, num_hiddens = 784, 10, 256
w1 = torch.tensor(np.random.normal(0, 0.01, (num_inputs, num_hiddens)), dtype=torch.float)
b1 = torch.zeros(num_hiddens, dtype=torch.float)
w2 = torch.tensor(np.random.normal(0, 0.01, (num_hiddens, num_outputs)), dtype=torch.float)
b2 = torch.zeros(num_outputs, dtype=torch.float)
##梯度附加
params = [w1, b1, w2, b2]
for i in params:
	i.requires_grad_(requires_grad=True)
## relu激活函数
def relu(x):
	return torch.max(x, other = torch.tensor(0.0))
## 定义网络
def net(x):
	x = x.view(-1, num_inputs)
	a = torch.matmul(x, w1) + b1
	b = relu(a)
	c = torch.matmul(b, w2) + b2
##损失函数
loss = torch.nn.CrossEntropyLoss()
##训练
num_epochs, lr = 5, 100.0

def train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, params=None, lr=None, optimizer=None):
	for epoch in range(num_epochs):
		train_l_sum, train_acc_sum, n = 0.0, 0.0, 0
		for x,y in train_iter:
			y_hat = net(x)
			l = loss(y_hat, y).sum()
			##梯度清零
			if optimizer is not None:
				optimizer.zero_grad()
			elif params is not None and params[0].grad is not None:
				for param in params:
					param.grad.data.zero_()
			l.backward()
			if optimizer is None:
				d2l.sgd(params, lr, batch_size)
			else:
				optimizer.step()
			
			train_l_sum += l.item()
			train_acc_sum +=  (y_hat.argmax(dim=1) == y).sum().item()
             n += y.shape[0]
         test_acc = evaluate_accuracy(test_iter, net)
         print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f'
               % (epoch + 1, train_l_sum / n, train_acc_sum / n, test_acc))

train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, params, lr)

##初始化-梯度附加-定义网络-损失函数-优化器-训练

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

pytorch简化实现

num_inputs, num_outputs, num_hiddens = 784, 10, 256
    
net = nn.Sequential(
				nn.Flatten(),
				nn.Linear(num_inputs, num_hiddens),
				nn.Relu(),
				nn.Linear(num_hiddens, num_outputs))
    
for param in net.paramters():
	init.normal_(params, mean=0, std=0.01)

batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size,root='/home/kesci/input/FashionMNIST2065')
loss = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.5)
num_epoch = 5

def train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size,  params=None, lr=None, optimizer=None):
	for epoch in range(num_epochs):
		train_l_sum, train_acc_sum, n = 0.0, 0.0, 0
		for x,y in train_iter:
			y_hat = net(x)
			l = loss(y_hat, y).sum()

			if optimizer is not None:
				optimizer.zero_grad()
			elif params is not None and params[0].grad is not None:
				for param in params:
                     param.grad.data.zero_()
            
            l.backward()
            if optimizer is None:
				d2l.sgd(params, lr, batch_size)
			else:
				optimizer.step()
			
			train_l_sum += l.item()
			train_acc_sum +=  (y_hat.argmax(dim=1) == y).sum().item()
             n += y.shape[0]
         test_acc = evaluate_accuracy(test_iter, net)
         print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f'
               % (epoch + 1, train_l_sum / n, train_acc_sum / n, test_acc))

train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, None, None, optimizer)
		
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/151630
推荐阅读
相关标签
  

闽ICP备14008679号