原文
import copy, numpy as np
np.random.seed(0)
# sigmoid函式
def sigmoid(x):
output = 1 / (1 + np.exp(-x))
return output
# sigmoid導數
def sigmoid_output_to_derivative(output):
return output * (1 - output)
# 訓練資料生成
int2binary = {}
binary_dim = 8
largest_number = pow(2, binary_dim)
binary = np.unpackbits(
np.array([range(largest_number)], dtype=np.uint8).t, axis=1)
for i in range(largest_number):
int2binary[i] = binary[i]
# 初始化一些變數
alpha = 0.1 #學習率
input_dim = 2 #輸入的大小
hidden_dim = 8 #隱含層的大小
output_dim = 1 #輸出層的大小
# 隨機初始化權重
synapse_0 = 2 * np.random.random((hidden_dim, input_dim)) - 1 #(8, 2)
synapse_1 = 2 * np.random.random((output_dim, hidden_dim)) - 1 #(1, 8)
synapse_h = 2 * np.random.random((hidden_dim, hidden_dim)) - 1 #(8, 8)
synapse_0_update = np.zeros_like(synapse_0) #(8, 2)
synapse_1_update = np.zeros_like(synapse_1) #(1, 8)
synapse_h_update = np.zeros_like(synapse_h) #(8, 8)
# 開始訓練
for j in range(100000):
# 二進位制相加
a_int = np.random.randint(largest_number / 2) # 隨機生成相加的數
a = int2binary[a_int] # 對映成二進位制值
b_int = np.random.randint(largest_number / 2) # 隨機生成相加的數
b = int2binary[b_int] # 對映成二進位制值
# 真實的答案
c_int = a_int + b_int #結果
c = int2binary[c_int] #對映成二進位制值
# 待存放**值
d = np.zeros_like(c)
overallerror = 0
layer_2_deltas = list() #輸出層的誤差
layer_2_values = list() #第二層的值(輸出的結果)
layer_1_values = list() #第一層的值(隱含狀態)
#前向傳播
for i in range(binary_dim):
x = np.array([[a[binary_dim - i - 1], b[binary_dim - i - 1]]]).t #(2,1)
y = np.array([[c[binary_dim - i - 1]]]).t #(1,1)
layer_1 = sigmoid(np.dot(synapse_h, layer_1_values[-1]) + np.dot(synapse_0, x)) #(1,1)
layer_2 = sigmoid(np.dot(synapse_1, layer_1)) #(1,1)
error = -(y-layer_2) #使用平方差作為損失函式
layer_delta2 = error * sigmoid_output_to_derivative(layer_2) #(1,1)
d[binary_dim - i - 1] = np.round(layer_2[0][0])
future_layer_1_delta = np.zeros((hidden_dim, 1))
#反向傳播
for i in range(binary_dim):
x = np.array([[a[i], b[i]]]).t
prev_layer_1 = layer_1_values[-i-2]
layer_1 = layer_1_values[-i-1]
layer_delta2 = layer_2_deltas[-i-1]
layer_delta1 = np.multiply(np.add(np.dot(synapse_h.t, future_layer_1_delta),np.dot(synapse_1.t, layer_delta2)), sigmoid_output_to_derivative(layer_1))
synapse_0_update += np.dot(layer_delta1, x.t)
synapse_h_update += np.dot(layer_delta1, prev_layer_1.t)
synapse_1_update += np.dot(layer_delta2, layer_1.t)
future_layer_1_delta = layer_delta1
synapse_0 -= alpha * synapse_0_update
synapse_h -= alpha * synapse_h_update
synapse_1 -= alpha * synapse_1_update
synapse_0_update *= 0
synapse_1_update *= 0
synapse_h_update *= 0
# 驗證結果
if (j % 100 == 0):
print("error:" + str(overallerror))
print("pred:" + str(d))
print("true:" + str(c))
out = 0
for index, x in enumerate(reversed(d)):
out += x * pow(2, index)
print(str(a_int) + " + " + str(b_int) + " = " + str(out))
print("------------")
純手擼 堆排序
堆排序學習筆記 外婆的澎湖灣 前提 堆用完全二叉樹表示時,其表示方法不唯一,但可以確定的是樹的根結點要麼是無序表中的最小值,要麼是最大值。思想 步驟 二叉堆在實現的時候,是採取陣列的形式來儲存的。從二叉堆中刪除乙個元素,為了充分利用空間,其實我們是可以把刪除的元素直接存放在二叉堆的最後乙個元素那裡的...
手擼乙個簡陋直播系統
目錄2.nginx rtmp module 3.安裝第乙個直播系統 2.修改配置 3.推流 4.拉流 4.rtm高階 5.ffmpeg 1.nginx概述和作用 2.安裝nginx 安裝 3.nginx 配置 4.配置變數 語法 set var name value set a hello worl...
純手擼 折半插入排序
折半插入排序需要注意的是 include 後面為了測試寫的輸出,輸出每一次排序後的資訊。void print int a,int n int i else 插入位置後的元素統一後移 for j i j low j a low tmp 插入元素 print a,8,i 測試 int main 預計 1...