tensorflow2.3实现多输出模型

tensorflow2.3实现多输出模型

对服装数据进行类别和颜色分类,称为多输出模型。
/black_jeans,/black_shoes,/blue_dress,/blue_jeans,/blue_shirt,/red_dress,/red_shirt,共3种颜色,4个类别。
导入包

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import random
import glob
import IPython.display as display

查看tensorflow的版本

print('Tensorflow version: {}'.format(tf.__version__))
Tensorflow version: 2.3

读取数据:

all_images = glob.glob('./dataset/*/*')
all_images_count = len(all_images)
print(len(all_images))
print(all_images[:5])

数据的数量和前5个数据

2525
['./dataset/black_jeans/00000364.jpeg', 
'./dataset/black_jeans/00000204.jpeg', 
'./dataset/black_jeans/00000169.png', 
'./dataset/black_jeans/00000241.jpg', '
./dataset/black_jeans/00000145.jpg']

数据预处理
先建立两个集合,类别结合和颜色集合

color_labels_names = set(p.split('/')[2].split('_')[0] for p in all_images)
item_labels_names = set(p.split('/')[2].split('_')[1] for p in all_images)
print(color_labels_names)
print(item_labels_names)

集合一3种颜色,集合二4个类别

{'red', 'black', 'blue'}
{'dress', 'jeans', 'shoes', 'shirt'}

两个集合数据进行编码

color_labels_to_index = dict((name,index) for index, name in enumerate(color_labels_names))
item_labels_to_index = dict((name,index) for index, name in enumerate(item_labels_names))
print(color_labels_to_index)
print(item_labels_to_index)
{'red': 0, 'black': 1, 'blue': 2}
{'dress': 0, 'jeans': 1, 'shoes': 2, 'shirt': 3}

前五个数据的类别和颜色

all_images_labels = sorted([p.split('/')[2] for p in all_images])
print(all_images_labels[:5])
['black_jeans', 'black_jeans', 'black_jeans', 'black_jeans', 'black_jeans']

把"black_jeans" 这种类别和颜色分开处理
颜色标签和数量

color_labels = [color_labels_to_index[label.split('_')[0]] for label in all_images_labels]
print(color_labels[:5])
print(len(color_labels))
[1, 1, 1, 1, 1]
2525

类别标签和数量

item_labels = [item_labels_to_index[item.split('_')[1]] for item in all_images_labels]
print(item_labels[:5])
print(len(item_labels))
[1, 1, 1, 1, 1]
2525

自定义一个函数,完成图片的读取,解码,形状变化,类型变化,标准化

def load_image(path):
    image = tf.io.read_file(path)
    image = tf.image.decode_jpeg(image, channels=3)
    image = tf.image.resize(image, [224, 224])
    image = tf.cast(image, tf.float32)
    image = image/255.0
    image = 2 * image - 1
    return image

利用tf.data模块构建dataset

image_dataset = tf.data.Dataset.from_tensor_slices(all_images)
AUTOTUNE = tf.data.experimental.AUTOTUNE

AUTOTUNE 根据计算机cpu个数自动进行计算
image_dataset map到自定义函数上。

image_dataset = image_dataset.map(load_image, num_parallel_calls=AUTOTUNE)

利用tf.data模块构建label_dataset ,把颜色和类别构造到一个dataset中

label_dataset = tf.data.Dataset.from_tensor_slices((color_labels, item_labels))
print(image_label_dataset)

查看label_dataset中的元素

for ele in label_dataset.take(3):
    print(ele[0].numpy(), ele[1].numpy())
0 2
0 2
0 2

构造数据集,把图片和label ZIP在一起

image_label_dataset = tf.data.Dataset.zip((image_dataset, label_dataset))
print(image_label_dataset)

设置训练数据和测试数据的数量

test_count = int(all_images_count * 0.2)
train_count = all_images_count - test_count

划分训练集和测试集

train_dataset = image_label_dataset.skip(test_count)
test_dataset = image_label_dataset.take(test_count)

设置每批次输入的数据量大小

BATCHSIZE = 32

设置训练和测试输入模式

train_dataset = train_dataset.shuffle(buffer_size=train_count).repeat().batch(BATCHSIZE)
train_dataset = train_dataset.prefetch(buffer_size=AUTOTUNE)#电脑根据内存预先读取数据等待训练
test_dataset = test_dataset.batch(BATCHSIZE)
print(train_dataset)
print(test_dataset)


加载MobileNetV2预训练网络参数,设置训练参数不可训练

mobile_net = tf.keras.applications.MobileNetV2(input_shape=(224, 224, 3), include_top=False, weights='imagenet')
mobile_net.trainable = False
mobile_net.summary()

模型的输入

inputs = tf.keras.Input(shape=(224, 224, 3))
x = mobile_net(inputs)
print(x.get_shape())     #mobile_net输出的形状
x = tf.keras.layers.GlobalAveragePooling2D()(x)
print(x.get_shape())#mobile_net输出是4维,所以在全连接输出前要使用GlobalAveragePooling2D
(None, 7, 7, 1280)
(None, 1280)

构建模型的输出,因为是要类别和颜色分别预测,所以有两个输出

x1 = tf.keras.layers.Dense(1024, activation='relu')(x)
out_color = tf.keras.layers.Dense(len(color_labels_names), activation='softmax', name='out_color')(x1)
x2 = tf.keras.layers.Dense(1024, activation='relu')(x)
out_item = tf.keras.layers.Dense(len(item_labels_names), activation='softmax', name='out_item')(x2)
model = tf.keras.Model(inputs=inputs, outputs=[out_color, out_item])
model.summary()

模型编译

model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.0001),
              loss={
     'out_color': 'sparse_categorical_crossentropy', 'out_item': 'sparse_categorical_crossentropy'},
              metrics=['acc'])

设置训练批次

train_steps = train_count//BATCHSIZE
test_steps = test_count//BATCHSIZE

模型训练

model.fit(train_dataset, epochs=5, steps_per_epoch=train_steps, validation_data=test_dataset, validation_steps=test_steps)

模型评估

print(model.evaluate(test_dataset)) #输出5个指标
my_image = load_image(r'./dataset/blue_jeans/00000001.jpeg')
print(my_image.shape)
my_image = tf.expand_dims(my_image, 0)#因为训练的时候是以batch的形式输入的,所以要维度扩张
print(my_image.shape)
pred = model.predict(my_image)
print(pred)
print(np.argmax(pred[1]))
[4.383560657501221, 0.25813135504722595, 4.125428676605225, 0.908910870552063, 0.31881189346313477]
(224, 224, 3)
(1, 224, 224, 3)
[array[[0.00171686, 0.00872022,0.98965629, ]],dtype=float32),
array[[ 3.9509824e-04,9.9927169e-01 , 3.298579e-04,3.3366025e-6]],dtype=float32)]
1
```{'red': 0, 'black': 1, 'blue': 2}
{'dress': 0, 'jeans': 1, 'shoes': 2, 'shirt': 3}

多分类输出,pred输出的是两个维度,第一维度pred[0]是颜色长度为3,0.98965629这个概率最大处在第三位,所以预测颜色是blue,第二维度pred[1]是类别, 9.9927169e-01,预测类别的概率最大值是99%,为jeans。

你可能感兴趣的:(tensorflow,深度学习,人工智能)