赞
踩
mxnet.nd用法对标numpy库
from mxnet import nd
nd.concat(X, Y ,dim=0)
nd.concat(X, Y, dim=1)
X, Y为两个矩阵nd.concat为连接矩阵,dim表示连接的维度,若原来两个矩阵为(4,3),dim=0就表示 新生成矩阵为(8,3)
dim=1表示 新生成矩阵为(4,6)
y = y + x
这样的算法会新开内存
y += x
而这种算法就可以减少运算的内存开销, 与上面那个式子的含义是一样的都是对y用x进行累加
通过 .asumpy() 用法可以使得nd实例转换为 numpy实例
X.asumpy() 就使得X变为 numpy实例
若果函数为 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
X.asscalar()
将向量X转换成标量,且向量X只能为一维含单个元素的向量
nd.random.normal(0, 1, shape=(3, 4))
是创建⼀个形状为(3,4)的NDArray。它的每个元素都随机采样于均值为0、标准差为1的正态分布。
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)
以下是运用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)
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)
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)
图片来自:动手学深度学习
多层感知机中的隐藏层和输出层都是全连接层,也就是 每一个单元都与上一层所有单元有关联
若我们设计
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) ##初始化-梯度附加-定义网络-损失函数-优化器-训练
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)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。