用英文描述一下我的LSTM架构，每一层是什么# 从yahoo读取股票数据
from pandas_datareader.data import DataReader
import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import keras.models
import tensorflow

from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import Dropout
sns.set_style('whitegrid')
plt.style.use('fivethirtyeight')
%matplotlib inline
# 时间戳
from datetime import datetime

# 设置股票名称
techList = ['GOOG', 'MSFT', 'AMZN']
# 设置起始时间 取过去一年的数据
end = datetime.now()
start = datetime(end.year - 1, end.month, end.day)
# 下载数据
for stock in techList:
    globals()[stock] = yf.download(stock, start, end)
companyList = [GOOG, MSFT, AMZN]
companyName = ['GOOGLE', 'MICROSOFT', 'AMAZON']
for company, comName in zip(companyList, companyName):
    company['Company Name'] = comName
df = pd.concat(companyList, axis=0)
df.tail(10)

plt.figure(figsize=(15, 5))
plt.subplots_adjust(top=1.25, bottom=1.2)

for i, company in enumerate(companyList, 1):
    plt.subplot(1, 3, i)
    company['Adj Close'].plot()
    plt.ylabel('Adj Close')
    plt.xlabel(None)
    plt.title(f"Closing Price of {techList[i-1]})")

plt.tight_layout()

# 交易量趋势图
plt.figure(figsize=(15, 5))
plt.subplots_adjust(top=1.25, bottom=1.2)

for i, company in enumerate(companyList, 1):
    plt.subplot(1, 3, i)
    company['Volume'].plot()
    plt.ylabel('Volume')
    plt.xlabel(None)
    plt.title(f"Sales Volume of {techList[i-1]}")

plt.tight_layout()

# 移动平均线
maDay = [10, 20, 50]

for ma in maDay:
    for company in companyList:
        column_name = f"MA for {ma} days"
        company[column_name] = company['Adj Close'].rolling(ma).mean()
        

fig, axes = plt.subplots(nrows=1, ncols=3)
fig.set_figheight(5)
fig.set_figwidth(15)

GOOG[['Adj Close', 'MA for 10 days', 'MA for 20 days', 'MA for 50 days']].plot(ax=axes[0])
axes[0].set_title('GOOGLE')

MSFT[['Adj Close', 'MA for 10 days', 'MA for 20 days', 'MA for 50 days']].plot(ax=axes[1])
axes[1].set_title('MICROSOFT')

AMZN[['Adj Close', 'MA for 10 days', 'MA for 20 days', 'MA for 50 days']].plot(ax=axes[2])
axes[2].set_title('AMAZON')

fig.tight_layout()

# 日均收益率
for company in companyList:
    company['Daily Return'] = company['Adj Close'].pct_change()

fig, axes = plt.subplots(nrows=1, ncols=3)
fig.set_figheight(5)
fig.set_figwidth(15)

GOOG['Daily Return'].plot(ax=axes[0], legend=True, linestyle='--', marker='o')
axes[0].set_title('GOOGLE')

MSFT['Daily Return'].plot(ax=axes[1], legend=True, linestyle='--', marker='o')
axes[1].set_title('MICROSOFT')

AMZN['Daily Return'].plot(ax=axes[2], legend=True, linestyle='--', marker='o')
axes[2].set_title('AMAZON')

fig.tight_layout()

plt.figure(figsize=(12, 3))

for i, company in enumerate(companyList, 1):
    plt.subplot(1, 3, i)
    company['Daily Return'].hist(bins=50)
    plt.xlabel('Daily Return')
    plt.ylabel('Counts')
    plt.title(f'{companyName[i - 1]}')
    
plt.tight_layout()


df = yf.download('GOOG', start='2003-01-01', end=end)
df# 创建一个只有收盘价的DF

data = df.filter(['Close'])
# 将DataFrame转换为numpy
dataset = data.values
# 获取行数
lenOfTrain = int(np.ceil(len(dataset) * .95))
lenOfTrain
# 标准化数据
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0,1))
scaled_data = scaler.fit_transform(dataset)
scaled_data
# 创建数据集
trainData = scaled_data[0:int(lenOfTrain), :]
X_train = []
y_train = []

for i in range(60, len(trainData)):
    X_train.append(trainData[i-60:i, 0])
    y_train.append(trainData[i,0])
    # 打印部分查看数据结构
    if i == 60:
        print(X_train)
        print(y_train)

# 转换为numpy
X_train, y_train = np.array(X_train), np.array(y_train)
# 转换数据形状
X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))
# 打印形状
print(f"训练集的形状为{X_train.shape}") 

model = keras.models.Sequential()
model.add(LSTM(64, return_sequences=True, input_shape= (X_train.shape[1], 1)))
model.add(LSTM(32, return_sequences=False))
model.add(Dense(25))
model.add(Dense(1))
# 添加优化器和损失函数
model.compile(optimizer='adam', loss='mean_squared_error')

# 训练模型
model.fit(X_train, y_train, batch_size=1, epochs=1)

# 创建验证集
testData = scaled_data[lenOfTrain - 60:,:]
X_test = []
y_test = dataset[lenOfTrain:, :]
for i in range(60, len(testData)):
    X_test.append(testData[i-60:i, 0])
X_test = np.array(X_test)
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))
# 预测
predictions = model.predict(X_test)
predictions = scaler.inverse_transform(predictions)
rmse = np.sqrt(np.mean(((predictions - y_test) ** 2)))
rmse

# 画图
train = data[:lenOfTrain]
valid = data[lenOfTrain:]
valid['Predictions'] = predictions
# Visualize the data
plt.figure(figsize=(16,6))
plt.title('Model')
plt.xlabel('Date', fontsize=18)
plt.ylabel('Close Price USD ($)', fontsize=18)
plt.plot(train['Close'],linewidth=0.6)
plt.plot(valid[['Close', 'Predictions']],linewidth=0.6)
plt.legend(['Train', 'Val', 'Predictions'], loc='lower right')
plt.show()

temp=np.array(valid['Predictions'])-np.array(valid['Close'])
residual=np.average(np.square(temp))
residual