创建循环神经网络(RNN)的NumPy实现教程

简介

深度学习的发展使得实现复杂神经网络变得更加容易,但对于初学者来说,了解其内部工作原理仍然至关重要。在本文中,我们将探讨如何使用NumPy从零开始构建递归神经网络(RNN),这将帮助我们更深入地理解其工作原理。

图片[1]-创建循环神经网络(RNN)的NumPy实现教程-山海云端论坛

初始化参数

与传统神经网络不同,RNN具有三个权重参数:输入权重(input weights)、内部状态权重(internal state weights)和输出权重(output weights)。我们首先将这些权重参数初始化为随机数,并设定词嵌入维度和输出维度。

<code># 初始化参数 hidden_dim = 100 output_dim = 80 input_weights = np.random.uniform(0, 1, (hidden_dim,hidden_dim)) internal_state_weights = np.random.uniform(0,1, (hidden_dim, hidden_dim)) output_weights = np.random.uniform(0,1, (output_dim,hidden_dim)) prev_memory = np.zeros((hidden_dim,1)) learning_rate = 0.0001 nepoch = 25 T = 4 bptt_truncate = 2 dU = np.zeros(input_weights.shape) dV = np.zeros(output_weights.shape) dW = np.zeros(internal_state_weights.shape)</code>

前向传播

在前向传播中,我们将输入和权重相乘,并应用激活函数(tanh)来计算内部状态。然后,我们将内部状态与输出权重相乘,并应用softmax函数以获取最终输出。

<code>def Rnn_forward(input_embedding, input_weights, internal_state_weights, prev_memory,output_weights): forward_params = [] W_frd = np.dot(internal_state_weights,prev_memory) U_frd = np.dot(input_weights,input_embedding) sum_s = W_frd + U_frd ht_activated = tanh_activation(sum_s) yt_unactivated = np.asarray(np.dot(output_weights, tanh_activation(sum_s))) yt_activated = softmax_activation(yt_unactivated) forward_params.append([W_frd,U_frd,sum_s,yt_unactivated]) return ht_activated,yt_activated,forward_params</code>

计算损失函数

我们使用交叉熵损失函数来计算模型的损失。需要将输出转换为独热编码形式,并与原始输出进行比较。

<code>def calculate_loss(output_mapper,predicted_output): total_loss = 0 layer_loss = [] for y,y_ in zip(output_mapper.values(),predicted_output): loss = -sum(y[i]*np.log2(y_[i]) for i in range(len(y))) loss = loss/ float(len(y)) layer_loss.append(loss) for i in range(len(layer_loss)): total_loss = total_loss + layer_loss[i] return total_loss/float(len(predicted_output))</code>

反向传播

在反向传播中,我们使用链式法则计算梯度。需要计算输入权重(dU)、内部状态权重(dW)和输出权重(dV)的梯度,并将它们用于权重更新。

<code>def rnn_backprop(embeddings,memory,output_t,dU,dV,dW,bptt_truncate,input_weights,output_weights,internal_state_weights): # 实现反向传播 # 返回权重的梯度 return (dU, dW, dV)</code>

权重更新

使用梯度下降法更新权重。

<code>def gd_step(learning_rate, dU,dW,dV, input_weights, internal_state_weights,output_weights ): input_weights -= learning_rate* dU internal_state_weights -= learning_rate * dW output_weights -=learning_rate * dV return input_weights,internal_state_weights,output_weights</code>

训练序列

训练神经网络,并在每个epoch后评估损失。我们采用静态学习率,但也可以使用动态调整学习率的方法。

<code>def train(T, embeddings,output_t,output_mapper,input_weights,internal_state_weights,output_weights,dU,dW,dV,prev_memory,learning_rate=0.001, nepoch=100, evaluate_loss_after=2): losses = [] for epoch in range(nepoch): if(epoch % evaluate_loss_after == 0): output_string,memory = full_forward_prop(T, embeddings ,input_weights,internal_state_weights,prev_memory,output_weights) loss = calculate_loss(output_mapper, output_string) losses.append(loss) time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') print("%s: Loss after epoch=%d: %f" % (time,epoch, loss)) sys.stdout.flush() dU,dW,dV = rnn_backprop(embeddings,memory,output_t,dU,dV,dW,bptt_truncate,input_weights,output_weights,internal_state_weights) input_weights,internal_state_weights,output_weights= sgd_step(learning_rate,dU,dW,dV,input_weights,internal_state_weights,output_weights) return losses losses = train(T, embeddings,output_t,output_mapper,input_weights,internal_state_weights,output_weights,dU,dW,dV,prev_memory,learning_rate=0.0001, nepoch=10, evaluate_loss_after=2)</code>

总结

通过本文,我们了解了如何使用NumPy从零开始构建递归神经网络。这使我们更深入地理解了神经网络的工作原理,并为我们探索更复杂的深度学习模型奠定了基础。现在,让我们继续向着LSTM和GRU等更高级的架构迈进吧!

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容