【发布时间】: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