- 1、数据采集
这是数据集的目录,里面放着各类衣服图片。
下面是这个工程的目录。
- 2.编写代码
mydata_provider.py:这个是数据处理,将数据编程模型想要的格式。
import numpy as np
import os
from PIL import Image
from sklearn.model_selection import train_test_split
label_index = {'yurongfu':7,'maozi': 6, 'weiyi': 5, 'waitao': 4, 'chenshan': 3, 'kuzi': 2, 'qunzi': 1, 'duanxiu': 0};
def loadsample(filename_path, train_x_shape):
# (220, 220, 3)
img = Image.open(filename_path).convert("RGB")
# print(train_x_shape[0], train_x_shape[1], train_x_shape[2], train_x_shape[3]) 17670 32 32 3
img = img.resize((train_x_shape[1], train_x_shape[2]), Image.ANTIALIAS)
img = np.array(img)
if img.shape != tuple(train_x_shape[1:]):
print(img.shape, filename_path)
# print("filename_path:", filename_path)
filename_path_split = filename_path.split("/")
# print("filename_path_split:", filename_path_split)['..', 'data', 'kuzi', 'img_02024.jpg']
segment = filename_path_split[-2]
label = label_index[segment]
return (img, label)
def load_data(datadir, input_shape, rate = 0.95):
num_train_examples = 17670 # 样本的总数量
examples = []
classNums_dict = {}
train_x_shape = (num_train_examples, ) + input_shape
train_y_shape = (num_train_examples, )
# print("train_x_shape:", train_x_shape)
# print("train_y_shape:", train_y_shape)
train_x = np.empty(train_x_shape, dtype = "uint8") # 这是训练集的train_x
train_y = np.empty(train_y_shape, dtype = "uint8") # 这是训练集train_y
print("train_x_shape:", train_x_shape)
print("train_y_shape:", train_y_shape)
# 遍历所有文件,加入到train_x,train_y中。
samples_index = 0
dir_list = os.listdir(datadir)
# print("dir_list:", dir_list) dir_list: ['chenshan', 'kuzi', 'waitao',
count = 0
for dir in dir_list:
# print("dir:", dir)
classNums_dict[dir] = 0
classPath = os.path.join(datadir, dir)
# print("classPath:", classPath) classPath: ../data/maozi
classNums_dict[dir] = 0
if os.path.exists(classPath):
filename_list = os.listdir(classPath)
# print("filename_list:", filename_list)
# print("len(filename_list)",len(filename_list))
for filename in filename_list:
# 这里获取标签和样本
if filename.endswith(".jpg"):
filename_path = os.path.join(classPath, filename)
# print("filename_path:", filename_path)
count = count + 1
print("count:", count)
classNums_dict[dir] = classNums_dict[dir] + 1
(img, label) = loadsample(filename_path, train_x_shape)
train_x[samples_index] = img
train_y[samples_index] = label
samples_index = samples_index + 1
# test 2
examples.append((img, label))
else:
print("不存在目录:", (classPath))
train_y = np.reshape(train_y, (len(train_y), 1))
print(len(train_x), len(train_y))
print("class distrubtion:", classNums_dict)
train_x, test_x, train_y,test_y = train_test_split(train_x, train_y, test_size = 1 - rate, stratify = train_y)
print('part-train-%d,part-test-%d;total:%d'%(len(train_x),len(test_x),len(train_x)+len(test_x)));
return train_x, train_y, test_x, test_y
if __name__ == "__main__":
datadir = "../data"
print("datadir:", datadir)
load_data(datadir, input_shape = (224, 224, 3))
model.py 这是网络:AleNet,VGG19
from keras.layers import Input
from keras.layers import Conv2D, MaxPool2D, Dense, Flatten, Dropout, Lambda
from keras.models import Model
from keras import optimizers
from keras.utils import plot_model
from keras import backend as K
# VGG16
import tensorflow as tf
from keras import Model, Sequential
from keras.layers import Flatten, Dense, Conv2D, GlobalAveragePooling2D
from keras.layers import Input, MaxPooling2D, GlobalMaxPooling2D
def VGG16(input_shape=(224,224,3), nclass=8):
input_ = Input(shape=input_shape)
# block1
x = Conv2D(64, (3, 3), activation = "relu", padding = "same", name = "block1_conv1")(input_)
x = Conv2D(64, (3, 3), activation = "relu", padding = "same", name = "block1_conv2")(x)
x = MaxPooling2D((2,2), strides = (2, 2), name="block1_pool")(x)
# block2
x = Conv2D(128, (3, 3),activation="relu",padding="same", name="block2_conv1")(x)
x = Conv2D(128, (3, 3),activation ="relu", padding ="same", name = "block2_conv2")(x)
x = MaxPooling2D((2,2), strides=(2,2), name="block2_pool")(x)
# block3
x = Conv2D(256,(3,3), activation="relu",padding="same", name="block3_conv1")(x)
x = Conv2D(256,(3,3),activation="relu",padding="same",name="block3_conv2")(x)
x = Conv2D(256,(3,3),activation="relu", padding="same", name="block3_conv3")(x)
x = MaxPooling2D((2,2),strides=(2,2), name = "block3_pool")(x)
# block4
x = Conv2D(512,(3,3),activation="relu",padding="same",name="block4_conv1")(x)
x = Conv2D(512,(3,3),activation="relu",padding="same",name="block4_conv2")(x)
x = Conv2D(512,(3,3),activation="relu",padding="same",name="block4_conv3")(x)
x = MaxPooling2D((2,2), strides=(2,2),name="block4_pool")(x)
# block5
x = Conv2D(512,(3,3),activation="relu",padding="same", name="block5_conv1")(x)
x = Conv2D(512,(3,3),activation="relu",padding="same",name="block5_conv2")(x)
x = Conv2D(512,(3,3),activation="relu",padding="same",name="block5_conv3")(x)
x = MaxPooling2D((2,2), strides=(2,2),name="block5_pool")(x)
#Classification block
x = Flatten(name = 'flatten')(x)
x = Dense(4096,activation = 'relu',name = 'fc1')(x)
x = Dropout(0.5)(x)
x = Dense(4096,activation = 'relu',name = 'fc2')(x)
x = Dropout(0.5)(x)
output_ = Dense(nclass, activation = 'softmax',name = 'fc3')(x)
model = Model(inputs=input_, outputs=output_)
model.summary()
opti_sgd = optimizers.sgd(lr=0.01, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=opti_sgd, metrics=['accuracy'])
return model
def LRN(alpha=1e-4, k=2, beta=0.75, n=5):
"""
LRN for cross channel normalization in the original Alexnet
parameters default as original paper.
"""
def f(X):
b, r, c, ch = X.shape
half = n // 2
square = K.square(X)
extra_channels = K.spatial_2d_padding(square, ((0, 0), (half, half)), data_format='channels_first')
scale = k
for i in range(n):
scale += alpha * extra_channels[:,:,:,i:i+int(ch)]
scale = scale ** beta
return X / scale
return Lambda(f, output_shape=lambda input_shape: input_shape)
def alexnet(input_shape=(224,224,3), nclass=8):
"""
build Alexnet model using keras with TensorFlow backend.
:param input_shape: input shape of network, default as (224,224,3)
:param nclass: numbers of class(output shape of network), default as 1000
:return: Alexnet model
"""
# conv1
input_ = Input(shape=input_shape)
x = Conv2D(96, kernel_size=(11, 11), strides=(4, 4), activation='relu')(input_)
x = LRN()(x)
x = MaxPool2D(pool_size=(3, 3), strides=(2, 2))(x)
# conv2
x = Conv2D(256, kernel_size=(5, 5), strides=(1, 1), activation='relu', padding='same')(x)
x = LRN()(x)
x = MaxPool2D(pool_size=(3, 3), strides=(2, 2))(x)
# conv3
x = Conv2D(384, kernel_size=(3, 3), strides=(1, 1), activation='relu', padding='same')(x)
# conv4
x = Conv2D(384, kernel_size=(3, 3), strides=(1, 1), activation='relu', padding='same')(x)
# conv5
x = Conv2D(256, kernel_size=(3, 3), strides=(1, 1), activation='relu', padding='same')(x)
x = MaxPool2D(pool_size=(3, 3), strides=(2, 2))(x)
x = Flatten()(x)
# fc6
x = Dense(4096, activation='relu')(x)
x = Dropout(0.5)(x)
# fc7
x = Dense(4096, activation='relu')(x)
x = Dropout(0.5)(x)
# fc8
output_ = Dense(nclass, activation='softmax')(x)
model = Model(inputs=input_, outputs= output_)
model.summary()
opti_sgd = optimizers.sgd(lr=0.01, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=opti_sgd, metrics=['accuracy'])
return model
if __name__ == "__main__":
model = alexnet()
plot_model(model, "Alexnet.png", show_shapes=True)# 保存模型图
train.py:这个是训练
import tensorflow as tf
import numpy as np
import keras
from mydata_provider import load_data
from mymodel import alexnet
def train():
num_classes = 8
batchsize = 64
epochs = 20
input_shape = (224, 224, 3)
dir_root = "../data"
save_path = "../model.h5"
train_x, train_y, test_x, test_y = load_data(dir_root, input_shape=input_shape)
train_y = keras.utils.to_categorical(train_y, num_classes)
test_y = keras.utils.to_categorical(test_y, num_classes)
train_x = train_x.astype("float32")
test_x = test_x.astype("float32")
train_x = train_x / 255.0
test_x = test_x / 255.0
model = alexnet(input_shape, num_classes)
model.summary()
History = model.fit(train_x, train_y, batch_size=batchsize,epochs=epochs, validation_data = (train_x, train_y), shuffle = True)
print("History-Train:", History, History.history)
metrics = model.evaluate(test_x, test_y)
print("metrics:", metrics)
# 保存模型
model.save(save_path)
if __name__ == "__main__":
train()
myinference.py这是预测
import os
import tensorflow as tf
import numpy as np
from PIL import Image
import tensorflow.keras as keras
from tensorflow.keras.models import load_model
from tensorflow.keras.utils import plot_model
index_label = {1:'短袖',2:'裙子',3:'裤子',4:'衬衫',5:'外套',6:'卫衣',7:'帽子',8:'羽绒服'}
# 进行预测
def inference(path, model_path, visual=False):
# load model
if not os.path.exists(model_path):
print("No model is here:%s, try again~"%(model_path))
model = load_model(model_path)
if visual:
model_plot = "./model.png"
plot_model(model, to_file=model_plot, show_shapes=True)
# 判断路径是目录还是路径
if os.path.isdir(path):
print("Direc:%s\n(only infer 4 imgs...)"%(path))
fileName_list = os.listdir(path)
img_paths = []
results = []
img_count = 0
for fileName in fileName_list:
if fileName.endswith(".jpg"):
img_paths.append(os.path.join(path, fileName))
img_count = img_count + 1
x_predict = np.empty((img_count, 224, 224, 3), dtype="float32")
for index in range(img_count):
img = Image.open(img_paths[index]).convert('RGB')
img = img.resize((224, 224), Image.ANTIALIAS)
img = np.array(img)
img = img / 255
x_predict[index] = img
y_predict = model.predict(x_predict)
print("Inference:")
for index in range(img_count):
res = np.argmax(y_predict[index]) + 1
results.append(index_label[res])
print(img_paths[index],'-->',results[index]);
else:
print("File:%s\n"%(path))
if path.endswith(".jpg"):
x_pre = np.empty((1, 224, 224, 3), dtype="float32")
img = Image.open(path).convert("RGB")
img = img / 255.0
x_pre[0] = img
y_pre = model.predict(x_pre)
res = np.argmax(y_pre[0] + 1)
print("单张预测res:\n %s -> %s"%(path, index_label[res]))
else:
print("just for jpg")
if __name__ == "__main__":
print("--Inference--")
# path = input("Please Input a path(相对路径):\n")
path = "../someimgs"
inference(path, "../model.h5")