当前位置: 首页 > news >正文

软件公司网站设计冠辰网站

软件公司网站设计,冠辰网站,评论插件wordpress,小公司没网站#x1f468;‍#x1f393;作者简介#xff1a;一位即将上大四#xff0c;正专攻机器学习的保研er #x1f30c;上期文章#xff1a;机器学习深度学习——循环神经网络RNN #x1f4da;订阅专栏#xff1a;机器学习深度学习 希望文章对你们有所帮… ‍作者简介一位即将上大四正专攻机器学习的保研er 上期文章机器学习深度学习——循环神经网络RNN 订阅专栏机器学习深度学习 希望文章对你们有所帮助 RNN的从零开始实现与简洁实现 RNN的从零开始实现读取数据集独热编码初始化模型参数循环神经网络模型返回初始化隐状态计算隐状态和输出包装检查 预测梯度裁剪训练小结 RNN的简洁实现读取数据集定义模型训练与预测小结 RNN的从零开始实现 读取数据集 我们将在之前所说的《时光机器》数据集上训练先读取数据集 import math import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2lbatch_size, num_steps 32, 35 train_iter, vocab d2l.load_data_time_machine(batch_size, num_steps)独热编码 回想一下在train_iter中每个词元都表示为一个数字索引将这些索引直接输入神经网络可能会使学习变得困难。我们通常将每个词元表示为更具表现力的特征向量。而之前讲过的独热编码就可以使用。 简言之将每个索引映射为相互不同的单位向量 假设词表中不同词元的数目为N也就是len(vocab)词元索引范围为0~N-1。若词元的索引是整数i 那么我们将创建一个长度为N的全0向量再将第i处的元素位置置1。 例如索引为0和2的独热向量分别为 print(F.one_hot(torch.tensor([0, 2]), len(vocab)))运行结果 tensor([[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) 我们每次采样的小批量数据形状是二维张量批量大小时间步数。而我们的one_hot函数会将这样的小批量数据转换为三维向量最后一个维度为词表大小N。我们也经常转换输入的维度以便获得形状为 时间步数批量大小词表大小的输出。 这将使我们能够更方便地通过最外层的维度 一步一步地更新小批量数据的隐状态。例如 X torch.arange(10).reshape((2, 5)) print(F.one_hot(X.T, 28).shape)输出结果 torch.Size([5, 2, 28]) 初始化模型参数 需要注意隐藏单元数num_hiddens是一个可调的超参数。 当训练语言模型时输入和输出来自相同的词表。 因此它们具有相同的维度即词表的大小。 def get_params(vocab_size, num_hiddens, device):num_inputs num_outputs vocab_sizedef normal(shape):return torch.randn(sizeshape, devicedevice) * 0.01# 隐藏层参数W_xh normal((num_inputs, num_hiddens))W_hh normal((num_hiddens, num_hiddens))b_h torch.zeros(num_hiddens, devicedevice)# 输出层参数W_hq normal((num_hiddens, num_outputs))b_q torch.zeros(num_outputs, devicedevice)# 附加梯度params [W_xh, W_hh, b_h, W_hq, b_q]for param in params:param.requires_grad_(True)return params循环神经网络模型 返回初始化隐状态 init_rnn_state在初始化时返回隐状态。这个函数的返回是一个张量张量全用0填充 形状为批量大小隐藏单元数。 def init_rnn_state(batch_size, num_hiddens, device):return (torch.zeros((batch_size, num_hiddens), devicedevice), )计算隐状态和输出 rnn函数定义了如何在一个时间步内计算隐状态和输出。循环神经网络模型通过inputs最外层的维度实现循环以便逐时间步更新小批量数据的隐状态H。这里使用tanh函数作为激活函数 def rnn(inputs, state, params):# inputs的形状(时间步数量批量大小词表大小)W_xh, W_hh, b_h, W_hq, b_q paramsH, stateoutputs []# X的形状(批量大小词表大小)for X in inputs:H torch.tanh(torch.mm(X, W_xh) torch.mm(H, W_hh) b_h)Y torch.mm(H, W_hq) b_qoutputs.append(Y)return torch.cat(outputs, dim0), (H,)包装 定义了所有需要的函数之后接下来我们创建一个类来包装这些函数 并存储从零开始实现的循环神经网络模型的参数。 class RNNModelScratch: #save从零开始实现的循环神经网络模型def __init__(self, vocab_size, num_hiddens, device,get_params, init_state, forward_fn):self.vocab_size, self.num_hiddens vocab_size, num_hiddensself.params get_params(vocab_size, num_hiddens, device)self.init_state, self.forward_fn init_state, forward_fndef __call__(self, X, state):X F.one_hot(X.T, self.vocab_size).type(torch.float32)return self.forward_fn(X, state, self.params)def begin_state(self, batch_size, device):return self.init_state(batch_size, self.num_hiddens, device)检查 检查输出是否具有正确的形状隐状态的维数是否保持不变 num_hiddens 512 net RNNModelScratch(len(vocab), num_hiddens, d2l.try_gpu(), get_params,init_rnn_state, rnn) state net.begin_state(X.shape[0], d2l.try_gpu()) Y, new_state net(X.to(d2l.try_gpu()), state) print(Y.shape, len(new_state), new_state[0].shape)运行结果 torch.Size([10, 28]) 1 torch.Size([2, 512]) 输出形状是时间步数×批量大小词表大小隐状态形状保持不变即批量大小隐藏单元数。 预测 首先定义一个预测函数来生成prefix之后的新字符prefix是一个用户提供的包含多个字符的字符串。 在循环遍历prefix中的开始字符时 我们不断地将隐状态传递到下一个时间步但是不生成任何输出这叫作预热期因为这个期间的模型会自我更新隐状态但是不会进行预测。等到预热期结束后开始预测字符并输出。 def predict_ch8(prefix, num_preds, net, vocab, device): #save在prefix后面生成新字符state net.begin_state(batch_size1, devicedevice)outputs [vocab[prefix[0]]]get_input lambda: torch.tensor([outputs[-1]], devicedevice).reshape((1, 1))for y in prefix[1:]: # 预热期_, state net(get_input(), state)outputs.append(vocab[y])for _ in range(num_preds): # 预测num_preds步y, state net(get_input(), state)outputs.append(int(y.argmax(dim1).reshape(1)))return .join([vocab.idx_to_token[i] for i in outputs])我们指定前缀prefix为time traveller基于这个前缀生成后序10个连续字符代码如下 print(predict_ch8(time traveller , 10, net, vocab, d2l.try_gpu()))因为还没有训练网络所以会生成奇怪的结果 time traveller srbmtd srb 梯度裁剪 一个长度为T的序列我们在迭代计算这T个时间步上的梯度将会在反向传播过程中产生长度为O(T)的矩阵乘法链。T太大就会数值不稳定可能会造成梯度爆炸或梯度消失。 我们的解决方案是将梯度投影回给定半径例如θ的球来裁剪梯度g g ← m i n ( 1 , θ ∣ ∣ g ∣ ∣ ) g g←min(1,\frac{θ}{||g||})g g←min(1,∣∣g∣∣θ​)g 这样做梯度范数永远不会超过θ并且更新后的梯度完全和g原始方向对其。 梯度裁剪提供了一个快速修复梯度爆炸的方法虽然它并不能完全解决问题无法应对梯度消失但它是众多有效的技术之一。 下面定义一个函数来裁剪模型可能是从零开始实现的模型可能是API构建的模型的梯度 def grad_clipping(net, theta): #save裁剪梯度if isinstance(net, nn.Module): # 高级API构建的模型params [p for p in net.parameters() if p.requires_grad]else: # 从零开始实现的模型params net.paramsnorm torch.sqrt(sum(torch.sum((p.grad ** 2)) for p in params))if norm theta:for param in params:param.grad[:] * theta / norm训练 在训练之前我们依旧是定义一个函数在一个迭代周期内训练模型这与之前的有以下不同 1、序列数据的不同采样方法随机采样和顺序分区将导致隐状态初始化的差异。 2、我们在更新模型参数之前裁剪梯度。 这样的操作的目的是即使训练过程中某个点上发生了梯度爆炸也能保证模型不会发散。 3、我们使用困惑度来评价模型确保了不同长度的序列具有可比性。 当使用顺序分区时我们只在每个迭代周期的开始位置初始化隐状态。由于下一个小批量数据中的第i个子序列样本与当前第i个子序列样本相邻因此当前小批量数据最后一个样本的隐状态将用于初始化下一个小批量数据第一个样本的隐状态。 这样存储在隐状态中的序列的历史信息可以在一个迭代周期内流经相邻的子序列。 但是在任何一点隐状态的计算都会依赖前一个迭代周期中前面所有的小批量数据梯度计算就会很复杂。要降低计算量我们需要在处理任何一个小批量数据前分离梯度使得隐状态的梯度计算总是限制在一个小批量数据的时间步内。 当使用随机抽样时因为每个样本都是在一个随机位置抽样的因此需要为每个迭代周期重新初始化隐状态。 剩下的部分都和之前的思想相同 #save def train_epoch_ch8(net, train_iter, loss, updater, device, use_random_iter):训练网络一个迭代周期state, timer None, d2l.Timer()metric d2l.Accumulator(2) # 训练损失之和,词元数量for X, Y in train_iter:if state is None or use_random_iter:# 在第一次迭代或使用随机抽样时初始化statestate net.begin_state(batch_sizeX.shape[0], devicedevice)else:if isinstance(net, nn.Module) and not isinstance(state, tuple):# state对于nn.GRU是个张量state.detach_()else:# state对于nn.LSTM或对于我们从零开始实现的模型是个张量for s in state:s.detach_()y Y.T.reshape(-1)X, y X.to(device), y.to(device)y_hat, state net(X, state)l loss(y_hat, y.long()).mean()if isinstance(updater, torch.optim.Optimizer):updater.zero_grad()l.backward()grad_clipping(net, 1)updater.step()else:l.backward()grad_clipping(net, 1)# 因为已经调用了mean函数updater(batch_size1)metric.add(l * y.numel(), y.numel())return math.exp(metric[0] / metric[1]), metric[1] / timer.stop()接下来我们定义RNN模型的训练函数 #save def train_ch8(net, train_iter, vocab, lr, num_epochs, device,use_random_iterFalse):训练模型loss nn.CrossEntropyLoss()animator d2l.Animator(xlabelepoch, ylabelperplexity,legend[train], xlim[10, num_epochs])# 初始化if isinstance(net, nn.Module):updater torch.optim.SGD(net.parameters(), lr)else:updater lambda batch_size: d2l.sgd(net.params, lr, batch_size)predict lambda prefix: predict_ch8(prefix, 50, net, vocab, device)# 训练和预测for epoch in range(num_epochs):ppl, speed train_epoch_ch8(net, train_iter, loss, updater, device, use_random_iter)if (epoch 1) % 10 0:print(predict(time traveller))animator.add(epoch 1, [ppl])print(f困惑度 {ppl:.1f}, {speed:.1f} 词元/秒 {str(device)})print(predict(time traveller))print(predict(traveller))现在我们训练循环神经网络模型。因为我们在数据集中只使用了10000个词元所以模型需要更多的迭代周期来更好地收敛。 num_epochs, lr 500, 1 train_ch8(net, train_iter, vocab, lr, num_epochs, d2l.try_gpu()) d2l.plt.show()运行结果 困惑度 1.1, 20920.1 词元/秒 cpu time traveller for so it will be convenient to speak of himwas e travelleryou can show black is white by argument said filby 运行图片 上面的内容从零开始实现可以更好的看看底层但是不太方便。下面会给出如何改进RNN模型和简单实现且运行的速度会更快。 小结 1、我们可以训练一个基于循环神经网络的字符级语言模型根据用户提供的文本的前缀生成后续文本。 2、一个简单的循环神经网络语言模型包括输入编码、循环神经网络模型和输出生成。 3、循环神经网络模型在训练以前需要初始化状态不过随机抽样和顺序划分使用初始化方法不同。 4、当使用顺序划分时我们需要分离梯度以减少计算量。 5、在进行任何预测之前模型通过预热期进行自我更新例如获得比初始值更好的隐状态。 6、梯度裁剪可以防止梯度爆炸但不能应对梯度消失。 RNN的简洁实现 简洁实现的思想大致还是和之前一样的但是有些细节上还是不太一样主要还是要学会用这个就好了。 读取数据集 import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2lbatch_size, num_steps 32, 35 train_iter, vocab d2l.load_data_time_machine(batch_size, num_steps)定义模型 高级API提供了RNN的实现。我们构造一个具有256个隐藏单元的单隐藏层的循环神经网络层rnn_layer。 num_hiddens 256 rnn_layer nn.RNN(len(vocab), num_hiddens)我们使用张量来初始化隐状态它的形状是隐藏层数批量大小隐藏单元数。 state torch.zeros((1, batch_size, num_hiddens))可以输出查看一下 print(state.shape)运行结果 torch.Size([1, 32, 256]) 通过一个隐状态和一个输入我们就可以用更新后的隐状态计算输出其中rnn_layer的输出Y并不涉及输出层的计算它是指每个时间步的隐状态这些隐状态可以用作后序输出层的输入 X torch.rand(size(num_steps, batch_size, len(vocab))) Y, state_new rnn_layer(X, state)我们可以输出一下Y和state_new的形状 print(Y.shape, state_new.shape)运行结果 torch.Size([35, 32, 256]) torch.Size([1, 32, 256]) 和之前一样我们为一个完整的循环神经网络模型定义了一个RNNModel类与之前不同的是rnn_layer只包含了隐藏循环层所以我们要单独创建一个单独的输出层Linear #save class RNNModel(nn.Module):循环神经网络模型def __init__(self, rnn_layer, vocab_size, **kwargs):super(RNNModel, self).__init__(**kwargs)self.rnn rnn_layerself.vocab_size vocab_sizeself.num_hiddens self.rnn.hidden_size# 如果RNN是双向的之后将介绍num_directions应该是2否则应该是1if not self.rnn.bidirectional:self.num_directions 1self.linear nn.Linear(self.num_hiddens, self.vocab_size)else:self.num_directions 2self.linear nn.Linear(self.num_hiddens * 2, self.vocab_size)def forward(self, inputs, state):X F.one_hot(inputs.T.long(), self.vocab_size)X X.to(torch.float32)Y, state self.rnn(X, state)# 全连接层首先将Y的形状改为(时间步数*批量大小,隐藏单元数)# 它的输出形状是(时间步数*批量大小,词表大小)。output self.linear(Y.reshape((-1, Y.shape[-1])))return output, statedef begin_state(self, device, batch_size1):if not isinstance(self.rnn, nn.LSTM):# nn.GRU以张量作为隐状态return torch.zeros((self.num_directions * self.rnn.num_layers,batch_size, self.num_hiddens),devicedevice)else:# nn.LSTM以元组作为隐状态return (torch.zeros((self.num_directions * self.rnn.num_layers,batch_size, self.num_hiddens), devicedevice),torch.zeros((self.num_directions * self.rnn.num_layers,batch_size, self.num_hiddens), devicedevice))训练与预测 接下来我们使用之前定义的超参数调用train_ch8并使用高级API训练模型 device d2l.try_gpu() net RNNModel(rnn_layer, vocab_sizelen(vocab)) net net.to(device) num_epochs, lr 500, 1 d2l.train_ch8(net, train_iter, vocab, lr, num_epochs, device) d2l.plt.show()运行结果 perplexity 1.3, 58549.5 tokens/sec on cpu time travellery a curfonty is and why cabnglwed of his fecupry h travelleryou can show black is white by ard whing to verint 运行图片 可以看出使用高级API后该模型在较短时间内达到较低的困惑度。 小结 1、深度学习框架的高级API提供了循环神经网络层的实现。 2、高级API的循环神经网络层返回一个输出和一个更新后的隐状态我们还需要计算整个模型的输出层。 3、相比从零开始实现的循环神经网络使用高级API实现可以加速训练。
http://wiki.neutronadmin.com/news/436234/

