【发布时间】:2017-09-07 15:15:38
【问题描述】:
我正在尝试修改 keras 的 blog 中显示的分类示例,以将图像分类为 3 个不同的类别。
我有 3000 张 (3 x 1000) 的训练图像和 1200 (3 x 400) 的验证图像。 代码修改为3类。
代码如下:
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dropout, Flatten, Dense
from keras import applications
# dimensions of our images.
img_width, img_height = 150, 150
top_model_weights_path = 'bottleneck_fc_model.h5'
train_data_dir = 'data/train'
validation_data_dir = 'data/validation'
nb_train_samples = 3000
nb_validation_samples = 1200
epochs = 50
batch_size = 16
n_classes = 3
def save_bottlebeck_features():
datagen = ImageDataGenerator(rescale=1. / 255)
# build the VGG16 network
model = applications.VGG16(include_top=False, weights='imagenet')
generator = datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
shuffle=False)
bottleneck_features_train = model.predict_generator(
generator, nb_train_samples // batch_size)
np.save(open('bottleneck_features_train.npy', 'wb'),
bottleneck_features_train)
generator = datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
shuffle=False)
bottleneck_features_validation = model.predict_generator(
generator, nb_validation_samples // batch_size)
np.save(open('bottleneck_features_validation.npy', 'wb'),
bottleneck_features_validation)
def train_top_model():
train_data = np.load(open('bottleneck_features_train.npy','rb'))
train_labels = np.array([0] * (nb_train_samples // n_classes) + [1] * (nb_train_samples // n_classes) + \
[2] * (nb_train_samples // n_classes))
validation_data = np.load(open('bottleneck_features_validation.npy','rb'))
validation_labels = np.array([0] * (nb_train_samples // n_classes) + [1] * (nb_train_samples // n_classes) + \
[2] * (nb_train_samples // n_classes))
model = Sequential()
model.add(Flatten(input_shape=train_data.shape[1:]))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(n_classes, activation='softmax'))
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(train_data, train_labels, epochs=epochs, batch_size=batch_size, \
validation_data=(validation_data, validation_labels))
model.save_weights(top_model_weights_path)
当我最终执行这两个函数时:
save_bottlebeck_features()
train_top_model()
第二个函数返回如下错误:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-143-070a6188c611> in <module>()
4 print(validation_labels.shape)
5
----> 6 train_top_model()
<ipython-input-129-ea2b02024693> in train_top_model()
64 loss='categorical_crossentropy', metrics=['accuracy'])
65
---> 66 model.fit(train_data, train_labels, epochs=epochs, batch_size=batch_size, validation_data=(validation_data, validation_labels))
67 model.save_weights(top_model_weights_path)
~/anaconda/lib/python3.6/site-packages/keras/models.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, **kwargs)
865 class_weight=class_weight,
866 sample_weight=sample_weight,
--> 867 initial_epoch=initial_epoch)
868
869 def evaluate(self, x, y, batch_size=32, verbose=1,
~/anaconda/lib/python3.6/site-packages/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)
1520 class_weight=class_weight,
1521 check_batch_axis=False,
-> 1522 batch_size=batch_size)
1523 # Prepare validation data.
1524 do_validation = False
~/anaconda/lib/python3.6/site-packages/keras/engine/training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_batch_axis, batch_size)
1380 output_shapes,
1381 check_batch_axis=False,
-> 1382 exception_prefix='target')
1383 sample_weights = _standardize_sample_weights(sample_weight,
1384 self._feed_output_names)
~/anaconda/lib/python3.6/site-packages/keras/engine/training.py in _standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
142 ' to have shape ' + str(shapes[i]) +
143 ' but got array with shape ' +
--> 144 str(array.shape))
145 return arrays
146
ValueError: Error when checking target: expected dense_58 to have shape (None, 3) but got array with shape (3000, 1)
如果我打印数据和标签的形状,它会返回:
print(train_labels.shape)
(3000, 3)
print(train_data.shape)
(3000, 3)
print(validation_data.shape)
(1200, 4, 4, 512)
print(validation_labels.shape)
(1200,)
编辑:
我正在发布完整代码以及包含我正在考虑的图像的数据库。
数据库可以下载here。
代码如下:
# dimensions of our images.
img_width, img_height = 150, 150
top_model_weights_path = 'what.h5'#'bottleneck_fc_model.h5'
train_data_dir = 'data_short/train'
validation_data_dir = 'data_short/validation'
nb_train_samples = 30
nb_validation_samples = 6
epochs = 50
batch_size = 16
n_classes = 3
def save_bottlebeck_features():
datagen = ImageDataGenerator(rescale=1. / 255)
# build the VGG16 network
model = applications.VGG16(include_top=False, weights='imagenet')
generator = datagen.flow_from_directory(train_data_dir, target_size=(img_width, img_height),\
batch_size=batch_size, class_mode='categorical', shuffle=False)
bottleneck_features_train = model.predict_generator(generator, nb_train_samples // batch_size)
np.save(open('bottleneck_features_train.npy', 'wb'), bottleneck_features_train)
generator = datagen.flow_from_directory(validation_data_dir, target_size=(img_width, img_height),\
batch_size=batch_size, class_mode='categorical', shuffle=False)
bottleneck_features_validation = model.predict_generator(generator, nb_validation_samples // batch_size)
np.save(open('bottleneck_features_validation.npy', 'wb'), bottleneck_features_validation)
def train_top_model():
encoder = OneHotEncoder()
#train_data = np.load(open('bottleneck_features_train.npy','rb'))
train_data = np.load('bottleneck_features_train.npy')
train_labels = np.array([0] * (nb_train_samples // n_classes) + [1] * (nb_train_samples // n_classes) +
[2] * (nb_train_samples // n_classes))
train_labels = to_categorical(train_labels)
validation_data = np.load(open('bottleneck_features_validation.npy','rb'))
validation_labels = np.array([0] * (nb_validation_samples // n_classes) + \
[1] * (nb_validation_samples // n_classes) + \
[2] * (nb_validation_samples // n_classes))
validation_labels = to_categorical(validation_labels)
model = Sequential()
model.add(Flatten(input_shape=train_data.shape[1:]))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(n_classes, activation='softmax'))
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(train_data, train_labels, epochs=epochs, batch_size=batch_size,\
validation_data=(validation_data, validation_labels))
model.save_weights(top_model_weights_path)
给出的错误如下:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-8-6869607a6e44> in <module>()
----> 1 train_top_model()
<ipython-input-6-933b6592c6c1> in train_top_model()
56 model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
57
---> 58 model.fit(train_data, train_labels, epochs=epochs, batch_size=batch_size, validation_data=(validation_data, validation_labels))
59 model.save_weights(top_model_weights_path)
~/anaconda/lib/python3.6/site-packages/keras/models.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, **kwargs)
861 class_weight=class_weight,
862 sample_weight=sample_weight,
--> 863 initial_epoch=initial_epoch)
864
865 def evaluate(self, x, y, batch_size=32, verbose=1,
~/anaconda/lib/python3.6/site-packages/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, **kwargs)
1356 class_weight=class_weight,
1357 check_batch_axis=False,
-> 1358 batch_size=batch_size)
1359 # Prepare validation data.
1360 if validation_data:
~/anaconda/lib/python3.6/site-packages/keras/engine/training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_batch_axis, batch_size)
1244 for (ref, sw, cw, mode)
1245 in zip(y, sample_weights, class_weights, self._feed_sample_weight_modes)]
-> 1246 _check_array_lengths(x, y, sample_weights)
1247 _check_loss_and_target_compatibility(y,
1248 self._feed_loss_fns,
~/anaconda/lib/python3.6/site-packages/keras/engine/training.py in _check_array_lengths(inputs, targets, weights)
235 'the same number of samples as target arrays. '
236 'Found ' + str(list(set_x)[0]) + ' input samples '
--> 237 'and ' + str(list(set_y)[0]) + ' target samples.')
238 if len(set_w) > 1:
239 raise ValueError('All sample_weight arrays should have '
ValueError: Input arrays should have the same number of samples as target arrays. Found 16 input samples and 30 target samples.
EDIT2解决办法:
我解决了这个问题,对代码进行了根本性的更改。可以看到here。
【问题讨论】:
-
train_lables.shape[1]应该是=到validation_labels.shape[1]和train_data.shape[1],train_data.shape[2],train_data.shape[3]应该等于validation_data.shape[1],validation_data.shape[2],validation_data.shape[3],这应该很清楚,因为数据测试和数据验证之间的唯一区别是第一个维度,即您拥有的“样本”总数 -
我认为这不是问题所在。我将系统减少为每个类 10 幅图像用于训练,2 幅图像用于验证。张量大小是正确的,它遵守您提出的规则。但是我仍然有错误。
-
ValueError:输入数组的样本数应与目标数组相同。找到 16 个输入样本和 30 个目标样本。
-
您能否更新代码以反映这一点,现在看来您的
train_data.shape[0]不等于train_labels.shape[0] -
您仍然提供一个只有 1 个类的数组作为标签。错误消息现在显示您的标签形状类似于
(30,1)。您创建标签的方式有问题。
标签: tensorflow keras classification