作者|Nouman
编译|VK
起源|Towards Data Science

在这篇文章中,我将教你建设你本人的网页应用程序,它将承受你的狗的图片,并输入其种类。准确率超过80%!

咱们将应用深度学习来训练一个模型的数据集的狗图像与他们的种类,以学习的特色来辨别每一个种类。


数据分析

数据集能够从这里下载(https://s3-us-west-1.amazonaw...)。在胜利加载和浏览数据集后,以下是对于数据的一些介绍:

  1. 犬种总数:133
  2. 狗图片总数:8351(训练集:6680,验证集:835,测试集:836)
  3. 最受欢迎的种类:阿拉斯加:96,博德牧羊犬:93

按图片数量排序的前30个种类如下:

咱们还能够在这里看到一些狗的图片和它们的种类:


数据预处理

通过剖析,为机器学习算法筹备数据。咱们将把每个图像作为一个numpy数组加载,并将它们的大小调整为224x224,因为这是大多数传统神经网络承受图像的默认大小。咱们还将为图像的数量增加另一个维度

from keras.preprocessing import image                  from tqdm import tqdmdef path_to_tensor(img_path):    '''将给定门路下的图像转换为张量'''    img = image.load_img(img_path, target_size=(224, 224))    x = image.img_to_array(img)    return np.expand_dims(x, axis=0)def paths_to_tensor(img_paths):    '''将给定门路中的所有图像转换为张量'''    list_of_tensors = [path_to_tensor(img_path) for img_path in tqdm(img_paths)]    return np.vstack(list_of_tensors)

最初,咱们将应用ImageDataGenerator对图像进行动静缩放和加强

train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255,                                                horizontal_flip=True,                                                vertical_flip=True,                                                rotation_range=20)valid_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255.)test_datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255.)train_generator = train_datagen.flow(train_tensors, train_targets, batch_size=32)valid_generator = train_datagen.flow(valid_tensors, valid_targets, batch_size=32)test_generator = train_datagen.flow(test_tensors, test_targets, batch_size=32)

CNN

咱们将在预处理数据集上从头开始训练卷积神经网络(CNN),如下所示:

model = tf.keras.models.Sequential([    tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(224, 224, 3)),    tf.keras.layers.MaxPooling2D(2, 2),    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),    tf.keras.layers.MaxPooling2D(2,2),    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),    tf.keras.layers.MaxPooling2D(2,2),    tf.keras.layers.Conv2D(128, (3,3), activation='relu'),    tf.keras.layers.MaxPooling2D(2,2),    tf.keras.layers.Conv2D(256, (3,3), activation='relu'),    tf.keras.layers.MaxPooling2D(2,2),    tf.keras.layers.Flatten(),    tf.keras.layers.Dense(2048, activation='softmax'),    tf.keras.layers.Dropout(0.5),    tf.keras.layers.Dense(1024, activation='softmax'),    tf.keras.layers.Dropout(0.5),    tf.keras.layers.Dense(133, activation='softmax')])model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])checkpointer = tf.keras.callbacks.ModelCheckpoint(filepath='../saved_models/weights_best_custom.hdf5',                                verbose=1, save_best_only=True)model.fit(train_generator, epochs=5, validation_data=valid_generator, callbacks=[checkpointer])

咱们应用一个ModelCheckpoint回调来保留基于验证分数的模型。测试这个模型,咱们失去的准确率只有1%左右


应用迁徙学习

当初,咱们将看到如何应用预训练的特色能够产生微小的不同。下载ResNet-50。你能够通过运行上面的代码单元来提取相应的训练集、测试和验证集:

bottleneck_features = np.load('Data/bottleneck_features/DogResnet50Data.npz')train_Resnet50 = bottleneck_features['train']valid_Resnet50 = bottleneck_features['valid']test_Resnet50 = bottleneck_features['test']

