m0_74420115 2024-04-28 21:40 采纳率: 71.9%
浏览 69
已结题

在lstm预测股票的问题中代码出错了


import pandas_datareader.data as web
import datetime
start = datetime.datetime(2000,1,1)
end = datetime.datetime(2024,1,1)
df = web.DataReader('GOOGL', 'stooq',start,end)
def Stock_Price_LSTM_Data_Precesing(df,mem_his_days,pre_days):
    df.dropna(inplace=True)
    df.sort_index(inplace=True)
    df['label']= df['Close'].shift(-pre_days)
    from sklearn.preprocessing import StandardScaler
    scaler = StandardScaler()
    sca_X=scaler.fit_transform(df.iloc[:,:-1])
    
    
    mem_his_days = 10
    
    from collections import deque
    deq = deque(maxlen=mem_his_days)
    
    X = []
    for i in sca_X:
        deq.append(list(i))
        if len(deq)==mem_his_days:
            X.append(list(deq))
    X_lately = X[-pre_days:]
    X = X[:-pre_days]
    y = df['label'].values[mem_his_days-1:-pre_days]
    
    
    import numpy as np
    X = np.array(X)
    y = np.array(y)
    return X,y,X_lately
X,y,X_lately = Stock_Price_LSTM_Data_Precesing(df,5,10)
pre_days = 10
# mem_days=[5,10,15]
# lstm_layers=[1,2,3]
# dense_layers=[1,2,3]
# units = [16,32]
mem_days =[5]
lstm_layers = [1]
dense_layers = [1]
units = [32]
from tensorflow.keras.callbacks import ModelCheckpoint
for the_mem_days in mem_days:
    for the_lstm_layers in lstm_layers:
        for the_dense_layers in dense_layers:
            for the_units in units:
                filepath=f"./chankankushuju/{{val_mape:.2f}}{{epoch:02d}}men{the_lstm_layers}lstm{the_lstm_layers}dense{the_dense_layers}unit{the_units}.weights.h5"
                checkpoint = ModelCheckpoint(
                    filepath=filepath,
                    save_weights_only=False,
                    monitor='val_mape',
                    mode='min',
                    save_best_only=True)
                X,y,X_lately = Stock_Price_LSTM_Data_Precesing(df,the_mem_days,pre_days)
                from sklearn.model_selection import train_test_split
                X_train,X_test,y_train,y_test = train_test_split(X,y,shuffle=False,test_size=0.1)
                import tensorflow as tf
                from tensorflow.keras.models import Sequential
                from tensorflow.keras.layers import LSTM,Dense,Dropout
                model = Sequential()
                model.add(LSTM(the_units,input_shape=X.shape[1:],activation='relu',return_sequences=True))
                model.add(Dropout(0.1))
                for i in range(the_lstm_layers):
                    model.add(LSTM(the_units,activation='relu',return_sequences=True))
                    model.add(Dropout(0.1))
                
                model.add(LSTM(the_units,activation='relu'))
                model.add(Dropout(0.1))
                for i in range(the_dense_layers):
                    model.add(Dense(the_units,activation='relu'))
                    model.add(Dropout(0.1))
                
                model.add(Dense(1))
                model.compile(optimizer='adam',
                             loss='mse',
                             metrics=['mape'])
                model.fit(X_train,y_train,batch_size=32,epochs=50,validation_data=(X_test,y_test),callbacks=[checkpoint])
from tensorflow.keras.models import load_model
best_model = load_model('./chankankushuju/10.3250men1lstm1dense1unit32.weights.h5')

这个是我的代码


ValueError                                Traceback (most recent call last)
Cell In[29], line 16
     14 for the_units in units:
     15     filepath=f"./chankankushuju/{{val_mape:.2f}}{{epoch:02d}}men{the_lstm_layers}lstm{the_lstm_layers}dense{the_dense_layers}unit{the_units}.weights.h5"
---> 16     checkpoint = ModelCheckpoint(
     17         filepath=filepath,
     18         save_weights_only=False,
     19         monitor='val_mape',
     20         mode='min',
     21         save_best_only=True)
     22     X,y,X_lately = Stock_Price_LSTM_Data_Precesing(df,the_mem_days,pre_days)
     23     from sklearn.model_selection import train_test_split

