In [1]:
import numpy as np
from keras.datasets import cifar10
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.optimizers import SGD
from keras.utils import np_utils
Using TensorFlow backend.
In [10]:
import keras
keras.__version__
Out[10]:
'2.0.5'
In [2]:
np.random.seed(42)
In [3]:
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
Downloading data from http://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz
170475520/170498071 [============================>.] - ETA: 0s   
In [16]:
# Размер мини-выборки
batch_size = 32
# Количество классов изображений
nb_classes = 10
# Количество эпох для обучения
num_epochs = 25
# Размер изображений
img_rows, img_cols = 32, 32
# Количество каналов в изображении: RGB
img_channels = 3
In [5]:
# Нормализация данных
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255

# Преобразуем метки в категории
y_train = np_utils.to_categorical(y_train, 10)
y_test = np_utils.to_categorical(y_test, 10)
In [8]:
# Создаем последовательную модель
model = Sequential()
# Первый сверточный слой
model.add(Conv2D(32, (3, 3), padding='same',
                        input_shape=(32, 32, 3), activation='relu'))
# Второй сверточный слой
model.add(Conv2D(32, (3, 3), activation='relu', padding='same'))
# Первый слой подвыборки
model.add(MaxPooling2D(pool_size=(2, 2)))
# Слой регуляризации Dropout
model.add(Dropout(0.25))

# Третий сверточный слой
model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
# Четвертый сверточный слой
model.add(Conv2D(64, (3, 3), activation='relu'))
# Второй слой подвыборки
model.add(MaxPooling2D(pool_size=(2, 2)))
# Слой регуляризации Dropout
model.add(Dropout(0.25))
# Слой преобразования данных из 2D представления в плоское
model.add(Flatten())
# Полносвязный слой для классификации
model.add(Dense(512, activation='relu'))
# Слой регуляризации Dropout
model.add(Dropout(0.5))
# Выходной полносвязный слой
model.add(Dense(nb_classes, activation='softmax'))
In [11]:
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
In [12]:
model.compile(loss='categorical_crossentropy',
              optimizer=sgd,
              metrics=['accuracy'])
In [13]:
from keras.callbacks import EarlyStopping  
early_stopping = EarlyStopping(monitor='loss')
In [14]:
from keras.callbacks import TensorBoard  
tensorboard = TensorBoard(log_dir='../logs/', write_graph=True)
In [17]:
%%time
model.fit(X_train, y_train,
          batch_size=batch_size,
          epochs=num_epochs,
          validation_split=0.1,
          shuffle=True,
          callbacks=[early_stopping, tensorboard],
          verbose=2)
Train on 45000 samples, validate on 5000 samples
Epoch 1/25
186s - loss: 1.6817 - acc: 0.3863 - val_loss: 1.2919 - val_acc: 0.5244
Epoch 2/25
190s - loss: 1.2907 - acc: 0.5369 - val_loss: 1.0549 - val_acc: 0.6302
Epoch 3/25
187s - loss: 1.1104 - acc: 0.6044 - val_loss: 0.9113 - val_acc: 0.6802
Epoch 4/25
181s - loss: 0.9996 - acc: 0.6460 - val_loss: 0.8370 - val_acc: 0.7126
Epoch 5/25
187s - loss: 0.9135 - acc: 0.6783 - val_loss: 0.7974 - val_acc: 0.7258
Epoch 6/25
190s - loss: 0.8592 - acc: 0.7000 - val_loss: 0.7935 - val_acc: 0.7272
Epoch 7/25
187s - loss: 0.8066 - acc: 0.7155 - val_loss: 0.7299 - val_acc: 0.7538
Epoch 8/25
187s - loss: 0.7678 - acc: 0.7306 - val_loss: 0.7629 - val_acc: 0.7398
Epoch 9/25
180s - loss: 0.7349 - acc: 0.7421 - val_loss: 0.7220 - val_acc: 0.7516
Epoch 10/25
187s - loss: 0.7092 - acc: 0.7503 - val_loss: 0.7223 - val_acc: 0.7548
Epoch 11/25
186s - loss: 0.6891 - acc: 0.7573 - val_loss: 0.7220 - val_acc: 0.7512
Epoch 12/25
181s - loss: 0.6643 - acc: 0.7653 - val_loss: 0.6828 - val_acc: 0.7708
Epoch 13/25
186s - loss: 0.6438 - acc: 0.7764 - val_loss: 0.7645 - val_acc: 0.7454
Epoch 14/25
182s - loss: 0.6295 - acc: 0.7793 - val_loss: 0.6794 - val_acc: 0.7662
Epoch 15/25
184s - loss: 0.6142 - acc: 0.7858 - val_loss: 0.7221 - val_acc: 0.7634
Epoch 16/25
185s - loss: 0.6121 - acc: 0.7865 - val_loss: 0.7092 - val_acc: 0.7620
Epoch 17/25
182s - loss: 0.5958 - acc: 0.7943 - val_loss: 0.7016 - val_acc: 0.7624
Epoch 18/25
190s - loss: 0.5815 - acc: 0.7978 - val_loss: 0.7340 - val_acc: 0.7546
Epoch 19/25
188s - loss: 0.5724 - acc: 0.8005 - val_loss: 0.6546 - val_acc: 0.7826
Epoch 20/25
183s - loss: 0.5694 - acc: 0.8015 - val_loss: 0.6828 - val_acc: 0.7786
Epoch 21/25
193s - loss: 0.5579 - acc: 0.8078 - val_loss: 0.6692 - val_acc: 0.7770
Epoch 22/25
185s - loss: 0.5540 - acc: 0.8085 - val_loss: 0.6567 - val_acc: 0.7852
Epoch 23/25
190s - loss: 0.5465 - acc: 0.8101 - val_loss: 0.7125 - val_acc: 0.7760
Epoch 24/25
181s - loss: 0.5364 - acc: 0.8152 - val_loss: 0.7574 - val_acc: 0.7554
Epoch 25/25
176s - loss: 0.5310 - acc: 0.8172 - val_loss: 0.6811 - val_acc: 0.7726
CPU times: user 9h 33min 52s, sys: 2h 36min 25s, total: 12h 10min 17s
Wall time: 1h 17min 29s
Out[17]:
<keras.callbacks.History at 0x7ff4d33a5290>
In [18]:
model_json = model.to_json()
with open("cifar_cnn_model.json", "w") as json_file:
    json_file.write(model_json)
model.save_weights("cifar_cnn_model.h5")
In [21]:
%%time
scores = model.evaluate(X_test, y_test, verbose=2)
print("Доля верных ответов на тестовых данных: %.2f%%" % (scores[1]*100))
Доля верных ответов на тестовых данных: 75.89%
CPU times: user 1min 22s, sys: 19.3 s, total: 1min 42s
Wall time: 16.3 s