Я строю модель Keras, чтобы классифицировать изображения кораллов по видам. Модель работает хорошо, но когда я создал Flask API для доступа к модели, я всегда получал один и тот же ответ. В настоящее время модель различает три разных коралла и хорошо работает при тестировании вне API.
Доминирующий цвет отправляется точно. Я пытался переучить модель, но это не сработало. Когда я переключился на другую бинарную модель, чтобы обнаружить кошку и собаку, она, кажется, работала нормально.
Я тестировал одни и те же изображения на jupyter и отправляя почтовые запросы и получал очень разные ответы. Вот код сервера
import os
from flask import Flask, flash, request, redirect, url_for, jsonify
from werkzeug.utils import secure_filename
import cv2
import numpy as np
import keras
from keras.models import load_model
from keras import backend as K
UPLOAD_FOLDER = './uploads/'
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg'])
DEBUG = True
app = Flask(__name__)
app.config.from_object(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
# if user does not select file, browser also
# submit an empty part without filename
if file.filename == '':
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
image = cv2.imread(os.path.dirname(os.path.realpath(__file__))+"/uploads/"+filename)
color_result = getDominantColor(image)
coral = coraltype(image)
#return redirect(url_for('upload_file',filename=filename)), jsonify({"key":
return jsonify({"MainColor": color_result, "species": coral} )
return '''
<!doctype html>
<title>API</title>
<h1>API Running Successfully</h1>'''
def coraltype(image):
'''Determines if the image contains a cat or dog'''
model = load_model('./models/coral_classifier_cnn_1.h5')
image = cv2.resize(image, (40,40), interpolation = cv2.INTER_AREA)
image = image.reshape(1,40,40,3)
res = model.predict_classes(image, 1, verbose = 0)
print(res)
print(type(res))
res = str(res)
K.clear_session()
return res
def getDominantColor(image):
'''returns the dominate color among Blue, Green and Reds in the image '''
B, G, R = cv2.split(image)
B, G, R = np.sum(B), np.sum(G), np.sum(R)
color_sums = [B,G,R]
color_values = {"0": "Blue", "1":"Green", "2": "Red"}
return color_values[str(np.argmax(color_sums))]
if __name__ == "__main__":
app.run()
Вот модель
from __future__ import print_function
import keras
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.preprocessing.image import ImageDataGenerator
import os
num_classes = 3
img_rows, img_cols = 40, 40
batch_size = 16
train_data_dir = './corals/train'
validation_data_dir = './corals/validation'
train_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=30,
width_shift_range=0.3,
height_shift_range=0.3,
horizontal_flip=True,
fill_mode='nearest')
validation_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_rows, img_cols),
batch_size=batch_size,
class_mode='categorical',
shuffle=True)
validation_generator = validation_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_rows, img_cols),
batch_size=batch_size,
class_mode='categorical',
shuffle=False)
model = Sequential()
# Padding = 'same' results in padding the input such that
# the output has the same length as the original input
model.add(Conv2D(32, (3, 3), padding='same',
input_shape= (img_rows, img_cols, 3)))
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))
from keras.optimizers import RMSprop, SGD
from keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau
checkpoint = ModelCheckpoint("/home/deeplearningcv/DeepLearningCV/Trained Models/coral_classifier_cnn_1.h5",
monitor="val_loss",
mode="min",
save_best_only = True,
verbose=1)
earlystop = EarlyStopping(monitor = 'val_loss',
min_delta = 0,
patience = 3,
verbose = 1,
restore_best_weights = True)
reduce_lr = ReduceLROnPlateau(monitor = 'val_loss',
factor = 0.2,
patience = 3,
verbose = 1,
min_delta = 0.0001)
# we put our call backs into a callback list
callbacks = [earlystop, checkpoint, reduce_lr]
# We use a very small learning rate
model.compile(loss = 'categorical_crossentropy',
optimizer = RMSprop(lr = 0.001),
metrics = ['accuracy'])
nb_train_samples = 793
nb_validation_samples = 42
epochs = 10
history = model.fit_generator(
train_generator,
steps_per_epoch = nb_train_samples,
epochs = epochs,
callbacks = callbacks,
validation_data = validation_generator,
validation_steps = nb_validation_samples)