rnn python实现

早上看到公众号用python代码实现rnn,看了下原地址,rnn原理比较简单,但是有了各种变种如lstm、seq2seq等模型,目前查看的一些资料rnn都是基于一些框架来实现,比如tensorflow、deeplearning4j,caffe等,很少有徒手实现,刚刚看好到一篇记录下:参考文献:https://iamtrask.github.io/2015/11/15/anyone-can-code-lstm/


   
   
  1. import copy,numpy as np
  2. np.random.seed(0)
  3. #sigmod函数
  4. def sigmoid(x):
  5. output=1/(1+np.exp(-x))
  6. return output
  7. #求导函数
  8. def sigmoid_output_to_derivative(output):
  9. return output*(1-output)
  10. int2binary={}
  11. binary_dim=8
  12. largest_number=pow(2,binary_dim)
  13. print(largest_number)
  14. binary=np.unpackbits(np.array([range(largest_number)],dtype=np.uint8).T,axis=1)
  15. for i in range(largest_number):
  16. int2binary[i]=binary[i]
  17. #input variables
  18. alpha=0.1
  19. input_dim=2
  20. hidden_dim=16
  21. output_dim=1
  22. # i这是输入层和隐层间的权重矩阵。所以就是输入层单元*隐层单元的矩阵(2 x 16 )。
  23. synapse_0=2*np.random.random((input_dim,hidden_dim))-1
  24. #这是隐层和输出层间的权重矩阵。所以就是隐层单元*输出层单元的矩阵(16*1 )
  25. synapse_1=2*np.random.random((hidden_dim,output_dim))-1
  26. #这是连接上一个时间戳隐层和当前时间戳隐层的矩阵,同时也是连接当前时间戳隐层和
  27. # 下一个时间戳隐层的矩阵。所以矩阵是隐层单元*隐层单元(16 x 16)。
  28. synapse_h=2*np.random.random((hidden_dim,hidden_dim))-1
  29. #这些变量保存对于权重矩阵的更新值,我们的目的不就是训练好的权重矩阵吗?
  30. # 在每次迭代积累权重更新值,然后一起更新
  31. synapse_0_update = np.zeros_like(synapse_0)
  32. synapse_1_update = np.zeros_like(synapse_1)
  33. synapse_h_update = np.zeros_like(synapse_h)
  34. # training logic
  35. for j in range(10000):
  36. #要生成一个随机加和问题。我随机生成的整数不会超过我们所能表达的整数的一半,
  37. # 否则两个整数相加就有可能超过我们可以用比特串表达的整数。
  38. a_int=np.random.randint(largest_number/2)
  39. a=int2binary[a_int] # binary encoding
  40. b_int = np.random.randint(largest_number / 2) # int versionxw
  41. b = int2binary[b_int] # binary encoding
  42. # true answer
  43. c_int=a_int+b_int
  44. c=int2binary[c_int]
  45. # 得到一个空的比特串来存储我们RNN神经网络的预测值。
  46. d=np.zeros_like(c)
  47. #初始化错误估计,作为收敛的依据。
  48. overallError=0
  49. #这两个列表是在每个时间戳跟踪输出层求导和隐层值的列表。
  50. layer_2_deltas=list()
  51. layer_1_values=list()
  52. #开始时没有上一个时间戳隐层,所有我们置为0.
  53. layer_1_values.append(np.zeros(hidden_dim))
  54. # 这个迭代可能的比特串表达(8位比特串
  55. for position in range(binary_dim):
  56. #X就像是文章开头图片中的”layer_0″. X 是一个2个元素的列表,第一个元素是比特串a中的
  57. # ,第二个元素是比特串b中的。我们用position定位比特位,是自右向左的
  58. X = np.array([[a[binary_dim - position - 1], b[binary_dim - position - 1]]])
  59. #正确结果 (1或0)
  60. Y = np.array([[c[binary_dim - position - 1]]]).T
  61. # hidden layer (input ~+ prev_hidden)
  62. #这行是代码申神奇之处!!! 请看懂这一行!!! 为了构造隐层,我们做两件事,
  63. # 第一步是从输入层传播到隐层(np.dot(X,synapse_0))。第二步,
  64. # 我们把上一个时间戳的隐层值传播到当前隐层
  65. # (np.dot(prev_layer_1, synapse_h)。最后我们把两个向量值相加! 最后交给sigmoid函数
  66. layer_1=sigmoid(np.dot(X,synapse_0)+np.dot(layer_1_values[-1],synapse_h))
  67. # output layer (new binary representation) 把隐层传播到输出层,做预测。
  68. layer_2=sigmoid(np.dot(layer_1,synapse_1))
  69. #计算预测的错误偏差。
  70. layer_2_error=Y-layer_2
  71. #计算并存储错误导数,在每个时间戳进行.
  72. layer_2_deltas.append((layer_2_error)*sigmoid_output_to_derivative(layer_2))
  73. #计算错误的绝对值的和,积累起来。
  74. overallError+=np.abs(layer_2_error[0])
  75. # 估计输出值。并且保存在d中
  76. d[binary_dim-position-1]=np.round(layer_2[0][0])
  77. # 保存当前隐层值,作为下个时间戳的上个隐层值
  78. layer_1_values.append(copy.deepcopy(layer_1))
  79. future_layer_1_delta=np.zeros(hidden_dim)
  80. #对于所有的时间戳做了前向传播,我们计算了输出层的求导并且把它们存在列表中。
  81. # 现在我们需要反向传播,从最后一个时间戳开始反向传播到第一个时间戳
  82. for position in range(binary_dim):
  83. #像我们之前一样获得输入数据。
  84. X=np.array([[a[position],b[position]]])
  85. #选择当前隐层。
  86. layer_1=layer_1_values[-position-1]
  87. #选择上个时间戳隐层。
  88. prev_layer_1=layer_1_values[-position-2]
  89. #选择当前输出错误。
  90. layer_2_delta=layer_2_deltas[-position-1]
  91. #这行在给定下一个时间戳隐层错误和当前输出错误的情况下,计算当前隐层错误
  92. layer_1_delta = (future_layer_1_delta.dot(synapse_h.T) +
  93. layer_2_delta.dot( synapse_1.T)) * sigmoid_output_to_derivative(layer_1)
  94. #当前时间戳通过反向传播得到了求导,我们可以构造权重更新了(但暂时不更新权重)。
  95. # 我们等到完全反向传播后,才真正去更新权重。为什么?因为反向传播也是需要权重的。
  96. synapse_1_update += np.atleast_2d(layer_1).T.dot(layer_2_delta)
  97. synapse_h_update += np.atleast_2d(prev_layer_1).T.dot(layer_1_delta)
  98. synapse_0_update+=X.T.dot(layer_1_delta)
  99. future_layer_1_delta = layer_1_delta
  100. #在我们反向传播完毕,可以真的更新所有权重了。
  101. synapse_0+=synapse_0_update*alpha
  102. synapse_1 += synapse_1_update * alpha
  103. synapse_h += synapse_h_update * alpha
  104. synapse_0_update *= 0
  105. synapse_1_update *= 0
  106. synapse_h_update *= 0
  107. # print out progress
  108. if (j % 1000 == 0):
  109. print("Error:" + str(overallError))
  110. print("Pred:" + str(d))
  111. print("True:" + str(c))
  112. out = 0
  113. for index, x in enumerate(reversed(d)):
  114. out += x * pow(2, index)
  115. print(str(a_int) + " + " + str(b_int) + " = " + str(out))

