m0_52265432 2023-07-19 11:00 采纳率: 75%
浏览 45

关于深度学习数据列的问题,如何解决?



```python
2023/07/19 10:58:28 [INFO]: There is a NaN in cycle10degC/582_LA92, removing row
Traceback (most recent call last):
  File "G:\研究生论文\OneDrive - stu.hebut.edu.cn\BMS PROJECT\soc_percentage.py", line 70, in <module>
    cycles = lg_data.get_discharge_whole_cycle(train_names, test_names, output_capacity=False, scale_test=True)
  File "G:\研究生论文\OneDrive - stu.hebut.edu.cn\BMS PROJECT\DATA.py", line 18, in get_discharge_whole_cycle
    test = self._get_data(test_names, output_capacity, output_time)  # 获取测试数据
  File "G:\研究生论文\OneDrive - stu.hebut.edu.cn\BMS PROJECT\DATA.py", line 26, in _get_data
    cycle.columns = ['Time Stamp', 'Step', 'Status', 'Prog Time', 'Step Time', 'Cycle', 'Cycle Level',
  File "H:\anaconda3\lib\site-packages\pandas\core\generic.py", line 5915, in __setattr__
    return object.__setattr__(self, name, value)
  File "pandas\_libs\properties.pyx", line 69, in pandas._libs.properties.AxisProperty.__set__
  File "H:\anaconda3\lib\site-packages\pandas\core\generic.py", line 823, in _set_axis
    self._mgr.set_axis(axis, labels)
  File "H:\anaconda3\lib\site-packages\pandas\core\internals\managers.py", line 230, in set_axis
    self._validate_set_axis(axis, new_labels)
  File "H:\anaconda3\lib\site-packages\pandas\core\internals\base.py", line 70, in _validate_set_axis
    raise ValueError(
ValueError: Length mismatch: Expected axis has 14 elements, new values have 15 elements

进程已结束,退出代码1


在做深度学习时间序列预测中遇到了以上问题,起初我认为是
```python
cycle.columns = ['Time Stamp', 'Step', 'Status', 'Prog Time', 'Step Time', 'Cycle', 'Cycle Level',
                             'Procedure', 'Voltage', 'Current','Temperature', 'Capacity', 'WhAccu', 'Cnt', 'Empty']  # 给列指定名称


```这一行出了问题,可是我再删除”Empty“后,报错显示
```python

