简体   繁体   English

在脑电图分类的 CNN (Keras) 模型中,损失为“nan”,准确度为 0

[英]loss is “nan” and accuracy is 0 in a CNN (Keras) model in EEG classification

I am trying to classify an EEG dataset I found online.我正在尝试对我在网上找到的 EEG 数据集进行分类。 (BCI comp III, Dataset V) (BCI comp III,数据集 V)

I am just playing around with different models as a side project, and I though I'd start with a CNN.我只是在玩不同的模型作为一个副项目,虽然我会从 CNN 开始。

This is the piece of code for extracting the data from the files:这是从文件中提取数据的一段代码:

def ext_data(subNum, rawNum):
file_name = r'C:\Users\me\OneDrive\Desktop\EEG\EEG datasets\BCI COMP III\Dataset V\train_subject{}_raw{:02d}.asc'.format(subNum, rawNum)
import numpy as np
data = np.loadtxt(file_name)
print("count of original data is {}".format(len(data)))
org_data = []
i = 0
while True:
    if i == len(data)-1:
        break
    meta = []
    cl = data[i,32]
    meta.append(data[i,0:32])
    while 1:
        i += 1
        if i == len(data)-1:
            meta.append(data[i, 0:32])
            org_data.append([np.array(meta).reshape(len(meta),32),cl])
            break
        if data[i,32] == cl:
            meta.append(data[i,0:32])
        else:
            org_data.append([np.array(meta).reshape(len(meta),32),cl])
            break
    #print(i)
print(len(org_data))
return np.array(org_data)

and then I make the training labels and data this way:然后我以这种方式制作训练标签和数据:

    # total number of inptu samples = 104
data = np.ones(shape=[104, 2], dtype=object)
index = 0
for i in range(1, 4):
    for j in range(1, 4):
        print("index is {}".format(index))
        dum = ext_data(i, j)
        data[index:len(dum) + index] = dum
        index += len(dum)
train_x = np.zeros(shape = [104,8000,32], dtype=np.float32)
for i in range(104):
    for j in range(32):
        train_x[i,:,j] = beta_filter(data[i,0][0:8000,j])
train_x = train_x/40
train_y = np.array(data[:,1])

beta_filter is just a band-pass filter and a notch filter: beta_filter只是一个带通滤波器和一个陷波滤波器:

def butter_bandpass(lowcut, highcut, fs, order=3):
    nyq = 0.5 * fs
    low = lowcut / nyq
    high = highcut / nyq
    sos = butter(order, [low, high], analog=False, btype='band', output='sos')
    return sos

def butter_bandpass_filter(data, lowcut, highcut, fs, order=3):
        sos = butter_bandpass(lowcut, highcut, fs, order=order)
        y = sosfiltfilt(sos, data)
        return y

def butter_notch_filter(data, lowcut, highcut, fs, order = 3):
    nyq = 0.5 * fs
    low = lowcut / nyq
    high = highcut / nyq
    sos = butter(order, [low, high], analog=False, btype='stop', output='sos')
    y = sosfiltfilt(sos, data)
    return y

def beta_filter(input):
    beta = butter_bandpass_filter(input, 12, 30, 512)
    beta = butter_notch_filter(beta,48,52,512)
    return beta

and finally, this is the model I made:最后,这是我制作的模型:

def generate_model():
model = tf.keras.Sequential([
    
    # first convolutional layer
    tf.keras.layers.Conv2D(32, (3, 3), strides=(1, 1), activation="relu"),
    tf.keras.layers.MaxPool2D(pool_size=2, strides=2),
    
    # second convolutional layer
    tf.keras.layers.Conv2D(16, (3, 3), strides=(1, 1), activation="relu"),
    tf.keras.layers.MaxPool2D(pool_size=2, strides=2),

    # fully connected classifier
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(32, activation='relu'),
    tf.keras.layers.Dense(3, activation='softmax')  # 3 outputs
])
return model

and finally, compile the model like this:最后,像这样编译模型:

model = generate_model()
model.compile(optimizer='adam',
            loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
            metrics=['accuracy'])

history = model.fit(train_x, train_y, epochs=15, batch_size=1)

but when training starts, I got nan for loss and 0 for accuracy!但是当训练开始时,我得到了nan损失和 0 准确性! sometimes accuracy starts with a value of 0.0903, and then goes to 0 and stays there.有时精度从 0.0903 的值开始,然后变为 0 并保持在那里。

I generated matrices of random values ( np.random.rand(size) ) to check the model, and ofc got an accuracy of 0.33 (the chance accuracy, three classes).我生成了随机值矩阵 ( np.random.rand(size) ) 来检查模型,ofc 的准确度为 0.33(机会准确度,三个类别)。

I also checked for nan within the input, and got nothing.我还在输入中检查了nan ,但一无所获。

what would be the problem?会有什么问题? is it the model?是模型吗? or is the data fundamentally wrong?还是数据根本错误?

What would be the problem?会有什么问题?

PS : I only use up to 8000 data points for the input to avoid the variable length input, as inputs have different lengths. PS :我最多只使用 8000 个数据点作为输入以避免可变长度输入,因为输入具有不同的长度。

PS : this is what the filter does to the data: PS :这是过滤器对数据的作用:

Unfiltered data:未过滤的数据:

在此处输入图片说明

filtered data:过滤数据:

在此处输入图片说明

This is one random input vector from the 32 columns of the input matrix.这是来自输入矩阵的 32 列的一个随机输入向量。

change改变

loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

to

loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False)

You use from_logits=True when the last layer of your model doesn't have an activation like softmax or sigmoid (without that activation it will return logits and hence you can have it set to True else False ).model的最后一层没有像softmaxsigmoid这样的激活时,您可以使用from_logits=True (没有该激活,它将返回 logits,因此您可以将其设置为True else False )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM