互动网站建设的主页,推广宝,找人做网站怎么做,江苏网站建设的案例展示【#x1f34a;易编橙#xff1a;一个帮助编程小伙伴少走弯路的终身成长社群#x1f34a;】 大家好#xff0c;我是小森( #xfe61;ˆoˆ#xfe61; ) #xff01; 易编橙终身成长社群创始团队嘉宾#xff0c;橙似锦计划领衔成员、阿里云专家博主、腾讯云内容共创官… 【易编橙一个帮助编程小伙伴少走弯路的终身成长社群】 大家好我是小森( ˆoˆ ) 易编橙·终身成长社群创始团队嘉宾橙似锦计划领衔成员、阿里云专家博主、腾讯云内容共创官、CSDN人工智能领域优质创作者 。 今天我们看一下用循环神经网络RNN的原理并且动手应用到案例。 循环神经网络 在普通的神经网络中信息的传递是单向的这种限制虽然使得网络变得更容易学习但在一定程度上也减弱了神经网络模型的能力。特别是在很多现实任务中网络的输出不仅和当前时刻的输入相关也和其过去一段时间的输出相关。此外普通网络难以处理时序数据比如视频、语音、文本等时序数据的长度一般是不固定的而前馈神经网络要求输入和输出的维数都是固定的不能任意改变。因此当处理这一类和时序相关的问题时就需要一种能力更强的模型。 循环神经网络 (RNN是一类具有短期记忆能力的神经网络。在循环神经网络中神经元不但可以接受其它神经元的信息也可以接受自身的信息形成具有环路的网络结构。 RNN比传统的神经网络多了一个循环圈这个循环表示的就是在下一个时间步上会返回作为输入的一部分我们把RNN在时间点上展开 在不同的时间步RNN的输入都将与之前的时间状态有关 具体来说每个时间步的RNN单元都会接收两个输入当前时间步的外部输入和前一时间步隐藏层的输出状态。通过这种方式RNN能够学习并理解数据中的长期依赖关系使得它在处理文本生成、语音识别、时间序列预测等序列数据时表现尤为出色。
此外RNN的隐藏状态或称为内部状态在每次迭代时都会更新这种更新过程包含了当前输入和前一时间步状态的非线性组合使得网络能够动态地调整其对序列中接下来内容的预测或理解。 LSTM和GRU
传统的RNN在处理长序列数据时常常面临梯度消失或梯度爆炸的问题这限制了其在处理长期依赖关系上的能力。为了克服这一局限性LSTMLong Short-Term Memory长短期记忆网络作为RNN的一种变体被引入。
LSTM是一种RNN特殊的类型可以学习长期依赖信息。在很多问题上LSTM都取得相当巨大的成功并得到了广泛的应用。 LSTM是通过一个叫做门的结构实现门可以选择让信息通过或者不通过。 这个门主要是通过sigmoid和点乘实现的 sigmoid 的取值范围是在(0,1)之间如果接近0表示不让任何信息通过如果接近1表示所有的信息都会通过。
遗忘门通过sigmoid函数来决定哪些信息会被遗忘 输入门决定哪些新的信息会被保留。
例如
我昨天吃了拉面今天我想吃炒饭在这个句子中通过遗忘门可以遗忘拉面,同时更新新的主语为炒饭。
输出门
我们需要决定什么信息会被输出也是一样这个输出经过变换之后会通过sigmoid函数的结果来决定那些细胞状态会被输出。 前一次的输出和当前时间步的输入的组合结果通过sigmoid函数进行处理得到O_t 更新后的细胞状态C_t会经过tanh层的处理把数据转化到(-1,1)的区间 tanh处理后的结果和O_t进行相乘把结果输出同时传到下一个LSTM的单元 GRU
GRU是一种LSTM的变形版本 它将遗忘和输入门组合成一个“更新门”。它还合并了单元状态和隐藏状态并进行了一些其他更改由于他的模型比标准LSTM模型简单所以越来越受欢迎。 双向LSTM
单向的 RNN是根据前面的信息推出后面的但有时候只看前面的词是不够的 可能需要预测的词语和后面的内容也相关那么此时需要一种机制能够让模型不仅能够从前往后的具有记忆还需要从后往前需要记忆。此时双向LSTM就可以帮助我们解决这个问题 由于是双向LSTM所以每个方向的LSTM都会有一个输出最终的输出会有2部分所以往往需要concat的操作。
RNN实现文本情感分类
torch.nn.LSTM(input_size,hidden_size,num_layers,batch_first,dropout,bidirectional) input_size输入数据的形状即embedding_dim hidden_size隐藏层神经元的数量即每一层有多少个LSTM单元 num_layer 即RNN的中LSTM单元的层数 batch_first默认值为False输入的数据需要[seq_len,batch,feature],如果为True则为[batch,seq_len,feature] dropout:dropout的比例默认值为0。dropout是一种训练过程中让部分参数随机失活的一种方式能够提高训练速度同时能够解决过拟合的问题。 bidirectional是否使用双向LSTM,默认是False
实例化LSTM对象之后,不仅需要传入数据还需要前一次的h_0(前一次的隐藏状态)和c_0
LSTM的默认输出为output, (h_n, c_n) output(seq_len, batch, num_directions * hidden_size)---batch_firstFalse h_n:(num_layers * num_directions, batch, hidden_size) c_n: (num_layers * num_directions, batch, hidden_size) LSTM和GRU的使用注意点 第一次调用之前需要初始化隐藏状态如果不初始化默认创建全为0的隐藏状态 往往会使用LSTM or GRU 的输出的最后一维的结果来代表LSTM、GRU对文本处理的结果其形状为[batch, num_directions*hidden_size]。
使用LSTM完成文本情感分类
class IMDBLstmmodel(nn.Module):def __init__(self):super(IMDBLstmmodel,self).__init__()self.hidden_size 64self.embedding_dim 200self.num_layer 2self.bidriectional Trueself.bi_num 2 if self.bidriectional else 1self.dropout 0.5self.embedding nn.Embedding(len(ws),self.embedding_dim,padding_idxws.PAD) #[N,300]self.lstm nn.LSTM(self.embedding_dim,self.hidden_size,self.num_layer,bidirectionalTrue,dropoutself.dropout)self.fc nn.Linear(self.hidden_size*self.bi_num,20)self.fc2 nn.Linear(20,2)def forward(self, x):x self.embedding(x)x x.permute(1,0,2) h_0,c_0 self.init_hidden_state(x.size(1))_,(h_n,c_n) self.lstm(x,(h_0,c_0))out torch.cat([h_n[-2, :, :], h_n[-1, :, :]], dim-1)out self.fc(out)out F.relu(out)out self.fc2(out)return F.log_softmax(out,dim-1)def init_hidden_state(self,batch_size):h_0 torch.rand(self.num_layer * self.bi_num, batch_size, self.hidden_size).to(device)c_0 torch.rand(self.num_layer * self.bi_num, batch_size, self.hidden_size).to(device)return h_0,c_0
为了提高程序的运行速度可以考虑把模型放在GPU上运行 device torch.device(cuda if torch.cuda.is_available() else cpu) model.to(device)
train_batch_size 64
test_batch_size 5000
imdb_model IMDBLstmmodel().to(device)
optimizer optim.Adam(imdb_model.parameters())
criterion nn.CrossEntropyLoss()def train(epoch):mode Trueimdb_model.train(mode)train_dataloader get_dataloader(mode,train_batch_size)for idx,(target,input,input_lenght) in enumerate(train_dataloader):target target.to(device)input input.to(device)optimizer.zero_grad()output imdb_model(input)loss F.nll_loss(output,target) loss.backward()optimizer.step()if idx %10 0:pred torch.max(output, dim-1, keepdimFalse)[-1]acc pred.eq(target.data).cpu().numpy().mean()*100.print(Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}\t ACC: {:.6f}.format(epoch, idx * len(input), len(train_dataloader.dataset),100. * idx / len(train_dataloader), loss.item(),acc))torch.save(imdb_model.state_dict(), model/mnist_net.pkl)torch.save(optimizer.state_dict(), model/mnist_optimizer.pkl)def test():mode Falseimdb_model.eval()test_dataloader get_dataloader(mode, test_batch_size)with torch.no_grad():for idx,(target, input, input_lenght) in enumerate(test_dataloader):target target.to(device)input input.to(device)output imdb_model(input)test_loss F.nll_loss(output, target,reductionmean)pred torch.max(output,dim-1,keepdimFalse)[-1]correct pred.eq(target.data).sum()acc 100. * pred.eq(target.data).cpu().numpy().mean()print(idx: {} Test set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.2f}%)\n.format(idx,test_loss, correct, target.size(0),acc))if __name__ __main__:test()for i in range(10):train(i)test()然后由大家写代码得到模型训练的最终输出大家可以改变模型来观察不同的结果。