【问题标题】:loss is "nan" and accuracy is 0 in a CNN (Keras) model in EEG classification在脑电图分类中的 CNN (Keras) 模型中,损失为“nan”且准确率为 0
【发布时间】:2021-07-22 01:49:21
【问题描述】:

我正在尝试对我在网上找到的 EEG 数据集进行分类。 (BCI comp III,数据集 V)

我只是在玩不同的模型作为一个副项目,我虽然会从 CNN 开始。

这是从文件中提取数据的一段代码:

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)

然后我以这种方式制作训练标签和数据:

    # 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 只是一个带通滤波器和一个陷波滤波器:

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

最后,这是我制作的模型:

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

最后,像这样编译模型:

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)

但是当训练开始时,我得到 nan 表示损失和 0 表示准确度!有时准确度从 0.0903 的值开始,然后变为 0 并保持在那里。

我生成了随机值矩阵 (np.random.rand(size)) 来检查模型,ofc 的准确度为 0.33(机会准确度,三类)。

我还在输入中检查了nan,但什么也没得到。

会有什么问题?是模型吗?还是数据根本上是错误的?

会有什么问题?

P.S:我最多只使用 8000 个数据点作为输入以避免可变长度输入,因为输入具有不同的长度。

P.S:这是过滤器对数据所做的:

未过滤的数据:

过滤后的数据:

这是输入矩阵的 32 列中的一个随机输入向量。

【问题讨论】:

    标签: python tensorflow machine-learning deep-learning conv-neural-network


    【解决方案1】:

    改变

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

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

    当您的model 的最后一层没有像softmaxsigmoid 这样的激活时,您使用from_logits=True(如果没有该激活,它将返回logits,因此您可以将其设置为True否则False)。

    【讨论】:

    • 嗨 Abhishek,我做到了,但仍然得到同样的结果
    • @NeuroEng 现在我看到您的批量大小只有 1。将批量大小增加到适合您的内存的任何内容,从 8,16,32... 等等.
    • 我改成 8 和 32,结果还是一样。如果模型在随机数据上给出了机会准确性,这是否意味着模型工作正常并且问题出在其他地方?
    • 好的。现在我有几个问题。你的模型的输入层在哪里,输入的形状是什么?另外,您有多少个课程,它们是否相互排斥?
    • 输入数据是104个输入集,每个输入集的维度为32x8000(较长的长度是可变的,但我只选择了8000,最大值为10100),数据有3个类
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    • 1970-01-01
    • 2023-03-23
    • 2018-08-03
    • 2019-10-06
    • 1970-01-01
    • 2020-06-05
    相关资源
    最近更新 更多