keras CNN 1-D -> Почему все предсказанные классы возвращаются равными?

Я закодировал 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)

экран - вывод CNN

2 ответа

Поэкспериментировав с этим, я считаю, что проблема связана с небольшим количеством обучающих примеров и тем фактом, что все примеры каждого из ваших двух классов идентичны. Как заявил Матиас, дисбаланс учебных классов тоже не идеален. Но, на самом деле, одни и те же примеры, как мне кажется, вызывают большинство проблем, поскольку способы обучения для подбора весов одинаковы для всех примеров каждого класса.

Итак, с таким небольшим количеством обучающих примеров вам нужно либо увеличить количество итераций, либо увеличить количество фильтров (или оба). Скорость обучения также может сыграть здесь свою роль, но сложнее настроить ее правильно.

То, что я придумал, что, казалось, работало надежно, - это следующее: я немного увеличил количество фильтров и немного увеличил количество итераций. Это не такая уж большая проблема, так как данные об обучении настолько малы и все же заканчиваются довольно быстро. Принимая во внимание характер сигналов в каждом классе, выбор размера ядра 2 не должен быть проблемой (у одного класса нет отклонений от 1, поэтому свертка по двум признакам должна быть удобной для их дифференциации). Вот код, который, кажется, работает для меня (примечание: я сбалансировал тренировочные данные, хотя это не имеет большого значения):

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)

Мне было бы интересно услышать от других, какие другие оптимизации и упрощения могут быть сделаны для этой сети.

Поскольку 80% ваших меток - "1", то сети учатся всегда выводить "1", и это легко даст 80% точности. Ваши ярлыки должны быть сбалансированы, чтобы научиться хорошо работать.

Другие вопросы по тегам