部分结果:

   
   
  1. 9 + 17 = 56
  2. 39 + 17 = 56
  3. 39 + 17 = 56
  4. Error:[ 0.21595037]
  5. Pred:[0 0 0 0 1 1 1 0]
  6. True:[0 0 0 0 1 1 1 0]
  7. 11 + 3 = 0
  8. 11 + 3 = 2
  9. 11 + 3 = 6
  10. 11 + 3 = 14
  11. 11 + 3 = 14
  12. 11 + 3 = 14
  13. 11 + 3 = 14
  14. 11 + 3 = 14

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RNNPython实现可以参考以下代码: ```python # 引用\[2\] # 定义RNN类 class RNN: def __init__(self): self.input_n = 0 self.hidden_n = 0 self.output_n = 0 self.input_weights = \[\] # (input, hidden) self.output_weights = \[\] # (hidden, output) self.hidden_weights = \[\] # (hidden, hidden) def setup(self, ni, nh, no): self.input_n = ni self.hidden_n = nh self.output_n = no self.input_weights = make_rand_mat(self.input_n, self.hidden_n) self.output_weights = make_rand_mat(self.hidden_n, self.output_n) self.hidden_weights = make_rand_mat(self.hidden_n, self.hidden_n) # 引用\[1\] # 定义test()方法作为示例代码的入口 def test(self): self.setup(2, 16, 1) for i in range(20000): a_int = int(rand(0, 127)) a = int_to_bin(a_int, dim=8) a = np.array(\[int(t) for t in a\]) b_int = int(rand(0, 127)) b = int_to_bin(b_int, dim=8) b = np.array(\[int(t) for t in b\]) c_int = a_int + b_int c = int_to_bin(c_int, dim=8) c = np.array(\[int(t) for t in c\]) guess, error = self.do_train(\[a, b\], c, dim=8) if i % 1000 == 0: print("Predict:" + str(guess)) print("True:" + str(c)) print("Error:" + str(error)) out = 0 for index, x in enumerate(reversed(guess)): out += x * pow(2, index) print(str(a_int) + " + " + str(b_int) + " = " + str(out)) result = str(self.predict(\[a, b\], dim=8)) print(result) print("===============") ``` 以上是一个简单的RNN类的Python实现示例,其中包括了初始化方法和设置方法。在示例代码的`test()`方法中,展示了如何使用RNN进行训练和预测。具体的实现细节可能需要根据具体的需求进行调整和修改。 #### 引用[.reference_title] - *1* *3* [Python实现RNN](https://blog.csdn.net/weixin_33853827/article/details/85889528)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [【深度学习系列(六)】:RNN系列(1):基于pythonRNN实现](https://blog.csdn.net/wxplol/article/details/103882564)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值