keras CNN模型精度未提高

pcrecxhr  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(158)

我有很多时间序列数据(时间和电压)。我试图将此时间序列数据转换为图像阵列,以便将其用作图像,我可以在图像上应用CNN,并可以对数据来自哪个设备进行分类。这是基于不同设备产生不同电压特征(应可区分)的假设。我应用了一个函数,将时间序列数据分割成一个图像数组,然后使用CNN进行分类。图像大小为14x100像素。问题是模型的准确性没有变化或几乎没有变化。请在下面找到完整的编码

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import os
import tensorflow as tf
from sklearn.metrics import plot_confusion_matrix, ConfusionMatrixDisplay, confusion_matrix

#Reading data from directory
import pathlib
data_dir = ('Test')
data_dir = pathlib.Path(data_dir)

#File name dictionary
file_name_dict = {
    'Device_1' : list(data_dir.glob('Device_1/*.csv')),
    'Device_2' : list(data_dir.glob('Device_2/*.csv')),
    'Device_3' : list(data_dir.glob('Device_3/*.csv')),
    'Device_4' : list(data_dir.glob('Device_4/*.csv')),
    'Device_5' : list(data_dir.glob('Device_5/*.csv')),
    'Device_6' : list(data_dir.glob('Device_6/*.csv'))
}

#File label dictionary
file_label_dict = {
    'Device_1' : 0,
    'Device_2' : 1,
    'Device_3' : 2,
    'Device_4' : 3,
    'Device_5' : 4,
    'Device_6' : 5,
}

#Processing and labelling the data

device_list, device_label = [],[]   #compressed

#Reading each file, replacing original value with moving average value
for device_name, folder in file_name_dict.items():
    for file in folder:
        file_df = pd.read_csv(str(file))
        file_df.columns = ['time', 'voltage']
        file_df['MA'] = file_df['voltage'].rolling(10,min_periods=0).mean()# moving average
        file_df= file_df.drop('voltage',axis=1)
        file_df.rename(columns={'MA':'voltage'},inplace=True)
        
        #Applying a function
        threshold = file_df['voltage'].diff().gt(1)
        group = (threshold&~threshold.shift(fill_value=False)).cumsum().add(1)
        time= lambda i: i['time'].groupby(group).apply(lambda j: j- j.iloc[0])
        df_2 = (file_df.assign(bit=group,time=time).pivot(index='bit', columns='time', values='voltage'))

        df_3 = df_2.copy()
        df_3.reset_index(drop=True, inplace=True)
        df_3 = df_3.rename_axis(None, axis=1)

        #Compressing to  14 rows 100 columns
        df_4=df_3.iloc[:10, :100]
        
        #Filling out null values
        df_4= df_4.fillna(method='pad')
        
        #Saving each dataframe to a list
        device_list.append(df_4)
        device_label.append(file_label_dict[device_name])
        
#Converting to numpy array
X = np.array(device_list)
y = np.array(device_label)

#Train test split
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size= 0.30,random_state=42)

#Adding 1 dimension to make it, two dimension, to use Conv2D
X_train = X_train.reshape(X_train.shape[0],X_train.shape[1],X_train.shape[2],1)
X_test = X_test.reshape(X_test.shape[0],X_test.shape[1],X_test.shape[2],1)

#scaling data from 0 to 1
X_train_scaled = X_train/36 #Max voltage value 36
X_test_scaled = X_test/36

#Building a CNN a model
#Set random seed
tf.random.set_seed(42)
model_2 = tf.keras.Sequential([
    
    tf.keras.layers.Conv2D(filters=3, kernel_size=3, strides=1, padding="same", activation='relu',kernel_initializer='normal',
                           input_shape=(X_train_scaled[0].shape)),
    tf.keras.layers.MaxPool2D(pool_size=2),
    
    
    tf.keras.layers.Conv2D(6,3, padding="same", activation='relu',kernel_initializer='normal',),
    tf.keras.layers.MaxPool2D(pool_size=2),
    
    tf.keras.layers.Conv2D(12,3, padding="same",activation='relu',kernel_initializer='normal',),
    tf.keras.layers.MaxPool2D(pool_size=2),
    
    
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(72,activation='relu',kernel_initializer='normal',),
    tf.keras.layers.Dense(6, activation= 'softmax') #Output layer

])
model_2.summary()

#Training
from tensorflow import keras
opt = keras.optimizers.Adam(lr=0.01)
model_2.compile(optimizer=opt,
              loss='sparse_categorical_crossentropy',
                metrics= ['accuracy'])

             
history= model_2.fit(X_train_scaled, y_train,batch_size= 128 , epochs=200,validation_split=0.20, verbose=1) 
history

#Test
loss, accuracy= model_2.evaluate(X_test_scaled, y_test)
print(f'Loss: {loss}, Accuracy: {accuracy}')
print('Test accuracy : ',accuracy*100,'%')

第一次
准确度从0.16开始上升到0.18,但未超过0.18。我尝试更改CNN模型的不同参数,如添加更多卷积层、密集层、更改adam优化器的学习速率、使用不同的优化器、尝试使用不同的batch_size,但模型的准确度根本没有提高。
我只是不知道我在处理数据的过程中是否做错了什么。有人能看一下代码,告诉我我标记数据的方式是正确的,还是我的代码有问题。如果代码是正确的,我非常感谢任何关于如何提高准确性的建议。我只是不确定这是编码问题还是模型有问题,或者数据不足以完成分类任务。

mkshixfv

mkshixfv1#

CNN通常用于数据之间的空间关系(就像你说的,比如图片)但是看起来,你的数据没有这种空间关系,而是你把它们描述成时间序列,对于时间序列,通常使用所谓的递归神经网络它们将时间序列的一个步骤作为输入,并且除了下一个时间序列步骤之外,还将隐藏状态传输到下一个步骤。也许这种型号更适合你的需要。

相关问题