如何为softmax分类指定onehot标签数组的形状?

问题描述 投票:0回答:1

我正在做一个简单的图像分类,我希望将图像放入16个类中的一个。我的标签是16长,一热的ndarray。

当我调用fit()时,很明显模型预期有16个样本,而不是一个由16个16号数组组成的标签。我无法理解我需要告诉Keras我要喂它的什么魔法。

代码和喷射如下。试着忽略传递给Dense()的不相关的大小,这只是一个玩具项目。我故意一次批量传递一个样本。

def main():
FLAGS, unparsed = ut.parseArgs()
print(FLAGS)
# TEST_DATA_PATH      = FLAGS.test_data_path
SAMPLE_FILE = FLAGS.train_data_path + FLAGS.sample
IMG_SHAPE   = ut.get_image_shape(filename=SAMPLE_FILE, scale=FLAGS.scale, show=FLAGS.show)
img = ut.read_image(filename=SAMPLE_FILE, show=False)
img = np.array(img)
IMG_SHAPE=img.shape
(x_train, y_train), (x_test, y_test)=load_data(numclasses=FLAGS.numclasses, train_path=FLAGS.train_data_path, sample_file=SAMPLE_FILE, onehot=True)


model = tf.keras.models.Sequential()


print(f'IMG_SHAPE:{IMG_SHAPE},  y_train shape:{y_train[0].shape}')

model.add(tf.keras.layers.Dense(256,activation='relu',input_shape=IMG_SHAPE, name='d1'))
model.add(tf.keras.layers.Dense(64, activation='sigmoid', name='d2'))
model.add(tf.keras.layers.Flatten(data_format='channels_last'))
model.add(tf.keras.layers.Dense(32, activation='softmax', name='d3'))

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.summary()
for nx in range(len(x_train)):
    file = x_train[nx]
    img = ut.read_image(filename=FLAGS.train_data_path+file, show=False)
    img=np.array(img)
    img = np.expand_dims(img, axis=0)
    model.fit(x=img, y=y_train[nx],verbose=2)

这是呕吐:

“C:\ Users \ WascallyWabbit \ AppData \ Local \ Programs \ Python \ Python36 \ python.exe”“C:/Users/WascallyWabbit/PycharmProjects/sentdex_keras/sentdex_keras.py”命名空间(batch_size = 4,epochs = 1,learning_rate = 0.01,numclasses = 16,sample ='0cdf5b5d0ce1_01.jpg',scale = 1.0,show = False,target ='mnist',tb_dir ='/ Users / WascallyWabbit / tensorlog /',test_data_path ='/ Users / WascallyWabbit / Downloads / carvana / test /',train_data_path ='/ Users / WascallyWabbit / Downloads / carvana / train /')IMG_SHAPE:(1280,1918,2),y_train shape:(16,)_________________________________________________________________图层(类型)输出形状参数# ================================================== =============== d1(密集)(无,1280,1918,256)768 _________________________________________________________________ d2(密集)(无,1280,1918,64)16448 _________________________________________________________________ flatten(Flatten)(无,157122560)0 _________________________________________________________________ d3(密集)(无,32)732954656 ======================================= ==========================总参数:732,971,872可训练的参数:732,971,872非训练参数:0 _________________________________________________________________跟踪(最近一次呼叫最后一次):档案“C:/Users/WascallyWabbit/PycharmProjects/sentdex_keras/sentdex_keras.py”,第113行,在main()文件“C:/Users/WascallyWabbit/PycharmProjects/sentdex_keras/sentdex_keras.py”,第74行,在main model.fit中(x = img,y = y_train [nx],verbose = 2)文件“C:\ Users \ WascallyWabbit \ AppData \ Roaming \ Python \ Python36 \ site-packages \ tensorflow \ python \ keras \ engine \ training.py”,第1536行,in fit validation_split = validation_split)文件“C:\ Users \ WascallyWabbit \ AppData \ Roaming \ Python \ Python36 \ site-packages \ tensorflow \ python \ keras \ engine \ training.py”,第992行,_standardize_user_data class_weight, batch_size)文件“C:\ Users \ WascallyWabbit \ AppData \ Roaming \ Python \ Python36 \ site-packages \ tensorflow \ python \ keras \ engine \ training.py“,第1169行,_standardize_weights training_utils.check_array_lengths(x,y,sample_weights)文件”C:\ Users \ WascallyWabbit \ AppData \ Roaming \ Python \ Python36 \ site-packages \ tensorflow \ python \ keras \ engine \ training_utils.py“,第426行,在check_array_lengths'和'+ str(list(set_y)[0])+'目标样本。')ValueError:输入数组应具有与目标阵列相同数量的样本。找到1个输入样本和16个目标样本。

