【问题标题】:keras CNN 1-D -> Why are all predicted classes returning equal?keras CNN 1-D -> 为什么所有预测的类都返回相等?
【发布时间】:2018-07-26 15:42:51
【问题描述】:

我编写了一个 CNN 1-D,但在执行 model.predict_classes(X) 命令时,所有返回的类都是相同的。返回示例在以下屏幕中。为什么所有预测的类都返回相等?我已经把输入改成不同的了,结果还是一样的。

model = ke.models.Sequential() 
nbfeatures=5
model.add(Conv1D(filters=2,kernel_size=2,input_shape=(nbfeatures, 1),activation = 'relu')) 
model.add(Conv1D(filters=2,kernel_size=2)) 
model.add( MaxPool1D(pool_size=2))
model.add( Flatten())
model.add(Dropout(0.4))
model.add( Dense(2))
model.add(Activation('softmax'))
sgd = optimizers.SGD(lr=0.01, nesterov=True, decay=1e-6, momentum=0.9)
model.compile(loss='sparse_categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])

# get some data
#X = np.expand_dims(np.random.randn(1000, 5), axis=2)
X = np.expand_dims([[1,2,3,4,5],[1,1,1,1,1],[1,2,3,4,5],[1,2,3,4,5], [1,2,3,4,5],[1,1,1,1,1],[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5]], axis=2)
#y = [np.random.randint(0,2) for p in range(0,10)]
y=[[1],[0],[1],[1],[1],[0],[1],[1],[1],[1]]
y=np.array(y)
y = np.reshape(np.array(y), (y.shape[0],1))

# fit model
model.fit(X, y,batch_size=5, epochs=3, verbose=1)
predictions = model.predict(X)
Y_predict = model.predict_classes(X)

screen - output CNN

【问题讨论】:

    标签: machine-learning neural-network keras output conv-neural-network


    【解决方案1】:

    在对此进行试验后,我认为问题是由于训练示例数量较少以及您的 2 个类中的每个类的所有示例都是相同的。正如马蒂亚斯所说,培训班的不平衡也不理想。但是,实际上,我认为相同的示例会导致最多的问题,因为调整权重的学习路径对于每个类的所有示例都是相同的。

    因此,由于训练示例如此之少,您需要增加迭代次数或增加过滤器的数量(或两者兼而有之)。学习率也可以在这里发挥作用,但要正确调整比较棘手。

    我想出的似乎工作可靠的方法是,我稍微增加了过滤器的数量和相当多的迭代次数。这不是什么大问题,因为训练数据非常小,而且仍然很快完成。根据每个类中信号的性质,选择 2 的内核大小应该不是问题(一个类与 1 没有偏差,因此跨 2 个特征的卷积应该可以很好地区分它们)。这是似乎对我有用的代码(注意:我已经平衡了训练数据,尽管它没有太大区别):

    from keras.models import Sequential
    from keras.layers import Conv1D, Dense, MaxPool1D, Flatten
    import numpy as np
    
    n_features = 5
    
    model = Sequential()
    model.add(
        Conv1D(
            filters=10,
            kernel_size=2,
            input_shape=(n_features, 1)
        )
    )
    model.add(MaxPool1D(pool_size=1))
    model.add(Flatten())
    model.add(Dense(1, activation='sigmoid'))
    
    model.compile(
        loss='mae',
        optimizer='adam',
        metrics=['accuracy']
    )
    
    print(model.summary())
    
    # get some data
    X = np.array(
        [[1, 2, 3, 4, 5], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5],
         [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]],
        dtype=np.float32
    )
    X = np.expand_dims(X, axis=2)
    
    y = np.array([1, 0, 0, 1, 1, 0, 0, 0, 1, 1])
    
    # fit model
    model.fit(X, y, epochs=1000)
    
    predictions = model.predict(X)
    Y_predict_classes = model.predict_classes(X)
    

    我很想听听其他人关于可以对该网络进行哪些其他优化和简化的意见。

    【讨论】:

      【解决方案2】:

      因为 80% 的标签都是“1”,所以网络学会了始终输出“1”,这很容易获得 80% 的准确率。你的标签应该是平衡的,这样才能很好地学习。

      【讨论】:

      • 我不确定这是不是真的。我一直在玩这个代码,想法相同,但平衡训练数据并没有帮助。我承认这里还有其他问题,例如训练示例的数量有限。但是,由于 2 个类中的每一个的示例都是相同的,人们会认为这应该是一个微不足道的问题。
      • @Fiver 是的,我没有注意到训练输入只有两个唯一值,这肯定有贡献。
      猜你喜欢
      • 2018-01-04
      • 2021-02-11
      • 2018-09-16
      • 2020-05-12
      • 2019-01-06
      • 1970-01-01
      • 1970-01-01
      • 2019-09-04
      • 1970-01-01
      相关资源
      最近更新 更多