VGGNet + CIFAR-100
写在最前:这个是和用户id:weixin_55841621的一个合作项目,得到对方允许后写了个心得总结,未经授权不得转载或直接复制使用。初学者,对于一些问题的理解可能不是很到位,请多多指教或者一起讨论~
导入数据
这个是从keras直接导入数据,y标签是用0-99的数字表示,但是从cifar数据官方网站下载的数据中,meta文件包含了y标签的文字表示,即类的语义名字。
# Load data from keras (https://keras.io/api/datasets/cifar100/),
# this will download dataset from https://www.cs.toronto.edu/~kriz/cifar-100-python.tar.gz
(X, y), (X_test, y_test) = tf.keras.datasets.cifar100.load_data(label_mode="fine") # "fine": the labels of 100 subclasses
print(X.shape, y.shape, X_test.shape, y_test.shape) # The dataset contains 50,000 32x32 color training images and 10,000 test images
数据预处理
将y标签的shape从(50000, 1)改成(50000,),为了与张量(tensor)相匹配。
方法1
# Change the shape of y to (50000,)
y = tf.squeeze(y)
y_test = tf.squeeze(y_test)
print(y.shape)
print(y_test.shape)
type(y)
type(y_test)
# 输出:
# (50000,)
# (10000,)
# tensorflow.python.framework.ops.EagerTensor
方法2
# Change the shape of y to (50000,)
y = y[:,0]
y_test = y_test[:,0]
print(y.shape)
print(y_test.shape)
type(y)
type(y_test)
# 输出:
# (50000,)
# (10000,)
# numpy.ndarray
可能会遇到的问题
两种方法的不同是他们最后生成的数据类型不同,如果使用方法1,在后面拆分训练集和验证集的时候会遇到如下错误:
TypeError: Only integers, slices (:
), ellipsis (...
), tf.newaxis (None
) and scalar tf.int32/tf.int64 tensors are valid indices, got array([36688, 3668, 12964, …, 14020, 49037, 29856])
解决办法
- 使用方法2
- 先拆分训练集和验证集,再将y的shape从(50000,1)变成(50000,)
- 按照这个方法(from_tensor_slices和map),图片来自于B站视频
Normalization和拆分训练集、验证集
# Normalization
X = X.astype('float32')/255.0 # tf.cast(X, dtype=tf.float32)/255.0
X_test = X_test.astype('float32')/255.0
# Split the data into training and validation set
X_train, X_valid, y_train, y_valid = train_test_split(X, y, shuffle=True, random_state=85, test_size=0.1)
print(X_train.shape, y_train.shape, X_valid.shape, y_valid.shape)
One-hot编码
关于one-hot我们有两种选择,
- one-hot编码 (softmax激活函数需要),加上softmax激活函数,加上’categorical_crossentropy’损失函数,VGGNet是采用了这种方法。代码如下:
# Change class labels to binary class matrix
y_train_cate = tf.keras.utils.to_categorical(y_train, 100)
print(y_train_cate.shape)
y_valid_cate = tf.keras.utils.to_categorical(y_valid, 100)
print(y_valid_cate.shape)
y_test_cate = tf.keras.utils.to_categorical(y_test, 100)
print(y_test_cate.shape)
- 不采用one-hot编码,这个时候我们y标签的shape是(50000,1),加上’SparseCategoricalCrossentropy’损失函数,设置参数from_logits=True,来应用softmax激活函数,另一篇博文AlexNet采用这种方法。