Keras【极简】RNN

手写数字识别

from keras.datasets import mnist  # 手写数字0-9
from keras.utils.np_utils import to_categorical
from keras.models import Sequential  # 顺序模型
from keras.layers import SimpleRNN, Dense

"""数据读取和预处理"""
(x, y), _ = mnist.load_data()
x = x / 255  # 像素值→[0,1]
y = to_categorical(y, 10)  # one-hot编码

"""建模"""
model = Sequential()
model.add(SimpleRNN(units=64, input_shape=(28, 28)))  # RNN
model.add(Dense(units=10, activation='softmax'))  # 输出层

"""编译"""
model.compile('adam', 'categorical_crossentropy', ['acc'])

"""拟合、取10%样本来验证"""
model.fit(x, y, batch_size=256, epochs=20, verbose=2, validation_split=.1)

文本序列预测

import numpy as np
from keras.models import Sequential  # 顺序模型
from keras.layers import Dense, LSTM  # 全连接层、LSTM
from keras.utils.np_utils import to_categorical

"""创建样本"""
sequence = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
chr2int = {c: i for i, c in enumerate(sequence)}
int2chr = {i: c for i, c in enumerate(sequence)}
seq_len = len(sequence)  # 序列总长
window = 4  # 滑窗大小
x_ls, y_ls = [], []
for i in range(seq_len - window):
    seq_in = sequence[i: i + window]
    seq_out = sequence[i + window]
    x_ls.append([chr2int[c] for c in seq_in])
    y_ls.append(chr2int[seq_out])
    print(seq_in, '->', seq_out)
x = np.reshape(x_ls, (len(x_ls), window, 1))  # 输入维度
y = to_categorical(y_ls)  # one-hot编码

"""建模"""
model = Sequential()
model.add(LSTM(40, input_shape=x.shape[1:]))
model.add(Dense(y.shape[1], activation='softmax'))
model.compile('RMSprop', 'categorical_crossentropy', ['acc'])
model.fit(x, y, batch_size=1, epochs=400, verbose=2)

"""预测和评分"""
prediction = np.argmax(model.predict(x), axis=1)
for seq_in, seq_out in zip(x, prediction):
    seq_in = [int2chr[i] for i in seq_in.reshape(-1)]
    seq_out = int2chr[seq_out]
    print(seq_in, '->', seq_out)
acc = model.evaluate(x, y, verbose=2)[1]
print('准确率:%.2f%%' % acc)

余弦曲线拟合

import numpy as np, matplotlib.pyplot as mp
from keras.models import Sequential
from keras.layers import Dense, LSTM

"""创建样本"""
x_len = 1075
x = np.linspace(0, np.pi * 10.75, x_len, endpoint=False)
y = np.cos(x)
window = 75  # 时序滑窗大小
X = [y[i: i + window] for i in range(x_len - window)]
X = np.reshape(X, (-1, window, 1))  # shape (1000, 75, 1)
Y = y[window:].reshape(-1, 1)  # shape (1000, 1)

"""建模"""
model = Sequential()
model.add(LSTM(units=50, input_shape=X.shape[1:],
               return_sequences=True))  # True返回输出序列的全部
model.add(LSTM(units=100,
               return_sequences=False))  # False返回输出序列的最后一个
model.add(Dense(1))
model.compile(optimizer='adam', loss='mse')  # 均方误差(Mean Square Error)
model.fit(X, Y, batch_size=100, epochs=10, verbose=2)

"""预测"""
pred_len = 150  # 预测序列长度
for start in range(0, 1000, 200):
    x_pred = x[window + start: window + start + pred_len]
    y_pred = []  # 存放拟合序列
    X_pred = X[start]
    for i in range(pred_len):
        Y_pred = model.predict(X_pred.reshape(-1, window, 1))  # 预测
        y_pred.append(Y_pred[0])
        X_pred = np.concatenate((X_pred, Y_pred))[1:]  # 窗口滑动
    mp.scatter(x_pred[0], y_pred[0], c='r', s=9)  # 预测起始点
    mp.plot(x_pred, y_pred, 'r')  # 预测序列
mp.plot(x, y, 'y', linewidth=5, alpha=0.3)  # 原序列
mp.show()

在这里插入图片描述

from keras.utils import plot_model
plot_model(model, show_shapes=True, show_layer_names=False)

在这里插入图片描述

打印state

from keras.models import Model
from keras.layers import Input, SimpleRNN, LSTM, GRU
from keras.utils import plot_model
from numpy import reshape

x = reshape([1, 1], (1, 2, 1))

units = 4
l_rnn_ls = [
    SimpleRNN(units, return_sequences=True, return_state=True),
    LSTM(units, return_sequences=True, return_state=True),
    GRU(units, return_sequences=True, return_state=True)]
path_ls = ['SimpleRNN.png', 'LSTM.png', 'GRU.png']

for l_rnn, path in zip(l_rnn_ls, path_ls):
    t_input = Input(shape=(2, 1))
    t_output_ls = l_rnn(t_input)
    model = Model(t_input, t_output_ls)
    plot_model(model, path, show_shapes=True, show_layer_names=False)
    # 打印RNN输出
    t_output_ls = model.predict(x)
    print(path.replace('.png', ''))
    for t_output in t_output_ls:
        print(t_output, t_output.shape)
    print()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小基基o_O

您的鼓励是我创作的巨大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值