为什么我的keras模型总是预测相同的结果?

时间:2019-04-13 13:55:05

标签: python tensorflow keras artificial-intelligence

我知道之前曾有人问过这个问题,但是这些解决方案似乎都与我的问题无关。

我正在尝试使用逻辑回归来实现基本的二进制分类算法,以识别图像是猫还是狗。

我相信我正在正确地构造数据,我在初始密集层之前添加了一个平坦的层,我认为该层接受了正确的形状,然后我将它遍历了另外两个密集层,最后一层只有2个输出(据我了解,这是二进制分类之类的方式。

请查看我的代码,并建议我可以做些什么:

1。)使预测输出变化(不一定总是选择其中一个)
2.)在第二个时期之后,使我的准确性和损失有所不同。

我尝试过: -更改致密层的数量及其参数
-更改数据集的大小(因此在处理文件时使用count变量)
-更改时代数
-将种类模型从sgd更改为adam

数据集初始化

import numpy as np
import cv2
import os
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
import random
import keras

dataDir = '/content/gdrive/My Drive/AI'
categories = ['dog', 'cat']

x, y = [], []

imgSize = 100

for cat in categories:
  folderPath = os.path.join(dataDir, cat) # path to the respective folders
  classNum = categories.index(cat)        # sets classification number (0 = dog, 1 = cat)
  count = 0                               # used for limiting the number of images to test
  for file in os.listdir(folderPath):
    count = count + 1                     
    try:
      # open image and convert to grayscale
      img = cv2.imread(os.path.join(folderPath, file), cv2.IMREAD_GRAYSCALE)

      # resize to a square of predefined dimensions
      newImg = cv2.resize(img, (imgSize, imgSize))

      # add images to x and labels to y
      x.append(newImg)
      y.append(classNum)
      if count >= 100:
        break;

    # some images may be broken
    except Exception as e:
      pass

# y array to categorical
y = keras.utils.to_categorical(y, num_classes=2)

# shuffle data to increase training
random.shuffle(x)
random.shuffle(y)

x = np.array(x).reshape(-1, imgSize, imgSize, 1)
y = np.array(y)

# split data into default sized groups (75% train, 25% test)
xTrain, xTest, yTrain, yTest = train_test_split(x, y, test_size=0.25)

# display bar chart
objects = ('xTrain', 'xTest', 'yTrain', 'yTest')
y_pos = np.arange(len(objects))
maxItems = int((len(x) / 2 ) + 1)
arrays = [len(xTrain), len(xTest), len(yTrain), len(yTest)]

plt.bar(y_pos, arrays, align='center')
plt.xticks(y_pos, objects)
plt.ylabel('# of items')
plt.title('Items in Arrays')

plt.show()

模型设置

from keras.layers import Dense, Flatten
from keras.models import Sequential

shape = xTest.shape
model = Sequential([Flatten(),
                   Dense(100, activation = 'relu', input_shape = shape),
                   Dense(50, activation = 'relu'),
                   Dense(2, activation = 'softmax')])

model.compile(loss = keras.losses.binary_crossentropy,
             optimizer = keras.optimizers.sgd(),
             metrics = ['accuracy'])

model.fit(xTrain, yTrain,
         epochs=3,
         verbose=1,
         validation_data=(xTest, yTest))

model.summary()

输出:

Train on 150 samples, validate on 50 samples
Epoch 1/3
150/150 [==============================] - 1s 6ms/step - loss: 7.3177 - acc: 0.5400 - val_loss: 1.9236 - val_acc: 0.8800
Epoch 2/3
150/150 [==============================] - 0s 424us/step - loss: 3.4198 - acc: 0.7867 - val_loss: 1.9236 - val_acc: 0.8800
Epoch 3/3
150/150 [==============================] - 0s 430us/step - loss: 3.4198 - acc: 0.7867 - val_loss: 1.9236 - val_acc: 0.8800
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
flatten_13 (Flatten)         (None, 10000)             0         
_________________________________________________________________
dense_45 (Dense)             (None, 100)               1000100   
_________________________________________________________________
dense_46 (Dense)             (None, 50)                5050      
_________________________________________________________________
dense_47 (Dense)             (None, 2)                 102       
=================================================================
Total params: 1,005,252
Trainable params: 1,005,252
Non-trainable params: 0

预测

y_pred = model.predict(xTest)

for y in y_pred:
  print(y)

输出:

[1. 0.]
[1. 0.]
[1. 0.]
.
.
.
[1. 0.]

1 个答案:

答案 0 :(得分:1)

有几种方法可以给这只猫蒙皮...我不知道您的工作是否正常。因此,假设您的数据和标签正确,那么我认为是您的数据收集和模型构建是问题所在。

首先,我认为您没有足够的数据。这些二进制分类模型中的大多数都是基于> 1000张图片构建的。您的工作量大大减少了。其次,您只需要执行3个纪元,那还远远不够。对于您需要的图片数量,我建议至少50个纪元。但这是尝试和确定正确的数字以及是否过拟合的错误。

这就是我用来构建二进制分类模型的方法。

from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Activation
from keras.optimizers import SGD
from keras.layers import Dense
from keras.utils import np_utils
import numpy as np
import cv2


data = []
labels = []
imageSize = 32
# Do whatever you gotta do to create a folder of flatten/resized images
# and another labels list with indexes that match the index of pitcure
for image in folder:
    imagePath = 'path/to/image/'
    imageLabel = 'whatever_label'
    image = cv2.imread(imagePath)
    features = cv2.resize(image, imageSize).flatten(image)
    data.append(features)
    labels.append(imageLabel)

# Encode the labels
labelEncoder = LabelEncoder()
labels = labelEncoder.fit_transforma(labels)

# Scale the image to [0, 1]
data = np.array(data) / 255.0
# Generate labels as [0, 1] instead of ['dog', 'cat']
labels = np_utils.to_categorical(labels, 2)

# Split data
(trainData, testData, trainLabels, testLabels) = train_test_split(data, labels, test_size = 0.25, random_state = 42)

# Construct Model
model = Sequential()
model.add(Dense(768, input_dim = imageSize * imageSize * 3, init = 'uniform', activation = 'relu'))
model.add(Dense(384, activation = 'relu', kernel_initializer = 'uniform'))
model.add(Dense(2))
model.add(Activation('softmax'))

# Compile
sgd = SGD(lr=0.01)
model.compile(loss = 'binary_crossentropy', optimizer = sgd, metrics = ['accuracy'])
model.fit(trainData, trainLabels, epochs = 50, batch_size = 128, verbose = 1)

# Determine Accuracy and loss
(loss, accuracy) = model.evaluate(testData, testLabels, batch_size = 128, verbose = 1)
print('[INFO] loss={:.4f}, accuracy: {:.4f}%'.format(loss, accuracy * 100))

希望有帮助!