您对华为云开发者网站的整体评价?

非常不满意 非常满意

0

1

2

3

4

5

6

7

8

9

10

*您遇到了哪些问题?(最多选三项)
*您感到满意的原因是?(最多选三项)
*请针对您所遇到的问题给出具体的反馈
200/200

Notebook
猪只关键点检测模型训练与转换
MobileNetV2
HouYanSong
13个月以前
0KB 154 6
  • 许可证类型 ? CC0: Public Domain
  • 标签
    计算机视觉关键点检测TensorFlow
  • 资产ID 92f1be97-5d46-4ec3-abd6-5097862fc542

描述

猪只关键点检测模型训练与转换

1. 模型训练

🔹 本案例需使用 P100 及以上规格运行,请确保运行规格一致,可按照下图切换规格。

🔹 点击Run in ModelArts,将会进入到ModelArts CodeLab中,这时需要你登录华为云账号,如果没有账号,则需要注册一个,且要进行实名认证,参考《ModelArts准备工作_简易版》 即可完成账号注册和实名认证。 登录之后,等待片刻,即可进入到CodeLab的运行环境

🔹 出现 Out Of Memory ,请检查是否为您的参数配置过高导致,修改参数配置,重启kernel或更换更高规格资源进行规避❗❗❗

准备环境

!pip install tensorflow==2.1.0
import os
import cv2
import glob
import random
import numpy as np
import moxing as mox
from tqdm import tqdm
import tensorflow as tf
import matplotlib.pyplot as plt
%matplotlib inline
!pip install h5py==2.10.0 protobuf==3.20.2
print('Tensorflow version: {}'.format(tf.__version__))
print('GPU available: {}'.format(tf.config.list_physical_devices('GPU')))
Tensorflow version: 2.1.0
GPU available: [PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]

下载资源

if not os.path.exists('datasets'):
    mox.file.copy_parallel('obs://houyansong/datasets', 'datasets')
    
if not os.path.exists('/home/ma-user/work/mobilenet_v2_weights_tf_dim_ordering_tf_kernels_1.0_224_no_top.h5'):
    mox.file.copy('obs://houyansong/mobilenet_v2_weights_tf_dim_ordering_tf_kernels_1.0_224_no_top.h5', 
                  '/home/ma-user/work/mobilenet_v2_weights_tf_dim_ordering_tf_kernels_1.0_224_no_top.h5')
    
if not os.path.exists("/home/ma-user/.keras/models"):
    os.makedirs("/home/ma-user/.keras/models") 
    
!cp /home/ma-user/work/mobilenet_v2_weights_tf_dim_ordering_tf_kernels_1.0_224_no_top.h5 /home/ma-user/.keras/models/

创建数据输入管道

imgs = glob.glob('datasets/img/*.jpg')
txts = glob.glob('datasets/txt/*.txt')

imgs.sort(key=lambda x: x.split('/')[-1])
txts.sort(key=lambda x: x.split('/')[-1])

index = np.random.permutation(len(imgs))

imgs = np.array(imgs)[index]
txts = np.array(txts)[index]

imgs.tolist()[:5], len(imgs), txts.tolist()[:5], len(txts)

数据预处理

labels = []

def to_labels(img, txt):
    label = []
    img = cv2.imread(img)
    h, w = img.shape[0], img.shape[1]
    with open(txt, 'r') as f:
        points_list = [t.strip() for t in f.readlines()]
        keypoint_features = np.array(points_list).reshape(-1, 2)
        for x, y in keypoint_features:
            label.append(int(x) / w)
            label.append(int(y) / h)
            
    return label
for i in tqdm(range(len(imgs)), desc='Processing'):
    label = to_labels(imgs[i], txts[i])
    labels.append(label)
Processing: 100%|██████████| 11140/11140 [00:07<00:00, 1445.16it/s]
def read_jpg(image):
    image = tf.io.read_file(image)
    image = tf.image.decode_jpeg(image, channels=1)
    
    return image
def image_enhance(image, label):
    if tf.random.uniform(()) > 0.5:
        image = tf.image.flip_up_down(image)
        image = tf.image.flip_left_right(image)
        label = 1 - label
        
    return image, label
def normalize(image, label):
    image = tf.cast(image, tf.float32) / 255
    label = tf.cast(label, tf.float32)
    
    return image, label
@tf.function
def load_image(image, label):
    image = read_jpg(image)
    image = tf.image.resize(image, (224, 224))
    image, label = image_enhance(image, label)
    image, label = normalize(image, label)
    image = tf.image.random_brightness(image, 0.5)

    return image, label

Dataset

