keras-多标签分类

51 篇文章 2 订阅
28 篇文章 0 订阅
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from keras.layers.core import Dense,Activation,Dropout,Flatten
from keras.layers.advanced_activations import PReLU
from keras.layers.convolutional import Convolution2D,MaxPooling2D
from keras.optimizers import SGD,Adadelta,Adagrad
from keras.utils import np_utils,generic_utils
import random
np.random.seed(1024)
from PIL import Image
from keras.models import Sequential
import time
from keras.layers import LSTM
import math
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
from keras import optimizers
import os
from keras.preprocessing.image import ImageDataGenerator
from keras import backend as K
from keras.models import Sequential
from keras.layers.normalization import BatchNormalization
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.core import Activation
from keras.layers.core import Flatten
from keras.layers.core import Dropout
from keras.layers.core import Dense
from keras import backend as K

class SmallerVGGNet:
    @staticmethod
    def build(width,height,depth,classes,finalAct="softmax"):
        #initialize the model along with the input shape to be channels last and the channels dimension itself
        model = Sequential()
        inputShape = (height,width,depth)
        chanDim = -1
        #if we are using "channel first",update the input shape and channels dimension
        if K.image_data_format()=='channels_first':
            inputShape = (depth,height,width)
            chanDim = 1
            # CONV => RELU => POOL
            model.add(Conv2D(32, (3, 3), padding="same",
                             input_shape=inputShape))
            model.add(Activation("relu"))
            model.add(BatchNormalization(axis=chanDim))
            model.add(MaxPooling2D(pool_size=(3, 3)))
            model.add(Dropout(0.25))
            # (CONV => RELU) * 2 => POOL
            model.add(Conv2D(64, (3, 3), padding="same"))
            model.add(Activation("relu"))
            model.add(BatchNormalization(axis=chanDim))
            model.add(Conv2D(64, (3, 3), padding="same"))
            model.add(Activation("relu"))
            model.add(BatchNormalization(axis=chanDim))
            model.add(MaxPooling2D(pool_size=(2, 2)))
            model.add(Dropout(0.25))

            # (CONV => RELU) * 2 => POOL
            model.add(Conv2D(128, (3, 3), padding="same"))
            model.add(Activation("relu"))
            model.add(BatchNormalization(axis=chanDim))
            model.add(Conv2D(128, (3, 3), padding="same"))
            model.add(Activation("relu"))
            model.add(BatchNormalization(axis=chanDim))
            model.add(MaxPooling2D(pool_size=(2, 2)))
            model.add(Dropout(0.25))
            # first (and only) set of FC => RELU layers
            model.add(Flatten())
            model.add(Dense(1024))
            model.add(Activation("relu"))
            model.add(BatchNormalization())
            model.add(Dropout(0.5))

            # use a *softmax* activation for single-label classification
            # and *sigmoid* activation for multi-label classification
            model.add(Dense(classes))
            model.add(Activation(finalAct))

            # return the constructed network architecture
            return model




from keras.preprocessing.image import ImageDataGenerator
from keras.optimizers import Adam
from keras.preprocessing.image import img_to_array
from sklearn.preprocessing import MultiLabelBinarizer
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
from imutils import paths
import numpy as np
import argparse
import random
import pickle
import cv2
import os


# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True,
	help="path to input dataset (i.e., directory of images)")
ap.add_argument("-m", "--model", required=True,
	help="path to output model")
ap.add_argument("-l", "--labelbin", required=True,
	help="path to output label binarizer")
ap.add_argument("-p", "--plot", type=str, default="plot.png",
	help="path to output accuracy/loss plot")
args = vars(ap.parse_args())


'''
--dataset : The path to our dataset.
--model : The path to our output #serialized Keras model.
--labelbin : The path to our output multi-label binarizer object.
--plot : The path to our output plot of training loss and accuracy.
'''

#intialize the number of epochs to train for,intial learning rate,batch size and image dimensions
epochs = 75
init_lr = 1e-3
bs = 32
image_dims = (96,96,3)

#grab the image pths and randomly shuffle them
print("[Info] loading images...")
imagePaths = sorted(list(paths.list_images(args["dataset"])))
random.seed(42)
random.shuffle(imagePaths)

#initizlize the data and labels
data = []
labels = []

#loop over the input images
for imagePath in imagePaths:
    #load the image ,pre-proces it and store it in the data list
    image = cv2.imread(imagePath)
    image = cv2.resize(image,(image_dims[1],image_dims[0]))
    image = img_to_array(image)
    data.append(image)

#scale the raw pixel intensities to the range[0,1

data = np.array(data,dtype="float")/255.0
labels = np.array(labels)
print("[Info] data matrix:{} images(:.2f)MB".format(len(imagePaths),data.nbytes/(1024*1000.0)))

#二值化标签
print("[Info] class labels:")
mlb = MultiLabelBinarizer()
labels = mlb.fit_transform(labels)

#loop over each of the possible class labels and show them
for (i,label) in enumerate(mlb.classes_):
    print("{}.{}".format(i+1,label))


(trainX, testX, trainY, testY) = train_test_split(data,
	labels, test_size=0.2, random_state=42)

#图像增强
aug = ImageDataGenerator(rotation_range=25,width_shift_range=0.1,height_shift_range=0.1,shear_range=0.2,zoom_range=0.2,horizontal_flip=True,fill_mode="nearest")