相关文章:

  • 北京十大平面设计公司阜新网站seo
  • 易网做的网站后台广州在建火车站在哪里
  • 网站设计前期沟通单html网站怎么做的
  • 佛山建设公司网站wordpress运营
  • 网站建设合同管辖fw可以做网站
  • 要维护公司的网站该怎么做舟山网站建设优化
  • 怎样给网站做流量郑州有免费建网站的公司吗
  • 培训学校网站建设公司网站自己创建
  • 外贸网站如何制作好的响应式网站
  • 南京网站设计价格五寨网站建设
  • 网站制作在线版点击一个网站跳转到图片怎么做
  • 如何使用上线了app建设网站dede做招聘网站
  • 做网站哪种字体好看自己做的网站不备案不能访问吗
  • 免费建立手机网站如何在自己网站上做支付宝吗
  • wordpress建博客网站网站建设情况
  • 个性化网站建设费用网站建设seo虾哥网络
  • 全国做网站的优惠券小程序源码
  • 深圳网站制作的英文网站编辑怎么做
  • 中牟做网站做网站如何不被忽悠
  • 网站 设计公司 温州求网站备案照片
  • 织梦响应式网站编写网站的软件
  • 个人网站备案没有座机企业网站备案好不好
  • 广州做淘宝的化妆品网站关于建网站做淘宝联盟
  • 网站的功能公司做网站的目的
  • 建立自己的网站步骤wordpress后台怎么登入
  • 衡水企业网站制作报价学做网站好做吗
  • 佛山骏域网站建设乐陵市属于哪个市
  • 重庆做商城网站建设动漫设计与制作软件
  • 医院做网站的意义wordpress配置文件下载
  • 辽宁建设执业信息网站wordpress网站速度检测