AUTOTUNE = tf.data.experimental.AUTOTUNE
dataset = tf.data.Dataset.from_tensor_slices((imgs, labels))
dataset = dataset.map(load_image, num_parallel_calls = AUTOTUNE)
dataset
<ParallelMapDataset shapes: ((224, 224, 1), (30,)), types: (tf.float32, tf.float32)>
test_count = int(len(imgs) * 0.2)
train_count = len(imgs) - test_count
train_count, test_count
(8912, 2228)
dataset_train = dataset.skip(test_count)
dataset_test = dataset.take(test_count)
BATCH_SIZE = 32
BUFFER_SIZE = 1000

STEPS_PER_EPOCH = train_count // BATCH_SIZE
VALIDATION_STEPS = test_count // BATCH_SIZE
train_dataset = dataset_train.shuffle(BUFFER_SIZE).batch(BATCH_SIZE).prefetch(buffer_size = AUTOTUNE).repeat()
test_dataset = dataset_test.batch(BATCH_SIZE)
train_dataset, test_dataset
(<RepeatDataset shapes: ((None, 224, 224, 1), (None, 30)), types: (tf.float32, tf.float32)>,
 <BatchDataset shapes: ((None, 224, 224, 1), (None, 30)), types: (tf.float32, tf.float32)>)
for image_batch, label_batch in train_dataset.take(1):
    plt.figure(figsize=(20, 10))
    for index in range(BATCH_SIZE):
        plt.subplot(4, 8, index + 1)
        plt.imshow((image_batch[index].numpy() + 1) / 2, cmap='gray')
        points_list = label_batch[index]
        points = points_list.numpy() * 224
        x_l = []
        y_l = []
        for x, y in points.reshape(-1, 2):
            x_l.append(x)
            y_l.append(y)
        plt.scatter(x_l, y_l, s=10, c='yellow')
        plt.axis('off')

搭建模型

conv_base = tf.keras.applications.MobileNetV2(input_shape=(224, 224, 3), include_top=False, weights='imagenet')
conv_base.summary()
inputs = tf.keras.Input(shape=(224, 224, 1))

x = tf.keras.layers.Conv2D(3, (1, 1), padding='same')(inputs)
x = conv_base(x)
x = tf.keras.layers.GlobalAveragePooling2D()(x)
x = tf.keras.layers.Dense(1024, activation='relu')(x)
x = tf.keras.layers.Dropout(0.1)(x)
x = tf.keras.layers.Dense(512, activation='relu')(x)
x = tf.keras.layers.Dropout(0.1)(x)

outputs = tf.keras.layers.Dense(30)(x)
model = tf.keras.Model(inputs=inputs, outputs=outputs)
model.summary()

模型编译

model.compile(optimizer = tf.keras.optimizers.Adam(learning_rate = 1e-4), 
              loss = 'mse',
              metrics = ['mae'])
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau

# 定期存储
checkpointer = ModelCheckpoint(filepath = 'best.hdf5', monitor='val_mae', verbose=1, save_best_only=True, mode='min')
# 提前终止
earlyStopping = EarlyStopping(monitor='loss', patience=30, mode='min',baseline=None)
# 减少learning rate
rlp = ReduceLROnPlateau(monitor='val_loss', factor=0.7, patience=5, min_lr=1e-15, mode='min', verbose=1)

开始训练

EPOCHS = 200
history = model.fit(train_dataset, 
                    epochs = EPOCHS,
                    steps_per_epoch = STEPS_PER_EPOCH,
                    validation_steps = VALIDATION_STEPS,
                    validation_data = test_dataset,
                    callbacks = [checkpointer, earlyStopping, rlp])
Train for 278 steps, validate for 69 steps
Epoch 1/200
2024-01-21 06:30:04.299650: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcublas.so.10
2024-01-21 06:30:04.936029: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudnn.so.7

查看结果

plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(history.epoch, history.history['loss'], 'r', label='loss')
plt.plot(history.epoch, history.history['val_loss'], 'b--', label='val_loss')
plt.title('MobielNetV2')
plt.xlabel('Epoch')
plt.ylabel('MSE')
plt.legend()

plt.subplot(1, 2, 2)
plt.plot(history.epoch, history.history['mae'], 'r', label='mae')
plt.plot(history.epoch, history.history['val_mae'], 'b--', label='val_mae')
plt.title('MobielNetV2')
plt.xlabel('Epoch')
plt.ylabel('MAE')
plt.legend()
<matplotlib.legend.Legend at 0x7f8ba00a8d10>
model = tf.keras.models.load_model('best.hdf5')
model.save('saved_model')
2024-01-21 08:51:57.583251: W tensorflow/python/util/util.cc:319] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
WARNING:tensorflow:From /home/ma-user/anaconda3/envs/TensorFlow-2.1/lib/python3.7/site-packages/tensorflow_core/python/ops/resource_variable_ops.py:1786: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.
INFO:tensorflow:Assets written to: saved_model/assets
model.evaluate(test_dataset)
70/70 [==============================] - 3s 43ms/step - loss: 5.3249e-05 - mae: 0.0058
[5.324874515021553e-05, 0.0057931826]