进程以退出代码1结束

还是卡住了,抱歉。

我已将问题简化为骨头:

import tensorflow as tf
import numpy as np
in_shape=(128,128,3)
a=np.zeros(shape=in_shape,dtype='float32')
np.fill_diagonal(a[:,:,0],1.)
np.fill_diagonal(a[:,:,1],1.)
np.fill_diagonal(a[:,:,2],1.)

model = tf.keras.models.Sequential([
    tf.keras.layers.Dense(64, input_shape=in_shape, activation=tf.nn.relu, batch_size=1,name='d0'),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(16, activation=tf.nn.softmax,name='d1')
])

model.compile(optimizer='adam',
                  loss='sparse_categorical_crossentropy',
                  metrics=['accuracy'])

Y=np.empty(16)
Y.fill(1.)
#forgot to make one of them 'hot' , does not matter now

#this line barfs
model.fit(x=np.expand_dims(a, axis=0), y=np.expand_dims(Y, axis=0),steps_per_epoch=1)

输出是:

“C:\ Users \ WascallyWabbit \ AppData \ Local \ Programs \ Python \ Python36 \ python.exe”“C:/Users/WascallyWabbit/.PyCharmCE2018.2/config/scratches/scratch_39.py”Traceback(最近一次调用最后一次) :文件“C:/Users/WascallyWabbit/.PyCharmCE2018.2/config/scratches/scratch_39.py”,第28行,在model.fit中(x = np.expand_dims(a,axis = 0),y = np.expand_dims (Y,axis = 0),steps_per_epoch = 1)文件“C:\ Users \ WascallyWabbit \ AppData \ Roaming \ Python \ Python36 \ site-packages \ tensorflow \ python \ keras \ engine \ training.py”,第1536行, fit validation_split = validation_split)文件“C:\ Users \ WascallyWabbit \ AppData \ Roaming \ Python \ Python36 \ site-packages \ tensorflow \ python \ keras \ engine \ training.py”,第992行,_standardize_user_data class_weight,batch_size)文件“ C:\ Users \ WascallyWabbit \ AppData \ Roaming \ Python \ Python36 \ site-packages \ tensorflow \ python \ keras \ engine \ training.py“,第1154行,_standardize_weights exception_prefix ='target')文件”C:\ Users \ WascallyWabbit \应用程序数据\漫游\ Python的\ Python36 \站点包\ tensorflow \蟒蛇\ KER as \ engine \ training_utils.py“,第332行,在standardize_input_data'但是得到的形状为'+ str(data_shape)')ValueError:检查目标时出错:期望d1有形状(1,)但是有形状的数组(16 )

我希望对16元素标签数组的'softmax'有一个16元素的概率数组。与np.expand_dims(...,axis =)相关并没有带来任何乐趣。

我没看到什么?

python tensorflow machine-learning keras
1个回答
0
投票

如果使用sparse_categorical_crossentropy,则y值应作为整数提供,因此会观察到错误预期的形状(1,)。以单热编码形式提供y是当损失函数是categorical_crossentropy时。

这个链接有一个很好的例证。 https://jovianlin.io/cat-crossentropy-vs-sparse-cat-crossentropy/

所以,修复是

model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

此外,np.expand_dims或y_train [nx] [无]可用于创建批量维度。

model.fit(x = img,y = np.expand_dims(y_train [nx],0),verbose = 2)

© www.soinside.com 2019 - 2024. All rights reserved.