File D:\anaconda\Lib\site-packages\keras\src\callbacks\model_checkpoint.py:191, in ModelCheckpoint.__init__(self, filepath, monitor, verbose, save_best_only, save_weights_only, mode, save_freq, initial_value_threshold)
    189 else:
    190     if not self.filepath.endswith(".keras"):
--> 191         raise ValueError(
    192             "The filepath provided must end in `.keras` "
    193             "(Keras model format). Received: "
    194             f"filepath={self.filepath}"
    195         )

ValueError: The filepath provided must end in `.keras` (Keras model format). Received: filepath=./chankankushuju/{val_mape:.2f}{epoch:02d}men1lstm1dense1unit32.weights.h5

找到了拟合最好的一个文件10.3250men1lstm1dense1unit32.weights.h5,想要查看这个文件的数据,但是报错了,这个错误,这是什么问题呢,应该怎么解决呢

  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-04-28 21:40
    关注

    引自免费微信小程序:皆我百晓生

    看起来你在尝试使用 Keras 的 ModelCheckpoint 来保存模型权重,并且在后续的部分试图加载这些保存的模型。然而,在创建 ModelCheckpoint 对象时,你使用的文件路径格式字符串包含动态变量(例如 {val_mape:.2f}{epoch:02d}),这会导致一个 ValueError,因为文件名不符合 Keras 模型文件的标准格式要求——它必须以 .h5 结尾。

    要解决这个问题,你需要在保存模型时使用动态文件名,然后在加载模型时重新构造相同的文件名。这里是一个修改后的代码段,展示了如何处理这种情况:

    首先,我们创建一个函数来动态地生成文件名:

    import os
    
    def generate_file_name(mem_days, lstm_layers, dense_layers, units, val_mape, epoch):
        return f"./chankankushuju/men{mem_days}lstm{lstm_layers}dense{dense_layers}unit{units}_val_mape_{val_mape:.2f}_epoch_{epoch:02d}.h5"
    

    接下来,修改 ModelCheckpoint 部分,这样它就可以接受动态参数了:

    # ... (其他部分保持不变)
    
    for the_mem_days in mem_days:
        for the_lstm_layers in lstm_layers:
            for the_dense_layers in dense_layers:
                for the_units in units:
                    # 生成临时文件名
                    temp_filepath = generate_file_name(
                        the_mem_days, 
                        the_lstm_layers, 
                        the_dense_layers, 
                        the_units, 
                        -1.0,  # 使用一个占位符值,因为我们此时不知道验证 MAPE
                        -1  # 同样,使用一个占位符值,因为我们此时不知道当前的 epoch
                    )
                    # 创建 ModelCheckpoint 对象
                    checkpoint = ModelCheckpoint(
                        filepath=temp_filepath,
                        save_weights_only=False,
                        monitor='val_mape',
                        mode='min',
                        save_best_only=True
                    )
                    # ... (其他部分保持不变)
    

    然后,为了找到并加载最佳模型,我们需要遍历可能的文件名,并检查它们是否存在。可以使用以下代码来完成这一任务:

    import glob
    
    # 找到具有最低验证MAPE的模型
    best_val_mape = float('inf')
    best_epoch = None
    best_filepath = None
    
    # 查找所有可能的模型文件
    pattern = "./chankankushuju/men{}lstm{}dense{}unit{}_val_mape_*.h5".format(*[str(x) for x in [the_mem_days, the_lstm_layers, the_dense_layers, the_units]])
    files = glob.glob(pattern)
    
    # 遍历文件,找出具有最低验证MAPE的模型
    for file in files:
        val_mape_str = file.split('_')[-2].split('.')[0]  # 提取 MAPE 值
        val_mape = float(val_mape_str)
        if val_mape < best_val_mape:
            best_val_mape = val_mape
            best_epoch = int(file.split('_')[-1].split('.')[0])  # 提取 epoch 数字
            best_filepath = file
    
    print(f"Best model found at {best_filepath}")
    
    # 加载最佳模型
    best_model = load_model(best_filepath)
    

    这段代码会找到具有最低验证MAPE的模型文件,并将其加载到 best_model 变量中。确保在运行上述代码之前,已经完成了整个训练循环。这样应该能正确地找到并加载最佳模型。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 5月14日
  • 已采纳回答 5月6日
  • 创建了问题 4月28日