Типичный день в нейрокурятнике — куры часто еще и крутятся в гнезде
Чтобы довести, наконец, проект нейрокурятника до своего логического завершения, нужно произвести на свет работающую модель и задеплоить ее на продакшен, да еще и так, чтобы соблюдался ряд условий:
Layer (type) Output Shape Param #
=================================================================
batch_normalization_1 (Batch (None, 700, 400, 3) 2800
_________________________________________________________________
conv2d_1 (Conv2D) (None, 698, 398, 32) 896
_________________________________________________________________
batch_normalization_2 (Batch (None, 698, 398, 32) 2792
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 232, 132, 32) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 230, 130, 64) 18496
_________________________________________________________________
batch_normalization_3 (Batch (None, 230, 130, 64) 920
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 76, 43, 64) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 209152) 0
_________________________________________________________________
dense_1 (Dense) (None, 200) 41830600
_________________________________________________________________
batch_normalization_4 (Batch (None, 200) 800
_________________________________________________________________
dense_2 (Dense) (None, 8) 1608
=================================================================
Total params: 41,858,912
Trainable params: 41,855,256
Non-trainable params: 3,656
_________________________________________________________________
genImage = imageGeneratorSugar(
featurewise_center = False,
samplewise_center = False,
featurewise_std_normalization = False,
samplewise_std_normalization = False,
rotation_range = 90,
width_shift_range = 0.05,
height_shift_range = 0.05,
shear_range = 0.2,
zoom_range = 0.2,
fill_mode='constant',
cval=0.,
horizontal_flip=False,
vertical_flip=False)
def getTestModelNormalize(inputShapeTuple, classNumber):
model = Sequential([
BatchNormalization(axis=1, input_shape = inputShapeTuple),
Convolution2D(32, (3,3), activation='relu'),
BatchNormalization(axis=1),
MaxPooling2D((3,3)),
Convolution2D(64, (3,3), activation='relu'),
BatchNormalization(axis=1),
MaxPooling2D((3,3)),
Flatten(),
Dense(200, activation='relu'),
BatchNormalization(),
Dense(classNumber, activation='softmax')
])
model.compile(Adam(lr=1e-4), loss='categorical_crossentropy', metrics=['accuracy'])
return model
# let's try a model w dropout!
def getTestModelNormalizeDropout(inputShapeTuple, classNumber):
model = Sequential([
BatchNormalization(axis=1, input_shape = inputShapeTuple),
Convolution2D(32, (3,3), activation='relu'),
BatchNormalization(axis=1),
Dropout(rate=0.3),
MaxPooling2D((3,3)),
Convolution2D(64, (3,3), activation='relu'),
BatchNormalization(axis=1),
Dropout(rate=0.1),
MaxPooling2D((3,3)),
Flatten(),
Dense(200, activation='relu'),
BatchNormalization(),
Dense(classNumber, activation='softmax')
])
model.compile(Adam(lr=1e-4), loss='categorical_crossentropy', metrics=['accuracy'])
return model
42/42 [==============================] - 87s - loss: 2.4055 - acc: 0.2783 - val_loss: 4.7899 - val_acc: 0.1771
Epoch 2/15
42/42 [==============================] - 90s - loss: 1.7039 - acc: 0.4049 - val_loss: 2.4489 - val_acc: 0.2011
Epoch 3/15
42/42 [==============================] - 90s - loss: 1.4435 - acc: 0.4827 - val_loss: 2.1080 - val_acc: 0.2402
Epoch 4/15
42/42 [==============================] - 90s - loss: 1.2525 - acc: 0.5311 - val_loss: 2.4556 - val_acc: 0.2179
Epoch 5/15
42/42 [==============================] - 85s - loss: 1.2024 - acc: 0.5549 - val_loss: 2.2180 - val_acc: 0.1955
Epoch 6/15
42/42 [==============================] - 84s - loss: 1.0820 - acc: 0.5858 - val_loss: 1.8620 - val_acc: 0.2849
Epoch 7/15
42/42 [==============================] - 84s - loss: 0.9475 - acc: 0.6535 - val_loss: 2.1256 - val_acc: 0.1955
Epoch 8/15
42/42 [==============================] - 84s - loss: 0.9283 - acc: 0.6665 - val_loss: 1.2578 - val_acc: 0.5642
Epoch 9/15
42/42 [==============================] - 84s - loss: 0.9238 - acc: 0.6792 - val_loss: 1.1639 - val_acc: 0.5698
Epoch 10/15
42/42 [==============================] - 84s - loss: 0.8451 - acc: 0.6963 - val_loss: 1.4899 - val_acc: 0.4581
Epoch 11/15
42/42 [==============================] - 84s - loss: 0.8026 - acc: 0.7183 - val_loss: 0.9561 - val_acc: 0.6480
Epoch 12/15
42/42 [==============================] - 84s - loss: 0.8353 - acc: 0.7064 - val_loss: 1.0533 - val_acc: 0.6145
Epoch 13/15
42/42 [==============================] - 84s - loss: 0.7687 - acc: 0.7380 - val_loss: 0.9039 - val_acc: 0.6760
Epoch 14/15
42/42 [==============================] - 84s - loss: 0.7683 - acc: 0.7287 - val_loss: 1.0038 - val_acc: 0.6704
Epoch 15/15
42/42 [==============================] - 84s - loss: 0.7076 - acc: 0.7451 - val_loss: 0.8953 - val_acc: 0.7039
# Mix iterator class for pseudo-labelling
class MixIterator(object):
def __init__(self, iters):
self.iters = iters
self.multi = type(iters) is list
if self.multi:
self.N = sum([it[0].N for it in self.iters])
else:
self.N = sum([it.N for it in self.iters])
def reset(self):
for it in self.iters: it.reset()
def __iter__(self):
return self
def next(self, *args, **kwargs):
if self.multi:
nexts = [[next(it) for it in o] for o in self.iters]
n0s = np.concatenate([n[0] for n in o])
n1s = np.concatenate([n[1] for n in o])
return (n0, n1)
else:
nexts = [next(it) for it in self.iters]
n0 = np.concatenate([n[0] for n in nexts])
n1 = np.concatenate([n[1] for n in nexts])
return (n0, n1)
mi = MixIterator([batches, test_batches, val_batches)
bn_model.fit_generator(mi, mi.N, nb_epoch=8, validation_data=(conv_val_feat, val_labels))
# dependencies
import numpy as np
import keras.models
from keras.models import model_from_json
from scipy.misc import imread, imresize,imshow
import tensorflow as tf?
?
In [3]:
def init(model_file,weights_file):
json_file = open(model_file,'r')
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
#load woeights into new model
loaded_model.load_weights(weights_file)
print("Loaded Model from disk")
#compile and evaluate loaded model
loaded_model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
#loss,accuracy = model.evaluate(X_test,y_test)
#print('loss:', loss)
#print('accuracy:', accuracy)
graph = tf.get_default_graph()
?
return loaded_model,graph
?
loaded_model,graph = init('model.json','model7_20_epochs.h5')
?
In [4]:
def predict(img_file, model):
# here you should read the image
img = imread(img_file,mode='RGB')
img = imresize(img,(400,800))
#convert to a 4D tensor to feed into our model
img = img.reshape(1,400,800,3)
# print ("debug2")
#in our computation graph
with graph.as_default():
#perform the prediction
out = model.predict(img)
print(out)
print(np.argmax(out,axis=1))
# print ("debug3")
#convert the response to a string
response = (np.argmax(out,axis=1))
return response
In [6]:
chick_dict = {0: 'back_spot',
1: 'beauty',
2: 'dirty',
3: 'egg',
4: 'empty',
5: 'light_back',
6: 'ordinary',
7: 'psycho',
8: 'red_star',
9: 'red_twin',
10: 'young_long'}
?
In [7]:
prediction = predict('test.jpg',loaded_model)
print (chick_dict[prediction[0]])
[[ 2.34186242e-04 5.02209296e-04 5.61403576e-04 9.51264706e-03
2.03147720e-04 1.70257801e-04 4.71635815e-03 5.06504579e-03
1.84403792e-01 7.92831838e-01 1.79908809e-03]]
Out [9]
red_twin
In [11]:
import matplotlib.pyplot as plt
img = imread('test.jpg',mode='RGB')
plt.imshow(img)
plt.show()
К сожалению, не доступен сервер mySQL