Traceback (most recent call last):
  File "G:\研究生论文\OneDrive - stu.hebut.edu.cn\BMS PROJECT\soc_percentage.py", line 70, in <module>
    cycles = lg_data.get_discharge_whole_cycle(train_names, test_names, output_capacity=False, scale_test=True)
  File "G:\研究生论文\OneDrive - stu.hebut.edu.cn\BMS PROJECT\DATA.py", line 17, in get_discharge_whole_cycle
    train = self._get_data(train_names, output_capacity, output_time)  # 获取训练数据
  File "G:\研究生论文\OneDrive - stu.hebut.edu.cn\BMS PROJECT\DATA.py", line 26, in _get_data
    cycle.columns = ['Time Stamp', 'Step', 'Status', 'Prog Time', 'Step Time', 'Cycle', 'Cycle Level',
  File "H:\anaconda3\lib\site-packages\pandas\core\generic.py", line 5915, in __setattr__
    return object.__setattr__(self, name, value)
  File "pandas\_libs\properties.pyx", line 69, in pandas._libs.properties.AxisProperty.__set__
  File "H:\anaconda3\lib\site-packages\pandas\core\generic.py", line 823, in _set_axis
    self._mgr.set_axis(axis, labels)
  File "H:\anaconda3\lib\site-packages\pandas\core\internals\managers.py", line 230, in set_axis
    self._validate_set_axis(axis, new_labels)
  File "H:\anaconda3\lib\site-packages\pandas\core\internals\base.py", line 70, in _validate_set_axis
    raise ValueError(
ValueError: Length mismatch: Expected axis has 15 elements, new values have 14 elements

进程已结束,退出代码1

并且第一行的INFO也没有了,实在不知道该如何修改了
贴上全部的代码

import pandas as pd
import numpy as np
import logging
import plotly.graph_objects as go
from datetime import timedelta

DATA_PATH = 'data/LG_HG2_Original_Dataset_McMasterUniversity_Jan_2020'


class LgData():
    def __init__(self, base_path="./"):
        self.path = base_path + DATA_PATH + '/'
        self.logger = logging.getLogger()

    def get_discharge_whole_cycle(self, train_names, test_names, output_capacity=False, scale_test=False,
                                  output_time=False):  # 获取完整的电池循环数据
        train = self._get_data(train_names, output_capacity, output_time)  # 获取训练数据
        test = self._get_data(test_names, output_capacity, output_time)  # 获取测试数据
        train, test = self._scale_x(train, test, scale_test=scale_test)  # 缩放,归一化到相同尺度
        return (train, test)

    def _get_data(self, names, output_capacity, output_time=False):  # 获取数据的内部方法,根据给定的文件名获取电池循环数据
        cycles = []  # 创建一个空列表cycles,用于存储电池循环的数据。
        for name in names:
            cycle = pd.read_csv(self.path + name + '.csv', skiprows=30)
            cycle.columns = ['Time Stamp', 'Step', 'Status', 'Prog Time', 'Step Time', 'Cycle', 'Cycle Level',
                             'Procedure', 'Voltage', 'Current','Temperature', 'Capacity', 'WhAccu', 'Cnt']  # 给列指定名称
            cycle = cycle[(cycle['Status'] == 'TABLE') | (cycle['Status'] == 'DCH')]  # 仅保留数据处于表格状态和放电状态的记录

            max_discharge = abs(min(cycle['Capacity']))  # 取容量的最小值的绝对值,代表电池放电过程中的最大变化
            cycle['Soc Capacity'] = max_discharge + cycle['Capacity']  # 最大容量减去放电容量等于现在剩余的容量
            cycle['Soc Percentage'] = cycle['Soc Capacity'] / max(cycle['Soc Capacity'])
            x = cycle[['Voltage', 'Current', 'Temperature']].to_numpy()  # 将这三列转化为numpy数组,两个括号是要把它作为数据框返回,不是单纯一列

            if output_time:
                cycle['Prog Time'] = cycle['Prog Time'].apply(
                    self._time_string_to_seconds)  # 将时间字符串转化为秒数表示,progtime表示从开始当当前的累计时间
                cycle['Time in Seconds'] = cycle['Prog Time'] - cycle['Prog Time'][0]  # 计算相对于第一个时间点的时间差,以秒为单位

            if output_capacity:
                if output_time:
                    y = cycle[['Soc Capacity',
                               'Time in Seconds']].to_numpy()  # 如果output_capacity为True且output_time为True
                    # ,表示需要输出电池循环数据中的容量信息,并且将时间信息也一同输出。
                    # 'Soc Capacity'(剩余容量):这一列包含了电池循环过程中每个时间点的剩余容量值。剩余容量是通过将电池的最大容量减去电池放电容量得到的,表示当前剩余可用的电荷容量。 'Time
                    # in Seconds'(相对于第一个时间点的时间差):这一列包含了电池循环过程中每个时间点相对于第一个时间点的时间差值。它表示从电池开始放电到当前时间经过的秒数,用于记录电池放电过程的时间信息。
                else:
                    y = cycle[['Soc Capacity', ]].to_numpy()
            # 如果output_capacity为False,且output_time为True,则y包含
            # 'Soc Percentage'(剩余容量相对于最大容量的百分比)和
            # 'Time in Seconds'(相对于第一个时间点的时间差)两列的数据。
            else:
                if output_time:
                    y = cycle[['Soc Percentage', 'Time in Seconds']].to_numpy()
                else:
                    y = cycle[['Soc Percentage', ]].to_numpy()

                if np.isnan(np.min(x)) or np.isnan(np.min(y)):  # 去除最小值
                    self.logger.info("There is a NaN in cycle" + name + ', removing row')  # 程序正常运行过程中产生的一些信息
                    x = x[~np.isnan(x).any(axis=1)]#axis = 1,按照列的方向对每一行操作
                    y = y[~np.isnan(y).any(axis=1)].reshape(-1, y.shape[1])#-1表示自动推断该维度的大小,而y.shape[1]表示要保持的列数。
                    # 因此,reshape(-1, y.shape[1])的作用是将数组y重新排列成一个新的二维数组,其中保持列数为y.shape[1],而行数根据数组的大小自动计算。

                cycles.append((x, y))

        return cycles

    # cycle[0] = array([[voltage_1, current_1, temperature_1],
    # [voltage_2, current_2, temperature_2],
    # ...
    #  [voltage_n, current_n, temperature_n]])

    def _time_string_to_seconds(self, input_string):  # 将时间字符串转化为秒数
        time_parts = input_string.split(':')  # 将时间字符串按照冒号进行分割,创建一个列表
        second_parts = time_parts[2].split(':')  # 得到列表的第三部分,就是秒
        return timedelta(hours=int(time_parts[0]),
                         minutes=int(time_parts[1]),
                         seconds=int(second_parts[0]),
                         microseconds=int(second_parts[1])).total_seconds()  # 使用int函数将字符串转化为整数,获取时间间隔的总秒数

    def _scale_x(self, train, test, scale_test=False):  # train是训练集的输入数据,test是测试集的输入数据,进行归一化
        for index_feature in range(len(
                train[0][0][0])):  # train[0][0][0] 表示训练集中的第一个循环数据的输入数据中的第一个时间步的特征数据。也就是说,它是输入数据的第一行,表示第一个时间步的特征向量或特征值。
            # train是一个三维列表,它的第一维表示样本(cycles),第二维表示时间步,第三维表示特征。train[0][0][0]表示第一个样本的第一个时间步的特征数据。
            feature_min = min([min(cycle[0][:, index_feature]) for cycle in train])
            feature_max = max([max(cycle[0][:, index_feature]) for cycle in train])
            # cycle[0]:这里的 cycle 是指训练数据集中的一个样本(电池循环)。cycle[0] 表示这个样本的特征数据数组,是一个二维数组,其中每一行代表一个时间步的特征数据。
            # cycle[0][:, index_feature]:这个索引操作提取了特定特征列 index_feature 中的所有数据。也就是说,它选择了所有时间步中特征数据的第 index_feature 列。
            # min(cycle[0][:, index_feature]):这是对选定的特征列求最小值,即找到这个样本中该特征列的最小值。
            for i in range(len(train)):
                train[i][0][:, index_feature] = (train[i][0][:, index_feature] - feature_min) / (
                        feature_max - feature_min)
            if scale_test:
                for i in range(len(test)):
                    test[i][0][:, index_feature] = (test[i][0][:, index_feature] - feature_min) / (
                            feature_max - feature_min)

        return train, test

    def get_stateful_cycle(self, cycles, pad_num=0, steps=100):
        """
        获取有状态的电池循环数据,可以设置填充数字和步长。
        参数:
        cycles: 包含训练和测试数据的元组 (train_cycles, test_cycles)。
                每个train_cycles或test_cycles是一个列表,包含电池循环数据。
                每个电池循环数据由特征数组和对应的标签数组组成。
        pad_num: 填充数字,当电池循环数据长度不足时,使用此数字填充数据,默认为0。
        steps: 步长,即每个有状态数据的长度,默认为100。
        返回值:
        包含有状态训练数据和测试数据的元组 (train_x, train_y, test_x, test_y)。
        train_x和test_x包含有状态的特征数据,train_y和test_y包含对应的目标标签数据。
        """
        # 计算所有电池循环数据中最长的长度,并作为有状态数据的长度
        # cycles[0] 表示 train_cycles 列表,而 cycles[1] 表示 test_cycles 列表。
        # len(cycle[0]) 表示 train_cycles 中每个电池循环数据的长度(特征数组的长度),而 len(cycle[1]) 表示 test_cycles 中每个电池循环数据的长度。
        # max(len(cycle[0]) for cycle in cycles[0]) 表示计算 train_cycles 中所有电池循环数据长度的最大值,即找到 train_cycles 中最长的电池循环数据长度。
        max_length = max(max(len(cycle[0]) for cycle in cycles[0]), max(len(cycle[0]) for cycle in cycles[1]))
        # 将训练和测试数据转换为有状态数据,并进行填充
        train_x, train_y = self._to_padded_cycle(cycles[0], pad_num, max_length)
        test_x, test_y = self._to_padded_cycle(cycles[1], pad_num, max_length)
        # 将有状态数据进一步切分为步长为steps的数据
        train_x = self._split_cycle(train_x, steps)
        train_y = self._split_cycle(train_y, steps)
        test_x = self._split_cycle(test_x, steps)
        test_y = self._split_cycle(test_y, steps)
        # 输出有状态数据的形状
        self.logger.info("Train x: %s, train y: %s | Test x: %s, test y: %s" %
                         (train_x.shape, train_y.shape, test_x.shape, test_y.shape))
        # 返回有状态的训练数据和测试数据
        return (train_x, train_y, test_x, test_y)

    def _to_padded_cycle(self, cycles, pad_num, max_length):  # 用于将给定的电池循环数据进行填充(padding)以匹配最大长度。
        # cycles: 电池循环数据的列表,其中每个元素是一个元组,包含两个numpy数组:
        # cycle[0]代表输入数据(通常是电池的特征数据,如电压、电流、温度等)
        # cycle[1]代表输出数据(通常是关于电池容量的信息,或者容量百分比等)
        x_length = len(cycles[0][0][0])  # 输入数据
        y_length = len(cycles[0][1][0])  # 输出数据
        x = np.full((len(cycles), max_length, x_length), pad_num,
                    dtype=float)  # 创建一个形状为(len(cycles), max_length, x_length)的数组x,并用pad_num填充,数据类型为浮点型。
        y = np.full((len(cycles), max_length, y_length), pad_num, dtype=float)
        for i, cycle in enumerate(cycles):  # 遍历电池循环数据列表cycles,同时获取索引i和每个循环数据cycle。
            x[i, :cycle[0].shape[0]] = cycle[0]  # 将当前循环数据cycle的特征数组cycle[0]的内容复制到数组x的第i行,保留原始数据的长度。
            y[i, :cycle[1].shape[0]] = cycle[1]
        return x, y  # 将不同长度的电池循环数据填充为相同的长度

    def _split_cycle(self, cycles, steps):  # 将循环数据切分成多个步长,用于模型训练。
        features = cycles.shape[2]  # 获取循环数据数组cycles的第三个维度的长度,即特征的数量。
        time_steps = cycles.shape[1]  # 获取循环数据数组cycles的第二个维度的长度,即时间步的数量。
        new_cycles = np.empty((0, time_steps // steps, steps, features), float)
        for cycle in cycles:  # 遍历循环数据数组cycles中的每个循环数据cycle
            new_cycle = np.empty((0, steps, features), float)  # 创建一个空的三维数组
            for i in range(0, len(cycle) - steps, steps):  # 在每个循环数据cycle中以步长为steps进行切分。
                next_split = np.array(cycle[i:i + steps]).reshape(1, steps,
                                                                  features)  # 将循环数据cycle中的一段切分为步长为steps的子数组,并将其转换为形状为(1, steps, features)的数组。
                new_cycle = np.concatenate((new_cycle, next_split))  # 将切分后的子数组添加到new_cycle中。
            new_cycles = np.concatenate((new_cycles, new_cycle.reshape(1, time_steps // steps, steps,
                                                                       features)))  # 将切分后的单个循环数据new_cycle添加到new_cycles中,
            # 并重新调整new_cycle的形状为(1, time_steps // steps, steps, features)。
        return new_cycles

    #################################
    #
    # get_discharge_multiple_step
    #
    #################################

    def get_discharge_multiple_step(self, cycles, steps):
        train_x, train_y = self._split_to_multiple_step(cycles[0], steps)  # 将训练数据cycles[0]切分为多步长的输入特征数据
        test_x, test_y = self._split_to_multiple_step(cycles[1],
                                                      steps)  # 将测试数据cycles[1]切分为多步长的输入特征数据test_x和目标标签数据test_y。
        self.logger.info("Train x: %s, train y: %s | Test x: %s, test y: %s" %
                         (train_x.shape, train_y.shape, test_x.shape,
                          test_y.shape))  # 打印训练数据和测试数据的形状信息,使用日志记录器self.logger输出。
        return (train_x, train_y, test_x, test_y)

    def _split_to_multiple_step(self, cycles, steps):  # 将给定的循环数据按照指定的步长切分为多个子数组
        x_length = len(cycles[0][0][0])
        y_length = len(cycles[0][1][0])
        x = np.empty((0, steps, x_length), float)
        y = np.empty((0, steps, y_length), float)
        for cycle in cycles:
            for i in range(0, len(cycle[0]) - steps, steps):
                next_x = np.array(cycle[0][i:i + steps]).reshape(1, steps, x_length)
                next_y = np.array(cycle[1][i:i + steps]).reshape(1, steps, y_length)
                x = np.concatenate((x, next_x))  # 将切分后的输入特征数据添加到已有的输入特征数据数组x中。
                y = np.concatenate((y, next_y))  # 将切分后的目标标签数据添加到已有的目标标签数据数组y中。
        return x, y

    def keep_only_y_end(self, y, step, is_stateful=False):
        if is_stateful:
            return y[:, :, ::step]  # 对于有状态的数据,保留目标标签数据的末尾数据,并按照步长进行采样。其中y[:, :, ::step]表示对y数组的第三个维度(时间步)进行步长为step的采样。
        else:
            return y[:, ::step]


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)#输出级别改为INFO

    train_names = [
        '25degC/551_LA92',
        '25degC/551_Mixed1',
        '25degC/551_Mixed2',
        '25degC/551_UDDS',
        # '25degC/551_US06',
        # '25degC/552_Mixed3',
        #
        # '25degC/552_Mixed7',
        # '25degC/552_Mixed8',

        # '0degC/589_LA92',
        #
        # '0degC/589_UDDS',
        # '0degC/589_US06',
        # '0degC/590_Mixed4',
        # '0degC/590_Mixed6',
        # '0degC/590_Mixed7',
        # '0degC/590_Mixed8',

        # '10degC/567_Mixed1',
        # '10degC/567_Mixed2',
        # '10degC/571_Mixed4',
        # '10degC/571_Mixed5',
        # '10degC/571_Mixed6',
        # '10degC/571_Mixed7',
        #
        # '10degC/582_LA92',

        # '40degC/556_Mixed2',
        # '40degC/556_UDDS',
        # '40degC/556_US06',
        # '40degC/557_Mixed3',
        # '40degC/562_Mixed4',
        # '40degC/562_Mixed5',
        # '40degC/562_Mixed6',
        #
        # '40degC/562_Mixed8',

        # 'n10degC/596_LA92',
        # 'n10degC/596_UDDS',
        # 'n10degC/601_Mixed1',
        # 'n10degC/601_Mixed2',
        # 'n10degC/601_US06',
        # 'n10degC/602_Mixed4',
        # 'n10degC/602_Mixed5',
        # 'n10degC/604_Mixed3',

        # 'n20degC/610_LA92',
        # 'n20degC/610_Mixed1',
        # 'n20degC/610_Mixed2',
        # 'n20degC/610_UDDS',
        # 'n20degC/610_US06',
        #
        # 'n20degC/611_Mixed4',
        # 'n20degC/611_Mixed5',
        #
        # 'n20degC/611_Mixed8',
    ]
    test_names = [
        '25degC/552_Mixed4',
        '25degC/552_Mixed5',
        '25degC/552_Mixed6',

        # '0degC/589_Mixed1',
        # '0degC/589_Mixed2',

        # '10degC/571_Mixed8',
        # '10degC/576_UDDS',

        # '40degC/556_LA92',
        # '40degC/556_Mixed1',
        #
        # '40degC/562_Mixed7',

        # 'n10degC/604_Mixed6',
        # 'n10degC/604_Mixed7',
        # 'n10degC/604_Mixed8',

        # 'n20degC/611_Mixed3',
        #
        # 'n20degC/611_Mixed6',
        # 'n20degC/611_Mixed7',
    ]

    stateful_config = True
    steps = 300

    lg_data = LgData()
    cycles = lg_data.get_discharge_whole_cycle(train_names, test_names)
    print("Train/Test %d" % len(cycles))
    print("Train cycles: %d" % len(cycles[0]))
    print("x/y %d" % len(cycles[0][0]))
    print("time_steps: %d" % len(cycles[0][0][0]))
    print("x features: %d" % len(cycles[0][0][0][0]))

    if not stateful_config:
        train_x, train_y, test_x, test_y = lg_data.get_discharge_multiple_step(cycles, steps)

        train_y = lg_data.keep_only_y_end(train_y, steps)
        test_y = lg_data.keep_only_y_end(test_y, steps)

        display_x = train_x.reshape(train_x.shape[0] * train_x.shape[1], train_x.shape[2])
        display_y = train_y.reshape(train_y.shape[0] * train_y.shape[1], train_y.shape[2])
    else:
        train_x, train_y, test_x, test_y = lg_data.get_stateful_cycle(cycles, steps=steps)

        display_x = train_x.reshape(train_x.shape[0] * train_x.shape[1] * train_x.shape[2], train_x.shape[3])
        display_y = train_y.reshape(train_y.shape[0] * train_y.shape[1] * train_y.shape[2], train_y.shape[3])

    fig = go.Figure()
    fig.add_trace(go.Scatter(y=display_x[:, 0],
                             mode='lines', name='Voltage'))
    fig.add_trace(go.Scatter(y=display_x[:, 1],
                             mode='lines', name='Current'))
    fig.add_trace(go.Scatter(y=display_x[:, 2],
                             mode='lines', name='Temperature'))
    fig.update_layout(title='X Data',
                      xaxis_title='Step',
                      yaxis_title='X',
                      width=1400,
                      height=600)#设置标签
    fig.show()#显示图

    fig = go.Figure()
    fig.add_trace(go.Scatter(y=display_y[:, 0],
                             mode='lines', name='SoC'))
    fig.update_layout(title='Y Data',
                      xaxis_title='Step',
                      yaxis_title='SoC',
                      width=1400,
                      height=600)
    fig.show()


```DATA文件单独运行是没有问题的,配上下面这个文件就会出现刚才的问题
```python
import numpy as np
import pandas as pd
import scipy.io
import math
import importlib
import ntpath
import logging
import time
import sys

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader

import matplotlib.pyplot as plt

data_path = "./"

sys.path.append(data_path)  # 将指定的路径 data_path 添加到系统的模块搜索路径中。这样做的目的是为了在程序中能够导入位于 data_path 目录下的自定义模块或库。
from DATA import LgData


importlib.reload(logging)
logging.basicConfig(format='%(asctime)s [%(levelname)s]: %(message)s', level=logging.DEBUG, datefmt='%Y/%m/%d %H:%M:%S')

train_names = [
    '0degC/589_Mixed1',
    '0degC/589_Mixed2',
    '0degC/590_Mixed4',
    '0degC/590_Mixed5',
    '0degC/590_Mixed6',
    '0degC/590_Mixed8',

    '10degC/567_Mixed1',
    '10degC/567_Mixed2',
    '10degC/571_Mixed4',
    '10degC/571_Mixed5',
    '10degC/571_Mixed6',
    '10degC/571_Mixed8',

    '25degC/551_Mixed1',
    '25degC/551_Mixed2',
    # '25degC/552_Mixed3',
    '25degC/552_Mixed4',
    '25degC/552_Mixed5',
    '25degC/552_Mixed6',
    '25degC/552_Mixed8',
]
test_names = [
    '0degC/589_LA92',
    '0degC/589_UDDS',
    '0degC/589_US06',
    '0degC/590_Mixed7',

    '10degC/582_LA92',
    '10degC/576_UDDS',
    '10degC/567_US06',
    '10degC/571_Mixed7',

    '25degC/551_LA92',
    '25degC/551_UDDS',
    '25degC/551_US06',
    '25degC/552_Mixed7',
]

steps = 300

lg_data = LgData(data_path)
cycles = lg_data.get_discharge_whole_cycle(train_names, test_names, output_capacity=False, scale_test=True)
train_x, train_y, test_x, test_y = lg_data.get_discharge_multiple_step(cycles, steps)

train_y = lg_data.keep_only_y_end(train_y, steps)
test_y = lg_data.keep_only_y_end(test_y, steps)

# Convert numpy arrays to PyTorch tensors
train_x = torch.tensor(train_x, dtype=torch.float32)
train_y = torch.tensor(train_y, dtype=torch.float32)
test_x = torch.tensor(test_x, dtype=torch.float32)
test_y = torch.tensor(test_y, dtype=torch.float32)


# Define custom dataset
class BatteryDataset(Dataset):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __len__(self):
        return len(self.x)

    def __getitem__(self, idx):
        return self.x[idx], self.y[idx]


# Create data loaders
train_dataset = BatteryDataset(train_x, train_y)
test_dataset = BatteryDataset(test_x, test_y)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)


# Define LSTM model
class LSTMModel(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(LSTMModel, self).__init__()
        self.hidden_size = hidden_size
        self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True)
        self.fc1 = nn.Linear(hidden_size, hidden_size)
        self.fc2 = nn.Linear(hidden_size, output_size)

    def forward(self, x):
        _, (h, _) = self.lstm(x)
        h = h.squeeze(0)
        out = self.fc1(h)
        out = self.fc2(out)
        return out


# Set device for training
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# Define model
input_size = train_x.shape[2]
hidden_size = 256
output_size = 1
model = LSTMModel(input_size, hidden_size, output_size)
model = model.to(device)

# Define loss function and optimizer
criterion = nn.SmoothL1Loss()
optimizer = optim.Adam(model.parameters(), lr=0.00001)

# Training loop
num_epochs = 1000
best_loss = float('inf')
best_model_path = data_path + 'results/trained_model/%s_best.pth' % experiment_name

for epoch in range(num_epochs):
    model.train()
    train_loss = 0.0

    for inputs, targets in train_loader:
        inputs = inputs.to(device)
        targets = targets.to(device)

        optimizer.zero_grad()

        outputs = model(inputs)
        loss = criterion(outputs, targets)

        loss.backward()
        optimizer.step()

        train_loss += loss.item()

    train_loss /= len(train_loader)

    # Validation
    model.eval()
    val_loss = 0.0

    with torch.no_grad():
        for inputs, targets in test_loader:
            inputs = inputs.to(device)
            targets = targets.to(device)

            outputs = model(inputs)
            loss = criterion(outputs, targets)

            val_loss += loss.item()

        val_loss /= len(test_loader)

    # Print epoch statistics
    print(f"Epoch [{epoch + 1}/{num_epochs}] - Train Loss: {train_loss:.6f} - Val Loss: {val_loss:.6f}")

    # Save best model
    if val_loss < best_loss:
        best_loss = val_loss
        torch.save(model.state_dict(), best_model_path)

# Load best model
model.load_state_dict(torch.load(best_model_path))

# Save model
model_path = data_path + 'results/trained_model/%s.pth' % experiment_name
torch.save(model.state_dict(), model_path)

# Testing
model.eval()
test_loss = 0.0

with torch.no_grad():
    for inputs, targets in test_loader:
        inputs = inputs.to(device)
        targets = targets.to(device)

        outputs = model(inputs)
        loss = criterion(outputs, targets)

        test_loss += loss.item()

test_loss /= len(test_loader)

print(f"Test Loss: {test_loss:.6f}")

  • 写回答

5条回答 默认 最新

  • 大师兄6668 Python领域新星创作者 2023-07-19 11:05
    关注

    以下回答部分来自GPT:
    根据错误信息,问题出现在以下代码段:

    cycle.columns = ['Time Stamp', 'Step', 'Status', 'Prog Time', 'Step Time', 'Cycle', 'Cycle Level', ...
    

    错误信息提示长度不匹配,预期的轴(axis)有14个元素,而新的值有15个元素。这可能意味着你给定的列名称数量与数据的列数不匹配。

    请确保 cycle 变量的列数与你尝试设置的列名称数量一致。你可以通过输出 cycle 的列数来进行检查:

    print(len(cycle.columns))
    

    然后确认给定的列名称数量与实际的列数相同。

    另外,还要检查一下数据是否存在缺失值(NaN)。根据日志信息,有一个 NaN 值在 cycle10degC/582_LA92 中,导致移除了该行数据。这可能会导致数据的列数发生变化,与设置的列名称数量不匹配。在处理数据之前,你可以先进行缺失值处理,如删除包含 NaN 的行或使用适当的填充方法。

    如果问题仍然存在,请提供更多代码和数据的相关信息,以便我能够更好地帮助你解决问题。

    评论

报告相同问题?

问题事件

  • 修改了问题 7月19日
  • 创建了问题 7月19日

悬赏问题

  • ¥20 求快手直播间榜单匿名采集ID用户名简单能学会的
  • ¥15 DS18B20内部ADC模数转换器
  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历