2. 模型转换

TensorFlow --> ONNX

!pip install keras2onnx
import keras2onnx
output_model_path = 'mbv2_pig.onnx'
onnx_model = keras2onnx.convert_keras(model, model.name, target_opset = 12)
keras2onnx.save_model(onnx_model, output_model_path) 

TensorFlow --> TFLite

converter = tf.lite.TFLiteConverter.from_saved_model('saved_model')
tflite_model = converter.convert()

with open('mbv2_pig.tflite', 'wb') as f:
  f.write(tflite_model)

TFLite --> RKNN

names = ["rknn_toolkit2-1.4.0_22dcfef4-cp36-cp36m-linux_x86_64.whl", "tqdm-4.64.0-py2.py3-none-any.whl"]
for name in names:
    if not os.path.exists(name):
        mox.file.copy(f'obs://modelarts-labs-bj4-v2/course/ModelBox/datasets/{name}', name)
!/home/ma-user/anaconda3/bin/conda create -n py36 python=3.6.10 -y --override-channels --channel https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
!/home/ma-user/anaconda3/envs/py36/bin/pip install ipykernel
import json
import os

data = {
   "display_name": "Python36",
   "env": {
      "PATH": "/home/ma-user/anaconda3/envs/py36/bin:/home/ma-user/anaconda3/envs/python-3.7.10/bin:/modelarts/authoring/notebook-conda/bin:/opt/conda/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/ma-user/modelarts/ma-cli/bin:/home/ma-user/modelarts/ma-cli/bin:/home/ma-user/anaconda3/envs/PyTorch-1.4/bin"
   },
   "language": "python",
   "argv": [
      "/home/ma-user/anaconda3/envs/py36/bin/python",
      "-m",
      "ipykernel",
      "-f",
      "{connection_file}"
   ]
}

if not os.path.exists("/home/ma-user/anaconda3/share/jupyter/kernels/py36/"):
    os.mkdir("/home/ma-user/anaconda3/share/jupyter/kernels/py36/")

with open('/home/ma-user/anaconda3/share/jupyter/kernels/py36/kernel.json', 'w') as f:
    json.dump(data, f, indent=4)
!python -V
Python 3.6.10 :: Anaconda, Inc.
!pip install tqdm-4.64.0-py2.py3-none-any.whl
!pip install numpy
!pip install rknn_toolkit2-1.4.0_22dcfef4-cp36-cp36m-linux_x86_64.whl
!pip show rknn-toolkit2
import glob
import numpy as np

images = glob.glob('datasets/img/*.jpg')

index = np.random.permutation(len(images))

images = np.array(images)[index]

images.tolist()[:5]
['datasets/img/2512.jpg',
 'datasets/img/437.jpg',
 'datasets/img/3309.jpg',
 'datasets/img/6229.jpg',
 'datasets/img/10039.jpg']
f = open('dataset.txt', 'w')

for i in range(100):
    out_path = images[i]
    f.write(out_path+'\n')
    print(out_path)
    
f.close()
%%python

from rknn.api import RKNN

rknn = RKNN(verbose=False)

print('--> Config model')
rknn.config(mean_values=[[0.]], std_values=[[255.]], target_platform="rk3568")
print('done')

print('--> Loading model')
ret = rknn.load_tflite(model='mbv2_pig.tflite')
if ret != 0:
    print('Load failed!')
    exit(ret)
print('done')

print('--> Building model')
ret = rknn.build(do_quantization=True, dataset='dataset.txt')
if ret != 0:
    print('Build failed!')
    exit(ret)
print('done')

print('--> Accuracy analysis')
ret = rknn.accuracy_analysis(inputs=['datasets/img/2512.jpg'])
if ret!=0:
    print('Accuracy analysis failed!')
    exit(ret)
print('done')

print('--> Export RKNN model')
ret = rknn.export_rknn('mbv2_pig.rknn')
if ret != 0:
    print('Export failed!')
    exit(ret)
print('done')

rknn.release()

模型转换验证结束,下载对应模型即可。

交付

华为云ModelArts

华北-北京四

限制

公开

版本

版本号
版本ID
发布时间
发布状态
版本说明
1.0.0
AVXtF6
2024-01-21 01:02
已完成
--

关联资产

  • 猪只关键点检测数据集

    MobileNetV2

    数据集
    0 0 79 3 1

    13个月以前

若您怀疑合法知识产权遭受侵犯,可以通过此链接进行投诉与建议。