Первоначально я экспериментировал с tensorflow.keras.datasets.mnist
, но я также столкнулся с этой ловушкой с подмножеством изображений Joost Hazelzet's LE GO Bricks .
Я разделяю набор данных на 3 части: train , val и test . После установки модели на train и val , оценка на test дает высокую точность - то есть обычно более 85%. Однако при сопоставлении с реальными изображениями модель дает худшие предсказания - точность около 50%.
Усложнение моделей - то есть заполнение более плотно связанных и сверточных нейронов и разбрасывание выпадающих элементов - и эмпирически. использование различных оптимизаторов улучшило результаты. Я ожидал, что результаты оценки будут solid, поскольку данные тест должны быть полностью неизвестными ... Теперь не всегда возможно получить дополнительные данные для дополнительных " this-time-it-the-real-one " оценка для большей реалистичности c оценка модели ...
Есть ли у этого явления название? С чем это могло быть связано? Неужели мои собственные чертежи di git, похожие на MNIST, настолько отличаются от данных обучения, что компьютер сбивает с толку - я слышал, что компьютеры не видят так же, как мы? Это случай переобучения, который у меня недостаточно опыта, чтобы его заметить?
Ниже приведен код, который я использовал для обучения моделей на MNIST. Импорт не включен для краткости.
( x_train, y_train ), ( x_test, y_test ) = mnist.load_data()
x_train = x_train / 255.0
x_test = x_test / 255.0
x_train, x_val, y_train, y_val = train_test_split(
x_train,
y_train,
test_size = 10000 / 60000)
На этом этапе набор данных нормализован со значениями от 0.0
до 1.0
и разделен на 3 части:
| Part | .dtype | .shape |
| ---------:|:--------- |:------------- |
| x_train | float64 | (50k, 28, 28) |
| y_train | uint8 | (50k, ) |
| x_val | float64 | (10k, 28, 28) |
| y_val | uint8 | (10k, ) |
| x_test | float64 | (10k, 28, 28) |
| y_test | uint8 | (10k, ) |
Выбор образца просто чтобы доказать, что он рандомизирован:
Here is how I'm building and training my models:
model = Sequential([
Input(( 28, 28 )),
# Reshape(( 28, 28, 1 )),
# Conv2D(32,
# kernel_size = ( 3, 3 ),
# strides = ( 1, 1 ),
# activation = relu,
# kernel_initializer = HeNormal()),
# Conv2D(32,
# kernel_size = ( 3, 3 ),
# strides = ( 1, 1 ),
# activation = relu,
# kernel_initializer = HeNormal()),
# MaxPooling2D(( 2, 2 )),
# SpatialDropout2D(0.30),
# Conv2D(64,
# kernel_size = ( 3, 3 ),
# strides = ( 1, 1 ),
# activation = relu,
# kernel_initializer = HeNormal()),
# Conv2D(64,
# kernel_size = ( 3, 3 ),
# strides = ( 1, 1 ),
# activation = relu,
# kernel_initializer = HeNormal()),
# MaxPooling2D(( 2, 2 )),
# SpatialDropout2D(0.30),
Flatten(),
# Dense(128,
# activation = relu,
# kernel_initializer = HeNormal()),
# Dropout(0.30),
# Dense(128,
# activation = relu,
# kernel_initializer = HeNormal()),
# Dropout(0.30),
Dense(10,
activation = softmax,
kernel_initializer = HeNormal())
])
model.compile(
optimizer = Adam(1 / 1000),
loss = SparseCategoricalCrossentropy(from_logits = False),
metrics = [ SparseCategoricalAccuracy() ])
fitting = model.fit(
x_train, y_train,
validation_data = ( x_val, y_val ),
batch_size = 128,
epochs = 10,
verbose = 0)
accuracy = model.evaluate(
x_test, y_test,
batch_size = 128,
verbose = 0)[1]
Здесь accuracy = model.evaluate(...)
должно быть 92,54%. Ниже представлен график fitting = model.fit(...)
:
The fitting plots of larger Dropout
-full models don't even show the symptoms of overfitting — which, to me, boil down to "train curve above val curve ⇒ overfitting".
I also drew some digits using GIMP, my computer mouse, and my terrible writing:
And I tried to make predictions on them:
x_drawing = Image.open(".../drawing-digits.png")
x_drawing = x_drawing.convert("L")
x_drawing = x_drawing.resize(( 28 * 12, 28))
x_drawing = ImageOps.invert(x_drawing) # Black/White => White/Black
x_drawing = np.asarray(x_drawing)
x_drawing = np.hsplit(x_drawing, 12) # Big image => 1 image/digit
x_drawing = np.array(x_drawing) # List<Array> => Array
x_drawing = x_drawing / 255.0 # 0-255 => 0-1
y_drawing = np.array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2 ])
y_pred = model.predict(x_drawing)
Ниже приведены прогнозы модели; точность на моих рисунках теперь составляет 58,33%, что далеко от 92%, которые у меня были раньше:
Below are the outputs of model.summary()
for 3 configurations.
- The simplest possible: all layers commented above stay commented.
Model: "sequential_17"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
flatten_17 (Flatten) (None, 784) 0
_________________________________________________________________
image_label_probabilities (D (None, 8) 6280
=================================================================
Total params: 6,280
Trainable params: 6,280
Non-trainable params: 0
_________________________________________________________________
- Добавление слоев
Dense
.
Model: "sequential_18"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
flatten_18 (Flatten) (None, 784) 0
_________________________________________________________________
dense_18 (Dense) (None, 128) 100480
_________________________________________________________________
dropout_18 (Dropout) (None, 128) 0
_________________________________________________________________
dense_19 (Dense) (None, 128) 16512
_________________________________________________________________
dropout_19 (Dropout) (None, 128) 0
_________________________________________________________________
image_label_probabilities (D (None, 8) 1032
=================================================================
Total params: 118,024
Trainable params: 118,024
Non-trainable params: 0
_________________________________________________________________
Добавление сверток.
Model: "sequential_19"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
reshape (Reshape) (None, 28, 28, 1) 0
_________________________________________________________________
conv2d_30 (Conv2D) (None, 26, 26, 32) 320
_________________________________________________________________
conv2d_31 (Conv2D) (None, 24, 24, 32) 9248
_________________________________________________________________
max_pooling2d_19 (MaxPooling (None, 12, 12, 32) 0
_________________________________________________________________
spatial_dropout2d_19 (Spatia (None, 12, 12, 32) 0
_________________________________________________________________
conv2d_32 (Conv2D) (None, 10, 10, 64) 18496
_________________________________________________________________
conv2d_33 (Conv2D) (None, 8, 8, 64) 36928
_________________________________________________________________
max_pooling2d_20 (MaxPooling (None, 4, 4, 64) 0
_________________________________________________________________
spatial_dropout2d_20 (Spatia (None, 4, 4, 64) 0
_________________________________________________________________
flatten_19 (Flatten) (None, 1024) 0
_________________________________________________________________
dense_20 (Dense) (None, 128) 131200
_________________________________________________________________
dropout_20 (Dropout) (None, 128) 0
_________________________________________________________________
dense_21 (Dense) (None, 128) 16512
_________________________________________________________________
dropout_21 (Dropout) (None, 128) 0
_________________________________________________________________
image_label_probabilities (D (None, 8) 1032
=================================================================
Total params: 213,736
Trainable params: 213,736
Non-trainable params: 0
_________________________________________________________________