numpy.where 缩小数组维度
numpy.where narrowing array dimensions
我想使用 cifar100 数据集中的一些 类 来训练模型。我使用 numpy where
来过滤数据集,但它缩小了图像数组的尺寸。
import numpy as np
from tensorflow.keras.datasets import cifar100
(x_train, y_train), (x_test, y_test) = cifar100.load_data()
index = np.where((y_train == 1) | (y_train == 2))
print('Images Shape: {}'.format(x_train.shape))
X_train = x_train[index]
Y_train = y_train[index]
print('Images Shape: {}'.format(X_train.shape))
打印:
Images Shape: (50000, 32, 32, 3)
Images Shape: (1000, 32, 3)
到目前为止我尝试了什么:
过滤后我尝试将结果转换为这样的图像形状:
index = np.asarray(index).reshape(x_train.shape[0])
但是我得到这个错误:
ValueError: cannot reshape array of size 2000 into shape (50000,)
我想仅使用来自 cifar100 数据集的 10 类 来训练模型。
这是我的模型:
import numpy as np
from tensorflow.keras.datasets import cifar100
from tensorflow.keras.layers import Conv2D, Flatten, Dense, MaxPool2D
from tensorflow.keras.models import Sequential
model = Sequential()
model.add(Conv2D(16, (3, 3),
# strides=(1, 1),
activation='relu',
padding='same', # 'valid',
input_shape=(32, 32, 3)))
model.add(MaxPool2D((2, 2)))
model.add(Conv2D(32, (3, 3),
# strides=(1, 1),
activation='relu'))
model.add(MaxPool2D((2, 2)))
model.add(Conv2D(32, (3, 3),
# strides=(1, 1),
activation='relu'))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(10, activation='softmax'))
model.summary()
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.fit(X_train,
Y_train,
epochs=5,
batch_size=64)
here 中的代码是您所需要的:
import tensorflow_datasets as tfds
import tensorflow as tf
def predicate(x, allowed_labels=tf.constant([0., 1., 2.])):
label = x['label']
isallowed = tf.equal(allowed_labels, tf.cast(label, tf.float32))
reduced = tf.reduce_sum(tf.cast(isallowed, tf.float32))
return tf.greater(reduced, tf.constant(0.))
cifar100_builder = tfds.builder("cifar100")
cifar100_builder.download_and_prepare()
ds_train = cifar100_builder.as_dataset(split="train")
ds_test = cifar100_builder.as_dataset(split="test")
filtered_ds_train=ds_train.filter(predicate)
filtered_ds_test=ds_test.filter(predicate)
我不确定对 y_train
个案例的子集进行培训是否正确。通常训练是在所有案例的 'random' 子集上完成的。 keras
等具有 split
将数据集(X
和 y
拆分为训练集和测试集的函数。
但是按照我的评论,解释您看到的行为。
有 (n,1) y_train
:
In [203]: y = np.arange(10)[:,None]
In [204]: idx = np.nonzero((y<4)|(y>7))
In [205]: idx
Out[205]: (array([0, 1, 2, 3, 8, 9]), array([0, 0, 0, 0, 0, 0]))
nonzero/where
returns 索引数组的元组,每个维度一个数组。由于2维为1,所以idx[1]
全为0,没有提供任何有用的信息。
当用于索引 4d x_train
时,idx
在第一个维度上选择 6 个值,而在第二个维度上只选择第一个值:
In [206]: x = np.ones((10,2,3,4),int)
In [207]: x[idx].shape
Out[207]: (6, 3, 4)
仅使用第一个数组进行索引保留第二个维度:
In [208]: x[idx[0]].shape
Out[208]: (6, 2, 3, 4)
我不知道你想做什么:
index = np.asarray(index).reshape(x_train.shape[0])
在我的示例中 x.shape[0]
是 10,但 idx[0]
是 (6,)。重塑 idx[0]
没有意义,更不用说两个数组了。
In [209]: np.array(idx)
Out[209]:
array([[0, 1, 2, 3, 8, 9],
[0, 0, 0, 0, 0, 0]])
我想使用 cifar100 数据集中的一些 类 来训练模型。我使用 numpy where
来过滤数据集,但它缩小了图像数组的尺寸。
import numpy as np
from tensorflow.keras.datasets import cifar100
(x_train, y_train), (x_test, y_test) = cifar100.load_data()
index = np.where((y_train == 1) | (y_train == 2))
print('Images Shape: {}'.format(x_train.shape))
X_train = x_train[index]
Y_train = y_train[index]
print('Images Shape: {}'.format(X_train.shape))
打印:
Images Shape: (50000, 32, 32, 3)
Images Shape: (1000, 32, 3)
到目前为止我尝试了什么:
过滤后我尝试将结果转换为这样的图像形状:
index = np.asarray(index).reshape(x_train.shape[0])
但是我得到这个错误:
ValueError: cannot reshape array of size 2000 into shape (50000,)
我想仅使用来自 cifar100 数据集的 10 类 来训练模型。 这是我的模型:
import numpy as np
from tensorflow.keras.datasets import cifar100
from tensorflow.keras.layers import Conv2D, Flatten, Dense, MaxPool2D
from tensorflow.keras.models import Sequential
model = Sequential()
model.add(Conv2D(16, (3, 3),
# strides=(1, 1),
activation='relu',
padding='same', # 'valid',
input_shape=(32, 32, 3)))
model.add(MaxPool2D((2, 2)))
model.add(Conv2D(32, (3, 3),
# strides=(1, 1),
activation='relu'))
model.add(MaxPool2D((2, 2)))
model.add(Conv2D(32, (3, 3),
# strides=(1, 1),
activation='relu'))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(10, activation='softmax'))
model.summary()
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.fit(X_train,
Y_train,
epochs=5,
batch_size=64)
here 中的代码是您所需要的:
import tensorflow_datasets as tfds
import tensorflow as tf
def predicate(x, allowed_labels=tf.constant([0., 1., 2.])):
label = x['label']
isallowed = tf.equal(allowed_labels, tf.cast(label, tf.float32))
reduced = tf.reduce_sum(tf.cast(isallowed, tf.float32))
return tf.greater(reduced, tf.constant(0.))
cifar100_builder = tfds.builder("cifar100")
cifar100_builder.download_and_prepare()
ds_train = cifar100_builder.as_dataset(split="train")
ds_test = cifar100_builder.as_dataset(split="test")
filtered_ds_train=ds_train.filter(predicate)
filtered_ds_test=ds_test.filter(predicate)
我不确定对 y_train
个案例的子集进行培训是否正确。通常训练是在所有案例的 'random' 子集上完成的。 keras
等具有 split
将数据集(X
和 y
拆分为训练集和测试集的函数。
但是按照我的评论,解释您看到的行为。
有 (n,1) y_train
:
In [203]: y = np.arange(10)[:,None]
In [204]: idx = np.nonzero((y<4)|(y>7))
In [205]: idx
Out[205]: (array([0, 1, 2, 3, 8, 9]), array([0, 0, 0, 0, 0, 0]))
nonzero/where
returns 索引数组的元组,每个维度一个数组。由于2维为1,所以idx[1]
全为0,没有提供任何有用的信息。
当用于索引 4d x_train
时,idx
在第一个维度上选择 6 个值,而在第二个维度上只选择第一个值:
In [206]: x = np.ones((10,2,3,4),int)
In [207]: x[idx].shape
Out[207]: (6, 3, 4)
仅使用第一个数组进行索引保留第二个维度:
In [208]: x[idx[0]].shape
Out[208]: (6, 2, 3, 4)
我不知道你想做什么:
index = np.asarray(index).reshape(x_train.shape[0])
在我的示例中 x.shape[0]
是 10,但 idx[0]
是 (6,)。重塑 idx[0]
没有意义,更不用说两个数组了。
In [209]: np.array(idx)
Out[209]:
array([[0, 1, 2, 3, 8, 9],
[0, 0, 0, 0, 0, 0]])