神经网络returns三class而实际是2

Neural network returns three class while it is actual 2

我想问一下与前面的问题相关的几乎最后一个问题:

有问题描述:

所以我有两个类别(狗和猫),下面我有以下代码用于将数据读入列表并将它们转换为数组(numpy 数组)

用于挂载google驱动器

from google.colab import drive
drive.mount("/content/drive", force_remount=True)

正在导入所有必要的库(实际上我不需要 glob 但保留)

import numpy as np
import matplotlib.pyplot as plt
import os
import cv2
import glob

只是演示读取和显示图片,以备后用

#Set main directory and also categories. read the images
MainDirectory ="/content/drive/My Drive/Colab Notebooks/2020YearDeepLearning/Animals/PetImages/"
Categories =["Dog","Cat"]
for  category in Categories:
   path =os.path.join(MainDirectory,category)
   print(path)
   for img in os.listdir(path):
      img_array =cv2.imread(os.path.join(path,img),cv2.IMREAD_GRAYSCALE)
      plt.imshow(img_array,cmap="gray")
      plt.show()
      break
   break

重塑图像演示

IMG_SIZE=70
img_array =cv2.resize(img_array,(IMG_SIZE,IMG_SIZE))
plt.imshow(img_array,cmap='gray')
plt.show()

现在有实际的代码,这意味着读取数据和标签(dogs 和 cat,dog 是 0,cat 是 1)并将它们放入数组中

#Create  a training Data
training_data =[]
for  category in Categories:
      path =os.path.join(MainDirectory,category)
      class_num =Categories.index(category)
      for img in os.listdir(path):
        try:
          img_array =cv2.imread(os.path.join(path,img),cv2.IMREAD_GRAYSCALE)
          img_array =cv2.resize(img_array,(IMG_SIZE,IMG_SIZE))
          training_data.append([img_array,class_num])
        except Exception as e:
          pass

在那之后我只是洗牌了数据

import random
random.shuffle(training_data)

将数据分离为 X 和 y 并转换为具有相应整形的 numpy 数组

X =[]
y =[]
for features,label in training_data:
  X.append(features)
  y.append(label)
X =np.array(X).reshape(-1,IMG_SIZE,IMG_SIZE,1)
y =np.array(y)

我想证明 y 只有两个可能的值(狗是 0,猫是 1)

print(np.unique(y)) - which returns[0, 1]

现在的实际代码

#create   simple convolutional neural network
#normalize data  and load all necessary  libraries
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,Dropout,Flatten,Conv2D,MaxPool2D,Activation
X =X/255.0
model =Sequential()
model.add(Conv2D(filters=32,kernel_size=(3,3),input_shape=X.shape[1:]))
model.add(Activation('relu'))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Conv2D(filters=32,kernel_size=(3,3)))
model.add(Activation('relu'))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(units=32))
model.add(Dense(units=1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy'])

我已经使用以下命令训练了数据

model.fit(X,y,batch_size=16,validation_split=0.1,epochs=10)

这是训练图像

之后,我随机拍了一张猫和狗的照片,然后运行按照命令(这个例子我使用的是狗照片)

#for testing
image =cv2.imread("/content/drive/My Drive/Colab Notebooks/2020YearDeepLearning/Animals/test.jpg")
image =cv2.resize(image,(IMG_SIZE,IMG_SIZE))
image =np.array(image).reshape(-1,IMG_SIZE,IMG_SIZE,1)
print(model.predict_classes(image))

结果是这个: 了解更多详情。

[[0]
 [0]
 [0]]

为了猫,我买了这个

[[1]
 [0]
 [0]]

我应该得到三个元素的结果吗?我的意思是三元素数组?其实我有两个 class 对吧?如果我错了请告诉我

这是我的怀疑:

如果您的图像不是灰色的,这意味着它像普通 RBG 图像一样具有三个通道,那么您在此处调整大小 image =np.array(image).reshape(-1,IMG_SIZE,IMG_SIZE,1) 实际上会使返回的图像成为 (3, IMG_SIZE, IMG_SIZE, 1) 的形状,这意味着你预测的时候实际上输入了三个样本,每个样本有一个通道,当然你会得到三个结果。

另外,当你加载图像进行训练时,你加载了 grayscale,但是当你加载预测时,你忘记这样做了。所以这就是为什么您的训练有效但无法预测的原因。