lstm学习

原文链接:
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:


Figure_1.png

你可能感兴趣的:(lstm学习)