我知道之前曾有人问过这个问题,但是这些解决方案似乎都与我的问题无关。
我正在尝试使用逻辑回归来实现基本的二进制分类算法,以识别图像是猫还是狗。
我相信我正在正确地构造数据,我在初始密集层之前添加了一个平坦的层,我认为该层接受了正确的形状,然后我将它遍历了另外两个密集层,最后一层只有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.]
答案 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))
希望有帮助!