#接下来就是建立模型了
#initialize the model using a sigmoid activation as the final layer in the network so we can perform multi-label classification
print("[Info] compilig model...")
model = SmallerVGGNet.build(width=image_dims[1],height=image_dims[0],depth=image_dims[2],classes=len(mlb.classes_),finalAct="sigmoid")

#初始化优化器
opt = Adam(lr=init_lr,decay=init_lr/epochs)


# compile the model using binary cross-entropy rather than
# categorical cross-entropy -- this may seem counterintuitive for
# multi-label classification, but keep in mind that the goal here
# is to treat each output label as an independent Bernoulli
# distribution
model.compile(loss="binary_crossentropy", optimizer=opt,
	metrics=["accuracy"])

#train the network
print("[Info] training network...")
H = model.fit_generator(aug.flow(trainX,trainY,batch_size=bs,validation_data=(testX,testY),steps_per_epoch=len(trainX)//bs,epochs=epochs,verbose=1))

#保存模型
print("[Info] serializing network...")

model.save(args["model"])

# save the multi-label binarizer to disk
print("[INFO] serializing label binarizer...")
f = open(args["labelbin"], "wb")
f.write(pickle.dumps(mlb))
f.close()

# plot the training loss and accuracy
plt.style.use("ggplot")
plt.figure()
N = epochs
plt.plot(np.arange(0, N), H.history["loss"], label="train_loss")
plt.plot(np.arange(0, N), H.history["val_loss"], label="val_loss")
plt.plot(np.arange(0, N), H.history["acc"], label="train_acc")
plt.plot(np.arange(0, N), H.history["val_acc"], label="val_acc")
plt.title("Training Loss and Accuracy")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend(loc="upper left")
plt.savefig(args["plot"])



'''
python GenderTrain.py --dataset dataset --model fashion.model --labelbin mlb.pickle
'''
# -*- coding: utf-8 -*-
"""
Created on 2019/5/25 17:00
@Author: Johnson
@Email:593956670@qq.com
@File: 3-classify.py
"""
from keras.preprocessing.image import img_to_array
from keras.models import load_model
import numpy as np
import argparse
import imutils
import pickle
import cv2
import os


#constuct the argument parse and parse the arguments

ap = argparse.ArgumentParser()
ap.add_argument("-m","--model",required=True,help="path to trained model model")
ap.add_argument("-l","--labelbin",required=True,help="path to label binarizer")
ap.add_argument("-i","--image",required=True,help="path to input image")

args = vars(ap.parse_args())

#load the image
image = cv2.imread(args["image"])
output = imutils.resize(image,width=400)

#pre-process the image for classification
image = cv2.resize(image,(96,96))
image = image.astype("float")/255.0
image = img_to_array(image)
image = np.expand_dims(image,axis=0)

#load the trained network and the multi-label
print("[Info] loading network...")
model = load_model(args["model"])
mlb = pickle.load(open(args["labelbin"],"rb").read())

#classify the input image then find the indexex of the two class
proba = model.predict(image)[0]
idxs = np.argsort(proba)[::-1][:2]

#loop over the indexes of the high confidence class labels
for (i,j) in enumerate(idxs):
    #build the lable and draw the label on the image
    label = "{}:{:.2f}%".format(mlb.class_[j],proba[j]*100)
    cv2.putText(output,label,(10,(0*30)+25),cv2.FONT_HERSHEY_SIMPLEX,0.7,(0,255,0),2)

# show the probabilities for each of the individual labels
for (label, p) in zip(mlb.classes_, proba):
    print("{}: {:.2f}%".format(label, p * 100))

# show the output image
cv2.imshow("Output", output)
cv2.waitKey(0)


'''
python classify.py --model fashion.model --labelbin mlb.pickle \
	--image examples/example_01.jpg
'''
Keras 是一个基于 Python 的深度学习库,可以帮助我们快速构建和训练神经网络模型。在 Keras 中,多标签分类是指一个样本可以同时属于多个类别,而不仅仅属于一个类别。 要实现多标签分类,我们首先需要准备好包含多个标签的数据集。每个样本都会有一个对应的标签集,标签集中的每个元素代表一个类别。例如,一个图像分类问题中,一张图片可能同时包含猫、狗和树的标签。 在 Keras 中,我们可以使用多种神经网络模型来进行多标签分类,例如多层感知器(MLP)、卷积神经网络(CNN)或循环神经网络(RNN)等。选择合适的模型取决于具体的问题和数据集。接下来,我们需要定义模型的结构。 使用 Keras,我们可以使用 Sequential 或 Functional API 来定义模型。在定义模型的过程中,我们可以添加各种层(如全连接层、卷积层、池化层等),并设置每层的参数和激活函数。最后,我们使用 compile 方法来配置模型。在模型编译的过程中,我们需要选择适当的损失函数和优化器,通常在多标签分类问题中我们使用二分类的交叉熵作为损失函数。 在训练模型之前,我们还需要将数据集划分为训练集和测试集。使用 fit 方法,我们可以指定训练集的输入特征和对应的标签集,并设置批次大小和训练轮数,以及验证集的数据。 在模型进行训练之后,我们可以使用 evaluate 方法评估模型在测试集上的性能。同时,我们还可以使用 predict 方法对新样本进行预测,并得到预测的标签。 总结来说,Keras 是一个用于构建深度学习模型的强大工具,可以很方便地实现多标签分类。通过准备好数据集、定义模型结构、编译模型、训练模型和评估模型的步骤,我们可以快速构建并训练一个适用于多标签分类问题的神经网络模型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值