【问题标题】:Keras error related to the fact that I only have one classKeras 错误与我只有一堂课有关
【发布时间】:2020-10-10 00:29:49
【问题描述】:

我正在尝试在 keras 中制作一个 CNN,但我只希望它有一个类,因此只有一个概率作为输出。因此,我使用 sigmoid 函数来预测概率(不能将 softmax 用于一类,我最终记住了)。通常我会做 1 - 获得损失的概率并使用优化器来减少它,因为我们所有的答案都将是 1。但是,我不确定如何实现所有人的目标这一事实在 keras 和 atm 中为 1,它会引发以下错误:

收到的标签值 1 超出了 [0, 1) 的有效范围。标签值:1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

因为我实际上只是使用一个包含 120 个 1 的列表(我有 120 个图像),否则它会说它们并不都有标签。

我的代码是以下atm:

import tensorflow as tf
from tensorflow import keras

from keras.utils import to_categorical
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Dense, Flatten
import glob
from PIL import Image

#!unzip not_dog4

images = []
image_data = []

for filename in glob.glob('not_dog/*.jpg'): 
  im = Image.open(filename)
  images.append(im)

for image in images:
  images2 = image.resize((28, 28))
  gs_image = images2.convert(mode='L')
  image_vector = np.array(gs_image)
  image_data.append(image_vector)

image_data = np.array(image_data)[..., None]

image_data_normalised = []

image_data = image_data.astype('float32')
image_data_normalised = image_data / 255 - 0.5

y = []

#y has to be 120 ones...?
for i in range(120):
  y.append(1)


num_filters = 1 #I guess you dictate the number of convolutions through the number of filters - 1 convolution for each filter.
filter_size = 3
pool_filter_size = 2


model = Sequential()
model.add(Conv2D(num_filters, filter_size, strides=(1, 1), input_shape=(28, 28, 1)))  
model.add(MaxPooling2D(pool_size=(3, 3), strides=(1, 1), padding='valid')) 
model.add(Flatten())  
model.add(Dense(1, activation = 'sigmoid'))  

#compile the model
model.compile('adam', loss = 'sparse_categorical_crossentropy')
model.fit(image_data_normalised, y, epochs=3)

这是我到目前为止所得到的。非常感谢任何帮助:)

【问题讨论】:

  • 你想用这个来完成什么?如果您只有一个类,您的模型将始终输出该类。如果您这样做只是为了习惯该软件,我建议您从二进制分类问题开始。
  • 所需的输出只是一个分类,它会告诉我某物是“狗”(输出的概率大于 0.5)还是不是狗,其概率小于 0.5。我知道你可以做一个二元分类器,但我不想做猫对狗之类的事情,因为我只想知道某物是否是狗,如果这有意义的话。我本可以做一个“不是狗”作为第二堂课,但我不确定我会给出什么样的训练数据?
  • 在这种情况下,您已经有了两个类别:“狗”和“非狗”。您的选择是让您的代码有两个输出(并返回使用 softmax)或使用不同的损失,例如均方误差。这两个选项中的第一个可能更好。
  • “not dog”的训练数据是什么?我不完全确定为什么我需要不同类型的损失(除非 cross_entropy 需要两个输入?)。我只是从 1 中取概率,所以我并不完全熟悉。
  • 我假设您已经有图像是狗而不是狗。如果你不这样做,那么你将遇到一个完全不同的问题,即你的模型不会学习是什么让某物成为狗或不是狗,它只会输出相同的东西。你是对的,如果你有两个输出,一个只是另一个输出,但它是使损失函数工作所必需的。 y_pred 的长度应等于您拥有的类别数,并且您有两个类别。

标签: python python-3.x tensorflow machine-learning keras


【解决方案1】:

您只导入图像“not_dogs”

尝试使用 ImageDataGenerator.flow_from_directories 导入,因为它会根据文件夹名称自动标记图像类。或者您可能想创建一个包含路径和类特征的数据框,然后使用 ImageDataGenerator.flow_from_dataframe。

ImageGenerator 方法是非常受欢迎的,因为它不会导致内存问题。如果您正在处理图像,非常推荐学习这个动作。

【讨论】:

  • “它将根据文件夹名称自动标记图像类”。因此,如果我将其标记为“狗”,它如何知道将其变为 1 以计算出我当前预测的损失?但如果我能做到这一点,我假设它给出的“1”以某种方式被接受了吗?
  • 您的目录应为 class_name/images.jpg 生成器读取 images.jpg 并将其标记为 class_name。例如:Not dogs/images.jpg Dogs/images.jpg 生成器将存储与“Not dogs”和“Dogs”标签对应的所有图像
  • “not dog”的训练数据是什么?
  • 图像被自动归类为“not dog”,位于“not dog”文件夹中。图像被自动归类为“狗”文件夹中的“狗”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-31
  • 2014-09-17
  • 2012-04-08
  • 1970-01-01
  • 1970-01-01
  • 2014-12-05
  • 1970-01-01
相关资源
最近更新 更多