昨天我们介绍了 Shuffle 这支 API 的使用方式,其中特别提到了如果今天资料集本身没有先打散的话,你後面再做 shuffle 时,如果 batch size 不等於整个资料数量的话,就不是打的非常散,基於此问题,今天我们用 mnist 来实验若资料没有事前打乱,单纯只靠 shuffle API 是否能有成效?
样本一,我们使用 tfds 提供的 mnist,要初始化非常简单。
ds_data, ds_info = tfds.load(
'mnist',
shuffle_files=False,
as_supervised=True,
with_info=True,
)
train_split, test_split = ds_data['train'], ds_data['test']
fig = tfds.show_examples(train_split, ds_info)
fig.show()
由於 tfds 所提供的资料集都已将资料打散了,为了要重现整齐的 mnist,我选择重新下载 mnist 来处理。
!wget http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz .
!wget http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz .
!wget http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz .
!wget http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz .
我们用 numpy 的 argsort 来排序资料。
idx = np.argsort(train_labels)
train_labels_sorted = train_labels[idx]
train_images_sorted = train_images[idx]
idx = np.argsort(test_labels)
test_labels_sorted = test_labels[idx]
test_images_sorted = test_images[idx]
我们印出 label 前20个元素,可以看到都是0,而图片也画出0。
print(test_labels_sorted[:20])
image = np.asarray(test_images_sorted[0]).squeeze()
plt.imshow(image)
plt.show()
接着就可以开始我们的实验,实验一,正常有打散的 mnist
model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(32, [3, 3], activation='relu', input_shape=(28,28,1)))
model.add(tf.keras.layers.Conv2D(64, [3, 3], activation='relu'))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
model.add(tf.keras.layers.Dropout(0.25))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(10))
model.compile(
optimizer=tf.keras.optimizers.SGD(LR),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=[tf.keras.metrics.SparseCategoricalAccuracy()],
)
history = model.fit(
ds_train_tf, # 打散的ds
epochs=EPOCHS,
validation_data=ds_test_tf, # 打散的ds
)
产出:
loss: 0.0473 - sparse_categorical_accuracy: 0.9850 - val_loss: 0.0314 - val_sparse_categorical_accuracy: 0.9901
看来我们建立的模型对於学习 mnist 错错有余,验证集的 loss 比训练值还低,验证集准确度也上升的比训练集快,代表模型不用一个 epoch 的时间就能学得很好。
实验二,label 照顺序的 mnist。
model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(32, [3, 3], activation='relu', input_shape=(28,28,1)))
model.add(tf.keras.layers.Conv2D(64, [3, 3], activation='relu'))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
model.add(tf.keras.layers.Dropout(0.25))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(10))
model.compile(
optimizer=tf.keras.optimizers.SGD(LR),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=[tf.keras.metrics.SparseCategoricalAccuracy()],
)
history = model.fit(
ds_train_m, # 照顺序的ds
epochs=EPOCHS,
validation_data=ds_test_m, # 照顺序的s
)
产出:
loss: 0.0631 - sparse_categorical_accuracy: 0.9845 - val_loss: 5.9616 - val_sparse_categorical_accuracy: 0.2695
非常诡异的图,在第一个 epoch 前,训练集 accuracy 接近100%,但是验证集准确度却非常低,为什麽会这样子呢?我自己的想像是我训练模型时,一个 epoch 假设有100个题目,但是前10题答案都是0,後面10题答案都是1,依序下去...
那模型会在前面就被训练成只要回答0就会对的懒惰模型,中间虽然答案变成1有诱发模型去学习1的特徵,但是回打没几题後发现反正答案都是1,又变回懒惰模型,所以整体模型要学会数字1~9的效率会非常差,这也就导致了这次实验模型学不太起来的窘境,而且即使套用了 shuffle 也没起色!
Step 1.add textbox 2.import js 3.bind textbox &...
万事起头难 平常的学习方式都是遇到问题才去学、上哪门课学什麽、对哪个主题有兴趣才去学,现在想要有组织...
上一篇所说到的textItem 仅能回答一行 若想要出问答题、申论题等 就要使用能回答多行的Para...
上一篇:[C 语言笔记--Day01] Hello World 大纲 什麽是 memory hier...
该文章同步发布於:我的部落格 什麽是表徵测试以及解决的问题是什麽? 假如我遇到一段想重构的代码,但...