加载fashion_mnist时train_labels数组只读无法修改的问题求助
解决tf.keras加载Fashion-MNIST时train_labels只读无法打乱的问题
问题根源
Fashion-MNIST加载返回的train_labels是只读数组视图(从数组标志能看到OWNDATA=False、WRITEABLE=False),它共享其他内存块的数据,没法直接修改可写权限;而MNIST数据集返回的数组拥有自身独立内存(OWNDATA=True),所以能正常修改或打乱。
解决方案
方案1:生成可写数组副本
加载数据集后立刻给train_labels做个副本,新数组会拥有独立内存,自动获得可写权限:
(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.fashion_mnist.load_data() # 复制生成可写的独立数组 train_labels = train_labels.copy() # 后续的归一化、打乱操作就正常了 train_images = train_images.reshape(train_images.shape[0], 28, 28, 1).astype('float32') train_images = (train_images - 127.5) / 127.5 test_images = test_images.reshape(test_images.shape[0], 28, 28, 1).astype('float32') test_images = (test_images - 127.5) / 127.5 state = np.random.get_state() np.random.shuffle(train_images) np.random.set_state(state) np.random.shuffle(train_labels)
方案2:通过索引同时打乱图像和标签(更高效)
不用单独保存随机状态再分别打乱,直接生成随机索引,一次性重排图像和标签,既省内存又避免只读数组问题:
(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.fashion_mnist.load_data() # 生成随机排列的索引 shuffle_idx = np.random.permutation(len(train_images)) # 用索引同时打乱图像和标签,保证对应关系正确 train_images = train_images[shuffle_idx] train_labels = train_labels[shuffle_idx] # 后续归一化处理 train_images = train_images.reshape(train_images.shape[0], 28, 28, 1).astype('float32') train_images = (train_images - 127.5) / 127.5 test_images = test_images.reshape(test_images.shape[0], 28, 28, 1).astype('float32') test_images = (test_images - 127.5) / 127.5
说明
- 方案1简单直接,适合小数据集;
- 方案2更高效,不需要额外复制数组内存,同时能确保图像和标签的对应关系不会出错,推荐优先使用。
内容的提问来源于stack exchange,提问作者Nidhogg
相关产品推荐
相关产品推荐

