RNN常用于序列数据的建模和预测,其与传统神经网络的区别在于隐藏层之间的结点有连接。
循环核:参数时间共享,循环层提取时间信息
循环神经网络:借助循环核提取时间特征后,送入全连接神经网络
循环核具有记忆力,通过不同时刻的参数共享,实现了对时间序列的提取。
RNN擅长处理序列数据。输出还作为下一个时刻的输入。
h[t]=fw(h[t-1],xt)
过程中一共有三个参数:U当前输入的权重矩阵,V隐层和输出层间的权重矩阵,W上一状态输入的权重矩阵。
入RNN时,x_train是三维的:[送入样本数,循环核时间展开步数,每个时间步输入特征步数]
独热码: 数据量大时,过于稀疏,映射之间是独立的,没有表现出关联性。
Embedding: 是一种单词编码方法,用低维向量实现了编码,这种编码通过神经网络训练优化,能表达出单词间的相关性。
tf.keras.layers.Embedding(词汇表大小,编码维度)
入RNN时,x_train是二维的:[送入样本数,循环核时间展开步数]
import tensorflow as tf
physical_devices = tf.config.list_physical_devices('GPU')
tf.config.experimental.set_memory_growth(physical_devices[0], True)
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras import Model
import pandas as pd
import os
input_word="abcde"
w_to_id={'a':0,'b':1,'c':2,'d':3,'e':4}
x_train=[w_to_id['a'],w_to_id['b'],w_to_id['c'],w_to_id['d'],w_to_id['e']]
y_train=[w_to_id['b'],w_to_id['c'],w_to_id['d'],w_to_id['e'],w_to_id['a']]
np.random.seed(7)
np.random.shuffle(x_train)
np.random.seed(7)
np.random.shuffle(y_train)
x_train=np.reshape(x_train,(len(x_train),1)) #送入样本数,循环核时间展开步数
y_train=np.array(y_train)
model=tf.keras.Sequential([
tf.keras.layers.Embedding(5,2),
tf.keras.layers.SimpleRNN(3),
tf.keras.layers.Dense(5,activation="softmax")
])
model.compile(optimizer=tf.keras.optimizers.Adam(0.01),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=['sparse_categorical_accuracy'])
checkpoint_save_path="./checkpoint/run_embedding_lprel.ckpt"
if os.path.exists(checkpoint_save_path+".index"):
print('---load the model-----')
model.load_weights(checkpoint_save_path)
cp_callback=tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,
save_weights_only=True,
save_best_only=True,
monitor='loss')
history=model.fit(x_train,y_train,batch_size=32,epochs=100,callbacks=[cp_callback])
model.summary()
file=open('./weights.txt','w')
for v in model.trainable_variables:
file.write(str(v.name)+'\n')
file.write(str(v.shape)+'\n')
file.write(str(v.numpy())+'\n')
file.close()
acc=history.history['sparse_categorical_accuracy']
loss=history.history['loss']
plt.subplot(121)
plt.plot(acc,label='Training Accuracy')
plt.title('Training Accuracy')
plt.legend()
plt.subplot(122)
plt.plot(loss,label='Training Loss')
plt.title('Training Loss')
plt.legend()
plt.show()
alphabet1=input('input the number of test alphabet:')
alphabet =[w_to_id[alphabet1]]
alphabet=np.reshape(alphabet,(1,1))
result=model.predict(alphabet)
pred = tf.argmax(result,axis=1)
pred = int(pred)
tf.print(alphabet1+'->'+input_word[pred])
**RNN 实现股票预测** 这里预测的是北方稀土的开盘价格
import tushare as ts
import pandas as pd
import numpy as np
import tensorflow as tf
import os
import math
import matplotlib.pyplot as plt
#sklearn 是 package,sklearn.preprocessing 是package import 只能导入package及 package下的变量,函数,类,不能导入package下的package
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error,mean_absolute_error
token='你的token'
ts.set_token(token)
pro=ts.pro_api()
data=pro.daily(ts_code="600111.SH",start_date='20020101', end_date='20211203')
data.to_csv("600111SH.csv")
xitu=pd.read_csv("600111SH.csv")
training_set=xitu.iloc[-1:200:-1,3:4].values
test_set=xitu.iloc[200:0:-1,3:4].values #对获取的数据切片,新的api日期近的排在前面,我们用的是倒序
#归一化
sc=MinMaxScaler(feature_range=(0,1))#定义归一化,归一化到[0,1]之间
training_set_scaled=sc.fit_transform(training_set)
test_set_scaled=sc.fit_transform(test_set)
x_train=[]
y_train=[]
x_test=[]
y_test=[]
for i in range(60,len(training_set_scaled)):
x_train.append(training_set_scaled[i-60:i,0])
y_train.append(training_set_scaled[i,0]) #60天之后的数据既是测试数据,也是训练数据
np.random.seed(7)
np.random.shuffle(x_train)
np.random.seed(7)
np.random.shuffle(y_train)
tf.random.set_seed(7)
x_train,y_train=np.array(x_train),np.array(y_train)
x_train=np.reshape(x_train,(x_train.shape[0],60,1))
for i in range(60,len(test_set_scaled)):
x_test.append(test_set_scaled[i-60:i,0])
y_test.append(test_set_scaled[i,0])
x_test,y_test=np.array(x_test),np.array(y_test)
x_test =np.reshape(x_test,(x_test.shape[0],60,1))
model=tf.keras.Sequential([
tf.keras.layers.SimpleRNN(80,return_sequences=True),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.SimpleRNN(100),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(1)
])
model.compile(optimizer=tf.keras.optimizers.Adam(0.001),
loss='mean_squared_error') #均方误差损失函数
checkpoint_save_path='./checkpoint/stock.ckpt'
if os.path.exists(checkpoint_sava_path+'.index'):
print('----load the model----')
model.load_weights(checkpoint_sava_path)
cp_callback=tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,
save_weight_only=True,
save_best_only=True,
monitor='val_loss')
history=model.fit(x_train,y_train,batch_size=64,epochs=50,validation_data=(x_test,y_test),validation_freq=1,callbacks=[cp_callback])
file=open('./weights.txt','w')
for v in model.trainable_variables:
file.write(str(v.name)+'\n')
file.write(str(v.shape)+'\n')
file.write(str(v.numpy())+'\n')
file.close()
loss=history.history['loss']
val_loss=history.history['val_loss']
plt.plot(loss,label='Training Loss')
plt.plot(val_loss,label='Validation Loss')
plt.title('Train and Validation Loss')
plt.legend()
plt.show()
pre=model.predict(x_test)
#将数据从(0,1)反归一化到原始范围
pre=sc.inverse_transform(pre)
real=sc.inverse_transform(test_set_scaled[60:])
plt.plot(pre,color='red',label='predicted')
plt.plot(real,color='blue',label='real')
plt.xlabel("Time")
plt.ylabel("Stock Price")
plt.title("BeiFangXiTu Stock Price Prediction")
plt.legend()
plt.show()
#MSE 均方误差
mse=mean_squared_error(pre,real)
#RMSE 均方根误差
rmse=math.sqrt(mse)
#MAE 平均绝对误差
mae=mean_absolute_error(pre,real)
print('均方误差:%.6f' %mse)
print('均方根误差:%.6f' %mse)
print('平均绝对误差:%.6f' %mae)
200个测试数据,该图2021年2月3日开始的北方稀土开盘价折线图
长短时记忆网络LSTM
RNN缺陷:时序过长时,梯度消失,导致遗忘,产生长跨度依赖问题(最后面的词与前面的词越来越难以拟合)
LSTM增加了三个门控单元,遗忘门、输入门和输出门。引入了表征长期记忆的细胞态Ct,引入了等待存入长期记忆的候选态~Ct
长期记忆=上一时刻的长期记忆×遗忘门+当前输入xt和上一时刻的短期留存ht-1×输入门
LSTM实现股票预测
#神经网络结构,代码其他部分与RNN相同
model=tf.keras.Sequential([
tf.keras.layers.LSTM(80,return_sequences=True),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.LSTM(100),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(1)
])
GRU
2014年cho等人简化了LSTM