咱们当初将再次定义模型,并对提取的特色应用GlobalAveragePooling2D,它将一组特色均匀为一个值。最初,如果验证损失在两个间断的epoch内没有减少,咱们应用额定的回调来升高学习率,升高平台,并且如果验证损失在间断的5个epoch内没有减少,也能够提前进行训练。

Resnet50_model = tf.keras.models.Sequential()Resnet50_model.add(tf.keras.layers.GlobalAveragePooling2D(input_shape=train_Resnet50.shape[1:]))Resnet50_model.add(tf.keras.layers.Dense(1024, activation='relu'))Resnet50_model.add(tf.keras.layers.Dense(133, activation='softmax'))Resnet50_model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])checkpointer = tf.keras.callbacks.ModelCheckpoint(filepath='saved_models/weights_best_Resnet50.hdf5',                                verbose=1, save_best_only=True)early_stopping = tf.keras.callbacks.EarlyStopping(patience=5, monitor='val_loss')reduce_lr = tf.keras.callbacks.ReduceLROnPlateau(patience=2, monitor='val_loss')Resnet50_model.fit(train_Resnet50, train_targets,           validation_data=(valid_Resnet50, valid_targets),          epochs=50, batch_size=20, callbacks=[checkpointer, early_stopping, reduce_lr], verbose=1)### 训练模型

在测试集上的准确率为82.65%。与咱们白手起家训练的模型相比,这是一个微小的提高。


构建web应用程序

对于web应用程序,咱们将首先编写一个helper函数,该函数承受图像门路并返回种类。label_to_cat字典将每个数字标签映射到它的狗种类。

def predict_breed(img_path):    '''预测给定图像的种类'''    # 提取特色    bottleneck_feature = extract_Resnet50(path_to_tensor(img_path))    bottleneck_feature = tf.keras.models.Sequential([                            tf.keras.layers.GlobalAveragePooling2D(input_shape=bottleneck_feature.shape[1:])                        ]).predict(bottleneck_feature).reshape(1, 1, 1, 2048)    # 取得预测向量    predicted_vector = Resnet50_model.predict(bottleneck_feature)    # 模型预测的犬种    return label_to_cat[np.argmax(predicted_vector)]

对于web应用程序,咱们将应用flaskweb框架来帮忙咱们用起码的代码创立web应用程序。咱们将定义一个承受图像的路由,并用狗的种类出现一个输入模板

@app.route('/upload', methods=['POST','GET'])def upload_file():    if request.method == 'GET':        return render_template('index.html')    else:        file = request.files['image']        full_name = os.path.join(UPLOAD_FOLDER, file.filename)        file.save(full_name)        dog_breed = dog_breed_classifier(full_name)    return render_template('predict.html', image_file_name = file.filename, label = dog_breed)

predict.html是别离显示图像及其犬种的模板。


论断

恭喜 你!你曾经胜利地实现了一个狗种类分类器,并且能够自信地分辨出狗的种类。让咱们总结一下咱们在这里学到的:

  1. 咱们对数据集进行了剖析和预处理。机器学习算法须要独自的训练集、测试集和验证集来进行相信预测。
  2. 咱们从零开始应用CNN,因为未能提取特色,所以体现不佳。
  3. 而后咱们应用迁徙学习,准确度大大提高
  4. 最初,咱们构建了一个Flask web应用程序来筹备咱们的我的项目产品

咱们的确学到了很多货色,但还有很多其余的事件你能够尝试。你能够在heroku上部署web应用程序,也能够尝试应用不同的层(如Dropout层)来进步准确性。

要取得更多信息和详细分析,请查看我的GitHub上的代码:https://github.com/nouman-10/...

原文链接:https://towardsdatascience.co...

欢送关注磐创AI博客站:
http://panchuang.net/

sklearn机器学习中文官网文档:
http://sklearn123.com/

欢送关注磐创博客资源汇总站:
http://docs.panchuang.net/