原文链接:
https://blog.csdn.net/zzukun/article/details/49968129
代码(python3.7 + tensorflow2.0):
# -- coding: utf-8 --
import copy
import numpy as np
from time import time
# sigmoid函数
def sigmoid(x):
return 1 / (1 + np.exp(-x))
# sigmoid函数的导数,这里out=sigmoid(x)
def sigmoid_out_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) # unpackbits函数, 将整数转为2进制
for i in range(largest_number):
int2binary[i] = binary[i] # 使用字典格式赋值,得到结果类似{0:array([0,0,0,0,0,0,0,1], dtype = uint8), 1:array(......}
def main():
start = time()
# 设置学习速率
alpha = 0.1
# 输入层
input_dim = 2
# 隐藏层神经元个数
hidden_dim = 16
# 输出层
output_dim = 1
# 连接输入层与隐藏层的权值矩阵2行16列,取值区间为[-1, 1),使用区间内随机数初始化
synapse_0 = 2 * np.random.random((input_dim, hidden_dim)) - 1
# 连接隐藏层与输出层的权值矩阵16行1列,取值区间为[-1, 1),使用区间内随机数初始化
synapse_1 = 2 * np.random.random((hidden_dim, output_dim)) - 1
# 连接(上一个)隐藏层与(当前)隐藏层的权值矩阵16行16列,取值区间为[-1, 1),使用区间内随机数初始化
synapse_h = 2 * np.random.random((hidden_dim, hidden_dim)) - 1
# 上面三个矩阵更新时的缓冲矩阵
synapse_0_update = np.zeros_like(synapse_0)
synapse_1_update = np.zeros_like(synapse_1)
synapse_h_update = np.zeros_like(synapse_h)
# 做一万次迭代
for j in range(10000):
# 针对其中一次:
# 生成一个简单的加法问题(a + b = c, a < max / 2, b < max/2, c
使用tensorflow实现(python3.7+tensorflow2.0):
# -- coding: utf-8 --
import numpy as np
from matplotlib import pyplot as plt
import tensorflow as tf
from tensorflow.keras import layers, models, Sequential
global binary_dim, largest_number
binary_dim = 8
largest_number = pow(2, binary_dim)
# binary = np.unpackbits(np.array([np.arange(largest_number)], dtype=np.uint8).T, axis=1)
# for i in range(largest_number):
# int2binary[i] = binary[i]
def main():
# X = np.random.randint(0, largest_number / 2, 4000).reshape(-1, 2)
# np.save("X", X)
X = np.load('X.npy')
X_train_old, X_test_old = X[:1800], X[1800:]
y = np.sum(X, axis=1).reshape(-1, 1)
y_train_old, y_test_old = y[:1800], y[1800:]
# X, y转二进制
# input: X_train (1800x2x8)
# output: y_train (1800x8)
# 单次输入 2x8的X 对应 1x8的y
X = np.unpackbits(X.astype(np.uint8), axis=1).reshape(-1, 2, 8).astype(np.float32)
X_train, X_test = X[:1800], X[1800:]
y = np.unpackbits(y.astype(np.uint8), axis=1).reshape(-1, 8).astype(np.float32)
y_train, y_test = y[:1800], y[1800:]
# 创建模型
model = Sequential()
# LSTM: 记忆相邻两组数据
model.add(layers.LSTM(16, activation='relu', input_shape=(2, 8)))
model.add(layers.Dense(8, activation='relu'))
model.compile(loss='mse', optimizer='adam')
h = model.fit(X_train, y_train, batch_size=20, epochs=1000)
# 绘制loss的变化
plt.figure(figsize=(16,2))
plt.plot(h.history['loss'])
plt.show()
model.save('lstm_model.h5')
model = models.load_model('lstm_model.h5')
cc = pow(2, np.arange(8))[::-1]
y_test_predict = np.round(model.predict(X_test))
# 将model预测值二级制转十进制
y_test_predict = np.dot(y_test_predict, cc).reshape(-1, 1)
print(X_test_old)
print(y_test_old)
print(y_test_predict)
print(y_test_predict - y_test_old)
# errorAll = np.sum(np.abs(y_test_predict - y_test_old)) / 200
# print(errorAll)
print('finish.')
if __name__ == '__main__':
main()
损失函数loss: